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;
|
||||
|
||||
#define MA_BACKEND_COUNT (ma_backend_null+1)
|
||||
|
||||
|
||||
/*
|
||||
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);
|
||||
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
@@ -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)
|
||||
{
|
||||
switch (backend)
|
||||
@@ -62603,6 +62814,7 @@ The following miscellaneous changes have also been made.
|
||||
REVISION HISTORY
|
||||
================
|
||||
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.
|
||||
- Core Audio: Fix a bug when using multiple contexts.
|
||||
- Core Audio: Fix a compilation warning.
|
||||
|
||||
@@ -357,7 +357,10 @@ int main(int argc, char** argv)
|
||||
{
|
||||
int iarg;
|
||||
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_context_config contextConfig;
|
||||
ma_device_type deviceType = ma_device_type_playback;
|
||||
@@ -403,6 +406,20 @@ int main(int argc, char** argv)
|
||||
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. */
|
||||
contextConfig = ma_context_config_init();
|
||||
contextConfig.logCallback = on_log;
|
||||
|
||||
Reference in New Issue
Block a user