Skip to content

Skip the engine warmup when the pinned recorder will record - #1874

Merged
r3dbars merged 2 commits into
mainfrom
claude/pinned-mic-skip-engine-warmup
Sep 28, 2026
Merged

r3dbars merged 2 commits into
mainfrom
claude/pinned-mic-skip-engine-warmup

Conversation

@r3dbars

@r3dbars r3dbars commented Sep 26, 2026

Copy link
Copy Markdown
Owner

Why

#1857 moved built-in and wired mics onto the pinned recorder. But pinnedDictationSkipsEngineWarmup() still only skipped the engine when the macOS input was a Bluetooth headset.

So after a wake or route change (readiness stale), a key press warmed AVAudioEngine on the default mic, waited for it, then recorded through the pinned recorder anyway. That start never uses the engine.

From local events.jsonl on 1.1.65+:

  • Pinned starts: p50 111 ms / p95 138 ms (120 starts).
  • The 2 starts that hit the stale wait: 233 and 327 ms. debug.log shows started after 289ms wait while the engine warmed the MacBook mic, then recording started on the pinned microphone.

What changed

  • One rule for warmup and recording. PinnedDictationInputPolicy.skipsEngineWarmup(for:afterEngineFallback:) decides warmup from the same pinnedDictationInputSelection() and recorderIsNeeded rule the start uses, so the two can't drift apart again.
  • Bluetooth guard kept. A Bluetooth macOS input (or an unreadable route) still never warms the engine, so idle AirPods never get pulled into call mode.
  • Warm again after a fallback. When a pinned start falls back to the engine, pinnedDictationFellBackToEngine turns warmup back on until the recorder next starts. That way a repeat fallback isn't also a cold start.
  • Updated the stale comments and the line in Sources/Speech/CLAUDE.md.

Tradeoff: built-in and wired mic users no longer get the engine prewarmed at launch or wake. So the first fallback after launch starts cold. Field data: 4 fallbacks in 117 pinned starts over 30 days, all from one install. Local: 0.

Verification

  • bash build.sh --no-open: pass
  • bash run-tests.sh: 18514 / 18514 pass
  • python3 scripts/dev/check-source-pins.py --changed-only: pass
  • Mutation check: removing the fallback clause fails the new test, so the test catches it.

Not verified on hardware. A live A/B (switch the macOS input to the MacBook mic, then dictate) was started but not finished. Plan: after merge, compare pinned starts that follow a route change, plus dictation_started_after_wait counts, in events.jsonl before and after.

🤖 Generated with Claude Code

r3dbars and others added 2 commits September 26, 2026 06:14
#1857 moved built-in and wired mics onto the pinned recorder, but the
warmup check still only skipped the engine for a Bluetooth macOS input.
So after a wake or route change, a key press warmed AVAudioEngine on the
default mic, waited for it, then recorded through the recorder anyway
(233 and 327 ms starts in local logs, against about 110 ms normally).

- PinnedDictationInputPolicy.skipsEngineWarmup decides warmup from the
  same selection and recorderIsNeeded rule the start uses, so the two
  can't drift apart again. A Bluetooth macOS input still never warms.
- After a fallback to the engine, warmup runs again until the recorder
  next starts, so a repeat fallback isn't also a cold start.
- Fast tests pin the agreement, the Bluetooth guard and the fallback.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Keeps #1880's speed-path fallback and this branch's warmup rule. Warmup
now asks the same question the recorder does, including whether empty
takes moved the mic back to the engine, so that mic's engine stays warm.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@r3dbars
r3dbars merged commit f1fe3db into main Sep 28, 2026
8 checks passed
@r3dbars
r3dbars deleted the claude/pinned-mic-skip-engine-warmup branch September 28, 2026 01:15
r3dbars added a commit that referenced this pull request Sep 28, 2026
Speech CLAUDE.md: keeps main's warmup sentence (#1874) and this branch's
0.5 s rule for empty takes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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