Repository navigation
Description
Summary
Since the #665 fix, FluidVoice no longer crashes on audio-device changes — it hangs instead. The window stays responsive, but dictation is dead: pressing the hotkey does nothing, because the audio pipeline is frozen. Only Force Quit clears it. I'm doing that ~10 times a day.
This is a different defect from #665 (that SIGABRT is fixed). Here the app spins/deadlocks inside AVAudioEngine start and stop, both stuck in Apple's hardware-format query _GetHWFormat.
Environment
- FluidVoice 1.6.5 (build 16)
- macOS 26.3.1 (25D2128), Apple Silicon, MacBook Pro (MacBookPro18,3), 16 GB
- Speech model: parakeet-tdt
- Mic: built-in —
PreferredInputDeviceUID = BuiltInMicrophoneDevice(nothing exotic selected) ExperimentalDirectAudioCaptureEnabled = true,ExperimentalDirectAudioCaptureForcedOff = true— the app auto-disabled its direct-capture fast path after repeated failures, so it now always uses the AVAudioEngine ("compatibility") path, which is the one that hangs- Audio devices that come and go here: iPhone Continuity mic, LG UltraFine Display Audio, Hue Sync Audio (4-ch), Microsoft Teams Audio, ZoomAudioDevice
Symptoms
- UI responds; dictation does not. Hotkey press does nothing.
- One thread pinned ~11% CPU; process otherwise idle.
- Never recovers on its own — requires Force Quit.
Evidence — two live sample captures
Both show the audio engine wedged in _GetHWFormat.
1) Hang while STARTING the engine (most recent):
ASRService audio-capture path
ASRService.startCompatibilityAudioCapture(reason:)
ASRService.startEngine()
AVAudioEngineImpl::Initialize(NSError**) <- ~85% of samples stuck here
AVAudioIOUnit queue (~100% CPU)
AVAudioIOUnit::IOUnitPropertyListener(...)
AVAudioIOUnit_OSX::_GetHWFormat(...) <- spinning
2) Hang while STOPPING/retiring the engine (earlier):
DispatchQueue app.fluidvoice.audio-engine-retirement (serial)
AudioEngineRetirementDrain.enqueueAndWait(_:) <- synchronous wait
-[AVAudioEngine dealloc] -> ~AVAudioIOUnit_OSX()
blocked on _dispatch_event_loop_wait_for_ownership
AVAudioIOUnit queue (~100% CPU)
AVAudioIOUnit::IOUnitPropertyListener(...)
AVAudioIOUnit_OSX::_GetHWFormat(...) <- spinning
In (2), the engine dealloc waits on the AVAudioIOUnit queue via enqueueAndWait, but that queue never yields because it's stuck in the hardware-format property listener. The process sat wedged like this for ~30 minutes.
Also observed (same subsystem)
- Main-thread deadlock in
ASRService.registerDefaultDeviceChangeListener()— beachball; macOS attributed the deadlock to a third-party agent (Logitech Logi Options+). - Occasional EXC_CRASH (SIGSEGV) on 1.6.5 during audio-device changes — the Reproducible crash (SIGABRT) on audio device change — v1.6.4 (build 15) #665 SIGABRT signature is gone, replaced by this.
Reproduction
- Run 1.6.5 on a machine with audio devices that appear/disappear.
- Trigger an audio-device change while using the app. Reliable triggers for me:
- Physically plugging or unplugging headphones or an external amplifier / audio interface.
- Virtual/multi-channel devices appearing or disappearing (Microsoft Teams, Zoom, Hue Sync).
- The iPhone Continuity mic or a display's audio waking up.
- FluidVoice hangs — either failing to start capture (hotkey does nothing) or freezing during engine teardown. Force Quit required. Happens even with the plain built-in mic selected.
Suggested directions
- The hang sits in AVAudioEngine start/stop, both blocked on
_GetHWFormat. Consider removing the IOUnit property listener before engine teardown, and not driving engine init/dealloc synchronously (enqueueAndWait) on a queue that the hardware-format listener can block. - Add a timeout/watchdog around engine start and retirement so a stuck
_GetHWFormatdegrades gracefully instead of freezing the whole capture path. - Debounce device/format-change events; a burst currently triggers repeated teardown/rebuild.
- Direct-capture got force-disabled on this machine, so the app is permanently on the hanging path — worth revisiting that fallback so a machine that fails direct capture isn't stranded on a compatibility path that also hangs.
Full .ips crash reports and .hang spindumps available on request.
Activity
poltorrr commentedon Jul 21, 2026
Reproduced live just now by plugging in earbuds — this time it crashed (EXC_BAD_ACCESS / SIGSEGV) instead of hanging, and the crash is in the same
_GetHWFormat/IOUnitPropertyListenerpath as the hangs in the report.FluidVoice 1.6.5 (build 16), macOS 26.3.1 (25D2128), 2026-07-21 20:28.
So the hardware-format property listener (
IOUnitPropertyListener->_GetHWFormat->-[AVAudioFormat isEqual:]) either spins (the hangs in the original report) or dereferences a bad/dangling AVAudioFormat and crashes (here), depending on timing — both on theAVAudioIOUnitqueue, both fired by a device change. Same root: the IOUnit property listener is live and racing during a device/format change while the format objects it compares are being torn down.A few seconds later, disabling AirPods dropped it straight back into the hung state — every audio-device change (plug/unplug earbuds, toggle AirPods) trips it.
grohith327 commentedon Jul 21, 2026
Hey @poltorrr thanks for the detailed report. Can you try one thing for me ? Can you restart your app and enable the
Faster Recording Startand let me know if it still crashes while switching audio.poltorrr commentedon Jul 21, 2026
Thanks @grohith327. One catch worth flagging:
Faster Recording Startis already enabled in the UI, but the app has silently force-disabled direct capture underneath it. Current defaults forcom.FluidApp.app:So after 2 consecutive failures the app set
...ForcedOff = 1and fell back to the AVAudioEngine compatibility path — which is the path that hangs/crashes (AVAudioEngineImpl::Initialize/_GetHWFormat). I just reproduced the crash again with the toggle on, which fits: the toggle is on, but direct capture isn't actually running because of the forced-off flag.How would you like me to clear the forced-off state so I can genuinely test direct capture — toggle the setting off and back on, delete one of those keys, or is there a hidden reset? Happy to run the test once direct capture is actually active.
exondus commentedon Jul 22, 2026
This worked for me. Thanks @grohith327
poltorrr commentedon Jul 22, 2026
Following up: enabling
Faster Recording Startdidn't help here — as I noted above, on my machine the app force-disables direct capture at startup (ForcedOffflips back to1, and it even turns the toggle back off), so it always runs the AVAudioEngine compatibility path. Glad it worked for @exondus, but I can't get direct capture to stay on to reproduce that.What did fix it: I downgraded to 1.6.0 (build 12) and the problem is gone. Plugging/unplugging AirPods no longer hangs or crashes — several device switches, no issue. So this looks like a regression introduced after 1.6.0, in the audio-capture / AVAudioEngine path.
One minor thing in 1.6.0: the first few times I hit record, the recorder flashes on and off and I have to retry once or twice, but it always starts eventually — no hangs, no crashes.
Environment unchanged: macOS 26.3.1 (25D2128), MacBookPro18,3, built-in mic. Happy to test a specific build between 1.6.0 and 1.6.4 if that would help pin down where the compatibility path broke.
adamgranted commentedon Jul 22, 2026
Seeing the same behavior as @poltorrr, AirPods are wrecking havoc on 1.6.5. I'm experiencing regular crashes as my AirPods automatically switch between devices.
Ironically this is what plagued open-wispr, prompting the switch to FluidVoice in the first place. Happy to collect any additional logs or details to help with the bug.
grohith327 commentedon Jul 22, 2026
@poltorrr / @adamgranted sorry you both are running into this issue and are blocked.
@poltorrr let me share a build that attempts to fix this. The
ExperimentalDirectAudioCaptureForcedOffis a one time marker. It might be confusing but toggling it back on in the app should ensure CoreAudio is used@adamgranted have you tried the turning the toggle back on as shown in the screenshot above or still no luck ??
We're trying to get a release out by EOD today/tomorrow that addresses. I am not fully able to replicate this on my machine so would it if you folks can try out a custom and let me know
poltorrr commentedon Jul 22, 2026
Thanks @grohith327, happy to test a custom build — I don't see a link in your comment though, so whenever it's ready drop it here and I'll run it.
When I cleared it manually (via
defaults) it re-armed to1on the next launch and the toggle flipped itself off — so the in-app toggle must reset it differently. I'll test that path on the build you send.grohith327 commentedon Jul 22, 2026
Sounds good, working on it now. Will get it to you in some time. Thank you for your patience @poltorrr
adamgranted commentedon Jul 22, 2026
@grohith327 all good, thanks for building it in the first place. I can confirm that I'm still experiencing crashes regardless of "Fast Recording State" enablement. So this is an identical bug to @poltorrr.
It pretty consistently looks like one of the following states:
*Occasionally I will be able to stop FluidVoice from recording but on second recording attempt (after state 2), FluidVoice will crash on attempt to use the AirPods as an audio input. In both cases, the AirPods still show as connected in macOS which I assume is apart of Apples handoff system attempting to be clever. Sometimes the crash is immediate, sometimes it's a lock up, sometimes I have to force quit FluidVoice via Activity Monitor.
Happy to test a custom build whenver its ready.
grohith327 commentedon Jul 22, 2026
Hey @adamgranted / @poltorrr here is the build. Please try it out and let me know if you are still experiencing the issue.
FluidVoice-682.zip
adamgranted commentedon Jul 22, 2026
@grohith327 macOS reports that the app is damaged because code-signature verification is failing. It looks like the ZIP is missing several signed files from CTranscribe.framework and also contains some extra macOS metadata files.
Would you mind checking the packaging/signing process and sending a fresh build when you have a chance? The app may need its embedded frameworks re-signed before the final app is signed and zipped.
grohith327 commentedon Jul 23, 2026
Hey @adamgranted, sorry I had to accept some new terms of service from Apple, my app signing was failing and I didn't realize 🙄. Please try this build and let me know. Thank you!
FluidVoice-SIGNED-NOTARIZED.zip
adamgranted commentedon Jul 25, 2026
@grohith327, thanks. The custom build still crashes. It occasionally successfully changes the microphone, but mostly fails during attempts, causing a crash. The floating UI shows it attempts recording, has no mic, requests AirPods transition, and then disappears.
I’ll stress the 1.6.0 build again, as I haven’t had any crashes during microphone transitions. Let me know what else you need.
grohith327 commentedon Jul 31, 2026
Hey folks, appreciate the patience. We released version 1.6.6 with some improvements. CoreAudio flow is made the default with a bunch of improvements and this should prevent a lot of the issues, especially audio device input changes. We will sunset the AVAudioEngine flow in the next 1-2 versions
adamgranted commentedon Aug 6, 2026
@grohith327 I don't think this one is out of the woods, even in 1.6.7 the AirPods mic stability is (anecdotally) worse than 1.6.0.
I'm about to downgrade again since 1.6.7 is hitting that similar wall of not being able to properly use my AirPods microphone even when the host shows a healthy system settings vu-meter on speaking.
I have not had a crash yet with 1.6.7 but the intermittent ability for FluidVoice to hear me persists. Anything else I can do to help capture this bug?
grohith327 commentedon Aug 6, 2026
Hey @adamgranted, is there a reason you prefer your AirPods mic over your MacBook mic ?
adamgranted commentedon Aug 6, 2026
@grohith327 yes, MacBook stays closed and docked at my primary desk.
I'll do some more digging and see if I can identify exactly why 1.6.0 is AirPod stable compared to 1.6.7
grohith327 commentedon Aug 6, 2026
Gotcha, that makes sense. And you don't any external mics is it ?
We generally do not recommend using Bluetooth devices as mics, we're trying to nudge people away from that unless absolutely necessary. The main reason being, even if reliability improves, there are still some issues which just cannot be solved. Like for example, the muffled audio issue when you some audio/video playing.
For the closed Mac thing, we'll get a fix out soon to pick the one available. Sorry about that.