Skip to content

fix: stop() in continuous mode now releases microphone immediately - #260

Open
Akram-Wa wants to merge 2 commits into
compulim:mainfrom
Akram-Wa:fix/stop-continuous-mode-microphone-not-released
Open

fix: stop() in continuous mode now releases microphone immediately#260
Akram-Wa wants to merge 2 commits into
compulim:mainfrom
Akram-Wa:fix/stop-continuous-mode-microphone-not-released

Conversation

@Akram-Wa

@Akram-Wa Akram-Wa commented Jun 30, 2026

Copy link
Copy Markdown

Fixes #166

In continuous mode, calling stop() during silence would leave the microphone open indefinitely. stopContinuousRecognitionAsync was only called inside the recognized event handler, which never fires when no speech has been detected. A subsequent start() would then fail silently until the page was refreshed.

The fix mirrors the existing abort() behavior: call stopContinuousRecognitionAsync immediately when stop is received, without waiting for a recognized event.

Also removes the deferred stopContinuousRecognitionAsync call in the recognized handler for the continuous+stopping path, which would have caused a double-call after the fix.

Adds a regression test: stop() during silence in continuous mode must fire stopContinuousRecognitionAsync immediately and cleanly fire soundend/audioend/end without a no-speech error.

SDK Contract

The JS SDK reference confirms:

startContinuousRecognitionAsync — Starts speech recognition, until stopContinuousRecognitionAsync() is called.

The SDK runs until stopContinuousRecognitionAsync is explicitly called — it does not self-terminate. Any code path that fails to call it leaves the microphone and session permanently open.

Why sessionStopped and speechEndDetected were never firing

Two existing comments in this codebase hint at a deeper symptom of the same bug:

recognizer.sessionStopped = () => {
  // "sessionStopped" is never fired, probably because we are using
  // startContinuousRecognitionAsync instead of recognizeOnceAsync.
};

recognizer.speechEndDetected = () => {
  // "speechEndDetected" is never fired, probably because we are using
  // startContinuousRecognitionAsync instead of recognizeOnceAsync.
};

These events were assumed to be a quirk of startContinuousRecognitionAsync. In reality they were not firing because stopContinuousRecognitionAsync was never being called promptly — the SDK had no signal that the session should end. With this fix, these events should now fire correctly when stop() is called.

Changelog

Fixed

  • Resolved microphone not released when stop() is called in continuous mode during silence, by @Akram-Wa in PR #260

Specific changes

createSpeechRecognitionPonyfillFromRecognizer.ts: removed abort && guard so stopContinuousRecognitionAsync is called immediately for both abort and stop when the stop signal is first received
createSpeechRecognitionPonyfillFromRecognizer.ts: removed deferred stopContinuousRecognitionAsync call in recognized handler for the continuous+stopping path to prevent double-call
createSpeechRecognitionPonyfill.test.js: added regression test — stop() during silence in continuous mode must release the mic immediately and close cleanly without a no-speech error

Akram-Wa added 2 commits June 30, 2026 17:48
Fixes compulim#166

In continuous mode, calling stop() during silence would leave the
microphone open indefinitely. stopContinuousRecognitionAsync was only
called inside the recognized event handler, which never fires when no
speech has been detected. A subsequent start() would then fail.

The fix mirrors the existing abort() behavior: call
stopContinuousRecognitionAsync immediately when stop is received,
without waiting for a recognized event.

Also removes the deferred stopContinuousRecognitionAsync call in the
recognized handler for the continuous+stopping path, which would have
caused a double-call after the fix.

Adds a regression test: stop() during silence in continuous mode must
fire stopContinuousRecognitionAsync immediately and cleanly fire
soundend/audioend/end without a no-speech error.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

stop appears to break the polyfill when continuously listening

1 participant