tblswvs 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/es5/helpers.d.ts +8 -0
- package/lib/es5/helpers.js +50 -0
- package/lib/es5/helpers.js.map +1 -0
- package/lib/es5/index.d.ts +8 -0
- package/lib/es5/index.js +25 -0
- package/lib/es5/index.js.map +1 -0
- package/lib/es5/key.d.ts +21 -0
- package/lib/es5/key.js +178 -0
- package/lib/es5/key.js.map +1 -0
- package/lib/es5/lindenmayer_system.d.ts +62 -0
- package/lib/es5/lindenmayer_system.js +94 -0
- package/lib/es5/lindenmayer_system.js.map +1 -0
- package/lib/es5/markov_chain.d.ts +8 -0
- package/lib/es5/markov_chain.js +28 -0
- package/lib/es5/markov_chain.js.map +1 -0
- package/lib/es5/melodic_vector.d.ts +29 -0
- package/lib/es5/melodic_vector.js +49 -0
- package/lib/es5/melodic_vector.js.map +1 -0
- package/lib/es5/melody.d.ts +106 -0
- package/lib/es5/melody.js +199 -0
- package/lib/es5/melody.js.map +1 -0
- package/lib/es5/mode.d.ts +33 -0
- package/lib/es5/mode.js +98 -0
- package/lib/es5/mode.js.map +1 -0
- package/lib/es5/note_data.d.ts +22 -0
- package/lib/es5/note_data.js +693 -0
- package/lib/es5/note_data.js.map +1 -0
- package/lib/es5/rhythm.d.ts +31 -0
- package/lib/es5/rhythm.js +68 -0
- package/lib/es5/rhythm.js.map +1 -0
- package/lib/es5/sequence.d.ts +3 -0
- package/lib/es5/sequence.js +3 -0
- package/lib/es5/sequence.js.map +1 -0
- package/lib/es5/tblswvs_error.d.ts +3 -0
- package/lib/es5/tblswvs_error.js +12 -0
- package/lib/es5/tblswvs_error.js.map +1 -0
- package/lib/es5/transformation.d.ts +4 -0
- package/lib/es5/transformation.js +3 -0
- package/lib/es5/transformation.js.map +1 -0
- package/lib/es6/helpers.js +43 -0
- package/lib/es6/helpers.js.map +1 -0
- package/lib/es6/index.js +9 -0
- package/lib/es6/index.js.map +1 -0
- package/lib/es6/key.js +174 -0
- package/lib/es6/key.js.map +1 -0
- package/lib/es6/lindenmayer_system.js +90 -0
- package/lib/es6/lindenmayer_system.js.map +1 -0
- package/lib/es6/markov_chain.js +24 -0
- package/lib/es6/markov_chain.js.map +1 -0
- package/lib/es6/melodic_vector.js +45 -0
- package/lib/es6/melodic_vector.js.map +1 -0
- package/lib/es6/melody.js +195 -0
- package/lib/es6/melody.js.map +1 -0
- package/lib/es6/mode.js +94 -0
- package/lib/es6/mode.js.map +1 -0
- package/lib/es6/note_data.js +690 -0
- package/lib/es6/note_data.js.map +1 -0
- package/lib/es6/rhythm.js +64 -0
- package/lib/es6/rhythm.js.map +1 -0
- package/lib/es6/sequence.js +2 -0
- package/lib/es6/sequence.js.map +1 -0
- package/lib/es6/tblswvs_error.js +8 -0
- package/lib/es6/tblswvs_error.js.map +1 -0
- package/lib/es6/transformation.js +2 -0
- package/lib/es6/transformation.js.map +1 -0
- package/package.json +23 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare const INCOMPATIBLE_SEQ_MSG: string;
|
|
2
|
+
export declare const NON_INTEGER_INPUTS = "Numbers must be integers";
|
|
3
|
+
export declare const SELF_SIMILARITY_REQUIRES_COPRIMES: string;
|
|
4
|
+
export declare const SCALE_DEGREE_ERROR = "Scale degrees must be negative or positive, but not 0";
|
|
5
|
+
export declare const unique: (value: any, index: number, self: any) => boolean;
|
|
6
|
+
export declare const areCoprime: (num1: number, num2: number) => boolean;
|
|
7
|
+
export declare const rotate: (arr: any[], offset: number) => any[];
|
|
8
|
+
export declare const inversionMap: (range: (number | number[])) => Map<number, number>;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.inversionMap = exports.rotate = exports.areCoprime = exports.unique = exports.SCALE_DEGREE_ERROR = exports.SELF_SIMILARITY_REQUIRES_COPRIMES = exports.NON_INTEGER_INPUTS = exports.INCOMPATIBLE_SEQ_MSG = void 0;
|
|
4
|
+
const tblswvs_error_1 = require("./tblswvs_error");
|
|
5
|
+
exports.INCOMPATIBLE_SEQ_MSG = "A Sequence can only be made new from and Array of Sequence " +
|
|
6
|
+
"objects that share the same rest symbol and mode";
|
|
7
|
+
exports.NON_INTEGER_INPUTS = "Numbers must be integers";
|
|
8
|
+
exports.SELF_SIMILARITY_REQUIRES_COPRIMES = "A self-similar melody can only be produced for an input sequence length " +
|
|
9
|
+
"that is coprime with the output sequence length";
|
|
10
|
+
exports.SCALE_DEGREE_ERROR = "Scale degrees must be negative or positive, but not 0";
|
|
11
|
+
const unique = (value, index, self) => {
|
|
12
|
+
return self.indexOf(value) === index;
|
|
13
|
+
};
|
|
14
|
+
exports.unique = unique;
|
|
15
|
+
const areCoprime = (num1, num2) => {
|
|
16
|
+
if (!Number.isInteger(num1) || !Number.isInteger(num2))
|
|
17
|
+
throw new tblswvs_error_1.TblswvsError(exports.NON_INTEGER_INPUTS);
|
|
18
|
+
const smaller = num1 > num2 ? num2 : num1;
|
|
19
|
+
for (let i = 2; i <= smaller; i++)
|
|
20
|
+
if ((num1 % i === 0) && (num2 % i === 0))
|
|
21
|
+
return false;
|
|
22
|
+
return true;
|
|
23
|
+
};
|
|
24
|
+
exports.areCoprime = areCoprime;
|
|
25
|
+
const rotate = (arr, offset) => {
|
|
26
|
+
let copy = arr.slice();
|
|
27
|
+
if (copy.length > offset) {
|
|
28
|
+
copy.unshift(...copy.splice(-offset));
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
let i = 0;
|
|
32
|
+
while (i < offset) {
|
|
33
|
+
copy.unshift(copy.splice(-1));
|
|
34
|
+
i++;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return copy;
|
|
38
|
+
};
|
|
39
|
+
exports.rotate = rotate;
|
|
40
|
+
const inversionMap = (range) => {
|
|
41
|
+
let map = new Map();
|
|
42
|
+
const intervals = (Array.isArray(range)) ?
|
|
43
|
+
range.filter(exports.unique).sort((a, b) => a - b) :
|
|
44
|
+
[...new Array(range).keys()].map(i => i + 1);
|
|
45
|
+
for (let i = 0; i < intervals.length; i++)
|
|
46
|
+
map.set(intervals[i], intervals[intervals.length - i - 1]);
|
|
47
|
+
return map;
|
|
48
|
+
};
|
|
49
|
+
exports.inversionMap = inversionMap;
|
|
50
|
+
//# sourceMappingURL=helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../../src/helpers.ts"],"names":[],"mappings":";;;AAAA,mDAA+C;AAGlC,QAAA,oBAAoB,GAC7B,6DAA6D;IAC7D,kDAAkD,CAAC;AAE1C,QAAA,kBAAkB,GAAG,0BAA0B,CAAC;AAEhD,QAAA,iCAAiC,GAC1C,0EAA0E;IAC1E,iDAAiD,CAAC;AAEzC,QAAA,kBAAkB,GAC3B,uDAAuD,CAAC;AAGrD,MAAM,MAAM,GAAG,CAAC,KAAU,EAAE,KAAa,EAAE,IAAS,EAAE,EAAE;IAC3D,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC;AACzC,CAAC,CAAA;AAFY,QAAA,MAAM,UAElB;AAGM,MAAM,UAAU,GAAG,CAAC,IAAY,EAAE,IAAY,EAAE,EAAE;IACrD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC;QAClD,MAAM,IAAI,4BAAY,CAAC,0BAAkB,CAAC,CAAC;IAE/C,MAAM,OAAO,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IAC1C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,OAAO,EAAE,CAAC,EAAE;QAC7B,IAAI,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;YACpC,OAAO,KAAK,CAAC;IAErB,OAAO,IAAI,CAAC;AAChB,CAAC,CAAC;AAVW,QAAA,UAAU,cAUrB;AAGK,MAAM,MAAM,GAAG,CAAC,GAAU,EAAE,MAAc,EAAS,EAAE;IACxD,IAAI,IAAI,GAAG,GAAG,CAAC,KAAK,EAAE,CAAC;IACvB,IAAI,IAAI,CAAC,MAAM,GAAG,MAAM,EAAE;QACtB,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;KACzC;SAAM;QACH,IAAI,CAAC,GAAG,CAAC,CAAC;QACV,OAAO,CAAC,GAAG,MAAM,EAAE;YACf,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC9B,CAAC,EAAE,CAAC;SACP;KACJ;IACD,OAAO,IAAI,CAAC;AAChB,CAAC,CAAA;AAZY,QAAA,MAAM,UAYlB;AAGM,MAAM,YAAY,GAAG,CAAC,KAAwB,EAAuB,EAAE;IAC1E,IAAI,GAAG,GAAG,IAAI,GAAG,EAAE,CAAC;IAEpB,MAAM,SAAS,GAAa,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC5C,KAAK,CAAC,MAAM,CAAC,cAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC5C,CAAC,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAErD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE;QACrC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAE/D,OAAO,GAAG,CAAC;AACf,CAAC,CAAA;AAXY,QAAA,YAAY,gBAWxB"}
|
package/lib/es5/index.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./melody"), exports);
|
|
18
|
+
__exportStar(require("./mode"), exports);
|
|
19
|
+
__exportStar(require("./key"), exports);
|
|
20
|
+
__exportStar(require("./melodic_vector"), exports);
|
|
21
|
+
__exportStar(require("./rhythm"), exports);
|
|
22
|
+
__exportStar(require("./lindenmayer_system"), exports);
|
|
23
|
+
__exportStar(require("./markov_chain"), exports);
|
|
24
|
+
__exportStar(require("./helpers"), exports);
|
|
25
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAAyB;AACzB,yCAAuB;AACvB,wCAAsB;AACtB,mDAAiC;AACjC,2CAAyB;AACzB,uDAAqC;AACrC,iDAA+B;AAC/B,4CAA0B"}
|
package/lib/es5/key.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Mode, Scale } from "./mode";
|
|
2
|
+
import * as noteData from "./note_data";
|
|
3
|
+
export declare class Key {
|
|
4
|
+
#private;
|
|
5
|
+
scale: Scale;
|
|
6
|
+
scaleName: string;
|
|
7
|
+
name: string;
|
|
8
|
+
mode: Mode;
|
|
9
|
+
tonic: string;
|
|
10
|
+
midiTonic: number;
|
|
11
|
+
octave: number;
|
|
12
|
+
scaleNotes: string[];
|
|
13
|
+
inversions: Map<number, number>;
|
|
14
|
+
inversionMin: number;
|
|
15
|
+
inversionMax: number;
|
|
16
|
+
constructor(tonic: (number | string), scale: Scale);
|
|
17
|
+
degree(d: number, octaveTranspose?: number): noteData.note;
|
|
18
|
+
chord(degree: number, type: string, octaveTransposition?: number): noteData.chord;
|
|
19
|
+
midi2note(midiNoteNumber: number): string;
|
|
20
|
+
degreeInversion(scaleDegree: number): noteData.note;
|
|
21
|
+
}
|
package/lib/es5/key.js
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
4
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
5
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
6
|
+
};
|
|
7
|
+
var _Key_instances, _Key_negativeDegree, _Key_calculateChordRoot, _Key_calculateChordDegree, _Key_calculateScaleNotes, _Key_calculateInversions;
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.Key = void 0;
|
|
10
|
+
const mode_1 = require("./mode");
|
|
11
|
+
const noteData = require("./note_data");
|
|
12
|
+
const helpers = require("./helpers");
|
|
13
|
+
const tblswvs_error_1 = require("./tblswvs_error");
|
|
14
|
+
class Key {
|
|
15
|
+
constructor(tonic, scale) {
|
|
16
|
+
_Key_instances.add(this);
|
|
17
|
+
this.scale = scale;
|
|
18
|
+
this.mode = new mode_1.Mode(scale);
|
|
19
|
+
if (typeof tonic == "string") {
|
|
20
|
+
this.tonic = tonic;
|
|
21
|
+
this.midiTonic = noteData.chromaticScale.indexOf(tonic);
|
|
22
|
+
this.octave = 1;
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
this.tonic = noteData.chromaticScale[tonic % 12];
|
|
26
|
+
this.midiTonic = tonic % 12;
|
|
27
|
+
this.octave = noteData.noteData[tonic].octave;
|
|
28
|
+
}
|
|
29
|
+
this.scaleName = mode_1.Scale[scale];
|
|
30
|
+
this.name = `${this.tonic} ${this.scaleName}`;
|
|
31
|
+
this.scaleNotes = __classPrivateFieldGet(this, _Key_instances, "m", _Key_calculateScaleNotes).call(this);
|
|
32
|
+
this.inversions = __classPrivateFieldGet(this, _Key_instances, "m", _Key_calculateInversions).call(this);
|
|
33
|
+
const inversionRange = Array.from(this.inversions.keys()).sort((a, b) => a - b);
|
|
34
|
+
this.inversionMin = inversionRange[0];
|
|
35
|
+
this.inversionMax = inversionRange[inversionRange.length - 1];
|
|
36
|
+
}
|
|
37
|
+
degree(d, octaveTranspose) {
|
|
38
|
+
if (d == 0)
|
|
39
|
+
throw new tblswvs_error_1.TblswvsError(helpers.SCALE_DEGREE_ERROR);
|
|
40
|
+
if (d < 0)
|
|
41
|
+
return __classPrivateFieldGet(this, _Key_instances, "m", _Key_negativeDegree).call(this, d, octaveTranspose);
|
|
42
|
+
// The degree octave may start higher than the current key's octave (e.g., the 9th in a diatonic scale)
|
|
43
|
+
let degreeOctave = this.octave + Math.floor((d - 1) / this.scaleNotes.length);
|
|
44
|
+
const noteIndex = this.mode.scaleOffsets[(d - 1) % this.scaleNotes.length] + this.midiTonic + (degreeOctave * 12) + 24;
|
|
45
|
+
let degree = Object.assign({}, noteData.noteData[noteIndex]);
|
|
46
|
+
// Reset the generic note to the scale notes to correctly identify when a scale degree should be a flat, rather than
|
|
47
|
+
// the default sharp for noteData.
|
|
48
|
+
degree.note = this.scaleNotes[(d - 1) % this.scaleNotes.length];
|
|
49
|
+
degree.scaleDegree = d;
|
|
50
|
+
if (octaveTranspose != undefined) {
|
|
51
|
+
degree.octave += octaveTranspose;
|
|
52
|
+
degree.midi += (octaveTranspose * 12);
|
|
53
|
+
}
|
|
54
|
+
return degree;
|
|
55
|
+
}
|
|
56
|
+
chord(degree, type, octaveTransposition) {
|
|
57
|
+
let quality = (type == "T") ? this.mode.chordQualities[degree - 1] : type;
|
|
58
|
+
/*
|
|
59
|
+
* octaveTransposition: the calling client may request transposition (-/+)
|
|
60
|
+
* this.midiTonic: scale pitch class (0-11)
|
|
61
|
+
* this.octave * 12: the Key has a default lowest octave
|
|
62
|
+
* + 24: lowest MIDI octave, -2, means this.octave*12 could be as low as -24, which should be brought up to MIDI note 0
|
|
63
|
+
*/
|
|
64
|
+
let midiTransposition = (octaveTransposition == undefined ? 0 : octaveTransposition * 12) + this.midiTonic + (this.octave * 12) + 24;
|
|
65
|
+
let midi = noteData.chordTypes[quality].intervals.reduce((midiNotes, intv) => {
|
|
66
|
+
midiNotes.push(intv + this.mode.scaleOffsets[degree - 1] + midiTransposition);
|
|
67
|
+
return midiNotes;
|
|
68
|
+
}, []);
|
|
69
|
+
return {
|
|
70
|
+
midi: midi,
|
|
71
|
+
quality: quality,
|
|
72
|
+
root: __classPrivateFieldGet(this, _Key_instances, "m", _Key_calculateChordRoot).call(this, midi, quality),
|
|
73
|
+
degree: __classPrivateFieldGet(this, _Key_instances, "m", _Key_calculateChordDegree).call(this, quality, degree),
|
|
74
|
+
keyTransposition: octaveTransposition == undefined ? 0 : octaveTransposition
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
midi2note(midiNoteNumber) {
|
|
78
|
+
const normalizedNumber = midiNoteNumber % 12;
|
|
79
|
+
const normalizedIndex = this.mode.scaleOffsets.indexOf(normalizedNumber);
|
|
80
|
+
if (normalizedIndex != -1) {
|
|
81
|
+
return this.scaleNotes[normalizedIndex] + noteData.noteData[midiNoteNumber].octave;
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
let note = noteData.noteData[midiNoteNumber].note;
|
|
85
|
+
const nearestNote = this.scaleNotes.find(n => n[0] == note[0]);
|
|
86
|
+
note += (nearestNote != undefined && nearestNote.length == 2) ? "♮" : "";
|
|
87
|
+
return note + noteData.noteData[midiNoteNumber].octave;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
degreeInversion(scaleDegree) {
|
|
91
|
+
if (scaleDegree < this.inversionMin)
|
|
92
|
+
scaleDegree = this.inversionMin;
|
|
93
|
+
else if (scaleDegree > this.inversionMax)
|
|
94
|
+
scaleDegree = this.inversionMax;
|
|
95
|
+
const invertedScaleDegree = this.inversions.get(scaleDegree);
|
|
96
|
+
if (invertedScaleDegree == undefined)
|
|
97
|
+
return { octave: -3, note: "", midi: -1 };
|
|
98
|
+
else
|
|
99
|
+
return this.degree(invertedScaleDegree);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
exports.Key = Key;
|
|
103
|
+
_Key_instances = new WeakSet(), _Key_negativeDegree = function _Key_negativeDegree(d, octaveTranspose) {
|
|
104
|
+
// For negative indices, start by getting the step offsets in reverse order...
|
|
105
|
+
let revCopy = this.mode.stepOffsets.slice().reverse();
|
|
106
|
+
// Then determine how many copies of the array are needed to index the current scale degree
|
|
107
|
+
// (e.g., -8 for C Major would be the second B, so copies should be 2)
|
|
108
|
+
let copies = Math.ceil(-d / revCopy.length);
|
|
109
|
+
// Create a version of the reversed step offsets that can reach the scale degree needed.
|
|
110
|
+
let expanded = new Array(copies).fill(revCopy).flat();
|
|
111
|
+
// Finally, subtract negative offsets from the current Key's root and correct the default sharps to flats as needed.
|
|
112
|
+
const noteIndex = this.octave * 12 + this.midiTonic + 24 - expanded.slice(0, -d).reduce((total, offset) => total += offset, 0);
|
|
113
|
+
let degree = Object.assign({}, noteData.noteData[noteIndex]);
|
|
114
|
+
degree.note = this.scaleNotes.at(d % this.scaleNotes.length);
|
|
115
|
+
degree.scaleDegree = d;
|
|
116
|
+
if (octaveTranspose != undefined) {
|
|
117
|
+
degree.octave += octaveTranspose;
|
|
118
|
+
degree.midi += (octaveTranspose * 12);
|
|
119
|
+
}
|
|
120
|
+
return degree;
|
|
121
|
+
}, _Key_calculateChordRoot = function _Key_calculateChordRoot(chordMidi, chordQuality) {
|
|
122
|
+
let inversion = chordQuality.split("/")[1];
|
|
123
|
+
if (inversion == undefined) {
|
|
124
|
+
return this.midi2note(chordMidi[0]).replace(/[0-9]/g, "");
|
|
125
|
+
}
|
|
126
|
+
else if (inversion == "2" || inversion == "3" || inversion == "4") {
|
|
127
|
+
return this.midi2note(chordMidi[2]).replace(/[0-9]/g, "");
|
|
128
|
+
}
|
|
129
|
+
else if (inversion == "5") {
|
|
130
|
+
return this.midi2note(chordMidi[1]).replace(/[0-9]/g, "");
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
return this.midi2note(chordMidi[0]).replace(/[0-9]/g, "");
|
|
134
|
+
}
|
|
135
|
+
}, _Key_calculateChordDegree = function _Key_calculateChordDegree(quality, degree) {
|
|
136
|
+
if (quality.startsWith("M")) {
|
|
137
|
+
return quality.replace("M", noteData.chordNumeralsMap[degree]);
|
|
138
|
+
}
|
|
139
|
+
else if (quality.startsWith("m")) {
|
|
140
|
+
return quality.replace("m", noteData.chordNumeralsMap[degree].toLowerCase());
|
|
141
|
+
}
|
|
142
|
+
else if (quality.startsWith("aug")) {
|
|
143
|
+
return quality.replace("aug", noteData.chordNumeralsMap[degree]) + "+";
|
|
144
|
+
}
|
|
145
|
+
else if (quality.startsWith("dim")) {
|
|
146
|
+
return quality.replace("dim", noteData.chordNumeralsMap[degree]).toLowerCase() + "o";
|
|
147
|
+
}
|
|
148
|
+
else if (quality.startsWith("sus2")) {
|
|
149
|
+
return noteData.chordNumeralsMap[degree] + quality;
|
|
150
|
+
}
|
|
151
|
+
else if (quality.startsWith("sus4")) {
|
|
152
|
+
return quality.replace("sus2", noteData.chordNumeralsMap[degree]) + "sus4";
|
|
153
|
+
}
|
|
154
|
+
else if (quality.startsWith("WT")) {
|
|
155
|
+
return quality.replace("WT", noteData.chordNumeralsMap[degree]).toLowerCase() + "WT";
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
return degree + quality;
|
|
159
|
+
}
|
|
160
|
+
}, _Key_calculateScaleNotes = function _Key_calculateScaleNotes() {
|
|
161
|
+
const rotatedAbsolute = helpers.rotate(noteData.scaleNoteCandidates, -noteData.scaleNoteCandidates.findIndex(n => n.includes(this.tonic)));
|
|
162
|
+
let scaleAbcNotes = helpers.rotate(noteData.abcNotesMidiOrder, -noteData.abcNotesMidiOrder.indexOf(this.tonic[0]));
|
|
163
|
+
if (this.mode.scaleDegreeMapping.length != 0) {
|
|
164
|
+
scaleAbcNotes = this.mode.scaleDegreeMapping.map(d => scaleAbcNotes[Math.floor(d) - 1]);
|
|
165
|
+
}
|
|
166
|
+
return scaleAbcNotes.map((n, i) => {
|
|
167
|
+
const absoluteIndex = this.mode.scaleOffsets[i];
|
|
168
|
+
return rotatedAbsolute[absoluteIndex].find((sn) => sn[0] == n);
|
|
169
|
+
});
|
|
170
|
+
}, _Key_calculateInversions = function _Key_calculateInversions() {
|
|
171
|
+
const positiveDegrees = [...new Array(this.mode.stepOffsets.length * 2 + 1).keys()].map(d => d + 1);
|
|
172
|
+
const negativeDegrees = positiveDegrees.slice(0, this.mode.stepOffsets.length).reverse().map(d => d * -1);
|
|
173
|
+
this.inversionMin = negativeDegrees[0];
|
|
174
|
+
this.inversionMax = positiveDegrees[positiveDegrees.length - 1];
|
|
175
|
+
const blerg = negativeDegrees.concat(positiveDegrees);
|
|
176
|
+
return helpers.inversionMap(blerg);
|
|
177
|
+
};
|
|
178
|
+
//# sourceMappingURL=key.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"key.js","sourceRoot":"","sources":["../../../src/key.ts"],"names":[],"mappings":";;;;;;;;;AAAA,iCAAqC;AACrC,wCAAwC;AACxC,qCAAqC;AACrC,mDAA+C;AAG/C,MAAa,GAAG;IAcZ,YAAY,KAAwB,EAAE,KAAY;;QAC9C,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,IAAI,GAAI,IAAI,WAAI,CAAC,KAAK,CAAC,CAAC;QAC7B,IAAI,OAAO,KAAK,IAAI,QAAQ,EAAE;YAC1B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;YACnB,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC,cAAc,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YACxD,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;SACnB;aAAM;YACH,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC,cAAc,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;YACjD,IAAI,CAAC,SAAS,GAAG,KAAK,GAAG,EAAE,CAAC;YAC5B,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC;SACjD;QACD,IAAI,CAAC,SAAS,GAAG,YAAK,CAAC,KAAK,CAAC,CAAC;QAC9B,IAAI,CAAC,IAAI,GAAG,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,SAAS,EAAE,CAAA;QAC7C,IAAI,CAAC,UAAU,GAAG,uBAAA,IAAI,gDAAqB,MAAzB,IAAI,CAAuB,CAAC;QAC9C,IAAI,CAAC,UAAU,GAAG,uBAAA,IAAI,gDAAqB,MAAzB,IAAI,CAAuB,CAAC;QAC9C,MAAM,cAAc,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAChF,IAAI,CAAC,YAAY,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC;QACtC,IAAI,CAAC,YAAY,GAAG,cAAc,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAClE,CAAC;IAGD,MAAM,CAAC,CAAS,EAAE,eAAwB;QACtC,IAAI,CAAC,IAAI,CAAC;YAAE,MAAM,IAAI,4BAAY,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;QAE/D,IAAI,CAAC,GAAG,CAAC;YAAE,OAAO,uBAAA,IAAI,2CAAgB,MAApB,IAAI,EAAiB,CAAC,EAAE,eAAe,CAAC,CAAC;QAE3D,uGAAuG;QACvG,IAAI,YAAY,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QAC9E,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,SAAS,GAAG,CAAC,YAAY,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC;QACvH,IAAI,MAAM,qBAAQ,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAE,CAAC;QACjD,oHAAoH;QACpH,kCAAkC;QAClC,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QAChE,MAAM,CAAC,WAAW,GAAG,CAAC,CAAC;QACvB,IAAI,eAAe,IAAI,SAAS,EAAE;YAC9B,MAAM,CAAC,MAAM,IAAI,eAAe,CAAC;YACjC,MAAM,CAAC,IAAI,IAAM,CAAC,eAAe,GAAG,EAAE,CAAC,CAAC;SAC3C;QACD,OAAO,MAAM,CAAC;IAClB,CAAC;IA4BD,KAAK,CAAC,MAAc,EAAE,IAAY,EAAE,mBAA4B;QAC5D,IAAI,OAAO,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAE1E;;;;;WAKG;QACH,IAAI,iBAAiB,GAAG,CAAC,mBAAmB,IAAI,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,mBAAmB,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC;QAErI,IAAI,IAAI,GAAG,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,SAAmB,EAAE,IAAY,EAAE,EAAE;YAC3F,SAAS,CAAC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,iBAAiB,CAAC,CAAC;YAC9E,OAAO,SAAS,CAAC;QACrB,CAAC,EAAE,EAAE,CAAC,CAAC;QAEP,OAAO;YACH,IAAI,EAAE,IAAI;YACV,OAAO,EAAE,OAAO;YAChB,IAAI,EAAE,uBAAA,IAAI,+CAAoB,MAAxB,IAAI,EAAqB,IAAI,EAAE,OAAO,CAAC;YAC7C,MAAM,EAAE,uBAAA,IAAI,iDAAsB,MAA1B,IAAI,EAAuB,OAAO,EAAE,MAAM,CAAC;YACnD,gBAAgB,EAAE,mBAAmB,IAAI,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,mBAAmB;SAC/E,CAAA;IACL,CAAC;IAsCD,SAAS,CAAC,cAAsB;QAC5B,MAAM,gBAAgB,GAAG,cAAc,GAAG,EAAE,CAAC;QAC7C,MAAM,eAAe,GAAI,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;QAC1E,IAAI,eAAe,IAAI,CAAC,CAAC,EAAE;YACvB,OAAO,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,GAAG,QAAQ,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC;SACtF;aAAM;YACH,IAAI,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC;YAClD,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;YAC9D,IAAI,IAAI,CAAC,WAAW,IAAI,SAAS,IAAI,WAAW,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YACzE,OAAO,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC;SAC1D;IACL,CAAC;IAkBD,eAAe,CAAC,WAAmB;QAC/B,IAAI,WAAW,GAAG,IAAI,CAAC,YAAY;YAAE,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC;aAChE,IAAI,WAAW,GAAG,IAAI,CAAC,YAAY;YAAE,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC;QAE1E,MAAM,mBAAmB,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QAC7D,IAAI,mBAAmB,IAAI,SAAS;YAChC,OAAO,EAAC,MAAM,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,EAAC,CAAC;;YAExC,OAAO,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;IAChD,CAAC;CAmBJ;AAxMD,kBAwMC;mFA/ImB,CAAS,EAAE,eAAwB;IAC/C,8EAA8E;IAC9E,IAAI,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,CAAC;IAEtD,2FAA2F;IAC3F,sEAAsE;IACtE,IAAI,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAE5C,wFAAwF;IACxF,IAAI,QAAQ,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;IAEtD,oHAAoH;IACpH,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,GAAG,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,KAAK,IAAI,MAAM,EAAE,CAAC,CAAC,CAAC;IAC/H,IAAI,MAAM,qBAAQ,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAE,CAAC;IACjD,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAE,CAAC;IAC9D,MAAM,CAAC,WAAW,GAAG,CAAC,CAAC;IACvB,IAAI,eAAe,IAAI,SAAS,EAAE;QAC9B,MAAM,CAAC,MAAM,IAAI,eAAe,CAAC;QACjC,MAAM,CAAC,IAAI,IAAM,CAAC,eAAe,GAAG,EAAE,CAAC,CAAC;KAC3C;IAED,OAAO,MAAM,CAAC;AAClB,CAAC,6DA6BmB,SAAmB,EAAE,YAAoB;IACzD,IAAI,SAAS,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3C,IAAI,SAAS,IAAI,SAAS,EAAE;QACxB,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;KAC7D;SAAM,IAAI,SAAS,IAAI,GAAG,IAAI,SAAS,IAAI,GAAG,IAAI,SAAS,IAAI,GAAG,EAAE;QACjE,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;KAC7D;SAAM,IAAI,SAAS,IAAI,GAAG,EAAE;QACzB,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;KAC7D;SAAM;QACH,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;KAC7D;AACL,CAAC,iEAGqB,OAAe,EAAE,MAAc;IACjD,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE;QACzB,OAAO,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,QAAQ,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC;KAClE;SAAM,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE;QAChC,OAAO,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,QAAQ,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;KAChF;SAAM,IAAI,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE;QAClC,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,GAAG,GAAG,CAAC;KAC1E;SAAM,IAAI,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE;QAClC,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,GAAG,CAAC;KACxF;SAAM,IAAI,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE;QACnC,OAAO,QAAQ,CAAC,gBAAgB,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC;KACtD;SAAM,IAAI,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE;QACnC,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC;KAC9E;SAAM,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE;QACjC,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC;KACxF;SAAM;QACH,OAAO,MAAM,GAAG,OAAO,CAAC;KAC3B;AACL,CAAC;IAkBG,MAAM,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,EAAE,CAAC,QAAQ,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC3I,IAAM,aAAa,GAAK,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,EAAE,CAAC,QAAQ,CAAC,iBAAiB,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAEvH,IAAI,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,MAAM,IAAI,CAAC,EAAE;QAC1C,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;KAC3F;IAED,OAAO,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QAC9B,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAChD,OAAO,eAAe,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,EAAY,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAC7E,CAAC,CAAC,CAAC;AACP,CAAC;IAqBG,MAAM,eAAe,GAAG,CAAC,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACpG,MAAM,eAAe,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC1G,IAAI,CAAC,YAAY,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC;IACvC,IAAI,CAAC,YAAY,GAAG,eAAe,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAEhE,MAAM,KAAK,GAAG,eAAe,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;IACtD,OAAO,OAAO,CAAC,YAAY,CACvB,KAAK,CACR,CAAC;AACN,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
type productionRule = {
|
|
2
|
+
matchStr: string;
|
|
3
|
+
output: string;
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* Lindenmayer Systems (or L-Systems) are string rewriting systems developed by, and named after, the Hungarian
|
|
7
|
+
* biologist who used the algorithm to model the growth of plants and cell structures.
|
|
8
|
+
*
|
|
9
|
+
* This class represents a simple implementation of L-Systems where you can create one with a starting axiom,
|
|
10
|
+
* add new "production rules," and generate new iterations of the L-System string. Additionally, this version
|
|
11
|
+
* implements branching using the square bracket characters '[' and ']'. Branching enables an L-System string
|
|
12
|
+
* to be translated into a 2-dimensional matrix.
|
|
13
|
+
*/
|
|
14
|
+
export declare class LindenmayerSystem {
|
|
15
|
+
axiom: string;
|
|
16
|
+
string: string;
|
|
17
|
+
productionRules: {
|
|
18
|
+
[index: string]: string;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Create a new LindenmayerSystem object.
|
|
22
|
+
*
|
|
23
|
+
* @param axiom the initial string for this L-System
|
|
24
|
+
*/
|
|
25
|
+
constructor(axiom: string);
|
|
26
|
+
/**
|
|
27
|
+
* Add a new production rule to the L-System.
|
|
28
|
+
*
|
|
29
|
+
* @param rule a string rewriting rule in the form of an object that has the properties "matchStr" and "output"
|
|
30
|
+
*/
|
|
31
|
+
add(rule: productionRule): void;
|
|
32
|
+
/**
|
|
33
|
+
* Get the current list of production rule matching strings. To see the rewriting output for each rule,
|
|
34
|
+
* access the productionRules property.
|
|
35
|
+
*
|
|
36
|
+
* @returns string[] the production rules matching strings
|
|
37
|
+
*/
|
|
38
|
+
rules(): string[];
|
|
39
|
+
/**
|
|
40
|
+
* Advance the L-System by one generation.
|
|
41
|
+
*
|
|
42
|
+
* The current string, which is equal to the axiom until advanced,
|
|
43
|
+
* will have its letters run thru the production rules. When a letter matches a production rule's "matchStr"
|
|
44
|
+
* property, it will be replaced by the same production rule's "output" property in the resulting string.
|
|
45
|
+
* When no match is found the current letter will simply be added without replacement.
|
|
46
|
+
*
|
|
47
|
+
* This will update the object's "string" property.
|
|
48
|
+
*/
|
|
49
|
+
advance(): void;
|
|
50
|
+
/**
|
|
51
|
+
* Get the current "string" as a matrix.
|
|
52
|
+
*
|
|
53
|
+
* A matrix representation is really only useful for L-System strings with branching characters so that
|
|
54
|
+
* the matrix has multiple rows. The intention is to return a 2-D table-like representation of a branching
|
|
55
|
+
* L-System string so that represents a polyphonic event sequence. The columns can be treated as sequencer
|
|
56
|
+
* steps and the rows as simultaneous/polyphonic events for the current step/column.
|
|
57
|
+
*
|
|
58
|
+
* @returns string[][] a 2-dimensional matrix representation of the current L-System string
|
|
59
|
+
*/
|
|
60
|
+
matrix(): string[][];
|
|
61
|
+
}
|
|
62
|
+
export {};
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LindenmayerSystem = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Lindenmayer Systems (or L-Systems) are string rewriting systems developed by, and named after, the Hungarian
|
|
6
|
+
* biologist who used the algorithm to model the growth of plants and cell structures.
|
|
7
|
+
*
|
|
8
|
+
* This class represents a simple implementation of L-Systems where you can create one with a starting axiom,
|
|
9
|
+
* add new "production rules," and generate new iterations of the L-System string. Additionally, this version
|
|
10
|
+
* implements branching using the square bracket characters '[' and ']'. Branching enables an L-System string
|
|
11
|
+
* to be translated into a 2-dimensional matrix.
|
|
12
|
+
*/
|
|
13
|
+
class LindenmayerSystem {
|
|
14
|
+
/**
|
|
15
|
+
* Create a new LindenmayerSystem object.
|
|
16
|
+
*
|
|
17
|
+
* @param axiom the initial string for this L-System
|
|
18
|
+
*/
|
|
19
|
+
constructor(axiom) {
|
|
20
|
+
this.axiom = axiom;
|
|
21
|
+
this.string = axiom;
|
|
22
|
+
this.productionRules = {};
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Add a new production rule to the L-System.
|
|
26
|
+
*
|
|
27
|
+
* @param rule a string rewriting rule in the form of an object that has the properties "matchStr" and "output"
|
|
28
|
+
*/
|
|
29
|
+
add(rule) {
|
|
30
|
+
this.productionRules[rule.matchStr] = rule.output;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Get the current list of production rule matching strings. To see the rewriting output for each rule,
|
|
34
|
+
* access the productionRules property.
|
|
35
|
+
*
|
|
36
|
+
* @returns string[] the production rules matching strings
|
|
37
|
+
*/
|
|
38
|
+
rules() {
|
|
39
|
+
return Object.keys(this.productionRules);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Advance the L-System by one generation.
|
|
43
|
+
*
|
|
44
|
+
* The current string, which is equal to the axiom until advanced,
|
|
45
|
+
* will have its letters run thru the production rules. When a letter matches a production rule's "matchStr"
|
|
46
|
+
* property, it will be replaced by the same production rule's "output" property in the resulting string.
|
|
47
|
+
* When no match is found the current letter will simply be added without replacement.
|
|
48
|
+
*
|
|
49
|
+
* This will update the object's "string" property.
|
|
50
|
+
*/
|
|
51
|
+
advance() {
|
|
52
|
+
this.string = this.string.split(" ").map(letter => {
|
|
53
|
+
return letter in this.productionRules ? this.productionRules[letter] : letter;
|
|
54
|
+
}).join(" ");
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Get the current "string" as a matrix.
|
|
58
|
+
*
|
|
59
|
+
* A matrix representation is really only useful for L-System strings with branching characters so that
|
|
60
|
+
* the matrix has multiple rows. The intention is to return a 2-D table-like representation of a branching
|
|
61
|
+
* L-System string so that represents a polyphonic event sequence. The columns can be treated as sequencer
|
|
62
|
+
* steps and the rows as simultaneous/polyphonic events for the current step/column.
|
|
63
|
+
*
|
|
64
|
+
* @returns string[][] a 2-dimensional matrix representation of the current L-System string
|
|
65
|
+
*/
|
|
66
|
+
matrix() {
|
|
67
|
+
let matrix = new Array();
|
|
68
|
+
matrix.push(new Array());
|
|
69
|
+
let rowIndex = 0, colIndex = 0, branchCoordinates = [rowIndex, colIndex];
|
|
70
|
+
this.string.split(" ").forEach((letter, i) => {
|
|
71
|
+
if (letter == "[") {
|
|
72
|
+
// When starting a new branch, note where the branch origin is for returning when the branch
|
|
73
|
+
// ceases, increment the row count and create an Array for the new row.
|
|
74
|
+
branchCoordinates = [rowIndex, colIndex];
|
|
75
|
+
rowIndex = matrix.length;
|
|
76
|
+
matrix.push(new Array());
|
|
77
|
+
colIndex -= 1;
|
|
78
|
+
}
|
|
79
|
+
else if (letter == "]") {
|
|
80
|
+
// When a branch terminates, return the cursor to the branching coordinates.
|
|
81
|
+
rowIndex = branchCoordinates[0];
|
|
82
|
+
colIndex = branchCoordinates[1];
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
// Add the current letter to the next position
|
|
86
|
+
matrix[rowIndex][colIndex] = letter;
|
|
87
|
+
colIndex += 1;
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
return matrix;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
exports.LindenmayerSystem = LindenmayerSystem;
|
|
94
|
+
//# sourceMappingURL=lindenmayer_system.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lindenmayer_system.js","sourceRoot":"","sources":["../../../src/lindenmayer_system.ts"],"names":[],"mappings":";;;AAMA;;;;;;;;GAQG;AACH,MAAa,iBAAiB;IAM1B;;;;OAIG;IACH,YAAY,KAAa;QACrB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;IAC9B,CAAC;IAGD;;;;OAIG;IACH,GAAG,CAAC,IAAoB;QACpB,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;IACtD,CAAC;IAGD;;;;;OAKG;IACH,KAAK;QACD,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAC7C,CAAC;IAGD;;;;;;;;;OASG;IACH,OAAO;QACH,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE;YAC9C,OAAO,MAAM,IAAI,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QAClF,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACjB,CAAC;IAGD;;;;;;;;;OASG;IACH,MAAM;QACF,IAAI,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC;QACzB,IAAI,QAAQ,GAAG,CAAC,EAAE,QAAQ,GAAG,CAAC,EAAE,iBAAiB,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAEzE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YACzC,IAAI,MAAM,IAAI,GAAG,EAAE;gBAEf,4FAA4F;gBAC5F,uEAAuE;gBACvE,iBAAiB,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;gBACzC,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC;gBACzB,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC;gBACzB,QAAQ,IAAI,CAAC,CAAC;aAEjB;iBAAM,IAAI,MAAM,IAAI,GAAG,EAAE;gBAEtB,4EAA4E;gBAC5E,QAAQ,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC;gBAChC,QAAQ,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC;aAEnC;iBAAM;gBAEH,8CAA8C;gBAC9C,MAAM,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,GAAG,MAAM,CAAC;gBACpC,QAAQ,IAAI,CAAC,CAAC;aACjB;QACL,CAAC,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC;IAClB,CAAC;CACJ;AAjGD,8CAiGC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Melody } from "./melody";
|
|
2
|
+
export declare class MarkovChain {
|
|
3
|
+
input: Melody;
|
|
4
|
+
stateTransitionMatrix: Map<(string), (string | number)[]>;
|
|
5
|
+
constructor(input: Melody);
|
|
6
|
+
get(previous: number, current: number): (string | number);
|
|
7
|
+
private generateStm;
|
|
8
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MarkovChain = void 0;
|
|
4
|
+
class MarkovChain {
|
|
5
|
+
constructor(input) {
|
|
6
|
+
this.input = input;
|
|
7
|
+
this.stateTransitionMatrix = this.generateStm();
|
|
8
|
+
}
|
|
9
|
+
get(previous, current) {
|
|
10
|
+
const candidates = this.stateTransitionMatrix.get(`${previous}:${current}`) || [];
|
|
11
|
+
return candidates[Math.floor(Math.random() * candidates.length)];
|
|
12
|
+
}
|
|
13
|
+
generateStm() {
|
|
14
|
+
return this.input.steps.reduce((stm, step, i, arr) => {
|
|
15
|
+
if (i < arr.length - 1) {
|
|
16
|
+
const prevStep = (i == 0) ? step : arr[i - 1];
|
|
17
|
+
const nextStep = arr[i + 1];
|
|
18
|
+
const key = `${prevStep}:${step}`;
|
|
19
|
+
const values = stm.get(key) || new Array();
|
|
20
|
+
values.push(nextStep);
|
|
21
|
+
stm.set(key, values);
|
|
22
|
+
}
|
|
23
|
+
return stm;
|
|
24
|
+
}, new Map);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.MarkovChain = MarkovChain;
|
|
28
|
+
//# sourceMappingURL=markov_chain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markov_chain.js","sourceRoot":"","sources":["../../../src/markov_chain.ts"],"names":[],"mappings":";;;AAGA,MAAa,WAAW;IAKpB,YAAY,KAAa;QACrB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACpD,CAAC;IAGD,GAAG,CAAC,QAAgB,EAAE,OAAe;QACjC,MAAM,UAAU,GAAG,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,GAAG,QAAQ,IAAI,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC;QAClF,OAAO,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;IACrE,CAAC;IAGO,WAAW;QACf,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE;YACjD,IAAI,CAAC,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE;gBACpB,MAAM,QAAQ,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;gBAC9C,MAAM,QAAQ,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;gBAC5B,MAAM,GAAG,GAAQ,GAAG,QAAQ,IAAI,IAAI,EAAE,CAAC;gBACvC,MAAM,MAAM,GAAK,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,KAAK,EAAE,CAAC;gBAC7C,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACtB,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;aACxB;YACD,OAAO,GAAG,CAAC;QACf,CAAC,EAAE,IAAI,GAAgC,CAAC,CAAC;IAC7C,CAAC;CACJ;AA9BD,kCA8BC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Sequence } from "./sequence";
|
|
2
|
+
import { Melody } from "./melody";
|
|
3
|
+
import { Transformation } from "./transformation";
|
|
4
|
+
/**
|
|
5
|
+
* A MelodicVector is a sequence of numbers that can transform a Melody object by applying vector
|
|
6
|
+
* addition to a numerical representation of the Melody's note data.
|
|
7
|
+
*
|
|
8
|
+
* This class is not a true vector in the mathematical sense. For example, the steps property of
|
|
9
|
+
* this class that stores its sequence data does not need to have the same number of elements as
|
|
10
|
+
* in the Melody that it is transforming. The MelodicVector's steps will instead be repeated until
|
|
11
|
+
* it is expanded to the size of the Melody's steps.
|
|
12
|
+
*/
|
|
13
|
+
export declare class MelodicVector implements Sequence, Transformation {
|
|
14
|
+
steps: number[];
|
|
15
|
+
/**
|
|
16
|
+
* Create a new MelodicVector object.
|
|
17
|
+
*
|
|
18
|
+
* @param steps number[] the steps that represent the object's vector
|
|
19
|
+
*/
|
|
20
|
+
constructor(steps: number[]);
|
|
21
|
+
/**
|
|
22
|
+
* Transforms a melody by vector addition. Note that the vector step length and melody step
|
|
23
|
+
* length do not need to be equal.
|
|
24
|
+
*
|
|
25
|
+
* @param Melody the melody to transform withe the current vector
|
|
26
|
+
* @returns new Melody with steps based on summing the input melody steps and the vector steps
|
|
27
|
+
*/
|
|
28
|
+
applyTo(melody: Melody): Melody;
|
|
29
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MelodicVector = void 0;
|
|
4
|
+
const melody_1 = require("./melody");
|
|
5
|
+
/**
|
|
6
|
+
* A MelodicVector is a sequence of numbers that can transform a Melody object by applying vector
|
|
7
|
+
* addition to a numerical representation of the Melody's note data.
|
|
8
|
+
*
|
|
9
|
+
* This class is not a true vector in the mathematical sense. For example, the steps property of
|
|
10
|
+
* this class that stores its sequence data does not need to have the same number of elements as
|
|
11
|
+
* in the Melody that it is transforming. The MelodicVector's steps will instead be repeated until
|
|
12
|
+
* it is expanded to the size of the Melody's steps.
|
|
13
|
+
*/
|
|
14
|
+
class MelodicVector {
|
|
15
|
+
/**
|
|
16
|
+
* Create a new MelodicVector object.
|
|
17
|
+
*
|
|
18
|
+
* @param steps number[] the steps that represent the object's vector
|
|
19
|
+
*/
|
|
20
|
+
constructor(steps) {
|
|
21
|
+
this.steps = steps;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Transforms a melody by vector addition. Note that the vector step length and melody step
|
|
25
|
+
* length do not need to be equal.
|
|
26
|
+
*
|
|
27
|
+
* @param Melody the melody to transform withe the current vector
|
|
28
|
+
* @returns new Melody with steps based on summing the input melody steps and the vector steps
|
|
29
|
+
*/
|
|
30
|
+
applyTo(melody) {
|
|
31
|
+
// First generate an array of steps that will match the melody's length.
|
|
32
|
+
const size = Math.ceil((melody.steps.length / this.steps.length));
|
|
33
|
+
const expandedSteps = new Array(size).fill(this.steps).flat().slice(0, melody.steps.length);
|
|
34
|
+
// Create a copy of the melody so that the rest symbol and mode are carried forward.
|
|
35
|
+
// Then apply the vector addition.
|
|
36
|
+
const transformedMelody = melody.clone();
|
|
37
|
+
transformedMelody.steps = expandedSteps.map((step, i) => {
|
|
38
|
+
if (melody.melodicMode == melody_1.MelodyType.Degrees && melody.steps[i] == 0)
|
|
39
|
+
return 0;
|
|
40
|
+
else if (melody.steps[i] == melody.restSymbol)
|
|
41
|
+
return melody.steps[i];
|
|
42
|
+
else
|
|
43
|
+
return step + melody.steps[i];
|
|
44
|
+
});
|
|
45
|
+
return transformedMelody;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
exports.MelodicVector = MelodicVector;
|
|
49
|
+
//# sourceMappingURL=melodic_vector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"melodic_vector.js","sourceRoot":"","sources":["../../../src/melodic_vector.ts"],"names":[],"mappings":";;;AACA,qCAA8C;AAI9C;;;;;;;;GAQG;AACH,MAAa,aAAa;IAItB;;;;OAIG;IACH,YAAY,KAAe;QACvB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACvB,CAAC;IAGD;;;;;;OAMG;IACH,OAAO,CAAC,MAAc;QAClB,wEAAwE;QACxE,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;QAClE,MAAM,aAAa,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAE5F,oFAAoF;QACpF,kCAAkC;QAClC,MAAM,iBAAiB,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;QACzC,iBAAiB,CAAC,KAAK,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;YACpD,IAAI,MAAM,CAAC,WAAW,IAAI,mBAAU,CAAC,OAAO,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;gBAChE,OAAO,CAAC,CAAC;iBACR,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,UAAU;gBACzC,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;;gBAEvB,OAAO,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;QAEH,OAAO,iBAAiB,CAAC;IAC7B,CAAC;CACJ;AAxCD,sCAwCC"}
|