Skip to content

Commit

Permalink
FEAT(client,mac): Add support for output device switching on macOS
Browse files Browse the repository at this point in the history
Previously, when switching output device at the system level, Mumble would ignore the switch and continue to output from the previous device. This patch adds support for proper output device switching, allowing Mumble to correctly follow the system output device.

Note that this does not cover input device switching, but in theory the solution for that should be similar to this. I'd be happy to add input device switching support as well, if requested.

Implements #1013
  • Loading branch information
jlsalmon committed Sep 29, 2021
1 parent 296956c commit 3401624
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/mumble/CoreAudio.h
Expand Up @@ -64,6 +64,10 @@ class CoreAudioOutput : public AudioOutput {
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 *inClientData);
static OSStatus outputCallback(void *udata, AudioUnitRenderActionFlags *flags, const AudioTimeStamp *ts,
UInt32 busnum, UInt32 npackets, AudioBufferList *buflist);

Expand Down
24 changes: 24 additions & 0 deletions src/mumble/CoreAudio.mm
Expand Up @@ -1017,6 +1017,13 @@ static void LogAUStreamDescription(AudioUnit au) {
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
};
AudioObjectAddPropertyListener(kAudioObjectSystemObject, &outputDeviceAddress, CoreAudioOutput::deviceChange, this);

AURenderCallbackStruct cb;
cb.inputProc = CoreAudioOutput::outputCallback;
cb.inputProcRefCon = this;
Expand Down Expand Up @@ -1108,3 +1115,20 @@ static void LogAUStreamDescription(AudioUnit au) {
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.");
o->stop();
Audio::stopOutput();
Audio::startOutput();

return noErr;
}

0 comments on commit 3401624

Please sign in to comment.