← Public packages
@kentcdodds/pocket-piano
A pocket piano for choir practice: your singing part's range on your phone, installable and offline.
src/index.ts
36 lines · 1.3 KB · TypeScriptimport { 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,
}
}