diff options
author | Robert Adam <dev@robert-adam.de> | 2021-10-01 09:33:31 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-10-01 09:33:31 +0300 |
commit | c453a8bded64914735c66e6f58cfdffb20999890 (patch) | |
tree | f9c19952668b55d8d3067e5acb16c09b78a03dca | |
parent | 296956c3e3e6100f05f6f2d1525fd592ef567a17 (diff) | |
parent | 7cf7b180f06b00c0b6fed27948692f96a2874800 (diff) |
Merge PR #5273: FIX(client,mac): Add support for input/output device switching on macOS
Previously, when switching input/output devices at the system level, Mumble would ignore the switch and continue to use the previous device. This patch adds support for proper device switching, allowing Mumble to correctly follow the system input/output device.
Fixes #1013
-rw-r--r-- | src/mumble/CoreAudio.h | 4 | ||||
-rw-r--r-- | src/mumble/CoreAudio.mm | 49 |
2 files changed, 53 insertions, 0 deletions
diff --git a/src/mumble/CoreAudio.h b/src/mumble/CoreAudio.h index 9e76618b0..98c3f9619 100644 --- a/src/mumble/CoreAudio.h +++ b/src/mumble/CoreAudio.h @@ -45,6 +45,8 @@ protected: AudioBufferList buflist{}; static void propertyChange(void *udata, AudioUnit au, AudioUnitPropertyID prop, AudioUnitScope scope, AudioUnitElement element); + static OSStatus deviceChange(AudioObjectID inObjectID, UInt32 inNumberAddresses, + const AudioObjectPropertyAddress inAddresses[], void *udata); static OSStatus inputCallback(void *udata, AudioUnitRenderActionFlags *flags, const AudioTimeStamp *ts, UInt32 busnum, UInt32 npackets, AudioBufferList *buflist); @@ -64,6 +66,8 @@ protected: AudioUnit auHAL{}; static void propertyChange(void *udata, AudioUnit au, AudioUnitPropertyID prop, AudioUnitScope scope, AudioUnitElement element); + static OSStatus deviceChange(AudioObjectID inObjectID, UInt32 inNumberAddresses, + const AudioObjectPropertyAddress inAddresses[], void *udata); static OSStatus outputCallback(void *udata, AudioUnitRenderActionFlags *flags, const AudioTimeStamp *ts, UInt32 busnum, UInt32 npackets, AudioBufferList *buflist); diff --git a/src/mumble/CoreAudio.mm b/src/mumble/CoreAudio.mm index 846d944fd..b1d01cbcc 100644 --- a/src/mumble/CoreAudio.mm +++ b/src/mumble/CoreAudio.mm @@ -825,6 +825,14 @@ void CoreAudioInput::run() { "events."); } + AudioObjectPropertyAddress inputDeviceAddress = { + kAudioHardwarePropertyDefaultInputDevice, + kAudioObjectPropertyScopeGlobal, + kAudioObjectPropertyElementMaster + }; + CHECK_WARN(AudioObjectAddPropertyListener(kAudioObjectSystemObject, &inputDeviceAddress, CoreAudioInput::deviceChange, this), + "CoreAudioInput: Unable to create input device change listener. Unable to listen to device changes."); + buflist.mNumberBuffers = 1; AudioBuffer *b = buflist.mBuffers; b->mNumberChannels = iMicChannels; @@ -916,6 +924,23 @@ void CoreAudioInput::propertyChange(void *udata, AudioUnit auHAL, AudioUnitPrope } } +OSStatus CoreAudioInput::deviceChange(AudioObjectID inObjectID, UInt32 inNumberAddresses, + const AudioObjectPropertyAddress inAddresses[], void *udata) { + Q_UNUSED(inObjectID); + Q_UNUSED(inNumberAddresses); + Q_UNUSED(inAddresses); + + CoreAudioInput *o = reinterpret_cast< CoreAudioInput * >(udata); + if (!o->bRunning) return noErr; + + qWarning("CoreAudioInput: Input device change detected. Restarting AudioInput."); + Audio::stopInput(); + Audio::startInput(); + + return noErr; +} + + CoreAudioOutput::CoreAudioOutput() { } @@ -1017,6 +1042,14 @@ void CoreAudioOutput::run() { CHECK_WARN(AudioUnitAddPropertyListener(auHAL, kAudioUnitProperty_StreamFormat, CoreAudioOutput::propertyChange, this), "CoreAudioOutput: Unable to create output property change listener. Unable to listen to property changes."); + AudioObjectPropertyAddress outputDeviceAddress = { + kAudioHardwarePropertyDefaultOutputDevice, + kAudioObjectPropertyScopeGlobal, + kAudioObjectPropertyElementMaster + }; + CHECK_WARN(AudioObjectAddPropertyListener(kAudioObjectSystemObject, &outputDeviceAddress, CoreAudioOutput::deviceChange, this), + "CoreAudioOutput: Unable to create output device change listener. Unable to listen to device changes."); + AURenderCallbackStruct cb; cb.inputProc = CoreAudioOutput::outputCallback; cb.inputProcRefCon = this; @@ -1108,3 +1141,19 @@ void CoreAudioOutput::propertyChange(void *udata, AudioUnit auHAL, AudioUnitProp qWarning("CoreAudioOutput: Unexpected property changed event received."); } } + +OSStatus CoreAudioOutput::deviceChange(AudioObjectID inObjectID, UInt32 inNumberAddresses, + const AudioObjectPropertyAddress inAddresses[], void *udata) { + Q_UNUSED(inObjectID); + Q_UNUSED(inNumberAddresses); + Q_UNUSED(inAddresses); + + CoreAudioOutput *o = reinterpret_cast< CoreAudioOutput * >(udata); + if (!o->bRunning) return noErr; + + qWarning("CoreAudioOutput: Output device change detected. Restarting AudioOutput."); + Audio::stopOutput(); + Audio::startOutput(); + + return noErr; +} |