import { midiToFrequency, midiToName } from './notes.ts' /** * Look up the name and frequency of a MIDI note number. * Use when an agent needs the same note naming the Pocket Piano app shows * (for example to tell Kent which key to press for a starting pitch). * * @param input - `{ midi }` where midi is an integer from 0 to 127 (60 is middle C, C4) * @returns `{ midi, name, frequency }` with frequency in Hz (A4 = 440) * * @example * import noteInfo from 'kody:@kentcdodds/pocket-piano' * * const info = await noteInfo({ midi: 60 }) // { midi: 60, name: 'C4', frequency: 261.63 } */ export default async function noteInfo(input: unknown) { if (!input || typeof input !== 'object') { throw new Error('Expected an object like { midi: 60 }.') } const keys = Object.keys(input) const unknown = keys.filter((key) => key !== 'midi') if (unknown.length > 0) { throw new Error( 'Unknown key(s): ' + unknown.join(', ') + '. Accepted shape: { midi: number }.', ) } const midi = (input as { midi?: unknown }).midi if (typeof midi !== 'number' || !Number.isInteger(midi) || midi < 0 || midi > 127) { throw new Error('midi must be an integer from 0 to 127 (60 is middle C).') } return { midi, name: midiToName(midi), frequency: Math.round(midiToFrequency(midi) * 100) / 100, } }