UNPKG

@tonaljs/voicing

Version:

Voicings and Voice Leading for Chords

106 lines (105 loc) 4.47 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; 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 __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // index.ts var index_exports = {}; __export(index_exports, { default: () => index_default, get: () => get, search: () => search, sequence: () => sequence }); module.exports = __toCommonJS(index_exports); var import_chord = __toESM(require("@tonaljs/chord")); var import_interval = __toESM(require("@tonaljs/interval")); var import_note = __toESM(require("@tonaljs/note")); var import_range = __toESM(require("@tonaljs/range")); var import_voice_leading = __toESM(require("@tonaljs/voice-leading")); var import_voicing_dictionary = __toESM(require("@tonaljs/voicing-dictionary")); var defaultRange = ["C3", "C5"]; var defaultDictionary = import_voicing_dictionary.default.all; var defaultVoiceLeading = import_voice_leading.default.topNoteDiff; function get(chord, range = defaultRange, dictionary = defaultDictionary, voiceLeading = defaultVoiceLeading, lastVoicing) { const voicings = search(chord, range, dictionary); if (!lastVoicing || !lastVoicing.length) { return voicings[0]; } else { return voiceLeading(voicings, lastVoicing); } } function search(chord, range = defaultRange, dictionary = import_voicing_dictionary.default.triads) { const [tonic, symbol] = import_chord.default.tokenize(chord); const sets = import_voicing_dictionary.default.lookup(symbol, dictionary); if (!sets) { return []; } const voicings = sets.map((intervals) => intervals.split(" ")); const notesInRange = import_range.default.chromatic(range); return voicings.reduce((voiced, voicing) => { const relativeIntervals = voicing.map( (interval) => import_interval.default.subtract(interval, voicing[0]) || "" ); const bottomPitchClass = import_note.default.transpose(tonic, voicing[0]); const starts = notesInRange.filter((note) => import_note.default.chroma(note) === import_note.default.chroma(bottomPitchClass)).filter( (note) => (import_note.default.midi( import_note.default.transpose( note, relativeIntervals[relativeIntervals.length - 1] ) ) || 0) <= (import_note.default.midi(range[1]) || 0) ).map((note) => import_note.default.enharmonic(note, bottomPitchClass)); const notes = starts.map( (start) => relativeIntervals.map((interval) => import_note.default.transpose(start, interval)) ); return voiced.concat(notes); }, []); } function sequence(chords, range = defaultRange, dictionary = defaultDictionary, voiceLeading = defaultVoiceLeading, lastVoicing) { const { voicings } = chords.reduce( ({ voicings: voicings2, lastVoicing: lastVoicing2 }, chord) => { const voicing = get(chord, range, dictionary, voiceLeading, lastVoicing2); lastVoicing2 = voicing; voicings2.push(voicing); return { voicings: voicings2, lastVoicing: lastVoicing2 }; }, { voicings: [], lastVoicing } ); return voicings; } var index_default = { get, search, sequence }; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { get, search, sequence }); //# sourceMappingURL=index.js.map