Skip to content

[refactor] centralize mic ownership in a single MicCoordinator#96

Merged
YJack0000 merged 1 commit into
mainfrom
claude/frosty-carson-8d865e
Jul 3, 2026
Merged

[refactor] centralize mic ownership in a single MicCoordinator#96
YJack0000 merged 1 commit into
mainfrom
claude/frosty-carson-8d865e

Conversation

@YJack0000

Copy link
Copy Markdown
Contributor

Summary

The meeting, Settings mic test, and voice typing each kept their own AtomicBool with hand-written pairwise exclusion checks — and the matrix had holes. This PR introduces capture.rs as the single source of truth for "who owns the mic":

  • MicCoordinator (Tauri managed state) guarantees at most one live capture session, with priority-based preemption (Meeting > VoiceTyping > MicTest) and idempotent restarts.
  • CaptureSession unifies the per-session gate (prevents a wedged old thread from being revived by a later start flipping a shared flag) + bounded-join teardown (1.5 s grace, then detach) — previously two divergent implementations.
  • The duplicated metered-session / usage://stt billing plumbing (commands.rs + voice_typing.rs copies) is now one run_metered_session.

MeetingState shrinks from 6 fields to 2; VoiceTypingState is deleted entirely. The IPC surface is unchanged (same command names/args).

Bugs fixed along the way

  1. Push-to-talk during a live meeting opened a second CoreAudio input stream that could silently kill the meeting's capture (per the codebase's own comment on stream contention). Now refused, with the error surfaced in the voice-typing overlay.
  2. stop_voice_typing joined unbounded on a shared flag — hang risk on a wedged device teardown, plus the exact thread-revival race the meeting code was built to prevent.
  3. A failed mic-test start leaked test_running=true, permanently refusing later tests.
  4. Meeting start preempted the mic test without waiting for the device to be released (brief double-stream window); preemption now joins first.

Also

  • Dedupes the app-config path/read/write helpers (app_config_file / read_config_file / write_config_file).
  • Clears all 5 outstanding clippy warnings (type alias in diarize, redundant casts in permissions, manual split_once, redundant closure).

Behavior change (user-visible)

Holding push-to-talk while a meeting is recording now shows an error in the overlay instead of silently corrupting the meeting's transcription.

Testing

  • cargo clippy: 0 warnings (was 5)
  • cargo test --lib: 13 passed
  • vitest: 96 passed

The meeting, Settings mic test, and voice typing each kept their own
AtomicBool with hand-written pairwise exclusion checks — and the matrix
had holes: voice typing checked nothing, so push-to-talk during a live
meeting opened a second CoreAudio input stream that could silently kill
the meeting's capture. The two stop paths also disagreed: meetings used
a per-session gate + bounded join while voice typing joined unbounded on
a shared flag (hang risk + the exact thread-revival race the meeting
code was built to prevent).

New capture.rs owns the whole story: MicCoordinator (managed state)
guarantees at most one live capture session, with priority-based
preemption (Meeting > VoiceTyping > MicTest) and idempotent restarts;
CaptureSession unifies per-session gates + bounded-join teardown; the
duplicated metered-session/usage-billing plumbing is now one function.

Fixes along the way:
- voice typing during a meeting is now refused (surfaced in the overlay)
  instead of corrupting the meeting's capture
- stop_voice_typing can no longer hang on a wedged device teardown
- a failed mic-test start no longer leaks its flag (which permanently
  refused later tests)
- meeting start now joins the preempted mic test before opening the
  device (was a brief double-stream window)

Also dedupes the app-config file path/read/write helpers and clears all
outstanding clippy warnings (type alias in diarize, redundant casts in
permissions, manual split_once, redundant closure).
@YJack0000 YJack0000 force-pushed the claude/frosty-carson-8d865e branch from 9dda240 to 943d3e8 Compare July 3, 2026 07:47
@sonarqubecloud

sonarqubecloud Bot commented Jul 3, 2026

Copy link
Copy Markdown

@YJack0000 YJack0000 merged commit f141392 into main Jul 3, 2026
1 check passed
@YJack0000 YJack0000 deleted the claude/frosty-carson-8d865e branch July 3, 2026 07:51
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.

1 participant