clean interface
This commit is contained in:
33
src/lib/utils/pitch.ts
Normal file
33
src/lib/utils/pitch.ts
Normal file
@ -0,0 +1,33 @@
|
||||
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);
|
||||
}
|
||||
@ -1,9 +1,13 @@
|
||||
const DEFAULT_VOLUME = 0.7;
|
||||
const DEFAULT_DURATION = 1.0;
|
||||
const DEFAULT_PITCH_LOCK_ENABLED = false;
|
||||
const DEFAULT_PITCH_LOCK_FREQUENCY = 440;
|
||||
|
||||
const STORAGE_KEYS = {
|
||||
VOLUME: 'volume',
|
||||
DURATION: 'duration',
|
||||
PITCH_LOCK_ENABLED: 'pitchLockEnabled',
|
||||
PITCH_LOCK_FREQUENCY: 'pitchLockFrequency',
|
||||
} as const;
|
||||
|
||||
export function loadVolume(): number {
|
||||
@ -23,3 +27,21 @@ export function loadDuration(): number {
|
||||
export function saveDuration(duration: number): void {
|
||||
localStorage.setItem(STORAGE_KEYS.DURATION, duration.toString());
|
||||
}
|
||||
|
||||
export function loadPitchLockEnabled(): boolean {
|
||||
const stored = localStorage.getItem(STORAGE_KEYS.PITCH_LOCK_ENABLED);
|
||||
return stored ? stored === 'true' : DEFAULT_PITCH_LOCK_ENABLED;
|
||||
}
|
||||
|
||||
export function savePitchLockEnabled(enabled: boolean): void {
|
||||
localStorage.setItem(STORAGE_KEYS.PITCH_LOCK_ENABLED, enabled.toString());
|
||||
}
|
||||
|
||||
export function loadPitchLockFrequency(): number {
|
||||
const stored = localStorage.getItem(STORAGE_KEYS.PITCH_LOCK_FREQUENCY);
|
||||
return stored ? parseFloat(stored) : DEFAULT_PITCH_LOCK_FREQUENCY;
|
||||
}
|
||||
|
||||
export function savePitchLockFrequency(frequency: number): void {
|
||||
localStorage.setItem(STORAGE_KEYS.PITCH_LOCK_FREQUENCY, frequency.toString());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user