UNPKG

@tonaljs/chord

Version:

Musical chords and its relations

210 lines (209 loc) 7.04 kB
"use strict"; 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