Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x | import { useState, useRef } from 'react';
import { api } from '../api';
export function useAudio({ voiceEnabledRef, logAgentAction }) {
const [isSpeaking, setIsSpeaking] = useState(false);
const [isTestingVoice, setIsTestingVoice] = useState(false);
const [isListening, setIsListening] = useState(false);
const audioRef = useRef(null);
const speechQueue = useRef([]);
const isSpeakingRef = useRef(false);
const mediaRecorderRef = useRef(null);
const audioChunksRef = useRef([]);
const sttIntervalRef = useRef(null);
const processSpeechQueue = async () => {
if (isSpeakingRef.current || speechQueue.current.length === 0) return;
const nextText = speechQueue.current.shift();
isSpeakingRef.current = true;
setIsSpeaking(true);
try {
const blob = await api.tts(nextText);
const url = URL.createObjectURL(blob);
if (audioRef.current) {
const cleanup = () => {
audioRef.current.removeEventListener('ended', cleanup);
audioRef.current.removeEventListener('error', cleanup);
isSpeakingRef.current = false;
setIsSpeaking(false);
URL.revokeObjectURL(url);
processSpeechQueue();
};
audioRef.current.addEventListener('ended', cleanup);
audioRef.current.addEventListener('error', cleanup);
audioRef.current.src = url;
audioRef.current.load();
await audioRef.current.play().catch(cleanup);
}
} catch (err) {
isSpeakingRef.current = false;
setIsSpeaking(false);
processSpeechQueue();
}
};
const speakText = (text) => {
if (!voiceEnabledRef.current || !text) return;
speechQueue.current.push(text);
processSpeechQueue();
};
const testVoiceDiagnostic = () => {
setIsTestingVoice(true);
logAgentAction("Diagnostic", "Testing ElevenLabs voice bridge...");
speakText("Scientific laboratory voice diagnostic complete. Communication flow is established.");
setTimeout(() => setIsTestingVoice(false), 3000);
};
return {
isSpeaking, setIsSpeaking,
isTestingVoice, setIsTestingVoice,
isListening, setIsListening,
audioRef,
speechQueue,
isSpeakingRef,
mediaRecorderRef,
audioChunksRef,
sttIntervalRef,
processSpeechQueue,
speakText,
testVoiceDiagnostic,
};
}
|