@tonaljs/pcset
Version:
Functions to work with midi numbers
205 lines (204 loc) • 5.57 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 pcset_exports = {};
__export(pcset_exports, {
EmptyPcset: () => EmptyPcset,
chroma: () => chroma,
chromas: () => chromas,
default: () => pcset_default,
filter: () => filter,
get: () => get,
includes: () => includes,
intervals: () => intervals,
isChroma: () => isChroma,
isEqual: () => isEqual,
isNoteIncludedIn: () => isNoteIncludedIn,
isSubsetOf: () => isSubsetOf,
isSupersetOf: () => isSupersetOf,
modes: () => modes,
notes: () => notes,
num: () => num,
pcset: () => pcset
});
module.exports = __toCommonJS(pcset_exports);
var import_collection = require("@tonaljs/collection");
var import_pitch_distance = require("@tonaljs/pitch-distance");
var import_pitch_interval = require("@tonaljs/pitch-interval");
var import_pitch_note = require("@tonaljs/pitch-note");
var EmptyPcset = {
empty: true,
name: "",
setNum: 0,
chroma: "000000000000",
normalized: "000000000000",
intervals: []
};
var setNumToChroma = (num2) => Number(num2).toString(2).padStart(12, "0");
var chromaToNumber = (chroma2) => parseInt(chroma2, 2);
var REGEX = /^[01]{12}$/;
function isChroma(set) {
return REGEX.test(set);
}
var isPcsetNum = (set) => typeof set === "number" && set >= 0 && set <= 4095;
var isPcset = (set) => set && isChroma(set.chroma);
var cache = { [EmptyPcset.chroma]: EmptyPcset };
function get(src) {
const chroma2 = isChroma(src) ? src : isPcsetNum(src) ? setNumToChroma(src) : Array.isArray(src) ? listToChroma(src) : isPcset(src) ? src.chroma : EmptyPcset.chroma;
return cache[chroma2] = cache[chroma2] || chromaToPcset(chroma2);
}
var pcset = get;
var chroma = (set) => get(set).chroma;
var intervals = (set) => get(set).intervals;
var num = (set) => get(set).setNum;
var IVLS = [
"1P",
"2m",
"2M",
"3m",
"3M",
"4P",
"5d",
"5P",
"6m",
"6M",
"7m",
"7M"
];
function chromaToIntervals(chroma2) {
const intervals2 = [];
for (let i = 0; i < 12; i++) {
if (chroma2.charAt(i) === "1") intervals2.push(IVLS[i]);
}
return intervals2;
}
function notes(set) {
return get(set).intervals.map((ivl) => (0, import_pitch_distance.transpose)("C", ivl));
}
function chromas() {
return (0, import_collection.range)(2048, 4095).map(setNumToChroma);
}
function modes(set, normalize = true) {
const pcs = get(set);
const binary = pcs.chroma.split("");
return (0, import_collection.compact)(
binary.map((_, i) => {
const r = (0, import_collection.rotate)(i, binary);
return normalize && r[0] === "0" ? null : r.join("");
})
);
}
function isEqual(s1, s2) {
return get(s1).setNum === get(s2).setNum;
}
function isSubsetOf(set) {
const s = get(set).setNum;
return (notes2) => {
const o = get(notes2).setNum;
return s && s !== o && (o & s) === o;
};
}
function isSupersetOf(set) {
const s = get(set).setNum;
return (notes2) => {
const o = get(notes2).setNum;
return s && s !== o && (o | s) === o;
};
}
function isNoteIncludedIn(set) {
const s = get(set);
return (noteName) => {
const n = (0, import_pitch_note.note)(noteName);
return s && !n.empty && s.chroma.charAt(n.chroma) === "1";
};
}
var includes = isNoteIncludedIn;
function filter(set) {
const isIncluded = isNoteIncludedIn(set);
return (notes2) => {
return notes2.filter(isIncluded);
};
}
var pcset_default = {
get,
chroma,
num,
intervals,
chromas,
isSupersetOf,
isSubsetOf,
isNoteIncludedIn,
isEqual,
filter,
modes,
notes,
// deprecated
pcset
};
function chromaRotations(chroma2) {
const binary = chroma2.split("");
return binary.map((_, i) => (0, import_collection.rotate)(i, binary).join(""));
}
function chromaToPcset(chroma2) {
const setNum = chromaToNumber(chroma2);
const normalizedNum = chromaRotations(chroma2).map(chromaToNumber).filter((n) => n >= 2048).sort()[0];
const normalized = setNumToChroma(normalizedNum);
const intervals2 = chromaToIntervals(chroma2);
return {
empty: false,
name: "",
setNum,
chroma: chroma2,
normalized,
intervals: intervals2
};
}
function listToChroma(set) {
if (set.length === 0) {
return EmptyPcset.chroma;
}
let pitch;
const binary = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
for (let i = 0; i < set.length; i++) {
pitch = (0, import_pitch_note.note)(set[i]);
if (pitch.empty) pitch = (0, import_pitch_interval.interval)(set[i]);
if (!pitch.empty) binary[pitch.chroma] = 1;
}
return binary.join("");
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
EmptyPcset,
chroma,
chromas,
filter,
get,
includes,
intervals,
isChroma,
isEqual,
isNoteIncludedIn,
isSubsetOf,
isSupersetOf,
modes,
notes,
num,
pcset
});
//# sourceMappingURL=index.js.map