@tonaljs/chord
Version:
Musical chords and its relations
210 lines (209 loc) • 7.04 kB
JavaScript
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// index.ts
var chord_exports = {};
__export(chord_exports, {
chord: () => chord,
chordScales: () => chordScales,
default: () => chord_default,
degrees: () => degrees,
detect: () => import_chord_detect2.detect,
extended: () => extended,
get: () => get,
getChord: () => getChord,
notes: () => notes,
reduced: () => reduced,
steps: () => steps,
tokenize: () => tokenize,
transpose: () => transpose
});
module.exports = __toCommonJS(chord_exports);
var import_chord_detect = require("@tonaljs/chord-detect");
var import_chord_type = require("@tonaljs/chord-type");
var import_interval = require("@tonaljs/interval");
var import_pcset = require("@tonaljs/pcset");
var import_pitch_distance = require("@tonaljs/pitch-distance");
var import_pitch_note = require("@tonaljs/pitch-note");
var import_scale_type = require("@tonaljs/scale-type");
var import_chord_detect2 = require("@tonaljs/chord-detect");
var NoChord = {
empty: true,
name: "",
symbol: "",
root: "",
bass: "",
rootDegree: 0,
type: "",
tonic: null,
setNum: NaN,
quality: "Unknown",
chroma: "",
normalized: "",
aliases: [],
notes: [],
intervals: []
};
function tokenize(name) {
const [letter, acc, oct, type] = (0, import_pitch_note.tokenizeNote)(name);
if (letter === "") {
return tokenizeBass("", name);
} else if (letter === "A" && type === "ug") {
return tokenizeBass("", "aug");
} else {
return tokenizeBass(letter + acc, oct + type);
}
}
function tokenizeBass(note2, chord2) {
const split = chord2.split("/");
if (split.length === 1) {
return [note2, split[0], ""];
}
const [letter, acc, oct, type] = (0, import_pitch_note.tokenizeNote)(split[1]);
if (letter !== "" && oct === "" && type === "") {
return [note2, split[0], letter + acc];
} else {
return [note2, chord2, ""];
}
}
function get(src) {
if (Array.isArray(src)) {
return getChord(src[1] || "", src[0], src[2]);
} else if (src === "") {
return NoChord;
} else {
const [tonic, type, bass] = tokenize(src);
const chord2 = getChord(type, tonic, bass);
return chord2.empty ? getChord(src) : chord2;
}
}
function getChord(typeName, optionalTonic, optionalBass) {
const type = (0, import_chord_type.get)(typeName);
const tonic = (0, import_pitch_note.note)(optionalTonic || "");
const bass = (0, import_pitch_note.note)(optionalBass || "");
if (type.empty || optionalTonic && tonic.empty || optionalBass && bass.empty) {
return NoChord;
}
const bassInterval = (0, import_pitch_distance.distance)(tonic.pc, bass.pc);
const bassIndex = type.intervals.indexOf(bassInterval);
const hasRoot = bassIndex >= 0;
const root = hasRoot ? bass : (0, import_pitch_note.note)("");
const rootDegree = bassIndex === -1 ? NaN : bassIndex + 1;
const hasBass = bass.pc && bass.pc !== tonic.pc;
const intervals = Array.from(type.intervals);
if (hasRoot) {
for (let i = 1; i < rootDegree; i++) {
const num = intervals[0][0];
const quality = intervals[0][1];
const newNum = parseInt(num, 10) + 7;
intervals.push(`${newNum}${quality}`);
intervals.shift();
}
} else if (hasBass) {
const ivl = (0, import_interval.subtract)((0, import_pitch_distance.distance)(tonic.pc, bass.pc), "8P");
if (ivl) intervals.unshift(ivl);
}
const notes2 = tonic.empty ? [] : intervals.map((i) => (0, import_pitch_distance.transpose)(tonic.pc, i));
typeName = type.aliases.indexOf(typeName) !== -1 ? typeName : type.aliases[0];
const symbol = `${tonic.empty ? "" : tonic.pc}${typeName}${hasRoot && rootDegree > 1 ? "/" + root.pc : hasBass ? "/" + bass.pc : ""}`;
const name = `${optionalTonic ? tonic.pc + " " : ""}${type.name}${hasRoot && rootDegree > 1 ? " over " + root.pc : hasBass ? " over " + bass.pc : ""}`;
return {
...type,
name,
symbol,
tonic: tonic.pc,
type: type.name,
root: root.pc,
bass: hasBass ? bass.pc : "",
intervals,
rootDegree,
notes: notes2
};
}
var chord = get;
function transpose(chordName, interval) {
const [tonic, type, bass] = tokenize(chordName);
if (!tonic) {
return chordName;
}
const tr = (0, import_pitch_distance.transpose)(bass, interval);
const slash = tr ? "/" + tr : "";
return (0, import_pitch_distance.transpose)(tonic, interval) + type + slash;
}
function chordScales(name) {
const s = get(name);
const isChordIncluded = (0, import_pcset.isSupersetOf)(s.chroma);
return (0, import_scale_type.all)().filter((scale) => isChordIncluded(scale.chroma)).map((scale) => scale.name);
}
function extended(chordName) {
const s = get(chordName);
const isSuperset = (0, import_pcset.isSupersetOf)(s.chroma);
return (0, import_chord_type.all)().filter((chord2) => isSuperset(chord2.chroma)).map((chord2) => s.tonic + chord2.aliases[0]);
}
function reduced(chordName) {
const s = get(chordName);
const isSubset = (0, import_pcset.isSubsetOf)(s.chroma);
return (0, import_chord_type.all)().filter((chord2) => isSubset(chord2.chroma)).map((chord2) => s.tonic + chord2.aliases[0]);
}
function notes(chordName, tonic) {
const chord2 = get(chordName);
const note2 = tonic || chord2.tonic;
if (!note2 || chord2.empty) return [];
return chord2.intervals.map((ivl) => (0, import_pitch_distance.transpose)(note2, ivl));
}
function degrees(chordName, tonic) {
const chord2 = get(chordName);
const note2 = tonic || chord2.tonic;
const transpose2 = (0, import_pitch_distance.tonicIntervalsTransposer)(chord2.intervals, note2);
return (degree) => degree ? transpose2(degree > 0 ? degree - 1 : degree) : "";
}
function steps(chordName, tonic) {
const chord2 = get(chordName);
const note2 = tonic || chord2.tonic;
return (0, import_pitch_distance.tonicIntervalsTransposer)(chord2.intervals, note2);
}
var chord_default = {
getChord,
get,
detect: import_chord_detect.detect,
chordScales,
extended,
reduced,
tokenize,
transpose,
degrees,
steps,
notes,
chord
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
chord,
chordScales,
degrees,
detect,
extended,
get,
getChord,
notes,
reduced,
steps,
tokenize,
transpose
});
//# sourceMappingURL=index.js.map
;