Skip to content

Fix recorder start/stop failures and debounce toggle shortcuts#644

Open
Korben00 wants to merge 3 commits intocjpais:mainfrom
Korben00:main
Open

Fix recorder start/stop failures and debounce toggle shortcuts#644
Korben00 wants to merge 3 commits intocjpais:mainfrom
Korben00:main

Conversation

@Korben00
Copy link

@Korben00 Korben00 commented Jan 22, 2026

I noticed that in some cases the recorder could fail the start/stop and leave the app in an inconsistent state (microstream stopped, toggle stuck). So I reinforced error management by restoring the microphone stream when it’s fairing, and I stabilized the toggle shortcut with a debounce to avoid double triggers.

Related Issues/Discussions

Fixes #
Discussion: #641

Testing

  • Manual: bun run tauri dev
  • Tested toggle bindings (start/stop) and confirmed debounce prevents rapid double-trigger
  • Tested recorder start/stop failure paths (by forcing recorder errors / device changes) and confirmed microphone stream is restored when in AlwaysOn mode

AI Assistance

  • No AI was used in this PR
  • AI was used

If AI was used:

  • Tools used: Windsurf with ChatGPT 5.2 (IDE assistant)
  • How extensively: How extensively: Used to brainstorm and implement parts of the code changes, and iterated on fixes/refactors.

- Refactor AudioRecorder::stop() to use map_err for cleaner error handling
- Simplify shortcut debounce logic and remove unnecessary variable extraction
- Remove extraneous whitespace in audio manager
- Add missing closing brace and comment in shortcut handler
- Extract magic number 250 to DEBOUNCE_MS constant
- Move active_toggles update inside lock scope to prevent race conditions
- Fix brace alignment and remove duplicate closing braces
@joshribakoff
Copy link
Contributor

Debouncing could make sense as a UX improvement, but it doesn't directly fix race conditions - it can mask them and make them harder to test.

Copy link

@virenpepper virenpepper left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hey, i reviewed this fix in detail and verified it compiles and works

the root cause is in recorder.rs - the consumer loop blocks on sample_rx.recv() waiting for audio, and only checks commands after receiving a sample. if the audio stream stops producing samples (race condition, device issue), stop() blocks forever because the command is never processed...

  1. recv_timeout(50ms) instead of blocking recv() - critical fix
  2. 5s timeout on stop() response - prevents infinite hang
  3. debouncing in handler (250ms) - prevents rapid triggers
  4. ui state changes after recording actually starts - correct state management
  5. early exit in on_end if not recording - prevents invalid stop calls

one minor note: 250ms debounce might feel slightly sluggish for power users, we should prob update to 150/200ms if possible

LGTM nice work! this should fix #641

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.

3 participants