aboutsummaryrefslogtreecommitdiffstats
path: root/alc
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2023-05-31 22:11:15 -0700
committerChris Robinson <[email protected]>2023-06-01 06:33:41 -0700
commitedc20c87d3cd37608e8fa50556d718cd32755f3d (patch)
treeca712a140ff79a21ba2c49d5c13b686c9679a143 /alc
parentd684c7617f2e13572b1c3f9a933a23e1f0e32d49 (diff)
Specify the device type for the event callback
Diffstat (limited to 'alc')
-rw-r--r--alc/backends/coreaudio.cpp28
-rw-r--r--alc/backends/pipewire.cpp22
-rw-r--r--alc/backends/pulseaudio.cpp6
-rw-r--r--alc/backends/wasapi.cpp38
-rw-r--r--alc/events.cpp10
-rw-r--r--alc/events.h11
-rw-r--r--alc/inprogext.h16
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