Files
personal_website/src/hooks/useAudioAnalyzer.ts
T
jory 1495a9a5c5 Implemented Oscilloscope correctly now
Have tested it with a 5 minute long audio file
Bigger files and different formats still needs testing
2025-12-21 13:51:16 +01:00

74 lines
2.1 KiB
TypeScript
Executable File

import { useRef, useState, useCallback } from 'react';
export interface AudioData {
leftChannel: Float32Array;
rightChannel: Float32Array;
sampleRate: number;
duration: number;
}
export function useAudioAnalyzer() {
const [audioData, setAudioData] = useState<AudioData | null>(null);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const [fileName, setFileName] = useState<string | null>(null);
const [originalFile, setOriginalFile] = useState<File | null>(null);
const audioContextRef = useRef<AudioContext | null>(null);
const loadAudioFile = useCallback(async (file: File) => {
setIsLoading(true);
setError(null);
setFileName(file.name);
setOriginalFile(file);
try {
// Create or reuse AudioContext
if (!audioContextRef.current) {
audioContextRef.current = new AudioContext();
}
const audioContext = audioContextRef.current;
// Read file as ArrayBuffer
const arrayBuffer = await file.arrayBuffer();
// Decode audio data
const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);
// Extract channel data
const leftChannel = audioBuffer.getChannelData(0);
const rightChannel = audioBuffer.numberOfChannels > 1
? audioBuffer.getChannelData(1)
: audioBuffer.getChannelData(0); // Mono: duplicate left channel
setAudioData({
leftChannel: new Float32Array(leftChannel),
rightChannel: new Float32Array(rightChannel),
sampleRate: audioBuffer.sampleRate,
duration: audioBuffer.duration,
});
} catch (err) {
setError(err instanceof Error ? err.message : 'Failed to load audio file');
setAudioData(null);
} finally {
setIsLoading(false);
}
}, []);
const reset = useCallback(() => {
setAudioData(null);
setFileName(null);
setOriginalFile(null);
setError(null);
}, []);
return {
audioData,
isLoading,
error,
fileName,
originalFile,
loadAudioFile,
reset,
};
}