diff options
author | Chris Robinson <[email protected]> | 2023-05-31 22:11:15 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2023-06-01 06:33:41 -0700 |
commit | edc20c87d3cd37608e8fa50556d718cd32755f3d (patch) | |
tree | ca712a140ff79a21ba2c49d5c13b686c9679a143 /alc | |
parent | d684c7617f2e13572b1c3f9a933a23e1f0e32d49 (diff) |
Specify the device type for the event callback
Diffstat (limited to 'alc')
-rw-r--r-- | alc/backends/coreaudio.cpp | 28 | ||||
-rw-r--r-- | alc/backends/pipewire.cpp | 22 | ||||
-rw-r--r-- | alc/backends/pulseaudio.cpp | 6 | ||||
-rw-r--r-- | alc/backends/wasapi.cpp | 38 | ||||
-rw-r--r-- | alc/events.cpp | 10 | ||||
-rw-r--r-- | alc/events.h | 11 | ||||
-rw-r--r-- | alc/inprogext.h | 16 |
7 files changed, 86 insertions, 45 deletions
diff --git a/alc/backends/coreaudio.cpp b/alc/backends/coreaudio.cpp index a9419e3d..1e8423b7 100644 --- a/alc/backends/coreaudio.cpp +++ b/alc/backends/coreaudio.cpp @@ -273,39 +273,39 @@ void EnumerateDevices(std::vector<DeviceEntry> &list, bool isCapture) newdevs.swap(list); } -struct DeviceHelper -{ -public: +struct DeviceHelper { DeviceHelper() { - AudioObjectPropertyAddress addr = {kAudioHardwarePropertyDefaultOutputDevice, - kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMain}; + 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}; + 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*/) + static OSStatus DeviceListenerProc(AudioObjectID /*inObjectID*/, UInt32 inNumberAddresses, + const AudioObjectPropertyAddress *inAddresses, void* /*inClientData*/) { - for (UInt32 i = 0; i < inNumberAddresses; ++i) + for(UInt32 i = 0; i < inNumberAddresses; ++i) { - switch (inAddresses[i].mSelector) + switch(inAddresses[i].mSelector) { case kAudioHardwarePropertyDefaultOutputDevice: case kAudioHardwarePropertyDefaultSystemOutputDevice: + alc::Event(alc::EventType::DefaultDeviceChanged, alc::DeviceType::Playback, + "Default playback device changed: "+std::to_string(inAddresses[i].mSelector)); + break; case kAudioHardwarePropertyDefaultInputDevice: - alc::Event(alc::EventType::DefaultDeviceChanged, "Default device changed: "+std::to_string(inAddresses[i].mSelector)); + alc::Event(alc::EventType::DefaultDeviceChanged, alc::DeviceType::Capture, + "Default capture device changed: "+std::to_string(inAddresses[i].mSelector)); break; } } diff --git a/alc/backends/pipewire.cpp b/alc/backends/pipewire.cpp index fad64f01..2bee4d7d 100644 --- a/alc/backends/pipewire.cpp +++ b/alc/backends/pipewire.cpp @@ -578,6 +578,16 @@ struct DeviceNode { void parseSampleRate(const spa_pod *value) noexcept; void parsePositions(const spa_pod *value) noexcept; void parseChannelCount(const spa_pod *value) noexcept; + + void callEvent(alc::EventType type, std::string_view message) + { + /* Source nodes aren't recognized for playback, only Sink and Duplex + * nodes are. All node types are recognized for capture. + */ + if(mType != NodeType::Source) + alc::Event(type, alc::DeviceType::Playback, message); + alc::Event(type, alc::DeviceType::Capture, message); + } }; std::vector<DeviceNode> DeviceNode::sList; std::string DefaultSinkDevice; @@ -641,7 +651,7 @@ void DeviceNode::Remove(uint32_t id) if(gEventHandler.initIsDone(std::memory_order_relaxed)) { const std::string msg{"Device removed: "+n.mName}; - alc::Event(alc::EventType::DeviceRemoved, msg); + n.callEvent(alc::EventType::DeviceRemoved, msg); } return true; }; @@ -940,10 +950,10 @@ void NodeProxy::infoCallback(const pw_node_info *info) noexcept if(!node.mName.empty()) { const std::string msg{"Device removed: "+node.mName}; - alc::Event(alc::EventType::DeviceRemoved, msg); + node.callEvent(alc::EventType::DeviceRemoved, msg); } const std::string msg{"Device added: "+name}; - alc::Event(alc::EventType::DeviceAdded, msg); + node.callEvent(alc::EventType::DeviceAdded, msg); } node.mName = std::move(name); } @@ -1065,7 +1075,8 @@ int MetadataProxy::propertyCallback(uint32_t id, const char *key, const char *ty auto entry = DeviceNode::FindByDevName(*propValue); const std::string msg{"Default playback device changed: "+ (entry ? entry->mName : std::string{})}; - alc::Event(alc::EventType::DefaultDeviceChanged, msg); + alc::Event(alc::EventType::DefaultDeviceChanged, alc::DeviceType::Playback, + msg); } DefaultSinkDevice = std::move(*propValue); } @@ -1079,7 +1090,8 @@ int MetadataProxy::propertyCallback(uint32_t id, const char *key, const char *ty auto entry = DeviceNode::FindByDevName(*propValue); const std::string msg{"Default capture device changed: "+ (entry ? entry->mName : std::string{})}; - alc::Event(alc::EventType::DefaultDeviceChanged, msg); + alc::Event(alc::EventType::DefaultDeviceChanged, alc::DeviceType::Capture, + msg); } DefaultSourceDevice = std::move(*propValue); } diff --git a/alc/backends/pulseaudio.cpp b/alc/backends/pulseaudio.cpp index 16a2450f..8c6cc4d3 100644 --- a/alc/backends/pulseaudio.cpp +++ b/alc/backends/pulseaudio.cpp @@ -452,11 +452,13 @@ struct MainloopUniqueLock : public std::unique_lock<PulseMainloop> { if(eventFacility == PA_SUBSCRIPTION_EVENT_SINK || eventFacility == PA_SUBSCRIPTION_EVENT_SOURCE) { + const auto deviceType = (eventFacility == PA_SUBSCRIPTION_EVENT_SINK) + ? alc::DeviceType::Playback : alc::DeviceType::Capture; const auto eventType = (t & PA_SUBSCRIPTION_EVENT_TYPE_MASK); if(eventType == PA_SUBSCRIPTION_EVENT_NEW) - alc::Event(alc::EventType::DeviceAdded, "Device added"); + alc::Event(alc::EventType::DeviceAdded, deviceType, "Device added"); else if(eventType == PA_SUBSCRIPTION_EVENT_REMOVE) - alc::Event(alc::EventType::DeviceRemoved, "Device removed"); + alc::Event(alc::EventType::DeviceRemoved, deviceType, "Device removed"); } }; pa_context_set_subscribe_callback(mutex()->mContext, handler, nullptr); diff --git a/alc/backends/wasapi.cpp b/alc/backends/wasapi.cpp index ccdc54e7..32a4334d 100644 --- a/alc/backends/wasapi.cpp +++ b/alc/backends/wasapi.cpp @@ -237,23 +237,33 @@ public: #if defined(ALSOFT_UWP) mActiveClientEvent = CreateEventW(nullptr, FALSE, FALSE, nullptr); - auto cb = [](const WCHAR *devid) + auto cb = [](alc::DeviceType type, const WCHAR *devid) { const std::string msg{"Default device changed: "+wstr_to_utf8(devid)}; - alc::Event(alc::EventType::DefaultDeviceChanged, msg); + alc::Event(alc::EventType::DefaultDeviceChanged, type, msg); }; mRenderDeviceChangedToken = MediaDevice::DefaultAudioRenderDeviceChanged += ref new TypedEventHandler<Platform::Object ^, DefaultAudioRenderDeviceChangedEventArgs ^>( [this,cb](Platform::Object ^ sender, DefaultAudioRenderDeviceChangedEventArgs ^ args) { - if (args->Role == AudioDeviceRole::Default) - cb(args->Id->Data()); + if(args->Role == AudioDeviceRole::Default) + { + const std::string msg{"Default playback device changed: "+ + wstr_to_utf8(args->Id->Data())}; + alc::Event(alc::EventType::DefaultDeviceChanged, alc::DeviceType::Playback, + msg); + } }); mCaptureDeviceChangedToken = MediaDevice::DefaultAudioCaptureDeviceChanged += ref new TypedEventHandler<Platform::Object ^, DefaultAudioCaptureDeviceChangedEventArgs ^>( [this,cb](Platform::Object ^ sender, DefaultAudioCaptureDeviceChangedEventArgs ^ args) { - if (args->Role == AudioDeviceRole::Default) - cb(args->Id->Data()); + if(args->Role == AudioDeviceRole::Default) + { + const std::string msg{"Default capture device changed: "+ + wstr_to_utf8(args->Id->Data())}; + alc::Event(alc::EventType::DefaultDeviceChanged, alc::DeviceType::Capture, + msg); + } }); #else HRESULT hr{CoCreateInstance(CLSID_MMDeviceEnumerator, nullptr, CLSCTX_INPROC_SERVER, @@ -370,10 +380,20 @@ public: STDMETHODIMP OnPropertyValueChanged(LPCWSTR /*pwstrDeviceId*/, const PROPERTYKEY /*key*/) noexcept override { return S_OK; } STDMETHODIMP OnDefaultDeviceChanged(EDataFlow flow, ERole role, LPCWSTR pwstrDefaultDeviceId) noexcept override { - if(role == eMultimedia && (flow == eRender || flow == eCapture)) + if(role != eMultimedia) + return S_OK; + + if(flow == eRender) + { + const std::string msg{"Default playback device changed: "+ + wstr_to_utf8(pwstrDefaultDeviceId)}; + alc::Event(alc::EventType::DefaultDeviceChanged, alc::DeviceType::Playback, msg); + } + else if(flow == eCapture) { - const std::string msg{"Default device changed: "+wstr_to_utf8(pwstrDefaultDeviceId)}; - alc::Event(alc::EventType::DefaultDeviceChanged, msg); + const std::string msg{"Default capture device changed: "+ + wstr_to_utf8(pwstrDefaultDeviceId)}; + alc::Event(alc::EventType::DefaultDeviceChanged, alc::DeviceType::Capture, msg); } return S_OK; } diff --git a/alc/events.cpp b/alc/events.cpp index 3c9c59ee..b5b65cb1 100644 --- a/alc/events.cpp +++ b/alc/events.cpp @@ -40,17 +40,17 @@ ALCenum EnumFromEventType(const alc::EventType type) namespace alc { -void Event(EventType eventType, ALCdevice *device, std::string_view message) noexcept +void Event(EventType eventType, DeviceType deviceType, ALCdevice *device, std::string_view message) noexcept { auto eventlock = std::unique_lock{EventMutex}; if(EventCallback && EventsEnabled.test(al::to_underlying(eventType))) - EventCallback(EnumFromEventType(eventType), device, + EventCallback(EnumFromEventType(eventType), al::to_underlying(deviceType), device, static_cast<ALCsizei>(message.length()), message.data(), EventUserPtr); } } // namespace alc -FORCE_ALIGN ALCboolean ALC_APIENTRY alcEventControlSOFT(ALCsizei count, const ALCenum *types, +FORCE_ALIGN ALCboolean ALC_APIENTRY alcEventControlSOFT(ALCsizei count, const ALCenum *events, ALCboolean enable) noexcept { if(enable != ALC_FALSE && enable != ALC_TRUE) @@ -65,14 +65,14 @@ FORCE_ALIGN ALCboolean ALC_APIENTRY alcEventControlSOFT(ALCsizei count, const AL } if(count == 0) return ALC_TRUE; - if(!types) + if(!events) { alcSetError(nullptr, ALC_INVALID_VALUE); return ALC_FALSE; } std::bitset<al::to_underlying(alc::EventType::Count)> eventSet{0}; - for(ALCenum type : al::span{types, static_cast<ALCuint>(count)}) + for(ALCenum type : al::span{events, static_cast<ALCuint>(count)}) { auto etype = GetEventType(type); if(!etype) diff --git a/alc/events.h b/alc/events.h index 3b22a4c4..ddb3808a 100644 --- a/alc/events.h +++ b/alc/events.h @@ -19,6 +19,11 @@ enum class EventType : uint8_t { Count }; +enum class DeviceType : ALCenum { + Playback = ALC_PLAYBACK_DEVICE_SOFT, + Capture = ALC_CAPTURE_DEVICE_SOFT, +}; + inline std::bitset<al::to_underlying(EventType::Count)> EventsEnabled{0}; inline std::mutex EventMutex; @@ -26,10 +31,10 @@ inline std::mutex EventMutex; inline ALCEVENTPROCTYPESOFT EventCallback{}; inline void *EventUserPtr{}; -void Event(alc::EventType eventType, ALCdevice *device, std::string_view message) noexcept; +void Event(EventType eventType, DeviceType deviceType, ALCdevice *device, std::string_view message) noexcept; -inline void Event(alc::EventType eventType, std::string_view message) noexcept -{ Event(eventType, nullptr, message); } +inline void Event(EventType eventType, DeviceType deviceType, std::string_view message) noexcept +{ Event(eventType, deviceType, nullptr, message); } } // namespace alc diff --git a/alc/inprogext.h b/alc/inprogext.h index 7cf49868..65e34ea4 100644 --- a/alc/inprogext.h +++ b/alc/inprogext.h @@ -445,15 +445,17 @@ ALenum AL_APIENTRY EAXGetBufferModeDirect(ALCcontext *context, ALuint buffer, AL #ifndef ALC_SOFT_system_events #define ALC_SOFT_system_events -#define ALC_EVENT_TYPE_DEFAULT_DEVICE_CHANGED_SOFT 0x19CF -#define ALC_EVENT_TYPE_DEVICE_ADDED_SOFT 0x19D0 -#define ALC_EVENT_TYPE_DEVICE_REMOVED_SOFT 0x19D1 -typedef void (ALC_APIENTRY*ALCEVENTPROCTYPESOFT)(ALCenum eventType, ALCdevice *device, - ALCsizei length, const ALCchar *message, void *userParam) ALC_API_NOEXCEPT17; -typedef ALCboolean (ALC_APIENTRY*LPALCEVENTCONTROLSOFT)(ALCsizei count, const ALCenum *types, ALCboolean enable) ALC_API_NOEXCEPT17; +#define ALC_PLAYBACK_DEVICE_SOFT 0x19CF +#define ALC_CAPTURE_DEVICE_SOFT 0x19D0 +#define ALC_EVENT_TYPE_DEFAULT_DEVICE_CHANGED_SOFT 0x19D1 +#define ALC_EVENT_TYPE_DEVICE_ADDED_SOFT 0x19D2 +#define ALC_EVENT_TYPE_DEVICE_REMOVED_SOFT 0x19D3 +typedef void (ALC_APIENTRY*ALCEVENTPROCTYPESOFT)(ALCenum eventType, ALCenum deviceType, + ALCdevice *device, ALCsizei length, const ALCchar *message, void *userParam) ALC_API_NOEXCEPT17; +typedef ALCboolean (ALC_APIENTRY*LPALCEVENTCONTROLSOFT)(ALCsizei count, const ALCenum *events, ALCboolean enable) ALC_API_NOEXCEPT17; typedef void (ALC_APIENTRY*LPALCEVENTCALLBACKSOFT)(ALCEVENTPROCTYPESOFT callback, void *userParam) ALC_API_NOEXCEPT17; #ifdef AL_ALEXT_PROTOTYPES -ALCboolean ALC_APIENTRY alcEventControlSOFT(ALCsizei count, const ALCenum *types, ALCboolean enable) ALC_API_NOEXCEPT; +ALCboolean ALC_APIENTRY alcEventControlSOFT(ALCsizei count, const ALCenum *events, ALCboolean enable) ALC_API_NOEXCEPT; void ALC_APIENTRY alcEventCallbackSOFT(ALCEVENTPROCTYPESOFT callback, void *userParam) ALC_API_NOEXCEPT; #endif #endif |