@tonaljs/chord 4.8.0 → 4.10.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/README.md +41 -0
- package/dist/index.d.ts +15 -1
- package/dist/index.js +23 -7
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +14 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -66,6 +66,47 @@ Important: currently chord with roots are NOT allowed (will be implemented in ne
|
|
|
66
66
|
Chord.get("Cmaj7/E"); // => { empty: true }
|
|
67
67
|
```
|
|
68
68
|
|
|
69
|
+
### `Chord.degrees(chordName: string) => (degree: number) => string`
|
|
70
|
+
|
|
71
|
+
`Scale.degrees` returns a function to get a note name from a scale degree:
|
|
72
|
+
|
|
73
|
+
```js
|
|
74
|
+
const c4m7 = Chord.degrees("C4m7");
|
|
75
|
+
c4m7(1); // => "C4"
|
|
76
|
+
c4m7(2); // => "Eb4"
|
|
77
|
+
c4m7(3); // => "G4"
|
|
78
|
+
c4m7(4); // => "Bb4"
|
|
79
|
+
c4m7(1); // => "C5"
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
It can be used to find chord inversions:
|
|
83
|
+
|
|
84
|
+
```js
|
|
85
|
+
[1, 2, 3, 4].map(chord); // => ["C4", "Eb4", "G4", "Bb4"]
|
|
86
|
+
[2, 3, 4, 5].map(chord); // => ["Eb4", "G4", "Bb4", "C5"]
|
|
87
|
+
[3, 4, 5, 6].map(chord); // => ["G4", "Bb4", "C5", "Eb5"]
|
|
88
|
+
[4, 5, 6, 7].map(chord); // => ["Bb4", "C5", "Eb5", "G5"]
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Bear in mind that degree numbers starts with 1 and 0 returns an empty string:
|
|
92
|
+
|
|
93
|
+
```js
|
|
94
|
+
c4m7(0); // => ""
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
See [`Scale.degrees`](https://github.com/tonaljs/tonal/tree/main/packages/scale#scaledegreesscalename-string--degree-number--string)
|
|
98
|
+
|
|
99
|
+
### `Chord.steps(chordName: string) => (degree: number) => string`
|
|
100
|
+
|
|
101
|
+
Same as `Chord.degrees` but 0 is the tonic. Plays better with numeric ranges:
|
|
102
|
+
|
|
103
|
+
```js
|
|
104
|
+
import { Range, Chord } from "tonal";
|
|
105
|
+
|
|
106
|
+
Range.numeric([-3, 3]).map(Chord.steps(["C4", "aug"]));
|
|
107
|
+
// => ["G#3", "E3", "C3", "C4", "E4", "G#4", "C5"]
|
|
108
|
+
```
|
|
109
|
+
|
|
69
110
|
#### `Chord.detect(notes: string[]) => string[]`
|
|
70
111
|
|
|
71
112
|
Given a list of notes, get the possible chord names:
|
package/dist/index.d.ts
CHANGED
|
@@ -78,6 +78,18 @@ declare function extended(chordName: string): string[];
|
|
|
78
78
|
* @example
|
|
79
79
|
*/
|
|
80
80
|
declare function reduced(chordName: string): string[];
|
|
81
|
+
/**
|
|
82
|
+
* Returns a function to get a note name from the scale degree.
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* [1, 2, 3, 4].map(Chord.degrees("C")) => ["C", "E", "G", "C"]
|
|
86
|
+
* [1, 2, 3, 4].map(Chord.degrees("C4")) => ["C4", "E4", "G4", "C5"]
|
|
87
|
+
*/
|
|
88
|
+
declare function degrees(chordName: string | ChordNameTokens): (degree: number) => string;
|
|
89
|
+
/**
|
|
90
|
+
* Sames as `degree` but with 0-based index
|
|
91
|
+
*/
|
|
92
|
+
declare function steps(chordName: string | ChordNameTokens): (normalized: number) => string;
|
|
81
93
|
declare const _default: {
|
|
82
94
|
getChord: typeof getChord;
|
|
83
95
|
get: typeof get;
|
|
@@ -87,7 +99,9 @@ declare const _default: {
|
|
|
87
99
|
reduced: typeof reduced;
|
|
88
100
|
tokenize: typeof tokenize;
|
|
89
101
|
transpose: typeof transpose;
|
|
102
|
+
degrees: typeof degrees;
|
|
103
|
+
steps: typeof steps;
|
|
90
104
|
chord: (this: unknown, ...args: unknown[]) => Chord;
|
|
91
105
|
};
|
|
92
106
|
|
|
93
|
-
export { Chord, chord, chordScales, _default as default, extended, get, getChord, reduced, tokenize, transpose };
|
|
107
|
+
export { Chord, chord, chordScales, _default as default, degrees, extended, get, getChord, reduced, steps, tokenize, transpose };
|
package/dist/index.js
CHANGED
|
@@ -23,11 +23,13 @@ __export(chord_exports, {
|
|
|
23
23
|
chord: () => chord,
|
|
24
24
|
chordScales: () => chordScales,
|
|
25
25
|
default: () => chord_default,
|
|
26
|
+
degrees: () => degrees,
|
|
26
27
|
detect: () => import_chord_detect2.detect,
|
|
27
28
|
extended: () => extended,
|
|
28
29
|
get: () => get,
|
|
29
30
|
getChord: () => getChord,
|
|
30
31
|
reduced: () => reduced,
|
|
32
|
+
steps: () => steps,
|
|
31
33
|
tokenize: () => tokenize,
|
|
32
34
|
transpose: () => transpose
|
|
33
35
|
});
|
|
@@ -35,6 +37,7 @@ module.exports = __toCommonJS(chord_exports);
|
|
|
35
37
|
var import_chord_detect = require("@tonaljs/chord-detect");
|
|
36
38
|
var import_chord_type = require("@tonaljs/chord-type");
|
|
37
39
|
var import_core = require("@tonaljs/core");
|
|
40
|
+
var import_core2 = require("@tonaljs/core");
|
|
38
41
|
var import_pcset = require("@tonaljs/pcset");
|
|
39
42
|
var import_scale_type = require("@tonaljs/scale-type");
|
|
40
43
|
var import_chord_detect2 = require("@tonaljs/chord-detect");
|
|
@@ -56,7 +59,7 @@ var NoChord = {
|
|
|
56
59
|
};
|
|
57
60
|
var NUM_TYPES = /^(6|64|7|9|11|13)$/;
|
|
58
61
|
function tokenize(name) {
|
|
59
|
-
const [letter, acc, oct, type] = (0,
|
|
62
|
+
const [letter, acc, oct, type] = (0, import_core2.tokenizeNote)(name);
|
|
60
63
|
if (letter === "") {
|
|
61
64
|
return ["", name];
|
|
62
65
|
}
|
|
@@ -86,12 +89,12 @@ function get(src) {
|
|
|
86
89
|
}
|
|
87
90
|
function getChord(typeName, optionalTonic, optionalRoot) {
|
|
88
91
|
const type = (0, import_chord_type.get)(typeName);
|
|
89
|
-
const tonic = (0,
|
|
90
|
-
const root = (0,
|
|
92
|
+
const tonic = (0, import_core2.note)(optionalTonic || "");
|
|
93
|
+
const root = (0, import_core2.note)(optionalRoot || "");
|
|
91
94
|
if (type.empty || optionalTonic && tonic.empty || optionalRoot && root.empty) {
|
|
92
95
|
return NoChord;
|
|
93
96
|
}
|
|
94
|
-
const rootInterval = (0,
|
|
97
|
+
const rootInterval = (0, import_core2.distance)(tonic.pc, root.pc);
|
|
95
98
|
const rootDegree = type.intervals.indexOf(rootInterval) + 1;
|
|
96
99
|
if (!root.empty && !rootDegree) {
|
|
97
100
|
return NoChord;
|
|
@@ -104,7 +107,7 @@ function getChord(typeName, optionalTonic, optionalRoot) {
|
|
|
104
107
|
intervals.push(`${newNum}${quality}`);
|
|
105
108
|
intervals.shift();
|
|
106
109
|
}
|
|
107
|
-
const notes = tonic.empty ? [] : intervals.map((i) => (0,
|
|
110
|
+
const notes = tonic.empty ? [] : intervals.map((i) => (0, import_core2.transpose)(tonic, i));
|
|
108
111
|
typeName = type.aliases.indexOf(typeName) !== -1 ? typeName : type.aliases[0];
|
|
109
112
|
const symbol = `${tonic.empty ? "" : tonic.pc}${typeName}${root.empty || rootDegree <= 1 ? "" : "/" + root.pc}`;
|
|
110
113
|
const name = `${optionalTonic ? tonic.pc + " " : ""}${type.name}${rootDegree > 1 && optionalRoot ? " over " + root.pc : ""}`;
|
|
@@ -120,13 +123,13 @@ function getChord(typeName, optionalTonic, optionalRoot) {
|
|
|
120
123
|
notes
|
|
121
124
|
};
|
|
122
125
|
}
|
|
123
|
-
var chord = (0,
|
|
126
|
+
var chord = (0, import_core2.deprecate)("Chord.chord", "Chord.get", get);
|
|
124
127
|
function transpose(chordName, interval) {
|
|
125
128
|
const [tonic, type] = tokenize(chordName);
|
|
126
129
|
if (!tonic) {
|
|
127
130
|
return chordName;
|
|
128
131
|
}
|
|
129
|
-
return (0,
|
|
132
|
+
return (0, import_core2.transpose)(tonic, interval) + type;
|
|
130
133
|
}
|
|
131
134
|
function chordScales(name) {
|
|
132
135
|
const s = get(name);
|
|
@@ -143,6 +146,15 @@ function reduced(chordName) {
|
|
|
143
146
|
const isSubset = (0, import_pcset.isSubsetOf)(s.chroma);
|
|
144
147
|
return (0, import_chord_type.all)().filter((chord2) => isSubset(chord2.chroma)).map((chord2) => s.tonic + chord2.aliases[0]);
|
|
145
148
|
}
|
|
149
|
+
function degrees(chordName) {
|
|
150
|
+
const { intervals, tonic } = get(chordName);
|
|
151
|
+
const transpose2 = (0, import_core.tonicIntervalsTransposer)(intervals, tonic);
|
|
152
|
+
return (degree) => degree ? transpose2(degree > 0 ? degree - 1 : degree) : "";
|
|
153
|
+
}
|
|
154
|
+
function steps(chordName) {
|
|
155
|
+
const { intervals, tonic } = get(chordName);
|
|
156
|
+
return (0, import_core.tonicIntervalsTransposer)(intervals, tonic);
|
|
157
|
+
}
|
|
146
158
|
var chord_default = {
|
|
147
159
|
getChord,
|
|
148
160
|
get,
|
|
@@ -152,17 +164,21 @@ var chord_default = {
|
|
|
152
164
|
reduced,
|
|
153
165
|
tokenize,
|
|
154
166
|
transpose,
|
|
167
|
+
degrees,
|
|
168
|
+
steps,
|
|
155
169
|
chord
|
|
156
170
|
};
|
|
157
171
|
// Annotate the CommonJS export names for ESM import in node:
|
|
158
172
|
0 && (module.exports = {
|
|
159
173
|
chord,
|
|
160
174
|
chordScales,
|
|
175
|
+
degrees,
|
|
161
176
|
detect,
|
|
162
177
|
extended,
|
|
163
178
|
get,
|
|
164
179
|
getChord,
|
|
165
180
|
reduced,
|
|
181
|
+
steps,
|
|
166
182
|
tokenize,
|
|
167
183
|
transpose
|
|
168
184
|
});
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../index.ts"],"sourcesContent":["import { detect } from \"@tonaljs/chord-detect\";\nimport {\n all as chordTypes,\n ChordType,\n get as getChordType,\n} from \"@tonaljs/chord-type\";\n\nimport {\n deprecate,\n distance,\n note,\n NoteName,\n tokenizeNote,\n transpose as transposeNote,\n} from \"@tonaljs/core\";\n\nimport { isSubsetOf, isSupersetOf } from \"@tonaljs/pcset\";\n\nimport { all as scaleTypes } from \"@tonaljs/scale-type\";\nexport { detect } from \"@tonaljs/chord-detect\";\n\ntype ChordName = string;\ntype ChordNameTokens = [string, string]; // [TONIC, SCALE TYPE]\n\nexport interface Chord extends ChordType {\n tonic: string | null;\n type: string;\n root: string;\n rootDegree: number;\n symbol: string;\n notes: NoteName[];\n}\n\nconst NoChord: Chord = {\n empty: true,\n name: \"\",\n symbol: \"\",\n root: \"\",\n rootDegree: 0,\n type: \"\",\n tonic: null,\n setNum: NaN,\n quality: \"Unknown\",\n chroma: \"\",\n normalized: \"\",\n aliases: [],\n notes: [],\n intervals: [],\n};\n\n// 6, 64, 7, 9, 11 and 13 are consider part of the chord\n// (see https://github.com/danigb/tonal/issues/55)\nconst NUM_TYPES = /^(6|64|7|9|11|13)$/;\n/**\n * Tokenize a chord name. It returns an array with the tonic and chord type\n * If not tonic is found, all the name is considered the chord name.\n *\n * This function does NOT check if the chord type exists or not. It only tries\n * to split the tonic and chord type.\n *\n * @function\n * @param {string} name - the chord name\n * @return {Array} an array with [tonic, type]\n * @example\n * tokenize(\"Cmaj7\") // => [ \"C\", \"maj7\" ]\n * tokenize(\"C7\") // => [ \"C\", \"7\" ]\n * tokenize(\"mMaj7\") // => [ null, \"mMaj7\" ]\n * tokenize(\"Cnonsense\") // => [ null, \"nonsense\" ]\n */\nexport function tokenize(name: string): ChordNameTokens {\n const [letter, acc, oct, type] = tokenizeNote(name);\n if (letter === \"\") {\n return [\"\", name];\n }\n // aug is augmented (see https://github.com/danigb/tonal/issues/55)\n if (letter === \"A\" && type === \"ug\") {\n return [\"\", \"aug\"];\n }\n // see: https://github.com/tonaljs/tonal/issues/70\n if (!type && (oct === \"4\" || oct === \"5\")) {\n return [letter + acc, oct];\n }\n\n if (NUM_TYPES.test(oct)) {\n return [letter + acc, oct + type];\n } else {\n return [letter + acc + oct, type];\n }\n}\n\n/**\n * Get a Chord from a chord name.\n */\nexport function get(src: ChordName | ChordNameTokens): Chord {\n if (src === \"\") {\n return NoChord;\n }\n if (Array.isArray(src) && src.length === 2) {\n return getChord(src[1], src[0]);\n } else {\n const [tonic, type] = tokenize(src);\n const chord = getChord(type, tonic);\n return chord.empty ? getChord(src) : chord;\n }\n}\n\n/**\n * Get chord properties\n *\n * @param typeName - the chord type name\n * @param [tonic] - Optional tonic\n * @param [root] - Optional root (requires a tonic)\n */\nexport function getChord(\n typeName: string,\n optionalTonic?: string,\n optionalRoot?: string\n): Chord {\n const type = getChordType(typeName);\n const tonic = note(optionalTonic || \"\");\n const root = note(optionalRoot || \"\");\n\n if (\n type.empty ||\n (optionalTonic && tonic.empty) ||\n (optionalRoot && root.empty)\n ) {\n return NoChord;\n }\n\n const rootInterval = distance(tonic.pc, root.pc);\n const rootDegree = type.intervals.indexOf(rootInterval) + 1;\n if (!root.empty && !rootDegree) {\n return NoChord;\n }\n\n const intervals = Array.from(type.intervals);\n\n for (let i = 1; i < rootDegree; i++) {\n const num = intervals[0][0];\n const quality = intervals[0][1];\n const newNum = parseInt(num, 10) + 7;\n intervals.push(`${newNum}${quality}`);\n intervals.shift();\n }\n\n const notes = tonic.empty\n ? []\n : intervals.map((i) => transposeNote(tonic, i));\n\n typeName = type.aliases.indexOf(typeName) !== -1 ? typeName : type.aliases[0];\n const symbol = `${tonic.empty ? \"\" : tonic.pc}${typeName}${\n root.empty || rootDegree <= 1 ? \"\" : \"/\" + root.pc\n }`;\n const name = `${optionalTonic ? tonic.pc + \" \" : \"\"}${type.name}${\n rootDegree > 1 && optionalRoot ? \" over \" + root.pc : \"\"\n }`;\n return {\n ...type,\n name,\n symbol,\n type: type.name,\n root: root.name,\n intervals,\n rootDegree,\n tonic: tonic.name,\n notes,\n };\n}\n\nexport const chord = deprecate(\"Chord.chord\", \"Chord.get\", get);\n\n/**\n * Transpose a chord name\n *\n * @param {string} chordName - the chord name\n * @return {string} the transposed chord\n *\n * @example\n * transpose('Dm7', 'P4') // => 'Gm7\n */\nexport function transpose(chordName: string, interval: string): string {\n const [tonic, type] = tokenize(chordName);\n if (!tonic) {\n return chordName;\n }\n return transposeNote(tonic, interval) + type;\n}\n\n/**\n * Get all scales where the given chord fits\n *\n * @example\n * chordScales('C7b9')\n * // => [\"phrygian dominant\", \"flamenco\", \"spanish heptatonic\", \"half-whole diminished\", \"chromatic\"]\n */\nexport function chordScales(name: string): string[] {\n const s = get(name);\n const isChordIncluded = isSupersetOf(s.chroma);\n return scaleTypes()\n .filter((scale) => isChordIncluded(scale.chroma))\n .map((scale) => scale.name);\n}\n/**\n * Get all chords names that are a superset of the given one\n * (has the same notes and at least one more)\n *\n * @function\n * @example\n * extended(\"CMaj7\")\n * // => [ 'Cmaj#4', 'Cmaj7#9#11', 'Cmaj9', 'CM7add13', 'Cmaj13', 'Cmaj9#11', 'CM13#11', 'CM7b9' ]\n */\nexport function extended(chordName: string): string[] {\n const s = get(chordName);\n const isSuperset = isSupersetOf(s.chroma);\n return chordTypes()\n .filter((chord) => isSuperset(chord.chroma))\n .map((chord) => s.tonic + chord.aliases[0]);\n}\n\n/**\n * Find all chords names that are a subset of the given one\n * (has less notes but all from the given chord)\n *\n * @example\n */\nexport function reduced(chordName: string): string[] {\n const s = get(chordName);\n const isSubset = isSubsetOf(s.chroma);\n return chordTypes()\n .filter((chord) => isSubset(chord.chroma))\n .map((chord) => s.tonic + chord.aliases[0]);\n}\n\nexport default {\n getChord,\n get,\n detect,\n chordScales,\n extended,\n reduced,\n tokenize,\n transpose,\n // deprecate\n chord,\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAAuB;AACvB,wBAIO;AAEP,kBAOO;AAEP,mBAAyC;AAEzC,wBAAkC;AAClC,IAAAA,uBAAuB;AAcvB,IAAM,UAAiB;AAAA,EACrB,OAAO;AAAA,EACP,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,YAAY;AAAA,EACZ,MAAM;AAAA,EACN,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,SAAS,CAAC;AAAA,EACV,OAAO,CAAC;AAAA,EACR,WAAW,CAAC;AACd;AAIA,IAAM,YAAY;AAiBX,SAAS,SAAS,MAA+B;AACtD,QAAM,CAAC,QAAQ,KAAK,KAAK,IAAI,QAAI,0BAAa,IAAI;AAClD,MAAI,WAAW,IAAI;AACjB,WAAO,CAAC,IAAI,IAAI;AAAA,EAClB;AAEA,MAAI,WAAW,OAAO,SAAS,MAAM;AACnC,WAAO,CAAC,IAAI,KAAK;AAAA,EACnB;AAEA,MAAI,CAAC,SAAS,QAAQ,OAAO,QAAQ,MAAM;AACzC,WAAO,CAAC,SAAS,KAAK,GAAG;AAAA,EAC3B;AAEA,MAAI,UAAU,KAAK,GAAG,GAAG;AACvB,WAAO,CAAC,SAAS,KAAK,MAAM,IAAI;AAAA,EAClC,OAAO;AACL,WAAO,CAAC,SAAS,MAAM,KAAK,IAAI;AAAA,EAClC;AACF;AAKO,SAAS,IAAI,KAAyC;AAC3D,MAAI,QAAQ,IAAI;AACd,WAAO;AAAA,EACT;AACA,MAAI,MAAM,QAAQ,GAAG,KAAK,IAAI,WAAW,GAAG;AAC1C,WAAO,SAAS,IAAI,IAAI,IAAI,EAAE;AAAA,EAChC,OAAO;AACL,UAAM,CAAC,OAAO,IAAI,IAAI,SAAS,GAAG;AAClC,UAAMC,SAAQ,SAAS,MAAM,KAAK;AAClC,WAAOA,OAAM,QAAQ,SAAS,GAAG,IAAIA;AAAA,EACvC;AACF;AASO,SAAS,SACd,UACA,eACA,cACO;AACP,QAAM,WAAO,kBAAAC,KAAa,QAAQ;AAClC,QAAM,YAAQ,kBAAK,iBAAiB,EAAE;AACtC,QAAM,WAAO,kBAAK,gBAAgB,EAAE;AAEpC,MACE,KAAK,SACJ,iBAAiB,MAAM,SACvB,gBAAgB,KAAK,OACtB;AACA,WAAO;AAAA,EACT;AAEA,QAAM,mBAAe,sBAAS,MAAM,IAAI,KAAK,EAAE;AAC/C,QAAM,aAAa,KAAK,UAAU,QAAQ,YAAY,IAAI;AAC1D,MAAI,CAAC,KAAK,SAAS,CAAC,YAAY;AAC9B,WAAO;AAAA,EACT;AAEA,QAAM,YAAY,MAAM,KAAK,KAAK,SAAS;AAE3C,WAAS,IAAI,GAAG,IAAI,YAAY,KAAK;AACnC,UAAM,MAAM,UAAU,GAAG;AACzB,UAAM,UAAU,UAAU,GAAG;AAC7B,UAAM,SAAS,SAAS,KAAK,EAAE,IAAI;AACnC,cAAU,KAAK,GAAG,SAAS,SAAS;AACpC,cAAU,MAAM;AAAA,EAClB;AAEA,QAAM,QAAQ,MAAM,QAChB,CAAC,IACD,UAAU,IAAI,CAAC,UAAM,YAAAC,WAAc,OAAO,CAAC,CAAC;AAEhD,aAAW,KAAK,QAAQ,QAAQ,QAAQ,MAAM,KAAK,WAAW,KAAK,QAAQ;AAC3E,QAAM,SAAS,GAAG,MAAM,QAAQ,KAAK,MAAM,KAAK,WAC9C,KAAK,SAAS,cAAc,IAAI,KAAK,MAAM,KAAK;AAElD,QAAM,OAAO,GAAG,gBAAgB,MAAM,KAAK,MAAM,KAAK,KAAK,OACzD,aAAa,KAAK,eAAe,WAAW,KAAK,KAAK;AAExD,SAAO;AAAA,IACL,GAAG;AAAA,IACH;AAAA,IACA;AAAA,IACA,MAAM,KAAK;AAAA,IACX,MAAM,KAAK;AAAA,IACX;AAAA,IACA;AAAA,IACA,OAAO,MAAM;AAAA,IACb;AAAA,EACF;AACF;AAEO,IAAM,YAAQ,uBAAU,eAAe,aAAa,GAAG;AAWvD,SAAS,UAAU,WAAmB,UAA0B;AACrE,QAAM,CAAC,OAAO,IAAI,IAAI,SAAS,SAAS;AACxC,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AACA,aAAO,YAAAA,WAAc,OAAO,QAAQ,IAAI;AAC1C;AASO,SAAS,YAAY,MAAwB;AAClD,QAAM,IAAI,IAAI,IAAI;AAClB,QAAM,sBAAkB,2BAAa,EAAE,MAAM;AAC7C,aAAO,kBAAAC,KAAW,EACf,OAAO,CAAC,UAAU,gBAAgB,MAAM,MAAM,CAAC,EAC/C,IAAI,CAAC,UAAU,MAAM,IAAI;AAC9B;AAUO,SAAS,SAAS,WAA6B;AACpD,QAAM,IAAI,IAAI,SAAS;AACvB,QAAM,iBAAa,2BAAa,EAAE,MAAM;AACxC,aAAO,kBAAAC,KAAW,EACf,OAAO,CAACJ,WAAU,WAAWA,OAAM,MAAM,CAAC,EAC1C,IAAI,CAACA,WAAU,EAAE,QAAQA,OAAM,QAAQ,EAAE;AAC9C;AAQO,SAAS,QAAQ,WAA6B;AACnD,QAAM,IAAI,IAAI,SAAS;AACvB,QAAM,eAAW,yBAAW,EAAE,MAAM;AACpC,aAAO,kBAAAI,KAAW,EACf,OAAO,CAACJ,WAAU,SAASA,OAAM,MAAM,CAAC,EACxC,IAAI,CAACA,WAAU,EAAE,QAAQA,OAAM,QAAQ,EAAE;AAC9C;AAEA,IAAO,gBAAQ;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AACF;","names":["import_chord_detect","chord","getChordType","transposeNote","scaleTypes","chordTypes"]}
|
|
1
|
+
{"version":3,"sources":["../index.ts"],"sourcesContent":["import { detect } from \"@tonaljs/chord-detect\";\nimport {\n all as chordTypes,\n ChordType,\n get as getChordType,\n} from \"@tonaljs/chord-type\";\nimport { tonicIntervalsTransposer } from \"@tonaljs/core\";\n\nimport {\n deprecate,\n distance,\n note,\n NoteName,\n tokenizeNote,\n transpose as transposeNote,\n} from \"@tonaljs/core\";\n\nimport { isSubsetOf, isSupersetOf } from \"@tonaljs/pcset\";\n\nimport { all as scaleTypes } from \"@tonaljs/scale-type\";\nexport { detect } from \"@tonaljs/chord-detect\";\n\ntype ChordName = string;\ntype ChordNameTokens = [string, string]; // [TONIC, SCALE TYPE]\n\nexport interface Chord extends ChordType {\n tonic: string | null;\n type: string;\n root: string;\n rootDegree: number;\n symbol: string;\n notes: NoteName[];\n}\n\nconst NoChord: Chord = {\n empty: true,\n name: \"\",\n symbol: \"\",\n root: \"\",\n rootDegree: 0,\n type: \"\",\n tonic: null,\n setNum: NaN,\n quality: \"Unknown\",\n chroma: \"\",\n normalized: \"\",\n aliases: [],\n notes: [],\n intervals: [],\n};\n\n// 6, 64, 7, 9, 11 and 13 are consider part of the chord\n// (see https://github.com/danigb/tonal/issues/55)\nconst NUM_TYPES = /^(6|64|7|9|11|13)$/;\n/**\n * Tokenize a chord name. It returns an array with the tonic and chord type\n * If not tonic is found, all the name is considered the chord name.\n *\n * This function does NOT check if the chord type exists or not. It only tries\n * to split the tonic and chord type.\n *\n * @function\n * @param {string} name - the chord name\n * @return {Array} an array with [tonic, type]\n * @example\n * tokenize(\"Cmaj7\") // => [ \"C\", \"maj7\" ]\n * tokenize(\"C7\") // => [ \"C\", \"7\" ]\n * tokenize(\"mMaj7\") // => [ null, \"mMaj7\" ]\n * tokenize(\"Cnonsense\") // => [ null, \"nonsense\" ]\n */\nexport function tokenize(name: string): ChordNameTokens {\n const [letter, acc, oct, type] = tokenizeNote(name);\n if (letter === \"\") {\n return [\"\", name];\n }\n // aug is augmented (see https://github.com/danigb/tonal/issues/55)\n if (letter === \"A\" && type === \"ug\") {\n return [\"\", \"aug\"];\n }\n // see: https://github.com/tonaljs/tonal/issues/70\n if (!type && (oct === \"4\" || oct === \"5\")) {\n return [letter + acc, oct];\n }\n\n if (NUM_TYPES.test(oct)) {\n return [letter + acc, oct + type];\n } else {\n return [letter + acc + oct, type];\n }\n}\n\n/**\n * Get a Chord from a chord name.\n */\nexport function get(src: ChordName | ChordNameTokens): Chord {\n if (src === \"\") {\n return NoChord;\n }\n if (Array.isArray(src) && src.length === 2) {\n return getChord(src[1], src[0]);\n } else {\n const [tonic, type] = tokenize(src);\n const chord = getChord(type, tonic);\n return chord.empty ? getChord(src) : chord;\n }\n}\n\n/**\n * Get chord properties\n *\n * @param typeName - the chord type name\n * @param [tonic] - Optional tonic\n * @param [root] - Optional root (requires a tonic)\n */\nexport function getChord(\n typeName: string,\n optionalTonic?: string,\n optionalRoot?: string\n): Chord {\n const type = getChordType(typeName);\n const tonic = note(optionalTonic || \"\");\n const root = note(optionalRoot || \"\");\n\n if (\n type.empty ||\n (optionalTonic && tonic.empty) ||\n (optionalRoot && root.empty)\n ) {\n return NoChord;\n }\n\n const rootInterval = distance(tonic.pc, root.pc);\n const rootDegree = type.intervals.indexOf(rootInterval) + 1;\n if (!root.empty && !rootDegree) {\n return NoChord;\n }\n\n const intervals = Array.from(type.intervals);\n\n for (let i = 1; i < rootDegree; i++) {\n const num = intervals[0][0];\n const quality = intervals[0][1];\n const newNum = parseInt(num, 10) + 7;\n intervals.push(`${newNum}${quality}`);\n intervals.shift();\n }\n\n const notes = tonic.empty\n ? []\n : intervals.map((i) => transposeNote(tonic, i));\n\n typeName = type.aliases.indexOf(typeName) !== -1 ? typeName : type.aliases[0];\n const symbol = `${tonic.empty ? \"\" : tonic.pc}${typeName}${\n root.empty || rootDegree <= 1 ? \"\" : \"/\" + root.pc\n }`;\n const name = `${optionalTonic ? tonic.pc + \" \" : \"\"}${type.name}${\n rootDegree > 1 && optionalRoot ? \" over \" + root.pc : \"\"\n }`;\n return {\n ...type,\n name,\n symbol,\n type: type.name,\n root: root.name,\n intervals,\n rootDegree,\n tonic: tonic.name,\n notes,\n };\n}\n\nexport const chord = deprecate(\"Chord.chord\", \"Chord.get\", get);\n\n/**\n * Transpose a chord name\n *\n * @param {string} chordName - the chord name\n * @return {string} the transposed chord\n *\n * @example\n * transpose('Dm7', 'P4') // => 'Gm7\n */\nexport function transpose(chordName: string, interval: string): string {\n const [tonic, type] = tokenize(chordName);\n if (!tonic) {\n return chordName;\n }\n return transposeNote(tonic, interval) + type;\n}\n\n/**\n * Get all scales where the given chord fits\n *\n * @example\n * chordScales('C7b9')\n * // => [\"phrygian dominant\", \"flamenco\", \"spanish heptatonic\", \"half-whole diminished\", \"chromatic\"]\n */\nexport function chordScales(name: string): string[] {\n const s = get(name);\n const isChordIncluded = isSupersetOf(s.chroma);\n return scaleTypes()\n .filter((scale) => isChordIncluded(scale.chroma))\n .map((scale) => scale.name);\n}\n/**\n * Get all chords names that are a superset of the given one\n * (has the same notes and at least one more)\n *\n * @function\n * @example\n * extended(\"CMaj7\")\n * // => [ 'Cmaj#4', 'Cmaj7#9#11', 'Cmaj9', 'CM7add13', 'Cmaj13', 'Cmaj9#11', 'CM13#11', 'CM7b9' ]\n */\nexport function extended(chordName: string): string[] {\n const s = get(chordName);\n const isSuperset = isSupersetOf(s.chroma);\n return chordTypes()\n .filter((chord) => isSuperset(chord.chroma))\n .map((chord) => s.tonic + chord.aliases[0]);\n}\n\n/**\n * Find all chords names that are a subset of the given one\n * (has less notes but all from the given chord)\n *\n * @example\n */\nexport function reduced(chordName: string): string[] {\n const s = get(chordName);\n const isSubset = isSubsetOf(s.chroma);\n return chordTypes()\n .filter((chord) => isSubset(chord.chroma))\n .map((chord) => s.tonic + chord.aliases[0]);\n}\n\n/**\n * Returns a function to get a note name from the scale degree.\n *\n * @example\n * [1, 2, 3, 4].map(Chord.degrees(\"C\")) => [\"C\", \"E\", \"G\", \"C\"]\n * [1, 2, 3, 4].map(Chord.degrees(\"C4\")) => [\"C4\", \"E4\", \"G4\", \"C5\"]\n */\nexport function degrees(chordName: string | ChordNameTokens) {\n const { intervals, tonic } = get(chordName);\n const transpose = tonicIntervalsTransposer(intervals, tonic);\n return (degree: number) =>\n degree ? transpose(degree > 0 ? degree - 1 : degree) : \"\";\n}\n\n/**\n * Sames as `degree` but with 0-based index\n */\nexport function steps(chordName: string | ChordNameTokens) {\n const { intervals, tonic } = get(chordName);\n return tonicIntervalsTransposer(intervals, tonic);\n}\n\nexport default {\n getChord,\n get,\n detect,\n chordScales,\n extended,\n reduced,\n tokenize,\n transpose,\n degrees,\n steps,\n\n // deprecate\n chord,\n};\n"],"mappings":"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","names":["import_core","import_chord_detect","chord","getChordType","transposeNote","scaleTypes","chordTypes","transpose"]}
|
package/dist/index.mjs
CHANGED
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
all as chordTypes,
|
|
5
5
|
get as getChordType
|
|
6
6
|
} from "@tonaljs/chord-type";
|
|
7
|
+
import { tonicIntervalsTransposer } from "@tonaljs/core";
|
|
7
8
|
import {
|
|
8
9
|
deprecate,
|
|
9
10
|
distance,
|
|
@@ -119,6 +120,15 @@ function reduced(chordName) {
|
|
|
119
120
|
const isSubset = isSubsetOf(s.chroma);
|
|
120
121
|
return chordTypes().filter((chord2) => isSubset(chord2.chroma)).map((chord2) => s.tonic + chord2.aliases[0]);
|
|
121
122
|
}
|
|
123
|
+
function degrees(chordName) {
|
|
124
|
+
const { intervals, tonic } = get(chordName);
|
|
125
|
+
const transpose2 = tonicIntervalsTransposer(intervals, tonic);
|
|
126
|
+
return (degree) => degree ? transpose2(degree > 0 ? degree - 1 : degree) : "";
|
|
127
|
+
}
|
|
128
|
+
function steps(chordName) {
|
|
129
|
+
const { intervals, tonic } = get(chordName);
|
|
130
|
+
return tonicIntervalsTransposer(intervals, tonic);
|
|
131
|
+
}
|
|
122
132
|
var chord_default = {
|
|
123
133
|
getChord,
|
|
124
134
|
get,
|
|
@@ -128,17 +138,21 @@ var chord_default = {
|
|
|
128
138
|
reduced,
|
|
129
139
|
tokenize,
|
|
130
140
|
transpose,
|
|
141
|
+
degrees,
|
|
142
|
+
steps,
|
|
131
143
|
chord
|
|
132
144
|
};
|
|
133
145
|
export {
|
|
134
146
|
chord,
|
|
135
147
|
chordScales,
|
|
136
148
|
chord_default as default,
|
|
149
|
+
degrees,
|
|
137
150
|
detect2 as detect,
|
|
138
151
|
extended,
|
|
139
152
|
get,
|
|
140
153
|
getChord,
|
|
141
154
|
reduced,
|
|
155
|
+
steps,
|
|
142
156
|
tokenize,
|
|
143
157
|
transpose
|
|
144
158
|
};
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../index.ts"],"sourcesContent":["import { detect } from \"@tonaljs/chord-detect\";\nimport {\n all as chordTypes,\n ChordType,\n get as getChordType,\n} from \"@tonaljs/chord-type\";\n\nimport {\n deprecate,\n distance,\n note,\n NoteName,\n tokenizeNote,\n transpose as transposeNote,\n} from \"@tonaljs/core\";\n\nimport { isSubsetOf, isSupersetOf } from \"@tonaljs/pcset\";\n\nimport { all as scaleTypes } from \"@tonaljs/scale-type\";\nexport { detect } from \"@tonaljs/chord-detect\";\n\ntype ChordName = string;\ntype ChordNameTokens = [string, string]; // [TONIC, SCALE TYPE]\n\nexport interface Chord extends ChordType {\n tonic: string | null;\n type: string;\n root: string;\n rootDegree: number;\n symbol: string;\n notes: NoteName[];\n}\n\nconst NoChord: Chord = {\n empty: true,\n name: \"\",\n symbol: \"\",\n root: \"\",\n rootDegree: 0,\n type: \"\",\n tonic: null,\n setNum: NaN,\n quality: \"Unknown\",\n chroma: \"\",\n normalized: \"\",\n aliases: [],\n notes: [],\n intervals: [],\n};\n\n// 6, 64, 7, 9, 11 and 13 are consider part of the chord\n// (see https://github.com/danigb/tonal/issues/55)\nconst NUM_TYPES = /^(6|64|7|9|11|13)$/;\n/**\n * Tokenize a chord name. It returns an array with the tonic and chord type\n * If not tonic is found, all the name is considered the chord name.\n *\n * This function does NOT check if the chord type exists or not. It only tries\n * to split the tonic and chord type.\n *\n * @function\n * @param {string} name - the chord name\n * @return {Array} an array with [tonic, type]\n * @example\n * tokenize(\"Cmaj7\") // => [ \"C\", \"maj7\" ]\n * tokenize(\"C7\") // => [ \"C\", \"7\" ]\n * tokenize(\"mMaj7\") // => [ null, \"mMaj7\" ]\n * tokenize(\"Cnonsense\") // => [ null, \"nonsense\" ]\n */\nexport function tokenize(name: string): ChordNameTokens {\n const [letter, acc, oct, type] = tokenizeNote(name);\n if (letter === \"\") {\n return [\"\", name];\n }\n // aug is augmented (see https://github.com/danigb/tonal/issues/55)\n if (letter === \"A\" && type === \"ug\") {\n return [\"\", \"aug\"];\n }\n // see: https://github.com/tonaljs/tonal/issues/70\n if (!type && (oct === \"4\" || oct === \"5\")) {\n return [letter + acc, oct];\n }\n\n if (NUM_TYPES.test(oct)) {\n return [letter + acc, oct + type];\n } else {\n return [letter + acc + oct, type];\n }\n}\n\n/**\n * Get a Chord from a chord name.\n */\nexport function get(src: ChordName | ChordNameTokens): Chord {\n if (src === \"\") {\n return NoChord;\n }\n if (Array.isArray(src) && src.length === 2) {\n return getChord(src[1], src[0]);\n } else {\n const [tonic, type] = tokenize(src);\n const chord = getChord(type, tonic);\n return chord.empty ? getChord(src) : chord;\n }\n}\n\n/**\n * Get chord properties\n *\n * @param typeName - the chord type name\n * @param [tonic] - Optional tonic\n * @param [root] - Optional root (requires a tonic)\n */\nexport function getChord(\n typeName: string,\n optionalTonic?: string,\n optionalRoot?: string\n): Chord {\n const type = getChordType(typeName);\n const tonic = note(optionalTonic || \"\");\n const root = note(optionalRoot || \"\");\n\n if (\n type.empty ||\n (optionalTonic && tonic.empty) ||\n (optionalRoot && root.empty)\n ) {\n return NoChord;\n }\n\n const rootInterval = distance(tonic.pc, root.pc);\n const rootDegree = type.intervals.indexOf(rootInterval) + 1;\n if (!root.empty && !rootDegree) {\n return NoChord;\n }\n\n const intervals = Array.from(type.intervals);\n\n for (let i = 1; i < rootDegree; i++) {\n const num = intervals[0][0];\n const quality = intervals[0][1];\n const newNum = parseInt(num, 10) + 7;\n intervals.push(`${newNum}${quality}`);\n intervals.shift();\n }\n\n const notes = tonic.empty\n ? []\n : intervals.map((i) => transposeNote(tonic, i));\n\n typeName = type.aliases.indexOf(typeName) !== -1 ? typeName : type.aliases[0];\n const symbol = `${tonic.empty ? \"\" : tonic.pc}${typeName}${\n root.empty || rootDegree <= 1 ? \"\" : \"/\" + root.pc\n }`;\n const name = `${optionalTonic ? tonic.pc + \" \" : \"\"}${type.name}${\n rootDegree > 1 && optionalRoot ? \" over \" + root.pc : \"\"\n }`;\n return {\n ...type,\n name,\n symbol,\n type: type.name,\n root: root.name,\n intervals,\n rootDegree,\n tonic: tonic.name,\n notes,\n };\n}\n\nexport const chord = deprecate(\"Chord.chord\", \"Chord.get\", get);\n\n/**\n * Transpose a chord name\n *\n * @param {string} chordName - the chord name\n * @return {string} the transposed chord\n *\n * @example\n * transpose('Dm7', 'P4') // => 'Gm7\n */\nexport function transpose(chordName: string, interval: string): string {\n const [tonic, type] = tokenize(chordName);\n if (!tonic) {\n return chordName;\n }\n return transposeNote(tonic, interval) + type;\n}\n\n/**\n * Get all scales where the given chord fits\n *\n * @example\n * chordScales('C7b9')\n * // => [\"phrygian dominant\", \"flamenco\", \"spanish heptatonic\", \"half-whole diminished\", \"chromatic\"]\n */\nexport function chordScales(name: string): string[] {\n const s = get(name);\n const isChordIncluded = isSupersetOf(s.chroma);\n return scaleTypes()\n .filter((scale) => isChordIncluded(scale.chroma))\n .map((scale) => scale.name);\n}\n/**\n * Get all chords names that are a superset of the given one\n * (has the same notes and at least one more)\n *\n * @function\n * @example\n * extended(\"CMaj7\")\n * // => [ 'Cmaj#4', 'Cmaj7#9#11', 'Cmaj9', 'CM7add13', 'Cmaj13', 'Cmaj9#11', 'CM13#11', 'CM7b9' ]\n */\nexport function extended(chordName: string): string[] {\n const s = get(chordName);\n const isSuperset = isSupersetOf(s.chroma);\n return chordTypes()\n .filter((chord) => isSuperset(chord.chroma))\n .map((chord) => s.tonic + chord.aliases[0]);\n}\n\n/**\n * Find all chords names that are a subset of the given one\n * (has less notes but all from the given chord)\n *\n * @example\n */\nexport function reduced(chordName: string): string[] {\n const s = get(chordName);\n const isSubset = isSubsetOf(s.chroma);\n return chordTypes()\n .filter((chord) => isSubset(chord.chroma))\n .map((chord) => s.tonic + chord.aliases[0]);\n}\n\nexport default {\n getChord,\n get,\n detect,\n chordScales,\n extended,\n reduced,\n tokenize,\n transpose,\n // deprecate\n chord,\n};\n"],"mappings":"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","names":["detect","chord"]}
|
|
1
|
+
{"version":3,"sources":["../index.ts"],"sourcesContent":["import { detect } from \"@tonaljs/chord-detect\";\nimport {\n all as chordTypes,\n ChordType,\n get as getChordType,\n} from \"@tonaljs/chord-type\";\nimport { tonicIntervalsTransposer } from \"@tonaljs/core\";\n\nimport {\n deprecate,\n distance,\n note,\n NoteName,\n tokenizeNote,\n transpose as transposeNote,\n} from \"@tonaljs/core\";\n\nimport { isSubsetOf, isSupersetOf } from \"@tonaljs/pcset\";\n\nimport { all as scaleTypes } from \"@tonaljs/scale-type\";\nexport { detect } from \"@tonaljs/chord-detect\";\n\ntype ChordName = string;\ntype ChordNameTokens = [string, string]; // [TONIC, SCALE TYPE]\n\nexport interface Chord extends ChordType {\n tonic: string | null;\n type: string;\n root: string;\n rootDegree: number;\n symbol: string;\n notes: NoteName[];\n}\n\nconst NoChord: Chord = {\n empty: true,\n name: \"\",\n symbol: \"\",\n root: \"\",\n rootDegree: 0,\n type: \"\",\n tonic: null,\n setNum: NaN,\n quality: \"Unknown\",\n chroma: \"\",\n normalized: \"\",\n aliases: [],\n notes: [],\n intervals: [],\n};\n\n// 6, 64, 7, 9, 11 and 13 are consider part of the chord\n// (see https://github.com/danigb/tonal/issues/55)\nconst NUM_TYPES = /^(6|64|7|9|11|13)$/;\n/**\n * Tokenize a chord name. It returns an array with the tonic and chord type\n * If not tonic is found, all the name is considered the chord name.\n *\n * This function does NOT check if the chord type exists or not. It only tries\n * to split the tonic and chord type.\n *\n * @function\n * @param {string} name - the chord name\n * @return {Array} an array with [tonic, type]\n * @example\n * tokenize(\"Cmaj7\") // => [ \"C\", \"maj7\" ]\n * tokenize(\"C7\") // => [ \"C\", \"7\" ]\n * tokenize(\"mMaj7\") // => [ null, \"mMaj7\" ]\n * tokenize(\"Cnonsense\") // => [ null, \"nonsense\" ]\n */\nexport function tokenize(name: string): ChordNameTokens {\n const [letter, acc, oct, type] = tokenizeNote(name);\n if (letter === \"\") {\n return [\"\", name];\n }\n // aug is augmented (see https://github.com/danigb/tonal/issues/55)\n if (letter === \"A\" && type === \"ug\") {\n return [\"\", \"aug\"];\n }\n // see: https://github.com/tonaljs/tonal/issues/70\n if (!type && (oct === \"4\" || oct === \"5\")) {\n return [letter + acc, oct];\n }\n\n if (NUM_TYPES.test(oct)) {\n return [letter + acc, oct + type];\n } else {\n return [letter + acc + oct, type];\n }\n}\n\n/**\n * Get a Chord from a chord name.\n */\nexport function get(src: ChordName | ChordNameTokens): Chord {\n if (src === \"\") {\n return NoChord;\n }\n if (Array.isArray(src) && src.length === 2) {\n return getChord(src[1], src[0]);\n } else {\n const [tonic, type] = tokenize(src);\n const chord = getChord(type, tonic);\n return chord.empty ? getChord(src) : chord;\n }\n}\n\n/**\n * Get chord properties\n *\n * @param typeName - the chord type name\n * @param [tonic] - Optional tonic\n * @param [root] - Optional root (requires a tonic)\n */\nexport function getChord(\n typeName: string,\n optionalTonic?: string,\n optionalRoot?: string\n): Chord {\n const type = getChordType(typeName);\n const tonic = note(optionalTonic || \"\");\n const root = note(optionalRoot || \"\");\n\n if (\n type.empty ||\n (optionalTonic && tonic.empty) ||\n (optionalRoot && root.empty)\n ) {\n return NoChord;\n }\n\n const rootInterval = distance(tonic.pc, root.pc);\n const rootDegree = type.intervals.indexOf(rootInterval) + 1;\n if (!root.empty && !rootDegree) {\n return NoChord;\n }\n\n const intervals = Array.from(type.intervals);\n\n for (let i = 1; i < rootDegree; i++) {\n const num = intervals[0][0];\n const quality = intervals[0][1];\n const newNum = parseInt(num, 10) + 7;\n intervals.push(`${newNum}${quality}`);\n intervals.shift();\n }\n\n const notes = tonic.empty\n ? []\n : intervals.map((i) => transposeNote(tonic, i));\n\n typeName = type.aliases.indexOf(typeName) !== -1 ? typeName : type.aliases[0];\n const symbol = `${tonic.empty ? \"\" : tonic.pc}${typeName}${\n root.empty || rootDegree <= 1 ? \"\" : \"/\" + root.pc\n }`;\n const name = `${optionalTonic ? tonic.pc + \" \" : \"\"}${type.name}${\n rootDegree > 1 && optionalRoot ? \" over \" + root.pc : \"\"\n }`;\n return {\n ...type,\n name,\n symbol,\n type: type.name,\n root: root.name,\n intervals,\n rootDegree,\n tonic: tonic.name,\n notes,\n };\n}\n\nexport const chord = deprecate(\"Chord.chord\", \"Chord.get\", get);\n\n/**\n * Transpose a chord name\n *\n * @param {string} chordName - the chord name\n * @return {string} the transposed chord\n *\n * @example\n * transpose('Dm7', 'P4') // => 'Gm7\n */\nexport function transpose(chordName: string, interval: string): string {\n const [tonic, type] = tokenize(chordName);\n if (!tonic) {\n return chordName;\n }\n return transposeNote(tonic, interval) + type;\n}\n\n/**\n * Get all scales where the given chord fits\n *\n * @example\n * chordScales('C7b9')\n * // => [\"phrygian dominant\", \"flamenco\", \"spanish heptatonic\", \"half-whole diminished\", \"chromatic\"]\n */\nexport function chordScales(name: string): string[] {\n const s = get(name);\n const isChordIncluded = isSupersetOf(s.chroma);\n return scaleTypes()\n .filter((scale) => isChordIncluded(scale.chroma))\n .map((scale) => scale.name);\n}\n/**\n * Get all chords names that are a superset of the given one\n * (has the same notes and at least one more)\n *\n * @function\n * @example\n * extended(\"CMaj7\")\n * // => [ 'Cmaj#4', 'Cmaj7#9#11', 'Cmaj9', 'CM7add13', 'Cmaj13', 'Cmaj9#11', 'CM13#11', 'CM7b9' ]\n */\nexport function extended(chordName: string): string[] {\n const s = get(chordName);\n const isSuperset = isSupersetOf(s.chroma);\n return chordTypes()\n .filter((chord) => isSuperset(chord.chroma))\n .map((chord) => s.tonic + chord.aliases[0]);\n}\n\n/**\n * Find all chords names that are a subset of the given one\n * (has less notes but all from the given chord)\n *\n * @example\n */\nexport function reduced(chordName: string): string[] {\n const s = get(chordName);\n const isSubset = isSubsetOf(s.chroma);\n return chordTypes()\n .filter((chord) => isSubset(chord.chroma))\n .map((chord) => s.tonic + chord.aliases[0]);\n}\n\n/**\n * Returns a function to get a note name from the scale degree.\n *\n * @example\n * [1, 2, 3, 4].map(Chord.degrees(\"C\")) => [\"C\", \"E\", \"G\", \"C\"]\n * [1, 2, 3, 4].map(Chord.degrees(\"C4\")) => [\"C4\", \"E4\", \"G4\", \"C5\"]\n */\nexport function degrees(chordName: string | ChordNameTokens) {\n const { intervals, tonic } = get(chordName);\n const transpose = tonicIntervalsTransposer(intervals, tonic);\n return (degree: number) =>\n degree ? transpose(degree > 0 ? degree - 1 : degree) : \"\";\n}\n\n/**\n * Sames as `degree` but with 0-based index\n */\nexport function steps(chordName: string | ChordNameTokens) {\n const { intervals, tonic } = get(chordName);\n return tonicIntervalsTransposer(intervals, tonic);\n}\n\nexport default {\n getChord,\n get,\n detect,\n chordScales,\n extended,\n reduced,\n tokenize,\n transpose,\n degrees,\n steps,\n\n // deprecate\n chord,\n};\n"],"mappings":"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","names":["detect","chord","transpose"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tonaljs/chord",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.10.0",
|
|
4
4
|
"description": "Musical chords and its relations",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"chord",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"@tonaljs/chord-detect": "^4.8.0",
|
|
20
20
|
"@tonaljs/chord-type": "^4.8.0",
|
|
21
21
|
"@tonaljs/collection": "^4.8.0",
|
|
22
|
-
"@tonaljs/core": "^4.
|
|
22
|
+
"@tonaljs/core": "^4.10.0",
|
|
23
23
|
"@tonaljs/pcset": "^4.8.0",
|
|
24
24
|
"@tonaljs/scale-type": "^4.8.0"
|
|
25
25
|
},
|