mirror of
https://github.com/myronblair/jarvis
synced 2026-06-30 17:50:23 -05:00
fix: voice mic race condition — onend blocks restart during TTS, clean abort+restart after speech, stuck isSpeaking watchdog
This commit is contained in:
+24
-5
@@ -1012,6 +1012,13 @@ function showApp(name, greeting, silent = false) {
|
||||
exitVoiceMode();
|
||||
}
|
||||
}, 60000);
|
||||
// Watchdog: reset isSpeaking if stuck (TTS error left it true)
|
||||
setInterval(() => {
|
||||
if (isSpeaking && !_ttsAudio && !window.speechSynthesis?.speaking) {
|
||||
isSpeaking = false;
|
||||
if (isListening) try { recognition?.start(); } catch(_) {}
|
||||
}
|
||||
}, 5000);
|
||||
startListening();
|
||||
loadNetwork();
|
||||
loadHA();
|
||||
@@ -1785,8 +1792,10 @@ function initVoice() {
|
||||
};
|
||||
|
||||
recognition.onend = () => {
|
||||
// Always restart for continuous wake word / command listening
|
||||
if (isListening) setTimeout(() => { try { recognition.start(); } catch(_) {} }, 100);
|
||||
// Only restart when not speaking — _resumeMic() handles restart after TTS
|
||||
if (isListening && !isSpeaking) {
|
||||
setTimeout(() => { try { recognition.start(); } catch(_) {} }, 150);
|
||||
}
|
||||
};
|
||||
|
||||
recognition.onerror = (e) => {
|
||||
@@ -1908,8 +1917,13 @@ async function speak(text) {
|
||||
const _resumeMic = () => {
|
||||
isSpeaking = false;
|
||||
reactor?.classList.remove('speaking');
|
||||
// Let onend restart recognition automatically (300ms buffer after audio ends)
|
||||
if (isListening) setTimeout(() => { try { recognition?.start(); } catch(_) {} }, 300);
|
||||
if (isListening) {
|
||||
// Abort any stale session then restart cleanly
|
||||
setTimeout(() => {
|
||||
try { recognition?.abort(); } catch(_) {}
|
||||
setTimeout(() => { try { recognition?.start(); } catch(_) {} }, 150);
|
||||
}, 200);
|
||||
}
|
||||
};
|
||||
try {
|
||||
const res = await fetch('/api/tts', {
|
||||
@@ -1942,7 +1956,12 @@ function _speakFallback(text) {
|
||||
utter.onend = () => {
|
||||
reactor?.classList.remove('speaking');
|
||||
isSpeaking = false;
|
||||
if (isListening) setTimeout(() => { try { recognition?.start(); } catch(_) {} }, 300);
|
||||
if (isListening) {
|
||||
setTimeout(() => {
|
||||
try { recognition?.abort(); } catch(_) {}
|
||||
setTimeout(() => { try { recognition?.start(); } catch(_) {} }, 150);
|
||||
}, 200);
|
||||
}
|
||||
};
|
||||
synth.speak(utter);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user