UNPKG

@tonaljs/midi

Version:

Functions to work with midi numbers

136 lines (135 loc) 3.84 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 index_exports = {}; __export(index_exports, { chroma: () => chroma, default: () => index_default, freqToMidi: () => freqToMidi, isMidi: () => isMidi, midiToFreq: () => midiToFreq, midiToNoteName: () => midiToNoteName, pcset: () => pcset, pcsetDegrees: () => pcsetDegrees, pcsetNearest: () => pcsetNearest, pcsetSteps: () => pcsetSteps, toMidi: () => toMidi }); module.exports = __toCommonJS(index_exports); var import_pitch_note = require("@tonaljs/pitch-note"); function isMidi(arg) { return +arg >= 0 && +arg <= 127; } function toMidi(note) { if (isMidi(note)) { return +note; } const n = (0, import_pitch_note.note)(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 }; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { chroma, freqToMidi, isMidi, midiToFreq, midiToNoteName, pcset, pcsetDegrees, pcsetNearest, pcsetSteps, toMidi }); //# sourceMappingURL=index.js.map