You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Meeting loses call audio for the rest of the recording when the system-audio tap switches to digital zeros mid-call (silence watch already disarmed) #1916
About 18 minutes into a 51-minute Google Meet call, the system-audio tap started delivering pure digital zeros and kept doing so until the recording stopped. The mic track is fine, but the other side of the call is missing for the last ~32 minutes. There was no reconnect, no "Can't hear the call" warning, and the meeting saved with capture_quality: excellent, audio_gaps: 0.
Root cause (from reading main): after the tap hears signal, nothing watches for it going back to digital zeros.
In CoreAudioSystemAudioCapture, the stall check only fires when buffers stop arriving (now - lastBuffer > 3). Here buffers kept arriving; they were just zeros ("Zero-valued PCM is valid audio. Only absent callbacks trigger recovery").
SystemAudioSilenceWatch (added in Stop Boost Mic from sticking, and catch meetings that lose call audio #1796) catches "zeros while another app plays", but it is armed only on .start, .wake, .rebuild and .outputChange. In noteSilenceWatchBuffer the first buffer with signal sets silenceWatch = nil. The call had audio from the first seconds, so the watch was gone long before the dropout and was never re-armed: no wake, no output change, no rebuild.
Steps to reproduce
Intermittent, I could not reproduce it on demand. What happened, in order:
Start recording a Google Meet call in Arc (Chromium). Output: Bluetooth headphones. Input: built-in mic.
Share a window of another app in Meet (Claude desktop), then stop sharing.
At the moment sharing stopped, the tap went to digital zeros for good.
Timeline (local time, from system_audio.m4a levels and log show):
Time
Event
12:30:44
Recording starts
12:33:02 – 12:34:51
First screen share (another app window). Stopping it caused no problem
12:44:07
Second share starts (Claude desktop window)
12:48:59.345
replayd: Arc's SCStream stopCapture / stopAndInvalidateWithStreamData, then [ERROR] RPRecordingManager updateStream… no client found for streamID
12:48:59.5
system_audio.m4a switches from normal call audio (pauses sit at about −78 dBFS) to exact digital zero (−inf) until the end
12:49:00.114
coreaudiod: HALS_OverloadMessage: Overload possibly due to safety violation / Audio IO Overload
12:49:10
Transcripted app.jsonl: one "System audio silent" {"duration":"10s"} (AudioLevelMonitor). Nothing else from audio.system until stop
12:49:11
New share (browser tab), audio does not come back
13:21:32
Recording stopped. playback.m4a equals the mic track after 12:48:59
Another app kept playing audio the whole time (the Meet tab), so anotherProcessIsPlayingAudio should have been true, if the watch had been armed.
Expected behavior
If the tap has already heard signal and then delivers only exact digital zeros for several seconds while another process is playing audio, rebuild the tap once. If that doesn't help, show "Can't hear the call", the same way the start/wake watch already does.
Actual behavior
32 minutes of zeros, no recovery, no in-meeting warning, and the capture is reported as excellent.
Proposed fix (sketch, not compiled)
Re-arm the existing watch when a tap that has heard signal goes back to digital zeros. Bound the re-arms so a call where the far end is quiet can't cause repeated rebuilds. A rebuild during zeros costs nothing that was actually heard, as the comment in SystemAudioSilenceWatch already notes.
// SystemAudioSilenceWatch.Reason
/// The tap heard signal, then went back to digital zeros mid-recording.
case lostMidRecording
// SystemAudioSilenceWatch.armed(_:at:) — same parameters as .rebuild
case .start,.rebuild,.outputChange,.lostMidRecording:
// CoreAudioSystemAudioCapture
privatevarlastSignalAt:TimeInterval?privatevarmidRecordingRearms=0staticletmaxMidRecordingRearms=3
// start(): reset both
lastSignalAt =nil
midRecordingRearms =0
// deliverQueued(...), next to `if silenceWatch != nil { noteSilenceWatchBuffer(...) }`
ifSelf.containsSignal(buffer){ lastSignalAt = now }
// drain tick, just before `if silenceWatch != nil { checkSilenceWatch(at: now) }`
if silenceWatch ==nil,let lastSignalAt,
now - lastSignalAt >=SystemAudioSilenceWatch.silenceSeconds,
midRecordingRearms <Self.maxMidRecordingRearms {
midRecordingRearms +=1
silenceWatch =.armed(.lostMidRecording, at: now)AppLogger.audioSystem.info("System audio went to digital silence after signal; watching")}
After that, the existing flow applies: evaluate(otherAudioPlaying:) asks for one .reconnect (→ recover(.silentWhilePlaying)), then .reportUnheard after unheardReportSeconds. If signal returns on a new tap, didLosePlayback marks the loss. A unit test can cover it on the pure watch plus a fake hardwareHooks: signal buffers → zero buffers for more than 5 s with otherAudioIsPlaying == true → expect one reconnect.
Side note: capture_quality: excellent / audio_gaps: 0 should probably take isNotHearingPlayback / didLosePlayback into account, so this case is visible after the meeting too.
Area
Meetings
Environment
macOS version: 26.6.2 (25G83), Apple Silicon
Transcripted version/commit: 1.1.66 (release). Code references are to main @ c2bb706
Audio source: Google Meet in Arc (Chromium). Output: Bluetooth headphones. Input: built-in mic
Storage details
~/Library/Application Support/Transcripted/
Diagnostics
I can share redacted app.jsonl / events.jsonl lines and log show excerpts for replayd / coreaudiod around 12:48:50–12:49:15 if useful. I'm not attaching audio or transcripts because they contain private meeting content.
About 18 minutes into a 51-minute Google Meet call, the system-audio tap started delivering pure digital zeros and kept doing so until the recording stopped. The mic track is fine, but the other side of the call is missing for the last ~32 minutes. There was no reconnect, no "Can't hear the call" warning, and the meeting saved with
capture_quality: excellent,audio_gaps: 0.Root cause (from reading
main): after the tap hears signal, nothing watches for it going back to digital zeros.CoreAudioSystemAudioCapture, the stall check only fires when buffers stop arriving (now - lastBuffer > 3). Here buffers kept arriving; they were just zeros ("Zero-valued PCM is valid audio. Only absent callbacks trigger recovery").SystemAudioSilenceWatch(added in Stop Boost Mic from sticking, and catch meetings that lose call audio #1796) catches "zeros while another app plays", but it is armed only on.start,.wake,.rebuildand.outputChange. InnoteSilenceWatchBufferthe first buffer with signal setssilenceWatch = nil. The call had audio from the first seconds, so the watch was gone long before the dropout and was never re-armed: no wake, no output change, no rebuild.Steps to reproduce
Intermittent, I could not reproduce it on demand. What happened, in order:
Timeline (local time, from
system_audio.m4alevels andlog show):replayd: Arc'sSCStream stopCapture/stopAndInvalidateWithStreamData, then[ERROR] RPRecordingManager updateStream… no client found for streamIDsystem_audio.m4aswitches from normal call audio (pauses sit at about −78 dBFS) to exact digital zero (−inf) until the endcoreaudiod:HALS_OverloadMessage: Overload possibly due to safety violation/Audio IO Overloadapp.jsonl: one"System audio silent" {"duration":"10s"}(AudioLevelMonitor). Nothing else fromaudio.systemuntil stopplayback.m4aequals the mic track after 12:48:59Another app kept playing audio the whole time (the Meet tab), so
anotherProcessIsPlayingAudioshould have been true, if the watch had been armed.Expected behavior
If the tap has already heard signal and then delivers only exact digital zeros for several seconds while another process is playing audio, rebuild the tap once. If that doesn't help, show "Can't hear the call", the same way the start/wake watch already does.
Actual behavior
32 minutes of zeros, no recovery, no in-meeting warning, and the capture is reported as excellent.
Proposed fix (sketch, not compiled)
Re-arm the existing watch when a tap that has heard signal goes back to digital zeros. Bound the re-arms so a call where the far end is quiet can't cause repeated rebuilds. A rebuild during zeros costs nothing that was actually heard, as the comment in
SystemAudioSilenceWatchalready notes.After that, the existing flow applies:
evaluate(otherAudioPlaying:)asks for one.reconnect(→recover(.silentWhilePlaying)), then.reportUnheardafterunheardReportSeconds. If signal returns on a new tap,didLosePlaybackmarks the loss. A unit test can cover it on the pure watch plus a fakehardwareHooks: signal buffers → zero buffers for more than 5 s withotherAudioIsPlaying == true→ expect one reconnect.Side note:
capture_quality: excellent/audio_gaps: 0should probably takeisNotHearingPlayback/didLosePlaybackinto account, so this case is visible after the meeting too.Area
Environment
main@c2bb706Storage details
~/Library/Application Support/Transcripted/Diagnostics
I can share redacted
app.jsonl/events.jsonllines andlog showexcerpts forreplayd/coreaudiodaround 12:48:50–12:49:15 if useful. I'm not attaching audio or transcripts because they contain private meeting content.