mirror of
https://github.com/mackron/miniaudio.git
synced 2026-04-21 15:56:58 +02:00
Add support for retrieving available backends at run-time.
The following APIs have been added: * ma_is_backend_available() * ma_get_avaialable_backends() Public issue https://github.com/mackron/miniaudio/issues/211
This commit is contained in:
+212
@@ -2948,6 +2948,8 @@ typedef enum
|
|||||||
ma_backend_null /* <-- Must always be the last item. Lowest priority, and used as the terminator for backend enumeration. */
|
ma_backend_null /* <-- Must always be the last item. Lowest priority, and used as the terminator for backend enumeration. */
|
||||||
} ma_backend;
|
} ma_backend;
|
||||||
|
|
||||||
|
#define MA_BACKEND_COUNT (ma_backend_null+1)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The callback for processing audio data from the device.
|
The callback for processing audio data from the device.
|
||||||
@@ -5097,6 +5099,84 @@ Retrieves a friendly name for a backend.
|
|||||||
*/
|
*/
|
||||||
MA_API const char* ma_get_backend_name(ma_backend backend);
|
MA_API const char* ma_get_backend_name(ma_backend backend);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Determines whether or not the given backend is available by the compilation environment.
|
||||||
|
*/
|
||||||
|
MA_API ma_bool32 ma_is_backend_available(ma_backend backend);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Retrieves available backends.
|
||||||
|
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
pBackends(out, optional)
|
||||||
|
A pointer to the buffer that will receive the available backends. Set to NULL to retrieve the backend count. Setting
|
||||||
|
the capacity of the buffer to `MA_BUFFER_COUNT` will guarantee it's large enough for all backends.
|
||||||
|
|
||||||
|
backendCap(in)
|
||||||
|
The capacity of the `pBackends` buffer.
|
||||||
|
|
||||||
|
pBackendCount(out)
|
||||||
|
A pointer to the variable that will receive the available backend count.
|
||||||
|
|
||||||
|
|
||||||
|
Return Value
|
||||||
|
------------
|
||||||
|
MA_SUCCESS if successful.
|
||||||
|
MA_INVALID_ARGS if `pBackendCount` is NULL.
|
||||||
|
MA_NO_SPACE if the capacity of `pBackends` is not large enough.
|
||||||
|
|
||||||
|
If `MA_NO_SPACE` is returned, the `pBackends` buffer will be filled with `*pBackendCount` values.
|
||||||
|
|
||||||
|
|
||||||
|
Thread Safety
|
||||||
|
-------------
|
||||||
|
Safe.
|
||||||
|
|
||||||
|
|
||||||
|
Callback Safety
|
||||||
|
---------------
|
||||||
|
Safe.
|
||||||
|
|
||||||
|
|
||||||
|
Remarks
|
||||||
|
-------
|
||||||
|
If you want to retrieve the number of backends so you can determine the capacity of `pBackends` buffer, you can call
|
||||||
|
this function with `pBackends` set to NULL.
|
||||||
|
|
||||||
|
This will also enumerate the null backend. If you don't want to include this you need to check for `ma_backend_null`
|
||||||
|
when you enumerate over the returned backends and handle it appropriately. Alternatively, you can disable it at
|
||||||
|
compile time with `MA_NO_NULL`.
|
||||||
|
|
||||||
|
The returned backends are determined based on compile time settings, not the platform it's currently running on. For
|
||||||
|
example, PulseAudio will be returned if it was enabled at compile time, even when the user doesn't actually have
|
||||||
|
PulseAudio installed.
|
||||||
|
|
||||||
|
|
||||||
|
Example 1
|
||||||
|
---------
|
||||||
|
The example below retrieves the available backend count using a fixed sized buffer allocated on the stack. The buffer
|
||||||
|
is given a capacity of `MA_BACKEND_COUNT` which will guarantee it'll be large enough to store all available backends.
|
||||||
|
Since `MA_BACKEND_COUNT` is always a relatively small value, this should be suitable for most scenarios.
|
||||||
|
|
||||||
|
```
|
||||||
|
ma_backend availableBackends[MA_BACKEND_COUNT];
|
||||||
|
size_t availableBackendCount;
|
||||||
|
|
||||||
|
result = ma_get_avaialable_backends(availableBackends, MA_BACKEND_COUNT, &availbleBackendCount);
|
||||||
|
if (result != MA_SUCCESS) {
|
||||||
|
// Failed to retrieve available backends. Should never happen in this example since all inputs are valid.
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
See Also
|
||||||
|
--------
|
||||||
|
ma_is_backend_available()
|
||||||
|
*/
|
||||||
|
MA_API ma_result ma_get_avaialable_backends(ma_backend* pBackends, size_t backendCap, size_t* pBackendCount);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Determines whether or not loopback mode is support by a backend.
|
Determines whether or not loopback mode is support by a backend.
|
||||||
*/
|
*/
|
||||||
@@ -9376,6 +9456,137 @@ MA_API const char* ma_get_backend_name(ma_backend backend)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MA_API ma_bool32 ma_is_backend_available(ma_backend backend)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
This looks a little bit gross, but we want all backends to be included in the switch to avoid warnings on some compilers
|
||||||
|
about some enums not being handled by the switch statement.
|
||||||
|
*/
|
||||||
|
switch (backend)
|
||||||
|
{
|
||||||
|
case ma_backend_wasapi:
|
||||||
|
#if defined(MA_HAS_WASAPI)
|
||||||
|
return MA_TRUE;
|
||||||
|
#else
|
||||||
|
return MA_FALSE;
|
||||||
|
#endif
|
||||||
|
case ma_backend_dsound:
|
||||||
|
#if defined(MA_HAS_DSOUND)
|
||||||
|
return MA_TRUE;
|
||||||
|
#else
|
||||||
|
return MA_FALSE;
|
||||||
|
#endif
|
||||||
|
case ma_backend_winmm:
|
||||||
|
#if defined(MA_HAS_WINMM)
|
||||||
|
return MA_TRUE;
|
||||||
|
#else
|
||||||
|
return MA_FALSE;
|
||||||
|
#endif
|
||||||
|
case ma_backend_coreaudio:
|
||||||
|
#if defined(MA_HAS_COREAUDIO)
|
||||||
|
return MA_TRUE;
|
||||||
|
#else
|
||||||
|
return MA_FALSE;
|
||||||
|
#endif
|
||||||
|
case ma_backend_sndio:
|
||||||
|
#if defined(MA_HAS_SNDIO)
|
||||||
|
return MA_TRUE;
|
||||||
|
#else
|
||||||
|
return MA_FALSE;
|
||||||
|
#endif
|
||||||
|
case ma_backend_audio4:
|
||||||
|
#if defined(MA_HAS_AUDIO4)
|
||||||
|
return MA_TRUE;
|
||||||
|
#else
|
||||||
|
return MA_FALSE;
|
||||||
|
#endif
|
||||||
|
case ma_backend_oss:
|
||||||
|
#if defined(MA_HAS_OSS)
|
||||||
|
return MA_TRUE;
|
||||||
|
#else
|
||||||
|
return MA_FALSE;
|
||||||
|
#endif
|
||||||
|
case ma_backend_pulseaudio:
|
||||||
|
#if defined(MA_HAS_PULSEAUDIO)
|
||||||
|
return MA_TRUE;
|
||||||
|
#else
|
||||||
|
return MA_FALSE;
|
||||||
|
#endif
|
||||||
|
case ma_backend_alsa:
|
||||||
|
#if defined(MA_HAS_ALSA)
|
||||||
|
return MA_TRUE;
|
||||||
|
#else
|
||||||
|
return MA_FALSE;
|
||||||
|
#endif
|
||||||
|
case ma_backend_jack:
|
||||||
|
#if defined(MA_HAS_JACK)
|
||||||
|
return MA_TRUE;
|
||||||
|
#else
|
||||||
|
return MA_FALSE;
|
||||||
|
#endif
|
||||||
|
case ma_backend_aaudio:
|
||||||
|
#if defined(MA_HAS_AAUDIO)
|
||||||
|
return MA_TRUE;
|
||||||
|
#else
|
||||||
|
return MA_FALSE;
|
||||||
|
#endif
|
||||||
|
case ma_backend_opensl:
|
||||||
|
#if defined(MA_HAS_OPENSL)
|
||||||
|
return MA_TRUE;
|
||||||
|
#else
|
||||||
|
return MA_FALSE;
|
||||||
|
#endif
|
||||||
|
case ma_backend_webaudio:
|
||||||
|
#if defined(MA_HAS_WEBAUDIO)
|
||||||
|
return MA_TRUE;
|
||||||
|
#else
|
||||||
|
return MA_FALSE;
|
||||||
|
#endif
|
||||||
|
case ma_backend_null:
|
||||||
|
#if defined(MA_HAS_NULL)
|
||||||
|
return MA_TRUE;
|
||||||
|
#else
|
||||||
|
return MA_FALSE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
default: return MA_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MA_API ma_result ma_get_avaialable_backends(ma_backend* pBackends, size_t backendCap, size_t* pBackendCount)
|
||||||
|
{
|
||||||
|
size_t backendCount;
|
||||||
|
size_t iBackend;
|
||||||
|
ma_result result = MA_SUCCESS;
|
||||||
|
|
||||||
|
if (pBackendCount == NULL) {
|
||||||
|
return MA_INVALID_ARGS;
|
||||||
|
}
|
||||||
|
|
||||||
|
backendCount = 0;
|
||||||
|
|
||||||
|
for (iBackend = 0; iBackend <= ma_backend_null; iBackend += 1) {
|
||||||
|
ma_backend backend = (ma_backend)iBackend;
|
||||||
|
|
||||||
|
if (ma_is_backend_available(backend)) {
|
||||||
|
/* The backend is available. Try adding it to the list. If there's no room, MA_NO_SPACE needs to be returned. */
|
||||||
|
if (backendCount == backendCap) {
|
||||||
|
result = MA_NO_SPACE;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
pBackends[backendCount] = backend;
|
||||||
|
backendCount += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pBackendCount != NULL) {
|
||||||
|
*pBackendCount = backendCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
MA_API ma_bool32 ma_is_loopback_supported(ma_backend backend)
|
MA_API ma_bool32 ma_is_loopback_supported(ma_backend backend)
|
||||||
{
|
{
|
||||||
switch (backend)
|
switch (backend)
|
||||||
@@ -62603,6 +62814,7 @@ The following miscellaneous changes have also been made.
|
|||||||
REVISION HISTORY
|
REVISION HISTORY
|
||||||
================
|
================
|
||||||
v0.10.21 - TBD
|
v0.10.21 - TBD
|
||||||
|
- Add ma_is_backend_available() and ma_get_avaialable_backends() for retrieving available backends at run-time.
|
||||||
- WASAPI: Fix a copy and paste bug relating to loopback mode.
|
- WASAPI: Fix a copy and paste bug relating to loopback mode.
|
||||||
- Core Audio: Fix a bug when using multiple contexts.
|
- Core Audio: Fix a bug when using multiple contexts.
|
||||||
- Core Audio: Fix a compilation warning.
|
- Core Audio: Fix a compilation warning.
|
||||||
|
|||||||
@@ -357,7 +357,10 @@ int main(int argc, char** argv)
|
|||||||
{
|
{
|
||||||
int iarg;
|
int iarg;
|
||||||
ma_result result;
|
ma_result result;
|
||||||
ma_backend backends[ma_backend_null+1];
|
ma_backend availableBackends[MA_BACKEND_COUNT];
|
||||||
|
size_t availbleBackendCount;
|
||||||
|
size_t iAvailableBackend;
|
||||||
|
ma_backend backends[MA_BACKEND_COUNT];
|
||||||
ma_uint32 backendCount = 0;
|
ma_uint32 backendCount = 0;
|
||||||
ma_context_config contextConfig;
|
ma_context_config contextConfig;
|
||||||
ma_device_type deviceType = ma_device_type_playback;
|
ma_device_type deviceType = ma_device_type_playback;
|
||||||
@@ -403,6 +406,20 @@ int main(int argc, char** argv)
|
|||||||
g_State.sourceType = source_type_decoder;
|
g_State.sourceType = source_type_decoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Here we'll quickly print the available backends. */
|
||||||
|
printf("Available Backends:\n");
|
||||||
|
result = ma_get_avaialable_backends(availableBackends, ma_countof(availableBackends), &availbleBackendCount);
|
||||||
|
if (result != MA_SUCCESS) {
|
||||||
|
printf("Failed to retrieve available backends.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (iAvailableBackend = 0; iAvailableBackend < availbleBackendCount; iAvailableBackend += 1) {
|
||||||
|
printf(" %s\n", ma_get_backend_name(availableBackends[iAvailableBackend]));
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
|
||||||
/* Initialize the context first. If no backends were passed into the command line we just use defaults. */
|
/* Initialize the context first. If no backends were passed into the command line we just use defaults. */
|
||||||
contextConfig = ma_context_config_init();
|
contextConfig = ma_context_config_init();
|
||||||
contextConfig.logCallback = on_log;
|
contextConfig.logCallback = on_log;
|
||||||
|
|||||||
Reference in New Issue
Block a user