diff options
Diffstat (limited to 'alc/backends/coreaudio.cpp')
-rw-r--r-- | alc/backends/coreaudio.cpp | 51 |
1 files changed, 50 insertions, 1 deletions
diff --git a/alc/backends/coreaudio.cpp b/alc/backends/coreaudio.cpp index 13665a4c..a9419e3d 100644 --- a/alc/backends/coreaudio.cpp +++ b/alc/backends/coreaudio.cpp @@ -32,12 +32,14 @@ #include <string.h> #include <unistd.h> #include <vector> +#include <optional> #include "alnumeric.h" #include "core/converter.h" #include "core/device.h" #include "core/logging.h" #include "ringbuffer.h" +#include "alc/events.h" #include <AudioUnit/AudioUnit.h> #include <AudioToolbox/AudioToolbox.h> @@ -271,6 +273,47 @@ void EnumerateDevices(std::vector<DeviceEntry> &list, bool isCapture) newdevs.swap(list); } +struct DeviceHelper +{ +public: + DeviceHelper() + { + AudioObjectPropertyAddress addr = {kAudioHardwarePropertyDefaultOutputDevice, + kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMain}; + OSStatus status = AudioObjectAddPropertyListener(kAudioObjectSystemObject, &addr, DeviceListenerProc, nil); + if (status != noErr) + ERR("AudioObjectAddPropertyListener fail: %d", status); + } + ~DeviceHelper() + { + AudioObjectPropertyAddress addr = {kAudioHardwarePropertyDefaultOutputDevice, + kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMain}; + OSStatus status = AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &addr, DeviceListenerProc, nil); + if (status != noErr) + ERR("AudioObjectRemovePropertyListener fail: %d", status); + } + + static OSStatus DeviceListenerProc(AudioObjectID /*inObjectID*/, + UInt32 inNumberAddresses, + const AudioObjectPropertyAddress *inAddresses, + void* /*inClientData*/) + { + for (UInt32 i = 0; i < inNumberAddresses; ++i) + { + switch (inAddresses[i].mSelector) + { + case kAudioHardwarePropertyDefaultOutputDevice: + case kAudioHardwarePropertyDefaultSystemOutputDevice: + case kAudioHardwarePropertyDefaultInputDevice: + alc::Event(alc::EventType::DefaultDeviceChanged, "Default device changed: "+std::to_string(inAddresses[i].mSelector)); + break; + } + } + } +}; + +static std::optional<DeviceHelper> sDeviceHelper; + #else static constexpr char ca_device[] = "CoreAudio Default"; @@ -915,7 +958,13 @@ BackendFactory &CoreAudioBackendFactory::getFactory() return factory; } -bool CoreAudioBackendFactory::init() { return true; } +bool CoreAudioBackendFactory::init() +{ +#if CAN_ENUMERATE + sDeviceHelper.emplace(); +#endif + return true; +} bool CoreAudioBackendFactory::querySupport(BackendType type) { return type == BackendType::Playback || type == BackendType::Capture; } |