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
The Microphone menu goes stale: a Bluetooth microphone (AirPods Pro) that is connected and visible in System Settings → Sound → Input does not appear in OpenSuperWhisper's Microphone menu until the app is restarted. Meanwhile the app silently falls back to a different device, which can produce recordings of pure digital silence that Whisper "transcribes" as hallucinated text like "Thank you."
Environment
OpenSuperWhisper 0.1.0 (Homebrew cask)
macOS 15.5, MacBook Air (Apple Silicon), lid closed on external display
AirPods Pro 2 (also paired to an iPhone, auto-switching enabled)
What happens
AirPods Pro disconnect (left the desk / auto-switched to iPhone) and later reconnect to the Mac.
System Settings → Sound → Input lists "AirPods Pro" as available. OpenSuperWhisper's Microphone submenu does not — it only shows "MacBook Air Microphone".
Because the previously selected device is no longer in the app's (stale) list, MicrophoneService.updateCurrentMicrophone() silently falls back to the "default" device, preferring the built-in microphone.
on AVCaptureDeviceWasConnected / AVCaptureDeviceWasDisconnected notifications.
Those AVFoundation notifications are not delivered reliably for Bluetooth audio devices re-registering with CoreAudio (they mostly fire for wired/USB plug events). So the app's list drifts out of sync with reality.
I verified the discovery API itself is fine: while the app's menu was missing the AirPods, a standalone script running the exact same AVCaptureDevice.DiscoverySession(deviceTypes: [.microphone, .external], mediaType: .audio, ...) query did return the AirPods (uid XX-XX-XX-XX-XX-XX:input, transport blue). The list in the app is stale — discovery is not the problem, the refresh triggers are.
System Settings stays correct because it observes CoreAudio's kAudioHardwarePropertyDevices property on the system object, which fires reliably whenever the HAL adds or removes any device, regardless of transport.
Suggested fix
Observe CoreAudio's device-list changes directly in MicrophoneService via AudioObjectAddPropertyListenerBlock(kAudioObjectSystemObject, kAudioHardwarePropertyDevices, ...) and refresh availableMicrophones + currentMicrophone when it fires. The status bar menu already rebuilds reactively from $availableMicrophones, so no UI changes are needed.
Two adjacent details worth handling in the same pass:
refreshAvailableMicrophones() currently clears selectedMicrophone whenever the list is momentarily empty, so the user's saved choice is not restored when their device reconnects mid-session.
Publishing the list only when it actually changed avoids rebuilding the status bar menu on every no-op HAL event.
I'll open a PR implementing this shortly.
Likely duplicates / related
Only Record Few Seconds of My Voice #84 — Sony WH-1000XM3 (Bluetooth) captures nothing while Voice Memos works; very likely the same stale-list → wrong-device failure mode.
Summary
The Microphone menu goes stale: a Bluetooth microphone (AirPods Pro) that is connected and visible in System Settings → Sound → Input does not appear in OpenSuperWhisper's Microphone menu until the app is restarted. Meanwhile the app silently falls back to a different device, which can produce recordings of pure digital silence that Whisper "transcribes" as hallucinated text like "Thank you."
Environment
What happens
MicrophoneService.updateCurrentMicrophone()silently falls back to the "default" device, preferring the built-in microphone.Restarting the app fixes the menu, because the device list is re-scanned at launch.
Root cause
MicrophoneServicerefreshesavailableMicrophonesonly:init, andAVCaptureDeviceWasConnected/AVCaptureDeviceWasDisconnectednotifications.Those AVFoundation notifications are not delivered reliably for Bluetooth audio devices re-registering with CoreAudio (they mostly fire for wired/USB plug events). So the app's list drifts out of sync with reality.
I verified the discovery API itself is fine: while the app's menu was missing the AirPods, a standalone script running the exact same
AVCaptureDevice.DiscoverySession(deviceTypes: [.microphone, .external], mediaType: .audio, ...)query did return the AirPods (uidXX-XX-XX-XX-XX-XX:input, transportblue). The list in the app is stale — discovery is not the problem, the refresh triggers are.System Settings stays correct because it observes CoreAudio's
kAudioHardwarePropertyDevicesproperty on the system object, which fires reliably whenever the HAL adds or removes any device, regardless of transport.Suggested fix
Observe CoreAudio's device-list changes directly in
MicrophoneServiceviaAudioObjectAddPropertyListenerBlock(kAudioObjectSystemObject, kAudioHardwarePropertyDevices, ...)and refreshavailableMicrophones+currentMicrophonewhen it fires. The status bar menu already rebuilds reactively from$availableMicrophones, so no UI changes are needed.Two adjacent details worth handling in the same pass:
refreshAvailableMicrophones()currently clearsselectedMicrophonewhenever the list is momentarily empty, so the user's saved choice is not restored when their device reconnects mid-session.I'll open a PR implementing this shortly.
Likely duplicates / related