@tonaljs/midi
Version:
Functions to work with midi numbers
102 lines • 2.53 kB
JavaScript
// index.ts
import { note as props } from "@tonaljs/pitch-note";
function isMidi(arg) {
return +arg >= 0 && +arg <= 127;
}
function toMidi(note) {
if (isMidi(note)) {
return +note;
}
const n = props(note);
return n.empty ? null : n.midi;
}
function midiToFreq(midi, tuning = 440) {
return Math.pow(2, (midi - 69) / 12) * tuning;
}
var L2 = Math.log(2);
var L440 = Math.log(440);
function freqToMidi(freq) {
const v = 12 * (Math.log(freq) - L440) / L2 + 69;
return Math.round(v * 100) / 100;
}
var SHARPS = "C C# D D# E F F# G G# A A# B".split(" ");
var FLATS = "C Db D Eb E F Gb G Ab A Bb B".split(" ");
function midiToNoteName(midi, options = {}) {
if (isNaN(midi) || midi === -Infinity || midi === Infinity) return "";
midi = Math.round(midi);
const pcs = options.sharps === true ? SHARPS : FLATS;
const pc = pcs[midi % 12];
if (options.pitchClass) {
return pc;
}
const o = Math.floor(midi / 12) - 1;
return pc + o;
}
function chroma(midi) {
return midi % 12;
}
function pcsetFromChroma(chroma2) {
return chroma2.split("").reduce((pcset2, val, index) => {
if (index < 12 && val === "1") pcset2.push(index);
return pcset2;
}, []);
}
function pcsetFromMidi(midi) {
return midi.map(chroma).sort((a, b) => a - b).filter((n, i, a) => i === 0 || n !== a[i - 1]);
}
function pcset(notes) {
return Array.isArray(notes) ? pcsetFromMidi(notes) : pcsetFromChroma(notes);
}
function pcsetNearest(notes) {
const set = pcset(notes);
return (midi) => {
const ch = chroma(midi);
for (let i = 0; i < 12; i++) {
if (set.includes(ch + i)) return midi + i;
if (set.includes(ch - i)) return midi - i;
}
return void 0;
};
}
function pcsetSteps(notes, tonic) {
const set = pcset(notes);
const len = set.length;
return (step) => {
const index = step < 0 ? (len - -step % len) % len : step % len;
const octaves = Math.floor(step / len);
return set[index] + octaves * 12 + tonic;
};
}
function pcsetDegrees(notes, tonic) {
const steps = pcsetSteps(notes, tonic);
return (degree) => {
if (degree === 0) return void 0;
return steps(degree > 0 ? degree - 1 : degree);
};
}
var index_default = {
chroma,
freqToMidi,
isMidi,
midiToFreq,
midiToNoteName,
pcsetNearest,
pcset,
pcsetDegrees,
pcsetSteps,
toMidi
};
export {
chroma,
index_default as default,
freqToMidi,
isMidi,
midiToFreq,
midiToNoteName,
pcset,
pcsetDegrees,
pcsetNearest,
pcsetSteps,
toMidi
};
//# sourceMappingURL=index.mjs.map