Restart microphone capture on audio device change#311
Open
MaxHeimbrock wants to merge 1 commit into
Open
Conversation
MaxHeimbrock
commented
Jun 15, 2026
| var outputSampleRate = (uint)AudioSettings.outputSampleRate; | ||
| if (outputSampleRate != _expectedSampleRate) | ||
| { | ||
| Utils.Warning($"MicrophoneSource: audio device change moved the DSP output rate to {outputSampleRate}Hz, but the native source is fixed at {_expectedSampleRate}Hz. Captured frames will be dropped until the track is recreated at the new rate."); |
Contributor
Author
There was a problem hiding this comment.
Triggered on Unity 6 editor on mac starting with MDR-1000x, disabling Bluetooth to switch to built in mic, then connecting to MDR-1000x again:
LiveKit: MicrophoneSource: audio device change moved the DSP output rate to 44100Hz, but the native source is fixed at 48000Hz. Captured frames will be dropped until the track is recreated at the new rate.
UnityEngine.Logger:LogWarning (string,object)
LiveKit.Internal.Utils:Warning (object) (at /Users/maxheimbrock/dev/unity/client-sdk-unity/Runtime/Scripts/Internal/Utils.cs:41)
LiveKit.MicrophoneSource:OnAudioConfigurationChanged (bool) (at /Users/maxheimbrock/dev/unity/client-sdk-unity/Runtime/Scripts/MicrophoneSource.cs:248)
UnityEngine.AudioSettings:InvokeOnAudioConfigurationChanged (bool) (at /Users/bokken/build/output/unity/unity/Modules/Audio/Public/ScriptBindings/Audio.bindings.cs:413)
Contributor
Author
There was a problem hiding this comment.
This worked on https://github.com/livekit/client-sdk-unity/pull/312/changes
266730d to
2a26265
Compare
When a capture device disappears mid-call (e.g. unplugging a Bluetooth headset), the local microphone went silent and never recovered: MicrophoneSource stayed bound to the gone device name and never re-registered the AudioProbe tap that Unity detaches when it rebuilds its audio graph. Subscribe to AudioSettings.OnAudioConfigurationChanged (mirroring the playback-side AudioStream handler) and restart capture on a device change, resolving to the OS default device when the preferred device is no longer present. Track the active device separately from the preferred one so Microphone.IsRecording/GetPosition/End target the right device, and guard against overlapping restarts. The native source's rate is fixed at construction, so if the device change moves Unity's DSP output rate, frames are still dropped; warn clearly in that case. Full rate-change recovery follows separately. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
37725a6 to
d19145d
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
When a capture device disappears mid-call (e.g. unplugging a Bluetooth headset and falling back to the built-in mic), the local microphone went silent and never recovered:
MicrophoneSourcestayed bound to the now-gone device name and never re-resolved to the new default.AudioProbe.OnAudioFilterReadtap — so even the capture tap stopped firing.The playback side already handles this in
AudioStream.OnAudioConfigurationChanged; this mirrors that pattern for capture.Change
MicrophoneSourcetoAudioSettings.OnAudioConfigurationChangedand restart capture on a device change (reusing the existingRestartMicrophonecoroutine, which re-adds theAudioSource/AudioProbeand re-registers the tap on the rebuilt graph).null) when the preferred device is gone, so an unplugged headset transparently hands off to the built-in mic.Microphone.IsRecording/GetPosition/Endtarget the device actually recording.The native source's rate is fixed at construction, so if the device change moves Unity's DSP output rate, frames are still dropped; this case is warned about clearly. Full rate-change recovery is a follow-up (stacked PR).
Testing
Scripts~/run_unity.sh build macos→ Build SUCCEEDED.🤖 Generated with Claude Code