Skip to content

Commit

Permalink
Add query fonction in ALC_SOFT_system_events unreleased extension (#938)
Browse files Browse the repository at this point in the history
* feat(ALC_SOFT_system_events): Add alcEventIsSupportedSOFT method in ALC_SOFT_system_events unreleased extension

The purpose of this addition (to my collection) are allow to retrieve which events are supported and if events are fully supported or if some case isn't managed for some reason

For exemple only some backends provide system events:
 * pipewire -> Full support of extension
 * wasapi -> Full support of extension
 * pulseaudio -> Support of add and remove devices events only
 * coreaudio -> Support of default device change only

* feat(ALC_SOFT_system_events): Fix typo in alext.h

Cf following review : #938 (comment)

* feat(ALC_SOFT_system_events): Remove ALC_EVENT_NOT_SUPPORTED_SOFT token

Cf following discussions between this comment : #938 (comment) to this comment : #938 (comment)
  • Loading branch information
MathiusD authored Nov 26, 2023
1 parent 1f6d19f commit c03603b
Show file tree
Hide file tree
Showing 15 changed files with 184 additions and 18 deletions.
40 changes: 40 additions & 0 deletions alc/alc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
#include "al/filter.h"
#include "al/listener.h"
#include "al/source.h"
#include "alc/events.h"
#include "albit.h"
#include "alconfig.h"
#include "almalloc.h"
Expand Down Expand Up @@ -3469,3 +3470,42 @@ FORCE_ALIGN ALCboolean ALC_APIENTRY alcReopenDeviceSOFT(ALCdevice *device,
ResetDeviceParams(dev.get(), attribs);
return ALC_TRUE;
}

/************************************************
* ALC event query functions
************************************************/

FORCE_ALIGN ALCenum ALC_APIENTRY alcEventIsSupportedSOFT(ALCenum eventType, ALCenum deviceType) noexcept
{
auto etype = alc::GetEventType(eventType);
if(!etype)
{
WARN("Invalid event type: 0x%04x\n", eventType);
alcSetError(nullptr, ALC_INVALID_ENUM);
return ALC_EVENT_NOT_SUPPORTED_SOFT;
}
switch(deviceType)
{
case al::to_underlying(alc::DeviceType::Playback):
{
if(!PlaybackFactory)
{
return ALC_EVENT_NOT_SUPPORTED_SOFT;
}

auto supported = PlaybackFactory->queryEventSupport(*etype, BackendType::Playback);
return al::to_underlying(supported);
}
case al::to_underlying(alc::DeviceType::Capture):
{
if(!CaptureFactory)
{
return ALC_EVENT_NOT_SUPPORTED_SOFT;
}

auto supported = CaptureFactory->queryEventSupport(*etype, BackendType::Capture);
return al::to_underlying(supported);
}
}
return ALC_EVENT_NOT_SUPPORTED_SOFT;
}
5 changes: 5 additions & 0 deletions alc/backends/base.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include "core/device.h"
#include "core/except.h"
#include "alc/events.h"


using uint = unsigned int;
Expand Down Expand Up @@ -79,6 +80,10 @@ struct BackendFactory {

virtual bool querySupport(BackendType type) = 0;

virtual alc::EventSupport queryEventSupport(alc::EventType eventType, BackendType type) {
return alc::EventSupport::NoSupport;
}

virtual std::string probe(BackendType type) = 0;

virtual BackendPtr createBackend(DeviceBase *device, BackendType type) = 0;
Expand Down
11 changes: 10 additions & 1 deletion alc/backends/coreaudio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
#include "core/device.h"
#include "core/logging.h"
#include "ringbuffer.h"
#include "alc/events.h"

#include <AudioUnit/AudioUnit.h>
#include <AudioToolbox/AudioToolbox.h>
Expand Down Expand Up @@ -1013,3 +1012,13 @@ BackendPtr CoreAudioBackendFactory::createBackend(DeviceBase *device, BackendTyp
return BackendPtr{new CoreAudioCapture{device}};
return nullptr;
}

alc::EventSupport CoreAudioBackendFactory::queryEventSupport(alc::EventType eventType, BackendType type)
{
switch(eventType) {
case alc::EventType::DefaultDeviceChanged: {
return alc::EventSupport::FullSupport;
}
}
return alc::EventSupport::NoSupport;
}
2 changes: 2 additions & 0 deletions alc/backends/coreaudio.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ struct CoreAudioBackendFactory final : public BackendFactory {

bool querySupport(BackendType type) override;

alc::EventSupport queryEventSupport(alc::EventType eventType, BackendType type) override;

std::string probe(BackendType type) override;

BackendPtr createBackend(DeviceBase *device, BackendType type) override;
Expand Down
17 changes: 16 additions & 1 deletion alc/backends/pipewire.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@

#include "albit.h"
#include "alc/alconfig.h"
#include "alc/events.h"
#include "almalloc.h"
#include "alnumeric.h"
#include "alspan.h"
Expand Down Expand Up @@ -2266,3 +2265,19 @@ BackendFactory &PipeWireBackendFactory::getFactory()
static PipeWireBackendFactory factory{};
return factory;
}

alc::EventSupport PipeWireBackendFactory::queryEventSupport(alc::EventType eventType, BackendType type)
{
switch(eventType) {
case alc::EventType::DefaultDeviceChanged: {
return alc::EventSupport::FullSupport;
}
case alc::EventType::DeviceAdded: {
return alc::EventSupport::FullSupport;
}
case alc::EventType::DeviceRemoved: {
return alc::EventSupport::FullSupport;
}
}
return alc::EventSupport::NoSupport;
}
2 changes: 2 additions & 0 deletions alc/backends/pipewire.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ struct PipeWireBackendFactory final : public BackendFactory {

bool querySupport(BackendType type) override;

alc::EventSupport queryEventSupport(alc::EventType eventType, BackendType type) override;

std::string probe(BackendType type) override;

BackendPtr createBackend(DeviceBase *device, BackendType type) override;
Expand Down
14 changes: 13 additions & 1 deletion alc/backends/pulseaudio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@

#include "albit.h"
#include "alc/alconfig.h"
#include "alc/events.h"
#include "almalloc.h"
#include "alnumeric.h"
#include "alspan.h"
Expand Down Expand Up @@ -1491,3 +1490,16 @@ BackendFactory &PulseBackendFactory::getFactory()
static PulseBackendFactory factory{};
return factory;
}

alc::EventSupport PulseBackendFactory::queryEventSupport(alc::EventType eventType, BackendType type)
{
switch(eventType) {
case alc::EventType::DeviceAdded: {
return alc::EventSupport::FullSupport;
}
case alc::EventType::DeviceRemoved: {
return alc::EventSupport::FullSupport;
}
}
return alc::EventSupport::NoSupport;
}
2 changes: 2 additions & 0 deletions alc/backends/pulseaudio.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ class PulseBackendFactory final : public BackendFactory {

bool querySupport(BackendType type) override;

alc::EventSupport queryEventSupport(alc::EventType eventType, BackendType type) override;

std::string probe(BackendType type) override;

BackendPtr createBackend(DeviceBase *device, BackendType type) override;
Expand Down
17 changes: 16 additions & 1 deletion alc/backends/wasapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@

#include "albit.h"
#include "alc/alconfig.h"
#include "alc/events.h"
#include "alnumeric.h"
#include "alspan.h"
#include "althrd_setname.h"
Expand Down Expand Up @@ -2741,3 +2740,19 @@ BackendFactory &WasapiBackendFactory::getFactory()
static WasapiBackendFactory factory{};
return factory;
}

alc::EventSupport WasapiBackendFactory::queryEventSupport(alc::EventType eventType, BackendType type)
{
switch(eventType) {
case alc::EventType::DefaultDeviceChanged: {
return alc::EventSupport::FullSupport;
}
case alc::EventType::DeviceAdded: {
return alc::EventSupport::FullSupport;
}
case alc::EventType::DeviceRemoved: {
return alc::EventSupport::FullSupport;
}
}
return alc::EventSupport::NoSupport;
}
2 changes: 2 additions & 0 deletions alc/backends/wasapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ struct WasapiBackendFactory final : public BackendFactory {

bool querySupport(BackendType type) override;

alc::EventSupport queryEventSupport(alc::EventType eventType, BackendType type) override;

std::string probe(BackendType type) override;

BackendPtr createBackend(DeviceBase *device, BackendType type) override;
Expand Down
26 changes: 12 additions & 14 deletions alc/events.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,13 @@

#include "events.h"

#include <optional>

#include "alspan.h"
#include "core/logging.h"
#include "device.h"


namespace {

std::optional<alc::EventType> GetEventType(ALCenum type)
{
switch(type)
{
case ALC_EVENT_TYPE_DEFAULT_DEVICE_CHANGED_SOFT: return alc::EventType::DefaultDeviceChanged;
case ALC_EVENT_TYPE_DEVICE_ADDED_SOFT: return alc::EventType::DeviceAdded;
case ALC_EVENT_TYPE_DEVICE_REMOVED_SOFT: return alc::EventType::DeviceRemoved;
}
return std::nullopt;
}

ALCenum EnumFromEventType(const alc::EventType type)
{
switch(type)
Expand All @@ -39,6 +26,17 @@ ALCenum EnumFromEventType(const alc::EventType type)

namespace alc {

std::optional<alc::EventType> GetEventType(ALCenum type)
{
switch(type)
{
case ALC_EVENT_TYPE_DEFAULT_DEVICE_CHANGED_SOFT: return alc::EventType::DefaultDeviceChanged;
case ALC_EVENT_TYPE_DEVICE_ADDED_SOFT: return alc::EventType::DeviceAdded;
case ALC_EVENT_TYPE_DEVICE_REMOVED_SOFT: return alc::EventType::DeviceRemoved;
}
return std::nullopt;
}

void Event(EventType eventType, DeviceType deviceType, ALCdevice *device, std::string_view message) noexcept
{
auto eventlock = std::unique_lock{EventMutex};
Expand Down Expand Up @@ -73,7 +71,7 @@ FORCE_ALIGN ALCboolean ALC_APIENTRY alcEventControlSOFT(ALCsizei count, const AL
alc::EventBitSet eventSet{0};
for(ALCenum type : al::span{events, static_cast<ALCuint>(count)})
{
auto etype = GetEventType(type);
auto etype = alc::GetEventType(type);
if(!etype)
{
WARN("Invalid event type: 0x%04x\n", type);
Expand Down
8 changes: 8 additions & 0 deletions alc/events.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include <bitset>
#include <mutex>
#include <optional>
#include <string_view>


Expand All @@ -19,6 +20,13 @@ enum class EventType : uint8_t {
Count
};

std::optional<alc::EventType> GetEventType(ALCenum type);

enum class EventSupport : ALCenum {
FullSupport = ALC_EVENT_SUPPORTED_SOFT,
NoSupport = ALC_EVENT_NOT_SUPPORTED_SOFT,
};

enum class DeviceType : ALCenum {
Playback = ALC_PLAYBACK_DEVICE_SOFT,
Capture = ALC_CAPTURE_DEVICE_SOFT,
Expand Down
1 change: 1 addition & 0 deletions alc/export_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ inline const FuncExport alcFunctions[]{

DECL(alcReopenDeviceSOFT),

DECL(alcEventIsSupportedSOFT),
DECL(alcEventControlSOFT),
DECL(alcEventCallbackSOFT),

Expand Down
4 changes: 4 additions & 0 deletions include/AL/alext.h
Original file line number Diff line number Diff line change
Expand Up @@ -720,11 +720,15 @@ void AL_APIENTRY alGetObjectLabelEXT(ALenum identifier, ALuint name, ALsizei buf
#define ALC_EVENT_TYPE_DEFAULT_DEVICE_CHANGED_SOFT 0x19D6
#define ALC_EVENT_TYPE_DEVICE_ADDED_SOFT 0x19D7
#define ALC_EVENT_TYPE_DEVICE_REMOVED_SOFT 0x19D8
#define ALC_EVENT_SUPPORTED_SOFT 0x19D9
#define ALC_EVENT_NOT_SUPPORTED_SOFT 0x19DA
typedef void (ALC_APIENTRY*ALCEVENTPROCTYPESOFT)(ALCenum eventType, ALCenum deviceType,
ALCdevice *device, ALCsizei length, const ALCchar *message, void *userParam) ALC_API_NOEXCEPT17;
typedef ALCenum (ALC_APIENTRY*LPALCEVENTISSUPPORTEDSOFT)(ALCenum eventType, ALCenum deviceType) 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
ALCenum ALC_APIENTRY alcEventIsSupportedSOFT(ALCenum eventType, ALCenum deviceType) 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
Expand Down
51 changes: 51 additions & 0 deletions utils/openal-info.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,56 @@ static void printModeInfo(ALCdevice *device)
}
}

static void printALCSOFTSystemEventIsSupportedResult(LPALCEVENTISSUPPORTEDSOFT alcEventIsSupportedSOFT, ALCenum eventType, ALCenum deviceType)
{
if (alcEventIsSupportedSOFT == NULL)
{
printf("ERROR (alcEventIsSupportedSOFT missing)\n");
return;
}
ALCenum supported = alcEventIsSupportedSOFT(eventType, deviceType);
if (supported == ALC_EVENT_SUPPORTED_SOFT)
{
printf("SUPPORTED\n");
}
else if (supported == ALC_EVENT_NOT_SUPPORTED_SOFT)
{
printf("NOT SUPPORTED\n");
}
else
{
printf("UNEXPECTED VALUE : %d\n", supported);
}
}

static void printALC_SOFT_system_event(void)
{
printf("ALC_SOFT_system_events:");
if (alcIsExtensionPresent(NULL, "ALC_SOFT_system_events"))
{
static LPALCEVENTISSUPPORTEDSOFT alcEventIsSupportedSOFT;
alcEventIsSupportedSOFT = FUNCTION_CAST(LPALCEVENTISSUPPORTEDSOFT, alGetProcAddress("alcEventIsSupportedSOFT"));
printf(" Supported.\n");
printf(" Events:\n");
printf(" ALC_EVENT_TYPE_DEFAULT_DEVICE_CHANGED_SOFT for ALC_PLAYBACK_DEVICE_SOFT - ");
printALCSOFTSystemEventIsSupportedResult(alcEventIsSupportedSOFT, ALC_EVENT_TYPE_DEFAULT_DEVICE_CHANGED_SOFT, ALC_PLAYBACK_DEVICE_SOFT);
printf(" ALC_EVENT_TYPE_DEFAULT_DEVICE_CHANGED_SOFT for ALC_CAPTURE_DEVICE_SOFT - ");
printALCSOFTSystemEventIsSupportedResult(alcEventIsSupportedSOFT, ALC_EVENT_TYPE_DEFAULT_DEVICE_CHANGED_SOFT, ALC_CAPTURE_DEVICE_SOFT);
printf(" ALC_EVENT_TYPE_DEVICE_ADDED_SOFT for ALC_PLAYBACK_DEVICE_SOFT - ");
printALCSOFTSystemEventIsSupportedResult(alcEventIsSupportedSOFT, ALC_EVENT_TYPE_DEVICE_ADDED_SOFT, ALC_PLAYBACK_DEVICE_SOFT);
printf(" ALC_EVENT_TYPE_DEVICE_ADDED_SOFT for ALC_CAPTURE_DEVICE_SOFT - ");
printALCSOFTSystemEventIsSupportedResult(alcEventIsSupportedSOFT, ALC_EVENT_TYPE_DEVICE_ADDED_SOFT, ALC_CAPTURE_DEVICE_SOFT);
printf(" ALC_EVENT_TYPE_DEVICE_REMOVED_SOFT for ALC_PLAYBACK_DEVICE_SOFT - ");
printALCSOFTSystemEventIsSupportedResult(alcEventIsSupportedSOFT, ALC_EVENT_TYPE_DEVICE_REMOVED_SOFT, ALC_PLAYBACK_DEVICE_SOFT);
printf(" ALC_EVENT_TYPE_DEVICE_REMOVED_SOFT for ALC_CAPTURE_DEVICE_SOFT - ");
printALCSOFTSystemEventIsSupportedResult(alcEventIsSupportedSOFT, ALC_EVENT_TYPE_DEVICE_REMOVED_SOFT, ALC_CAPTURE_DEVICE_SOFT);
}
else
{
printf(" Not supported.\n");
}
}

static void printALInfo(void)
{
printf("OpenAL vendor string: %s\n", alGetString(AL_VENDOR));
Expand Down Expand Up @@ -435,6 +485,7 @@ int main(int argc, char *argv[])
}
printALCInfo(device);
printHRTFInfo(device);
printALC_SOFT_system_event();

context = alcCreateContext(device, NULL);
if(!context || alcMakeContextCurrent(context) == ALC_FALSE)
Expand Down

0 comments on commit c03603b

Please sign in to comment.