const NOTE_NAMES = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B']; const A4_FREQUENCY = 440; const A4_MIDI_NOTE = 69; export function noteToFrequency(noteName: string): number | null { const match = noteName.match(/^([A-G]#?)(-?\d+)$/i); if (!match) return null; const [, note, octave] = match; const noteIndex = NOTE_NAMES.indexOf(note.toUpperCase()); if (noteIndex === -1) return null; const octaveNum = parseInt(octave, 10); const midiNote = (octaveNum + 1) * 12 + noteIndex; const semitonesDiff = midiNote - A4_MIDI_NOTE; return A4_FREQUENCY * Math.pow(2, semitonesDiff / 12); } export function parseFrequencyInput(input: string): number | null { const trimmed = input.trim(); const asNumber = parseFloat(trimmed); if (!isNaN(asNumber) && asNumber > 0 && asNumber < 20000) { return asNumber; } return noteToFrequency(trimmed); } export function formatFrequency(frequency: number): string { return frequency.toFixed(2); }