import { useRef, useState, useCallback } from 'react'; export interface AudioData { leftChannel: Float32Array; rightChannel: Float32Array; sampleRate: number; duration: number; } export function useAudioAnalyzer() { const [audioData, setAudioData] = useState(null); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null); const [fileName, setFileName] = useState(null); const [originalFile, setOriginalFile] = useState(null); const audioContextRef = useRef(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, }; }