diff --git a/lib/hooks/useMultiTrackPlayer.ts b/lib/hooks/useMultiTrackPlayer.ts index 2bdd6bc..6b923ad 100644 --- a/lib/hooks/useMultiTrackPlayer.ts +++ b/lib/hooks/useMultiTrackPlayer.ts @@ -51,6 +51,23 @@ export function useMultiTrackPlayer(tracks: Track[], masterVolume: number = 1) { setDuration(maxDuration); }, [tracks]); + // Convert linear amplitude to dB scale normalized to 0-1 range + const linearToDbScale = (linear: number): number => { + if (linear === 0) return 0; + + // Convert to dB (20 * log10(linear)) + const db = 20 * Math.log10(linear); + + // Normalize -60dB to 0dB range to 0-1 + // -60dB or lower = 0%, 0dB = 100% + const minDb = -60; + const maxDb = 0; + const normalized = (db - minDb) / (maxDb - minDb); + + // Clamp to 0-1 range + return Math.max(0, Math.min(1, normalized)); + }; + // Monitor playback levels for all tracks const monitorPlaybackLevels = useCallback(() => { if (!isMonitoringLevelsRef.current || analyserNodesRef.current.length === 0) return; @@ -73,7 +90,8 @@ export function useMultiTrackPlayer(tracks: Track[], masterVolume: number = 1) { } } - levels[track.id] = peak; + // Convert linear peak to logarithmic dB scale + levels[track.id] = linearToDbScale(peak); }); setTrackLevels(levels); diff --git a/lib/hooks/useRecording.ts b/lib/hooks/useRecording.ts index a120a2b..a43cc13 100644 --- a/lib/hooks/useRecording.ts +++ b/lib/hooks/useRecording.ts @@ -66,6 +66,23 @@ export function useRecording(): UseRecordingReturn { selectedDeviceIdRef.current = deviceId; }, []); + // Convert linear amplitude to dB scale normalized to 0-1 range + const linearToDbScale = React.useCallback((linear: number): number => { + if (linear === 0) return 0; + + // Convert to dB (20 * log10(linear)) + const db = 20 * Math.log10(linear); + + // Normalize -60dB to 0dB range to 0-1 + // -60dB or lower = 0%, 0dB = 100% + const minDb = -60; + const maxDb = 0; + const normalized = (db - minDb) / (maxDb - minDb); + + // Clamp to 0-1 range + return Math.max(0, Math.min(1, normalized)); + }, []); + // Monitor input level const monitorInputLevel = React.useCallback(() => { if (!analyserRef.current) return; @@ -87,13 +104,16 @@ export function useRecording(): UseRecordingReturn { } } - setState((prev) => ({ ...prev, inputLevel: peak })); + // Convert linear peak to logarithmic dB scale + const dbLevel = linearToDbScale(peak); + + setState((prev) => ({ ...prev, inputLevel: dbLevel })); animationFrameRef.current = requestAnimationFrame(updateLevel); }; updateLevel(); - }, []); + }, [linearToDbScale]); // Start recording const startRecording = React.useCallback(async (): Promise => {