summaryrefslogtreecommitdiffhomepage
path: root/src/external/miniaudio.h
diff options
context:
space:
mode:
authorRay <[email protected]>2019-08-07 00:33:57 +0200
committerRay <[email protected]>2019-08-07 00:33:57 +0200
commit3d46297cc150803a55e27f446b2d4708ff0b04bd (patch)
treeed441cacca41738d27371e2d49c11be250ba2462 /src/external/miniaudio.h
parent439e73a8ece912f2a7df5f4c0ed7fc6fb7673672 (diff)
downloadraylib-3d46297cc150803a55e27f446b2d4708ff0b04bd.tar.gz
raylib-3d46297cc150803a55e27f446b2d4708ff0b04bd.zip
Update external libraries
Diffstat (limited to 'src/external/miniaudio.h')
-rw-r--r--src/external/miniaudio.h1219
1 files changed, 841 insertions, 378 deletions
diff --git a/src/external/miniaudio.h b/src/external/miniaudio.h
index f51a1b68..e6752fbf 100644
--- a/src/external/miniaudio.h
+++ b/src/external/miniaudio.h
@@ -1,8 +1,10 @@
/*
Audio playback and capture library. Choice of public domain or MIT-0. See license statements at the end of this file.
-miniaudio (formerly mini_al) - v0.9.4 - 2019-05-06
+miniaudio (formerly mini_al) - v0.9.6 - 2019-xx-xx
David Reid - [email protected]
+
+https://github.com/dr-soft/miniaudio
*/
/*
@@ -304,7 +306,7 @@ UWP
Web Audio / Emscripten
----------------------
-- The first time a context is initialized it will create a global object called "mal" whose primary purpose is to act
+- The first time a context is initialized it will create a global object called "miniaudio" whose primary purpose is to act
as a factory for device objects.
- Currently the Web Audio backend uses ScriptProcessorNode's, but this may need to change later as they've been deprecated.
- Google is implementing a policy in their browsers that prevent automatic media output without first receiving some kind
@@ -395,7 +397,7 @@ OPTIONS
MA_LOG_LEVEL_WARNING
MA_LOG_LEVEL_ERROR
-#define MA_DEBUT_OUTPUT
+#define MA_DEBUG_OUTPUT
Enable printf() debug output.
#define MA_COINIT_VALUE
@@ -542,10 +544,10 @@ extern "C" {
#endif
#endif
-typedef ma_uint8 ma_bool8;
-typedef ma_uint32 ma_bool32;
-#define MA_TRUE 1
-#define MA_FALSE 0
+typedef ma_uint8 ma_bool8;
+typedef ma_uint32 ma_bool32;
+#define MA_TRUE 1
+#define MA_FALSE 0
typedef void* ma_handle;
typedef void* ma_ptr;
@@ -944,7 +946,7 @@ MA_ALIGNED_STRUCT(MA_SIMD_ALIGNMENT) ma_src
};
typedef struct ma_pcm_converter ma_pcm_converter;
-typedef ma_uint32 (* ma_pcm_converter_read_proc)(ma_pcm_converter* pDSP, void* pSamplesOut, ma_uint32 frameCount, void* pUserData);
+typedef ma_uint32 (* ma_pcm_converter_read_proc)(ma_pcm_converter* pDSP, void* pFramesOut, ma_uint32 frameCount, void* pUserData);
typedef struct
{
@@ -987,7 +989,7 @@ MA_ALIGNED_STRUCT(MA_SIMD_ALIGNMENT) ma_pcm_converter
ma_bool32 isChannelRoutingRequired : 1;
ma_bool32 isSRCRequired : 1;
ma_bool32 isChannelRoutingAtStart : 1;
- ma_bool32 isPassthrough : 1; /* <-- Will be set to true when the DSP pipeline is an optimized passthrough. */
+ ma_bool32 isPassthrough : 1; /* <-- Will be set to true when the conversion pipeline is an optimized passthrough. */
};
@@ -1342,7 +1344,7 @@ determine the required size of the output buffer.
A return value of 0 indicates an error.
-This function is useful for one-off bulk conversions, but if you're streaming data you should use the DSP APIs instead.
+This function is useful for one-off bulk conversions, but if you're streaming data you should use the ma_pcm_converter APIs instead.
*/
ma_uint64 ma_convert_frames(void* pOut, ma_format formatOut, ma_uint32 channelsOut, ma_uint32 sampleRateOut, const void* pIn, ma_format formatIn, ma_uint32 channelsIn, ma_uint32 sampleRateIn, ma_uint64 frameCount);
ma_uint64 ma_convert_frames_ex(void* pOut, ma_format formatOut, ma_uint32 channelsOut, ma_uint32 sampleRateOut, ma_channel channelMapOut[MA_MAX_CHANNELS], const void* pIn, ma_format formatIn, ma_uint32 channelsIn, ma_uint32 sampleRateIn, ma_channel channelMapIn[MA_MAX_CHANNELS], ma_uint64 frameCount);
@@ -1770,7 +1772,9 @@ pInput is a pointer to a buffer containing input data from the device. This will
null for a playback device.
frameCount is the number of PCM frames to process. If an output buffer is provided (pOutput is not null), applications should write out
-to the entire output buffer.
+to the entire output buffer. Note that frameCount will not necessarily be exactly what you asked for when you initialized the deviced.
+The bufferSizeInFrames and bufferSizeInMilliseconds members of the device config are just hints, and are not necessarily exactly what
+you'll get.
Do _not_ call any miniaudio APIs from the callback. Attempting the stop the device can result in a deadlock. The proper way to stop the
device is to call ma_device_stop() from a different thread, normally the main application thread.
@@ -2691,8 +2695,8 @@ Retrieves information about a device with the given ID.
Do _not_ call this from within the ma_context_enumerate_devices() callback.
-It's possible for a device to have different information and capabilities depending on wether or
-not it's opened in shared or exclusive mode. For example, in shared mode, WASAPI always uses
+It's possible for a device to have different information and capabilities depending on whether
+or not it's opened in shared or exclusive mode. For example, in shared mode, WASAPI always uses
floating point samples for mixing, but in exclusive mode it can be anything. Therefore, this
function allows you to specify which share mode you want information for. Note that not all
backends and devices support shared or exclusive mode, in which case this function will fail
@@ -2723,7 +2727,8 @@ initialization of other devices.
The device's configuration is controlled with pConfig. This allows you to configure the sample
format, channel count, sample rate, etc. Before calling ma_device_init(), you will need to
initialize a ma_device_config object using ma_device_config_init(). You must set the callback in
-the device config.
+the device config. Once initialized, the device's config is immutable. If you need to change the
+config you will need to initialize a new device.
Passing in 0 to any property in pConfig will force the use of a default value. In the case of
sample format, channel count, sample rate and channel map it will default to the values used by
@@ -2787,6 +2792,8 @@ Uninitializes a device.
This will explicitly stop the device. You do not need to call ma_device_stop() beforehand, but it's
harmless if you do.
+Do not call this in any callback.
+
Return Value:
MA_SUCCESS if successful; any other error code otherwise.
@@ -2815,6 +2822,8 @@ to be done _before_ the device begins playback.
This API waits until the backend device has been started for real by the worker thread. It also
waits on a mutex for thread-safety.
+Do not call this in any callback.
+
Return Value:
MA_SUCCESS if successful; any other error code otherwise.
@@ -2836,6 +2845,8 @@ the resuming it with ma_device_start() (which you might do when your program los
in a situation where those samples are never output to the speakers or received from the microphone
which can in turn result in de-syncs.
+Do not call this in any callback.
+
Return Value:
MA_SUCCESS if successful; any other error code otherwise.
@@ -2990,10 +3001,11 @@ typedef enum
ma_seek_origin_current
} ma_seek_origin;
-typedef size_t (* ma_decoder_read_proc) (ma_decoder* pDecoder, void* pBufferOut, size_t bytesToRead); /* Returns the number of bytes read. */
-typedef ma_bool32 (* ma_decoder_seek_proc) (ma_decoder* pDecoder, int byteOffset, ma_seek_origin origin);
-typedef ma_result (* ma_decoder_seek_to_pcm_frame_proc)(ma_decoder* pDecoder, ma_uint64 frameIndex);
-typedef ma_result (* ma_decoder_uninit_proc) (ma_decoder* pDecoder);
+typedef size_t (* ma_decoder_read_proc) (ma_decoder* pDecoder, void* pBufferOut, size_t bytesToRead); /* Returns the number of bytes read. */
+typedef ma_bool32 (* ma_decoder_seek_proc) (ma_decoder* pDecoder, int byteOffset, ma_seek_origin origin);
+typedef ma_result (* ma_decoder_seek_to_pcm_frame_proc) (ma_decoder* pDecoder, ma_uint64 frameIndex);
+typedef ma_result (* ma_decoder_uninit_proc) (ma_decoder* pDecoder);
+typedef ma_uint64 (* ma_decoder_get_length_in_pcm_frames_proc)(ma_decoder* pDecoder);
typedef struct
{
@@ -3027,6 +3039,7 @@ struct ma_decoder
ma_pcm_converter dsp; /* <-- Format conversion is achieved by running frames through this. */
ma_decoder_seek_to_pcm_frame_proc onSeekToPCMFrame;
ma_decoder_uninit_proc onUninit;
+ ma_decoder_get_length_in_pcm_frames_proc onGetLengthInPCMFrames;
void* pInternalDecoder; /* <-- The drwav/drflac/stb_vorbis/etc. objects. */
struct
{
@@ -3055,10 +3068,33 @@ ma_result ma_decoder_init_memory_raw(const void* pData, size_t dataSize, const m
#ifndef MA_NO_STDIO
ma_result ma_decoder_init_file(const char* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
ma_result ma_decoder_init_file_wav(const char* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
+ma_result ma_decoder_init_file_flac(const char* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
+ma_result ma_decoder_init_file_vorbis(const char* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
+ma_result ma_decoder_init_file_mp3(const char* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
+
+ma_result ma_decoder_init_file_w(const wchar_t* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
+ma_result ma_decoder_init_file_wav_w(const wchar_t* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
+ma_result ma_decoder_init_file_flac_w(const wchar_t* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
+ma_result ma_decoder_init_file_vorbis_w(const wchar_t* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
+ma_result ma_decoder_init_file_mp3_w(const wchar_t* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
#endif
ma_result ma_decoder_uninit(ma_decoder* pDecoder);
+/*
+Retrieves the length of the decoder in PCM frames.
+
+Do not call this on streams of an undefined length, such as internet radio.
+
+If the length is unknown or an error occurs, 0 will be returned.
+
+This will always return 0 for Vorbis decoders. This is due to a limitation with stb_vorbis in push mode which is what miniaudio
+uses internally.
+
+This will run in linear time for MP3 decoders. Do not call this in time critical scenarios.
+*/
+ma_uint64 ma_decoder_get_length_in_pcm_frames(ma_decoder* pDecoder);
+
ma_uint64 ma_decoder_read_pcm_frames(ma_decoder* pDecoder, void* pFramesOut, ma_uint64 frameCount);
ma_result ma_decoder_seek_to_pcm_frame(ma_decoder* pDecoder, ma_uint64 frameIndex);
@@ -3192,7 +3228,7 @@ typedef struct tagBITMAPINFOHEADER {
#endif
#else
-#include <stdlib.h> /* For malloc()/free() */
+#include <stdlib.h> /* For malloc(), free(), wcstombs(). */
#include <string.h> /* For memset() */
#endif
@@ -3345,7 +3381,7 @@ typedef struct tagBITMAPINFOHEADER {
#define MA_NO_CPUID
#endif
- #if _MSC_VER >= 1600
+ #if _MSC_VER >= 1600 && (defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 160040219)
static MA_INLINE unsigned __int64 ma_xgetbv(int reg)
{
return _xgetbv(reg);
@@ -3827,6 +3863,52 @@ int ma_strcat_s(char* dst, size_t dstSizeInBytes, const char* src)
return 0;
}
+int ma_strncat_s(char* dst, size_t dstSizeInBytes, const char* src, size_t count)
+{
+ char* dstorig;
+
+ if (dst == 0) {
+ return 22;
+ }
+ if (dstSizeInBytes == 0) {
+ return 34;
+ }
+ if (src == 0) {
+ return 22;
+ }
+
+ dstorig = dst;
+
+ while (dstSizeInBytes > 0 && dst[0] != '\0') {
+ dst += 1;
+ dstSizeInBytes -= 1;
+ }
+
+ if (dstSizeInBytes == 0) {
+ return 22; /* Unterminated. */
+ }
+
+
+ if (count == ((size_t)-1)) { /* _TRUNCATE */
+ count = dstSizeInBytes - 1;
+ }
+
+ while (dstSizeInBytes > 0 && src[0] != '\0' && count > 0) {
+ *dst++ = *src++;
+ dstSizeInBytes -= 1;
+ count -= 1;
+ }
+
+ if (dstSizeInBytes > 0) {
+ dst[0] = '\0';
+ } else {
+ dstorig[0] = '\0';
+ return 34;
+ }
+
+ return 0;
+}
+
int ma_itoa_s(int value, char* dst, size_t dstSizeInBytes, int radix)
{
int sign;
@@ -3919,6 +4001,23 @@ int ma_strcmp(const char* str1, const char* str2)
return ((unsigned char*)str1)[0] - ((unsigned char*)str2)[0];
}
+int ma_strappend(char* dst, size_t dstSize, const char* srcA, const char* srcB)
+{
+ int result;
+
+ result = ma_strncpy_s(dst, dstSize, srcA, (size_t)-1);
+ if (result != 0) {
+ return result;
+ }
+
+ result = ma_strncat_s(dst, dstSize, srcB, (size_t)-1);
+ if (result != 0) {
+ return result;
+ }
+
+ return result;
+}
+
char* ma_copy_string(const char* src)
{
size_t sz = strlen(src)+1;
@@ -4383,6 +4482,63 @@ typedef LONG (WINAPI * MA_PFN_RegQueryValueExA)(HKEY hKey, LPCSTR lpValueName, L
#define MA_DEFAULT_CAPTURE_DEVICE_NAME "Default Capture Device"
+const char* ma_log_level_to_string(ma_uint32 logLevel)
+{
+ switch (logLevel)
+ {
+ case MA_LOG_LEVEL_VERBOSE: return "";
+ case MA_LOG_LEVEL_INFO: return "INFO";
+ case MA_LOG_LEVEL_WARNING: return "WARNING";
+ case MA_LOG_LEVEL_ERROR: return "ERROR";
+ default: return "ERROR";
+ }
+}
+
+/* Posts a log message. */
+void ma_log(ma_context* pContext, ma_device* pDevice, ma_uint32 logLevel, const char* message)
+{
+ if (pContext == NULL) {
+ return;
+ }
+
+#if defined(MA_LOG_LEVEL)
+ if (logLevel <= MA_LOG_LEVEL) {
+ ma_log_proc onLog;
+
+ #if defined(MA_DEBUG_OUTPUT)
+ if (logLevel <= MA_LOG_LEVEL) {
+ printf("%s: %s\n", ma_log_level_to_string(logLevel), message);
+ }
+ #endif
+
+ onLog = pContext->logCallback;
+ if (onLog) {
+ onLog(pContext, pDevice, logLevel, message);
+ }
+ }
+#endif
+}
+
+/* Posts an log message. Throw a breakpoint in here if you're needing to debug. The return value is always "resultCode". */
+ma_result ma_context_post_error(ma_context* pContext, ma_device* pDevice, ma_uint32 logLevel, const char* message, ma_result resultCode)
+{
+ /* Derive the context from the device if necessary. */
+ if (pContext == NULL) {
+ if (pDevice != NULL) {
+ pContext = pDevice->pContext;
+ }
+ }
+
+ ma_log(pContext, pDevice, logLevel, message);
+ return resultCode;
+}
+
+ma_result ma_post_error(ma_device* pDevice, ma_uint32 logLevel, const char* message, ma_result resultCode)
+{
+ return ma_context_post_error(NULL, pDevice, logLevel, message, resultCode);
+}
+
+
/*******************************************************************************
Timing
@@ -4499,48 +4655,96 @@ double ma_timer_get_time_in_seconds(ma_timer* pTimer)
Dynamic Linking
*******************************************************************************/
-ma_handle ma_dlopen(const char* filename)
+ma_handle ma_dlopen(ma_context* pContext, const char* filename)
{
+ ma_handle handle;
+
+#if MA_LOG_LEVEL >= MA_LOG_LEVEL_VERBOSE
+ if (pContext != NULL) {
+ char message[256];
+ ma_strappend(message, sizeof(message), "Loading library: ", filename);
+ ma_log(pContext, NULL, MA_LOG_LEVEL_VERBOSE, message);
+ }
+#endif
+
#ifdef _WIN32
#ifdef MA_WIN32_DESKTOP
- return (ma_handle)LoadLibraryA(filename);
+ handle = (ma_handle)LoadLibraryA(filename);
#else
/* *sigh* It appears there is no ANSI version of LoadPackagedLibrary()... */
WCHAR filenameW[4096];
if (MultiByteToWideChar(CP_UTF8, 0, filename, -1, filenameW, sizeof(filenameW)) == 0) {
- return NULL;
+ handle = NULL;
+ } else {
+ handle = (ma_handle)LoadPackagedLibrary(filenameW, 0);
}
-
- return (ma_handle)LoadPackagedLibrary(filenameW, 0);
#endif
#else
- return (ma_handle)dlopen(filename, RTLD_NOW);
+ handle = (ma_handle)dlopen(filename, RTLD_NOW);
+#endif
+
+ /*
+ I'm not considering failure to load a library an error nor a warning because seamlessly falling through to a lower-priority
+ backend is a deliberate design choice. Instead I'm logging it as an informational message.
+ */
+#if MA_LOG_LEVEL >= MA_LOG_LEVEL_INFO
+ if (handle == NULL) {
+ char message[256];
+ ma_strappend(message, sizeof(message), "Failed to load library: ", filename);
+ ma_log(pContext, NULL, MA_LOG_LEVEL_INFO, message);
+ }
#endif
+
+ (void)pContext; /* It's possible for pContext to be unused. */
+ return handle;
}
-void ma_dlclose(ma_handle handle)
+void ma_dlclose(ma_context* pContext, ma_handle handle)
{
#ifdef _WIN32
FreeLibrary((HMODULE)handle);
#else
dlclose((void*)handle);
#endif
+
+ (void)pContext;
}
-ma_proc ma_dlsym(ma_handle handle, const char* symbol)
+ma_proc ma_dlsym(ma_context* pContext, ma_handle handle, const char* symbol)
{
+ ma_proc proc;
+
+#if MA_LOG_LEVEL >= MA_LOG_LEVEL_VERBOSE
+ if (pContext != NULL) {
+ char message[256];
+ ma_strappend(message, sizeof(message), "Loading symbol: ", symbol);
+ ma_log(pContext, NULL, MA_LOG_LEVEL_VERBOSE, message);
+ }
+#endif
+
#ifdef _WIN32
- return (ma_proc)GetProcAddress((HMODULE)handle, symbol);
+ proc = (ma_proc)GetProcAddress((HMODULE)handle, symbol);
#else
#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"
#endif
- return (ma_proc)dlsym((void*)handle, symbol);
+ proc = (ma_proc)dlsym((void*)handle, symbol);
#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
#pragma GCC diagnostic pop
#endif
#endif
+
+#if MA_LOG_LEVEL >= MA_LOG_LEVEL_WARNING
+ if (handle == NULL) {
+ char message[256];
+ ma_strappend(message, sizeof(message), "Failed to load symbol: ", symbol);
+ ma_log(pContext, NULL, MA_LOG_LEVEL_WARNING, message);
+ }
+#endif
+
+ (void)pContext; /* It's possible for pContext to be unused. */
+ return proc;
}
@@ -4560,7 +4764,7 @@ int ma_thread_priority_to_win32(ma_thread_priority priority)
case ma_thread_priority_high: return THREAD_PRIORITY_ABOVE_NORMAL;
case ma_thread_priority_highest: return THREAD_PRIORITY_HIGHEST;
case ma_thread_priority_realtime: return THREAD_PRIORITY_TIME_CRITICAL;
- default: return ma_thread_priority_normal;
+ default: return THREAD_PRIORITY_NORMAL;
}
}
@@ -5102,63 +5306,6 @@ void ma_zero_pcm_frames(void* p, ma_uint32 frameCount, ma_format format, ma_uint
}
-const char* ma_log_level_to_string(ma_uint32 logLevel)
-{
- switch (logLevel)
- {
- case MA_LOG_LEVEL_VERBOSE: return "";
- case MA_LOG_LEVEL_INFO: return "INFO";
- case MA_LOG_LEVEL_WARNING: return "WARNING";
- case MA_LOG_LEVEL_ERROR: return "ERROR";
- default: return "ERROR";
- }
-}
-
-/* Posts a log message. */
-void ma_log(ma_context* pContext, ma_device* pDevice, ma_uint32 logLevel, const char* message)
-{
- if (pContext == NULL) {
- return;
- }
-
-#if defined(MA_LOG_LEVEL)
- if (logLevel <= MA_LOG_LEVEL) {
- ma_log_proc onLog;
-
- #if defined(MA_DEBUG_OUTPUT)
- if (logLevel <= MA_LOG_LEVEL) {
- printf("%s: %s\n", ma_log_level_to_string(logLevel), message);
- }
- #endif
-
- onLog = pContext->logCallback;
- if (onLog) {
- onLog(pContext, pDevice, logLevel, message);
- }
- }
-#endif
-}
-
-/* Posts an error. Throw a breakpoint in here if you're needing to debug. The return value is always "resultCode". */
-ma_result ma_context_post_error(ma_context* pContext, ma_device* pDevice, ma_uint32 logLevel, const char* message, ma_result resultCode)
-{
- /* Derive the context from the device if necessary. */
- if (pContext == NULL) {
- if (pDevice != NULL) {
- pContext = pDevice->pContext;
- }
- }
-
- ma_log(pContext, pDevice, logLevel, message);
- return resultCode;
-}
-
-ma_result ma_post_error(ma_device* pDevice, ma_uint32 logLevel, const char* message, ma_result resultCode)
-{
- return ma_context_post_error(NULL, pDevice, logLevel, message, resultCode);
-}
-
-
/* The callback for reading from the client -> DSP -> device. */
ma_uint32 ma_device__on_read_from_client(ma_pcm_converter* pDSP, void* pFramesOut, ma_uint32 frameCount, void* pUserData)
@@ -5421,13 +5568,10 @@ static MA_INLINE void ma_device__set_state(ma_device* pDevice, ma_uint32 newStat
/* A helper for getting the state of the device. */
static MA_INLINE ma_uint32 ma_device__get_state(ma_device* pDevice)
{
- return pDevice->state;
-}
+ ma_uint32 state;
+ ma_atomic_exchange_32(&state, pDevice->state);
-/* A helper for determining whether or not the device is running in async mode. */
-static MA_INLINE ma_bool32 ma_device__is_async(ma_device* pDevice)
-{
- return pDevice->onData != NULL;
+ return state;
}
@@ -7116,6 +7260,8 @@ ma_result ma_context_get_device_info_from_IAudioClient__wasapi(ma_context* pCont
ma_IPropertyStore_Release(pProperties);
return ma_context_post_error(pContext, NULL, MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to retrieve device format for device info retrieval.", MA_FAILED_TO_OPEN_BACKEND_DEVICE);
}
+
+ ma_IPropertyStore_Release(pProperties);
} else {
return ma_context_post_error(pContext, NULL, MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to open property store for device info retrieval.", MA_FAILED_TO_OPEN_BACKEND_DEVICE);
}
@@ -7578,6 +7724,8 @@ ma_result ma_device_init_internal__wasapi(ma_context* pContext, ma_device_type d
clientProperties.eCategory = MA_AudioCategory_Other;
ma_IAudioClient2_SetClientProperties(pAudioClient2, &clientProperties);
}
+
+ pAudioClient2->lpVtbl->Release(pAudioClient2);
}
@@ -7688,7 +7836,7 @@ ma_result ma_device_init_internal__wasapi(ma_context* pContext, ma_device_type d
}
if (hr == MA_AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED) {
- UINT bufferSizeInFrames;
+ ma_uint32 bufferSizeInFrames;
hr = ma_IAudioClient_GetBufferSize((ma_IAudioClient*)pData->pAudioClient, &bufferSizeInFrames);
if (SUCCEEDED(hr)) {
bufferDuration = (MA_REFERENCE_TIME)((10000.0 * 1000 / wf.Format.nSamplesPerSec * bufferSizeInFrames) + 0.5);
@@ -8744,7 +8892,6 @@ ma_result ma_context_init__wasapi(const ma_context_config* pConfig, ma_context*
ma_assert(pContext != NULL);
- (void)pContext;
(void)pConfig;
#ifdef MA_WIN32_DESKTOP
@@ -8760,15 +8907,15 @@ ma_result ma_context_init__wasapi(const ma_context_config* pConfig, ma_context*
ma_PFNVerifyVersionInfoW _VerifyVersionInfoW;
ma_PFNVerSetConditionMask _VerSetConditionMask;
- kernel32DLL = ma_dlopen("kernel32.dll");
+ kernel32DLL = ma_dlopen(pContext, "kernel32.dll");
if (kernel32DLL == NULL) {
return MA_NO_BACKEND;
}
- _VerifyVersionInfoW = (ma_PFNVerifyVersionInfoW)ma_dlsym(kernel32DLL, "VerifyVersionInfoW");
- _VerSetConditionMask = (ma_PFNVerSetConditionMask)ma_dlsym(kernel32DLL, "VerSetConditionMask");
+ _VerifyVersionInfoW = (ma_PFNVerifyVersionInfoW)ma_dlsym(pContext, kernel32DLL, "VerifyVersionInfoW");
+ _VerSetConditionMask = (ma_PFNVerSetConditionMask)ma_dlsym(pContext, kernel32DLL, "VerSetConditionMask");
if (_VerifyVersionInfoW == NULL || _VerSetConditionMask == NULL) {
- ma_dlclose(kernel32DLL);
+ ma_dlclose(pContext, kernel32DLL);
return MA_NO_BACKEND;
}
@@ -8783,7 +8930,7 @@ ma_result ma_context_init__wasapi(const ma_context_config* pConfig, ma_context*
result = MA_NO_BACKEND;
}
- ma_dlclose(kernel32DLL);
+ ma_dlclose(pContext, kernel32DLL);
}
#endif
@@ -10436,7 +10583,7 @@ ma_result ma_context_uninit__dsound(ma_context* pContext)
ma_assert(pContext != NULL);
ma_assert(pContext->backend == ma_backend_dsound);
- ma_dlclose(pContext->dsound.hDSoundDLL);
+ ma_dlclose(pContext, pContext->dsound.hDSoundDLL);
return MA_SUCCESS;
}
@@ -10447,15 +10594,15 @@ ma_result ma_context_init__dsound(const ma_context_config* pConfig, ma_context*
(void)pConfig;
- pContext->dsound.hDSoundDLL = ma_dlopen("dsound.dll");
+ pContext->dsound.hDSoundDLL = ma_dlopen(pContext, "dsound.dll");
if (pContext->dsound.hDSoundDLL == NULL) {
return MA_API_NOT_FOUND;
}
- pContext->dsound.DirectSoundCreate = ma_dlsym(pContext->dsound.hDSoundDLL, "DirectSoundCreate");
- pContext->dsound.DirectSoundEnumerateA = ma_dlsym(pContext->dsound.hDSoundDLL, "DirectSoundEnumerateA");
- pContext->dsound.DirectSoundCaptureCreate = ma_dlsym(pContext->dsound.hDSoundDLL, "DirectSoundCaptureCreate");
- pContext->dsound.DirectSoundCaptureEnumerateA = ma_dlsym(pContext->dsound.hDSoundDLL, "DirectSoundCaptureEnumerateA");
+ pContext->dsound.DirectSoundCreate = ma_dlsym(pContext, pContext->dsound.hDSoundDLL, "DirectSoundCreate");
+ pContext->dsound.DirectSoundEnumerateA = ma_dlsym(pContext, pContext->dsound.hDSoundDLL, "DirectSoundEnumerateA");
+ pContext->dsound.DirectSoundCaptureCreate = ma_dlsym(pContext, pContext->dsound.hDSoundDLL, "DirectSoundCaptureCreate");
+ pContext->dsound.DirectSoundCaptureEnumerateA = ma_dlsym(pContext, pContext->dsound.hDSoundDLL, "DirectSoundCaptureEnumerateA");
pContext->onUninit = ma_context_uninit__dsound;
pContext->onDeviceIDEqual = ma_context_is_device_id_equal__dsound;
@@ -11454,7 +11601,7 @@ ma_result ma_context_uninit__winmm(ma_context* pContext)
ma_assert(pContext != NULL);
ma_assert(pContext->backend == ma_backend_winmm);
- ma_dlclose(pContext->winmm.hWinMM);
+ ma_dlclose(pContext, pContext->winmm.hWinMM);
return MA_SUCCESS;
}
@@ -11464,28 +11611,28 @@ ma_result ma_context_init__winmm(const ma_context_config* pConfig, ma_context* p
(void)pConfig;
- pContext->winmm.hWinMM = ma_dlopen("winmm.dll");
+ pContext->winmm.hWinMM = ma_dlopen(pContext, "winmm.dll");
if (pContext->winmm.hWinMM == NULL) {
return MA_NO_BACKEND;
}
- pContext->winmm.waveOutGetNumDevs = ma_dlsym(pContext->winmm.hWinMM, "waveOutGetNumDevs");
- pContext->winmm.waveOutGetDevCapsA = ma_dlsym(pContext->winmm.hWinMM, "waveOutGetDevCapsA");
- pContext->winmm.waveOutOpen = ma_dlsym(pContext->winmm.hWinMM, "waveOutOpen");
- pContext->winmm.waveOutClose = ma_dlsym(pContext->winmm.hWinMM, "waveOutClose");
- pContext->winmm.waveOutPrepareHeader = ma_dlsym(pContext->winmm.hWinMM, "waveOutPrepareHeader");
- pContext->winmm.waveOutUnprepareHeader = ma_dlsym(pContext->winmm.hWinMM, "waveOutUnprepareHeader");
- pContext->winmm.waveOutWrite = ma_dlsym(pContext->winmm.hWinMM, "waveOutWrite");
- pContext->winmm.waveOutReset = ma_dlsym(pContext->winmm.hWinMM, "waveOutReset");
- pContext->winmm.waveInGetNumDevs = ma_dlsym(pContext->winmm.hWinMM, "waveInGetNumDevs");
- pContext->winmm.waveInGetDevCapsA = ma_dlsym(pContext->winmm.hWinMM, "waveInGetDevCapsA");
- pContext->winmm.waveInOpen = ma_dlsym(pContext->winmm.hWinMM, "waveInOpen");
- pContext->winmm.waveInClose = ma_dlsym(pContext->winmm.hWinMM, "waveInClose");
- pContext->winmm.waveInPrepareHeader = ma_dlsym(pContext->winmm.hWinMM, "waveInPrepareHeader");
- pContext->winmm.waveInUnprepareHeader = ma_dlsym(pContext->winmm.hWinMM, "waveInUnprepareHeader");
- pContext->winmm.waveInAddBuffer = ma_dlsym(pContext->winmm.hWinMM, "waveInAddBuffer");
- pContext->winmm.waveInStart = ma_dlsym(pContext->winmm.hWinMM, "waveInStart");
- pContext->winmm.waveInReset = ma_dlsym(pContext->winmm.hWinMM, "waveInReset");
+ pContext->winmm.waveOutGetNumDevs = ma_dlsym(pContext, pContext->winmm.hWinMM, "waveOutGetNumDevs");
+ pContext->winmm.waveOutGetDevCapsA = ma_dlsym(pContext, pContext->winmm.hWinMM, "waveOutGetDevCapsA");
+ pContext->winmm.waveOutOpen = ma_dlsym(pContext, pContext->winmm.hWinMM, "waveOutOpen");
+ pContext->winmm.waveOutClose = ma_dlsym(pContext, pContext->winmm.hWinMM, "waveOutClose");
+ pContext->winmm.waveOutPrepareHeader = ma_dlsym(pContext, pContext->winmm.hWinMM, "waveOutPrepareHeader");
+ pContext->winmm.waveOutUnprepareHeader = ma_dlsym(pContext, pContext->winmm.hWinMM, "waveOutUnprepareHeader");
+ pContext->winmm.waveOutWrite = ma_dlsym(pContext, pContext->winmm.hWinMM, "waveOutWrite");
+ pContext->winmm.waveOutReset = ma_dlsym(pContext, pContext->winmm.hWinMM, "waveOutReset");
+ pContext->winmm.waveInGetNumDevs = ma_dlsym(pContext, pContext->winmm.hWinMM, "waveInGetNumDevs");
+ pContext->winmm.waveInGetDevCapsA = ma_dlsym(pContext, pContext->winmm.hWinMM, "waveInGetDevCapsA");
+ pContext->winmm.waveInOpen = ma_dlsym(pContext, pContext->winmm.hWinMM, "waveInOpen");
+ pContext->winmm.waveInClose = ma_dlsym(pContext, pContext->winmm.hWinMM, "waveInClose");
+ pContext->winmm.waveInPrepareHeader = ma_dlsym(pContext, pContext->winmm.hWinMM, "waveInPrepareHeader");
+ pContext->winmm.waveInUnprepareHeader = ma_dlsym(pContext, pContext->winmm.hWinMM, "waveInUnprepareHeader");
+ pContext->winmm.waveInAddBuffer = ma_dlsym(pContext, pContext->winmm.hWinMM, "waveInAddBuffer");
+ pContext->winmm.waveInStart = ma_dlsym(pContext, pContext->winmm.hWinMM, "waveInStart");
+ pContext->winmm.waveInReset = ma_dlsym(pContext, pContext->winmm.hWinMM, "waveInReset");
pContext->onUninit = ma_context_uninit__winmm;
pContext->onDeviceIDEqual = ma_context_is_device_id_equal__winmm;
@@ -13261,14 +13408,29 @@ ma_result ma_device_stop__alsa(ma_device* pDevice)
if (pDevice->type == ma_device_type_capture || pDevice->type == ma_device_type_duplex) {
((ma_snd_pcm_drain_proc)pDevice->pContext->alsa.snd_pcm_drain)((ma_snd_pcm_t*)pDevice->alsa.pPCMCapture);
+
+ /* We need to prepare the device again, otherwise we won't be able to restart the device. */
+ if (((ma_snd_pcm_prepare_proc)pDevice->pContext->alsa.snd_pcm_prepare)((ma_snd_pcm_t*)pDevice->alsa.pPCMCapture) < 0) {
+ #ifdef MA_DEBUG_OUTPUT
+ printf("[ALSA] Failed to prepare capture device after stopping.\n");
+ #endif
+ }
}
if (pDevice->type == ma_device_type_playback || pDevice->type == ma_device_type_duplex) {
/* Using drain instead of drop because ma_device_stop() is defined such that pending frames are processed before returning. */
((ma_snd_pcm_drain_proc)pDevice->pContext->alsa.snd_pcm_drain)((ma_snd_pcm_t*)pDevice->alsa.pPCMPlayback);
+
+ /* We need to prepare the device again, otherwise we won't be able to restart the device. */
+ if (((ma_snd_pcm_prepare_proc)pDevice->pContext->alsa.snd_pcm_prepare)((ma_snd_pcm_t*)pDevice->alsa.pPCMPlayback) < 0) {
+ #ifdef MA_DEBUG_OUTPUT
+ printf("[ALSA] Failed to prepare playback device after stopping.\n");
+ #endif
+ }
}
+
return MA_SUCCESS;
}
@@ -13415,7 +13577,7 @@ ma_result ma_context_uninit__alsa(ma_context* pContext)
((ma_snd_config_update_free_global_proc)pContext->alsa.snd_config_update_free_global)();
#ifndef MA_NO_RUNTIME_LINKING
- ma_dlclose(pContext->alsa.asoundSO);
+ ma_dlclose(pContext, pContext->alsa.asoundSO);
#endif
ma_mutex_uninit(&pContext->alsa.internalDeviceEnumLock);
@@ -13433,7 +13595,7 @@ ma_result ma_context_init__alsa(const ma_context_config* pConfig, ma_context* pC
size_t i;
for (i = 0; i < ma_countof(libasoundNames); ++i) {
- pContext->alsa.asoundSO = ma_dlopen(libasoundNames[i]);
+ pContext->alsa.asoundSO = ma_dlopen(pContext, libasoundNames[i]);
if (pContext->alsa.asoundSO != NULL) {
break;
}
@@ -13446,61 +13608,61 @@ ma_result ma_context_init__alsa(const ma_context_config* pConfig, ma_context* pC
return MA_NO_BACKEND;
}
- pContext->alsa.snd_pcm_open = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_open");
- pContext->alsa.snd_pcm_close = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_close");
- pContext->alsa.snd_pcm_hw_params_sizeof = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_hw_params_sizeof");
- pContext->alsa.snd_pcm_hw_params_any = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_hw_params_any");
- pContext->alsa.snd_pcm_hw_params_set_format = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_hw_params_set_format");
- pContext->alsa.snd_pcm_hw_params_set_format_first = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_hw_params_set_format_first");
- pContext->alsa.snd_pcm_hw_params_get_format_mask = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_hw_params_get_format_mask");
- pContext->alsa.snd_pcm_hw_params_set_channels_near = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_hw_params_set_channels_near");
- pContext->alsa.snd_pcm_hw_params_set_rate_resample = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_hw_params_set_rate_resample");
- pContext->alsa.snd_pcm_hw_params_set_rate_near = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_hw_params_set_rate_near");
- pContext->alsa.snd_pcm_hw_params_set_buffer_size_near = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_hw_params_set_buffer_size_near");
- pContext->alsa.snd_pcm_hw_params_set_periods_near = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_hw_params_set_periods_near");
- pContext->alsa.snd_pcm_hw_params_set_access = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_hw_params_set_access");
- pContext->alsa.snd_pcm_hw_params_get_format = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_hw_params_get_format");
- pContext->alsa.snd_pcm_hw_params_get_channels = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_hw_params_get_channels");
- pContext->alsa.snd_pcm_hw_params_get_channels_min = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_hw_params_get_channels_min");
- pContext->alsa.snd_pcm_hw_params_get_channels_max = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_hw_params_get_channels_max");
- pContext->alsa.snd_pcm_hw_params_get_rate = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_hw_params_get_rate");
- pContext->alsa.snd_pcm_hw_params_get_rate_min = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_hw_params_get_rate_min");
- pContext->alsa.snd_pcm_hw_params_get_rate_max = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_hw_params_get_rate_max");
- pContext->alsa.snd_pcm_hw_params_get_buffer_size = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_hw_params_get_buffer_size");
- pContext->alsa.snd_pcm_hw_params_get_periods = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_hw_params_get_periods");
- pContext->alsa.snd_pcm_hw_params_get_access = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_hw_params_get_access");
- pContext->alsa.snd_pcm_hw_params = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_hw_params");
- pContext->alsa.snd_pcm_sw_params_sizeof = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_sw_params_sizeof");
- pContext->alsa.snd_pcm_sw_params_current = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_sw_params_current");
- pContext->alsa.snd_pcm_sw_params_get_boundary = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_sw_params_get_boundary");
- pContext->alsa.snd_pcm_sw_params_set_avail_min = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_sw_params_set_avail_min");
- pContext->alsa.snd_pcm_sw_params_set_start_threshold = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_sw_params_set_start_threshold");
- pContext->alsa.snd_pcm_sw_params_set_stop_threshold = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_sw_params_set_stop_threshold");
- pContext->alsa.snd_pcm_sw_params = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_sw_params");
- pContext->alsa.snd_pcm_format_mask_sizeof = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_format_mask_sizeof");
- pContext->alsa.snd_pcm_format_mask_test = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_format_mask_test");
- pContext->alsa.snd_pcm_get_chmap = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_get_chmap");
- pContext->alsa.snd_pcm_state = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_state");
- pContext->alsa.snd_pcm_prepare = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_prepare");
- pContext->alsa.snd_pcm_start = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_start");
- pContext->alsa.snd_pcm_drop = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_drop");
- pContext->alsa.snd_pcm_drain = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_drain");
- pContext->alsa.snd_device_name_hint = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_device_name_hint");
- pContext->alsa.snd_device_name_get_hint = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_device_name_get_hint");
- pContext->alsa.snd_card_get_index = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_card_get_index");
- pContext->alsa.snd_device_name_free_hint = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_device_name_free_hint");
- pContext->alsa.snd_pcm_mmap_begin = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_mmap_begin");
- pContext->alsa.snd_pcm_mmap_commit = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_mmap_commit");
- pContext->alsa.snd_pcm_recover = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_recover");
- pContext->alsa.snd_pcm_readi = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_readi");
- pContext->alsa.snd_pcm_writei = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_writei");
- pContext->alsa.snd_pcm_avail = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_avail");
- pContext->alsa.snd_pcm_avail_update = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_avail_update");
- pContext->alsa.snd_pcm_wait = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_wait");
- pContext->alsa.snd_pcm_info = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_info");
- pContext->alsa.snd_pcm_info_sizeof = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_info_sizeof");
- pContext->alsa.snd_pcm_info_get_name = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_pcm_info_get_name");
- pContext->alsa.snd_config_update_free_global = (ma_proc)ma_dlsym(pContext->alsa.asoundSO, "snd_config_update_free_global");
+ pContext->alsa.snd_pcm_open = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_open");
+ pContext->alsa.snd_pcm_close = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_close");
+ pContext->alsa.snd_pcm_hw_params_sizeof = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_sizeof");
+ pContext->alsa.snd_pcm_hw_params_any = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_any");
+ pContext->alsa.snd_pcm_hw_params_set_format = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_set_format");
+ pContext->alsa.snd_pcm_hw_params_set_format_first = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_set_format_first");
+ pContext->alsa.snd_pcm_hw_params_get_format_mask = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_get_format_mask");
+ pContext->alsa.snd_pcm_hw_params_set_channels_near = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_set_channels_near");
+ pContext->alsa.snd_pcm_hw_params_set_rate_resample = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_set_rate_resample");
+ pContext->alsa.snd_pcm_hw_params_set_rate_near = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_set_rate_near");
+ pContext->alsa.snd_pcm_hw_params_set_buffer_size_near = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_set_buffer_size_near");
+ pContext->alsa.snd_pcm_hw_params_set_periods_near = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_set_periods_near");
+ pContext->alsa.snd_pcm_hw_params_set_access = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_set_access");
+ pContext->alsa.snd_pcm_hw_params_get_format = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_get_format");
+ pContext->alsa.snd_pcm_hw_params_get_channels = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_get_channels");
+ pContext->alsa.snd_pcm_hw_params_get_channels_min = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_get_channels_min");
+ pContext->alsa.snd_pcm_hw_params_get_channels_max = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_get_channels_max");
+ pContext->alsa.snd_pcm_hw_params_get_rate = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_get_rate");
+ pContext->alsa.snd_pcm_hw_params_get_rate_min = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_get_rate_min");
+ pContext->alsa.snd_pcm_hw_params_get_rate_max = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_get_rate_max");
+ pContext->alsa.snd_pcm_hw_params_get_buffer_size = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_get_buffer_size");
+ pContext->alsa.snd_pcm_hw_params_get_periods = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_get_periods");
+ pContext->alsa.snd_pcm_hw_params_get_access = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params_get_access");
+ pContext->alsa.snd_pcm_hw_params = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_hw_params");
+ pContext->alsa.snd_pcm_sw_params_sizeof = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_sw_params_sizeof");
+ pContext->alsa.snd_pcm_sw_params_current = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_sw_params_current");
+ pContext->alsa.snd_pcm_sw_params_get_boundary = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_sw_params_get_boundary");
+ pContext->alsa.snd_pcm_sw_params_set_avail_min = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_sw_params_set_avail_min");
+ pContext->alsa.snd_pcm_sw_params_set_start_threshold = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_sw_params_set_start_threshold");
+ pContext->alsa.snd_pcm_sw_params_set_stop_threshold = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_sw_params_set_stop_threshold");
+ pContext->alsa.snd_pcm_sw_params = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_sw_params");
+ pContext->alsa.snd_pcm_format_mask_sizeof = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_format_mask_sizeof");
+ pContext->alsa.snd_pcm_format_mask_test = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_format_mask_test");
+ pContext->alsa.snd_pcm_get_chmap = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_get_chmap");
+ pContext->alsa.snd_pcm_state = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_state");
+ pContext->alsa.snd_pcm_prepare = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_prepare");
+ pContext->alsa.snd_pcm_start = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_start");
+ pContext->alsa.snd_pcm_drop = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_drop");
+ pContext->alsa.snd_pcm_drain = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_drain");
+ pContext->alsa.snd_device_name_hint = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_device_name_hint");
+ pContext->alsa.snd_device_name_get_hint = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_device_name_get_hint");
+ pContext->alsa.snd_card_get_index = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_card_get_index");
+ pContext->alsa.snd_device_name_free_hint = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_device_name_free_hint");
+ pContext->alsa.snd_pcm_mmap_begin = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_mmap_begin");
+ pContext->alsa.snd_pcm_mmap_commit = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_mmap_commit");
+ pContext->alsa.snd_pcm_recover = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_recover");
+ pContext->alsa.snd_pcm_readi = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_readi");
+ pContext->alsa.snd_pcm_writei = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_writei");
+ pContext->alsa.snd_pcm_avail = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_avail");
+ pContext->alsa.snd_pcm_avail_update = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_avail_update");
+ pContext->alsa.snd_pcm_wait = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_wait");
+ pContext->alsa.snd_pcm_info = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_info");
+ pContext->alsa.snd_pcm_info_sizeof = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_info_sizeof");
+ pContext->alsa.snd_pcm_info_get_name = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_pcm_info_get_name");
+ pContext->alsa.snd_config_update_free_global = (ma_proc)ma_dlsym(pContext, pContext->alsa.asoundSO, "snd_config_update_free_global");
#else
/* The system below is just for type safety. */
ma_snd_pcm_open_proc _snd_pcm_open = snd_pcm_open;
@@ -14830,7 +14992,7 @@ ma_pa_buffer_attr ma_device__pa_buffer_attr_new(ma_uint32 bufferSizeInFrames, ma
attr.maxlength = bufferSizeInFrames * ma_get_bytes_per_sample(ma_format_from_pulse(ss->format)) * ss->channels;
attr.tlength = attr.maxlength / periods;
attr.prebuf = (ma_uint32)-1;
- attr.minreq = attr.maxlength / periods;
+ attr.minreq = (ma_uint32)-1;
attr.fragsize = attr.maxlength / periods;
return attr;
@@ -15481,7 +15643,7 @@ ma_result ma_context_uninit__pulse(ma_context* pContext)
pContext->pulse.pApplicationName = NULL;
#ifndef MA_NO_RUNTIME_LINKING
- ma_dlclose(pContext->pulse.pulseSO);
+ ma_dlclose(pContext, pContext->pulse.pulseSO);
#endif
return MA_SUCCESS;
@@ -15497,7 +15659,7 @@ ma_result ma_context_init__pulse(const ma_context_config* pConfig, ma_context* p
size_t i;
for (i = 0; i < ma_countof(libpulseNames); ++i) {
- pContext->pulse.pulseSO = ma_dlopen(libpulseNames[i]);
+ pContext->pulse.pulseSO = ma_dlopen(pContext, libpulseNames[i]);
if (pContext->pulse.pulseSO != NULL) {
break;
}
@@ -15507,50 +15669,50 @@ ma_result ma_context_init__pulse(const ma_context_config* pConfig, ma_context* p
return MA_NO_BACKEND;
}
- pContext->pulse.pa_mainloop_new = (ma_proc)ma_dlsym(pContext->pulse.pulseSO, "pa_mainloop_new");
- pContext->pulse.pa_mainloop_free = (ma_proc)ma_dlsym(pContext->pulse.pulseSO, "pa_mainloop_free");
- pContext->pulse.pa_mainloop_get_api = (ma_proc)ma_dlsym(pContext->pulse.pulseSO, "pa_mainloop_get_api");
- pContext->pulse.pa_mainloop_iterate = (ma_proc)ma_dlsym(pContext->pulse.pulseSO, "pa_mainloop_iterate");
- pContext->pulse.pa_mainloop_wakeup = (ma_proc)ma_dlsym(pContext->pulse.pulseSO, "pa_mainloop_wakeup");
- pContext->pulse.pa_context_new = (ma_proc)ma_dlsym(pContext->pulse.pulseSO, "pa_context_new");
- pContext->pulse.pa_context_unref = (ma_proc)ma_dlsym(pContext->pulse.pulseSO, "pa_context_unref");
- pContext->pulse.pa_context_connect = (ma_proc)ma_dlsym(pContext->pulse.pulseSO, "pa_context_connect");
- pContext->pulse.pa_context_disconnect = (ma_proc)ma_dlsym(pContext->pulse.pulseSO, "pa_context_disconnect");
- pContext->pulse.pa_context_set_state_callback = (ma_proc)ma_dlsym(pContext->pulse.pulseSO, "pa_context_set_state_callback");
- pContext->pulse.pa_context_get_state = (ma_proc)ma_dlsym(pContext->pulse.pulseSO, "pa_context_get_state");
- pContext->pulse.pa_context_get_sink_info_list = (ma_proc)ma_dlsym(pContext->pulse.pulseSO, "pa_context_get_sink_info_list");
- pContext->pulse.pa_context_get_source_info_list = (ma_proc)ma_dlsym(pContext->pulse.pulseSO, "pa_context_get_source_info_list");
- pContext->pulse.pa_context_get_sink_info_by_name = (ma_proc)ma_dlsym(pContext->pulse.pulseSO, "pa_context_get_sink_info_by_name");
- pContext->pulse.pa_context_get_source_info_by_name = (ma_proc)ma_dlsym(pContext->pulse.pulseSO, "pa_context_get_source_info_by_name");
- pContext->pulse.pa_operation_unref = (ma_proc)ma_dlsym(pContext->pulse.pulseSO, "pa_operation_unref");
- pContext->pulse.pa_operation_get_state = (ma_proc)ma_dlsym(pContext->pulse.pulseSO, "pa_operation_get_state");
- pContext->pulse.pa_channel_map_init_extend = (ma_proc)ma_dlsym(pContext->pulse.pulseSO, "pa_channel_map_init_extend");
- pContext->pulse.pa_channel_map_valid = (ma_proc)ma_dlsym(pContext->pulse.pulseSO, "pa_channel_map_valid");
- pContext->pulse.pa_channel_map_compatible = (ma_proc)ma_dlsym(pContext->pulse.pulseSO, "pa_channel_map_compatible");
- pContext->pulse.pa_stream_new = (ma_proc)ma_dlsym(pContext->pulse.pulseSO, "pa_stream_new");
- pContext->pulse.pa_stream_unref = (ma_proc)ma_dlsym(pContext->pulse.pulseSO, "pa_stream_unref");
- pContext->pulse.pa_stream_connect_playback = (ma_proc)ma_dlsym(pContext->pulse.pulseSO, "pa_stream_connect_playback");
- pContext->pulse.pa_stream_connect_record = (ma_proc)ma_dlsym(pContext->pulse.pulseSO, "pa_stream_connect_record");
- pContext->pulse.pa_stream_disconnect = (ma_proc)ma_dlsym(pContext->pulse.pulseSO, "pa_stream_disconnect");
- pContext->pulse.pa_stream_get_state = (ma_proc)ma_dlsym(pContext->pulse.pulseSO, "pa_stream_get_state");
- pContext->pulse.pa_stream_get_sample_spec = (ma_proc)ma_dlsym(pContext->pulse.pulseSO, "pa_stream_get_sample_spec");
- pContext->pulse.pa_stream_get_channel_map = (ma_proc)ma_dlsym(pContext->pulse.pulseSO, "pa_stream_get_channel_map");
- pContext->pulse.pa_stream_get_buffer_attr = (ma_proc)ma_dlsym(pContext->pulse.pulseSO, "pa_stream_get_buffer_attr");
- pContext->pulse.pa_stream_set_buffer_attr = (ma_proc)ma_dlsym(pContext->pulse.pulseSO, "pa_stream_set_buffer_attr");
- pContext->pulse.pa_stream_get_device_name = (ma_proc)ma_dlsym(pContext->pulse.pulseSO, "pa_stream_get_device_name");
- pContext->pulse.pa_stream_set_write_callback = (ma_proc)ma_dlsym(pContext->pulse.pulseSO, "pa_stream_set_write_callback");
- pContext->pulse.pa_stream_set_read_callback = (ma_proc)ma_dlsym(pContext->pulse.pulseSO, "pa_stream_set_read_callback");
- pContext->pulse.pa_stream_flush = (ma_proc)ma_dlsym(pContext->pulse.pulseSO, "pa_stream_flush");
- pContext->pulse.pa_stream_drain = (ma_proc)ma_dlsym(pContext->pulse.pulseSO, "pa_stream_drain");
- pContext->pulse.pa_stream_is_corked = (ma_proc)ma_dlsym(pContext->pulse.pulseSO, "pa_stream_is_corked");
- pContext->pulse.pa_stream_cork = (ma_proc)ma_dlsym(pContext->pulse.pulseSO, "pa_stream_cork");
- pContext->pulse.pa_stream_trigger = (ma_proc)ma_dlsym(pContext->pulse.pulseSO, "pa_stream_trigger");
- pContext->pulse.pa_stream_begin_write = (ma_proc)ma_dlsym(pContext->pulse.pulseSO, "pa_stream_begin_write");
- pContext->pulse.pa_stream_write = (ma_proc)ma_dlsym(pContext->pulse.pulseSO, "pa_stream_write");
- pContext->pulse.pa_stream_peek = (ma_proc)ma_dlsym(pContext->pulse.pulseSO, "pa_stream_peek");
- pContext->pulse.pa_stream_drop = (ma_proc)ma_dlsym(pContext->pulse.pulseSO, "pa_stream_drop");
- pContext->pulse.pa_stream_writable_size = (ma_proc)ma_dlsym(pContext->pulse.pulseSO, "pa_stream_writable_size");
- pContext->pulse.pa_stream_readable_size = (ma_proc)ma_dlsym(pContext->pulse.pulseSO, "pa_stream_readable_size");
+ pContext->pulse.pa_mainloop_new = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_mainloop_new");
+ pContext->pulse.pa_mainloop_free = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_mainloop_free");
+ pContext->pulse.pa_mainloop_get_api = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_mainloop_get_api");
+ pContext->pulse.pa_mainloop_iterate = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_mainloop_iterate");
+ pContext->pulse.pa_mainloop_wakeup = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_mainloop_wakeup");
+ pContext->pulse.pa_context_new = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_context_new");
+ pContext->pulse.pa_context_unref = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_context_unref");
+ pContext->pulse.pa_context_connect = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_context_connect");
+ pContext->pulse.pa_context_disconnect = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_context_disconnect");
+ pContext->pulse.pa_context_set_state_callback = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_context_set_state_callback");
+ pContext->pulse.pa_context_get_state = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_context_get_state");
+ pContext->pulse.pa_context_get_sink_info_list = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_context_get_sink_info_list");
+ pContext->pulse.pa_context_get_source_info_list = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_context_get_source_info_list");
+ pContext->pulse.pa_context_get_sink_info_by_name = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_context_get_sink_info_by_name");
+ pContext->pulse.pa_context_get_source_info_by_name = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_context_get_source_info_by_name");
+ pContext->pulse.pa_operation_unref = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_operation_unref");
+ pContext->pulse.pa_operation_get_state = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_operation_get_state");
+ pContext->pulse.pa_channel_map_init_extend = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_channel_map_init_extend");
+ pContext->pulse.pa_channel_map_valid = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_channel_map_valid");
+ pContext->pulse.pa_channel_map_compatible = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_channel_map_compatible");
+ pContext->pulse.pa_stream_new = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_new");
+ pContext->pulse.pa_stream_unref = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_unref");
+ pContext->pulse.pa_stream_connect_playback = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_connect_playback");
+ pContext->pulse.pa_stream_connect_record = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_connect_record");
+ pContext->pulse.pa_stream_disconnect = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_disconnect");
+ pContext->pulse.pa_stream_get_state = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_get_state");
+ pContext->pulse.pa_stream_get_sample_spec = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_get_sample_spec");
+ pContext->pulse.pa_stream_get_channel_map = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_get_channel_map");
+ pContext->pulse.pa_stream_get_buffer_attr = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_get_buffer_attr");
+ pContext->pulse.pa_stream_set_buffer_attr = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_set_buffer_attr");
+ pContext->pulse.pa_stream_get_device_name = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_get_device_name");
+ pContext->pulse.pa_stream_set_write_callback = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_set_write_callback");
+ pContext->pulse.pa_stream_set_read_callback = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_set_read_callback");
+ pContext->pulse.pa_stream_flush = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_flush");
+ pContext->pulse.pa_stream_drain = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_drain");
+ pContext->pulse.pa_stream_is_corked = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_is_corked");
+ pContext->pulse.pa_stream_cork = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_cork");
+ pContext->pulse.pa_stream_trigger = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_trigger");
+ pContext->pulse.pa_stream_begin_write = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_begin_write");
+ pContext->pulse.pa_stream_write = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_write");
+ pContext->pulse.pa_stream_peek = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_peek");
+ pContext->pulse.pa_stream_drop = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_drop");
+ pContext->pulse.pa_stream_writable_size = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_writable_size");
+ pContext->pulse.pa_stream_readable_size = (ma_proc)ma_dlsym(pContext, pContext->pulse.pulseSO, "pa_stream_readable_size");
#else
/* This strange assignment system is just for type safety. */
ma_pa_mainloop_new_proc _pa_mainloop_new = pa_mainloop_new;
@@ -15678,7 +15840,7 @@ ma_result ma_context_init__pulse(const ma_context_config* pConfig, ma_context* p
ma_free(pContext->pulse.pServerName);
ma_free(pContext->pulse.pApplicationName);
#ifndef MA_NO_RUNTIME_LINKING
- ma_dlclose(pContext->pulse.pulseSO);
+ ma_dlclose(pContext, pContext->pulse.pulseSO);
#endif
return MA_NO_BACKEND;
}
@@ -15689,7 +15851,7 @@ ma_result ma_context_init__pulse(const ma_context_config* pConfig, ma_context* p
ma_free(pContext->pulse.pApplicationName);
((ma_pa_mainloop_free_proc)pContext->pulse.pa_mainloop_free)(pMainLoop);
#ifndef MA_NO_RUNTIME_LINKING
- ma_dlclose(pContext->pulse.pulseSO);
+ ma_dlclose(pContext, pContext->pulse.pulseSO);
#endif
return MA_NO_BACKEND;
}
@@ -15700,7 +15862,7 @@ ma_result ma_context_init__pulse(const ma_context_config* pConfig, ma_context* p
ma_free(pContext->pulse.pApplicationName);
((ma_pa_mainloop_free_proc)pContext->pulse.pa_mainloop_free)(pMainLoop);
#ifndef MA_NO_RUNTIME_LINKING
- ma_dlclose(pContext->pulse.pulseSO);
+ ma_dlclose(pContext, pContext->pulse.pulseSO);
#endif
return MA_NO_BACKEND;
}
@@ -15712,7 +15874,7 @@ ma_result ma_context_init__pulse(const ma_context_config* pConfig, ma_context* p
((ma_pa_context_unref_proc)pContext->pulse.pa_context_unref)(pPulseContext);
((ma_pa_mainloop_free_proc)pContext->pulse.pa_mainloop_free)(pMainLoop);
#ifndef MA_NO_RUNTIME_LINKING
- ma_dlclose(pContext->pulse.pulseSO);
+ ma_dlclose(pContext, pContext->pulse.pulseSO);
#endif
return MA_NO_BACKEND;
}
@@ -16253,7 +16415,7 @@ ma_result ma_context_uninit__jack(ma_context* pContext)
pContext->jack.pClientName = NULL;
#ifndef MA_NO_RUNTIME_LINKING
- ma_dlclose(pContext->jack.jackSO);
+ ma_dlclose(pContext, pContext->jack.jackSO);
#endif
return MA_SUCCESS;
@@ -16273,7 +16435,7 @@ ma_result ma_context_init__jack(const ma_context_config* pConfig, ma_context* pC
size_t i;
for (i = 0; i < ma_countof(libjackNames); ++i) {
- pContext->jack.jackSO = ma_dlopen(libjackNames[i]);
+ pContext->jack.jackSO = ma_dlopen(pContext, libjackNames[i]);
if (pContext->jack.jackSO != NULL) {
break;
}
@@ -16283,22 +16445,22 @@ ma_result ma_context_init__jack(const ma_context_config* pConfig, ma_context* pC
return MA_NO_BACKEND;
}
- pContext->jack.jack_client_open = (ma_proc)ma_dlsym(pContext->jack.jackSO, "jack_client_open");
- pContext->jack.jack_client_close = (ma_proc)ma_dlsym(pContext->jack.jackSO, "jack_client_close");
- pContext->jack.jack_client_name_size = (ma_proc)ma_dlsym(pContext->jack.jackSO, "jack_client_name_size");
- pContext->jack.jack_set_process_callback = (ma_proc)ma_dlsym(pContext->jack.jackSO, "jack_set_process_callback");
- pContext->jack.jack_set_buffer_size_callback = (ma_proc)ma_dlsym(pContext->jack.jackSO, "jack_set_buffer_size_callback");
- pContext->jack.jack_on_shutdown = (ma_proc)ma_dlsym(pContext->jack.jackSO, "jack_on_shutdown");
- pContext->jack.jack_get_sample_rate = (ma_proc)ma_dlsym(pContext->jack.jackSO, "jack_get_sample_rate");
- pContext->jack.jack_get_buffer_size = (ma_proc)ma_dlsym(pContext->jack.jackSO, "jack_get_buffer_size");
- pContext->jack.jack_get_ports = (ma_proc)ma_dlsym(pContext->jack.jackSO, "jack_get_ports");
- pContext->jack.jack_activate = (ma_proc)ma_dlsym(pContext->jack.jackSO, "jack_activate");
- pContext->jack.jack_deactivate = (ma_proc)ma_dlsym(pContext->jack.jackSO, "jack_deactivate");
- pContext->jack.jack_connect = (ma_proc)ma_dlsym(pContext->jack.jackSO, "jack_connect");
- pContext->jack.jack_port_register = (ma_proc)ma_dlsym(pContext->jack.jackSO, "jack_port_register");
- pContext->jack.jack_port_name = (ma_proc)ma_dlsym(pContext->jack.jackSO, "jack_port_name");
- pContext->jack.jack_port_get_buffer = (ma_proc)ma_dlsym(pContext->jack.jackSO, "jack_port_get_buffer");
- pContext->jack.jack_free = (ma_proc)ma_dlsym(pContext->jack.jackSO, "jack_free");
+ pContext->jack.jack_client_open = (ma_proc)ma_dlsym(pContext, pContext->jack.jackSO, "jack_client_open");
+ pContext->jack.jack_client_close = (ma_proc)ma_dlsym(pContext, pContext->jack.jackSO, "jack_client_close");
+ pContext->jack.jack_client_name_size = (ma_proc)ma_dlsym(pContext, pContext->jack.jackSO, "jack_client_name_size");
+ pContext->jack.jack_set_process_callback = (ma_proc)ma_dlsym(pContext, pContext->jack.jackSO, "jack_set_process_callback");
+ pContext->jack.jack_set_buffer_size_callback = (ma_proc)ma_dlsym(pContext, pContext->jack.jackSO, "jack_set_buffer_size_callback");
+ pContext->jack.jack_on_shutdown = (ma_proc)ma_dlsym(pContext, pContext->jack.jackSO, "jack_on_shutdown");
+ pContext->jack.jack_get_sample_rate = (ma_proc)ma_dlsym(pContext, pContext->jack.jackSO, "jack_get_sample_rate");
+ pContext->jack.jack_get_buffer_size = (ma_proc)ma_dlsym(pContext, pContext->jack.jackSO, "jack_get_buffer_size");
+ pContext->jack.jack_get_ports = (ma_proc)ma_dlsym(pContext, pContext->jack.jackSO, "jack_get_ports");
+ pContext->jack.jack_activate = (ma_proc)ma_dlsym(pContext, pContext->jack.jackSO, "jack_activate");
+ pContext->jack.jack_deactivate = (ma_proc)ma_dlsym(pContext, pContext->jack.jackSO, "jack_deactivate");
+ pContext->jack.jack_connect = (ma_proc)ma_dlsym(pContext, pContext->jack.jackSO, "jack_connect");
+ pContext->jack.jack_port_register = (ma_proc)ma_dlsym(pContext, pContext->jack.jackSO, "jack_port_register");
+ pContext->jack.jack_port_name = (ma_proc)ma_dlsym(pContext, pContext->jack.jackSO, "jack_port_name");
+ pContext->jack.jack_port_get_buffer = (ma_proc)ma_dlsym(pContext, pContext->jack.jackSO, "jack_port_get_buffer");
+ pContext->jack.jack_free = (ma_proc)ma_dlsym(pContext, pContext->jack.jackSO, "jack_free");
#else
/*
This strange assignment system is here just to ensure type safety of miniaudio's function pointer
@@ -16365,7 +16527,7 @@ ma_result ma_context_init__jack(const ma_context_config* pConfig, ma_context* pC
if (result != MA_SUCCESS) {
ma_free(pContext->jack.pClientName);
#ifndef MA_NO_RUNTIME_LINKING
- ma_dlclose(pContext->jack.jackSO);
+ ma_dlclose(pContext, pContext->jack.jackSO);
#endif
return MA_NO_BACKEND;
}
@@ -18793,9 +18955,9 @@ ma_result ma_context_uninit__coreaudio(ma_context* pContext)
ma_assert(pContext->backend == ma_backend_coreaudio);
#if !defined(MA_NO_RUNTIME_LINKING) && !defined(MA_APPLE_MOBILE)
- ma_dlclose(pContext->coreaudio.hAudioUnit);
- ma_dlclose(pContext->coreaudio.hCoreAudio);
- ma_dlclose(pContext->coreaudio.hCoreFoundation);
+ ma_dlclose(pContext, pContext->coreaudio.hAudioUnit);
+ ma_dlclose(pContext, pContext->coreaudio.hCoreAudio);
+ ma_dlclose(pContext, pContext->coreaudio.hCoreFoundation);
#endif
(void)pContext;
@@ -18824,24 +18986,24 @@ ma_result ma_context_init__coreaudio(const ma_context_config* pConfig, ma_contex
#endif
#if !defined(MA_NO_RUNTIME_LINKING) && !defined(MA_APPLE_MOBILE)
- pContext->coreaudio.hCoreFoundation = ma_dlopen("CoreFoundation.framework/CoreFoundation");
+ pContext->coreaudio.hCoreFoundation = ma_dlopen(pContext, "CoreFoundation.framework/CoreFoundation");
if (pContext->coreaudio.hCoreFoundation == NULL) {
return MA_API_NOT_FOUND;
}
- pContext->coreaudio.CFStringGetCString = ma_dlsym(pContext->coreaudio.hCoreFoundation, "CFStringGetCString");
+ pContext->coreaudio.CFStringGetCString = ma_dlsym(pContext, pContext->coreaudio.hCoreFoundation, "CFStringGetCString");
- pContext->coreaudio.hCoreAudio = ma_dlopen("CoreAudio.framework/CoreAudio");
+ pContext->coreaudio.hCoreAudio = ma_dlopen(pContext, "CoreAudio.framework/CoreAudio");
if (pContext->coreaudio.hCoreAudio == NULL) {
- ma_dlclose(pContext->coreaudio.hCoreFoundation);
+ ma_dlclose(pContext, pContext->coreaudio.hCoreFoundation);
return MA_API_NOT_FOUND;
}
- pContext->coreaudio.AudioObjectGetPropertyData = ma_dlsym(pContext->coreaudio.hCoreAudio, "AudioObjectGetPropertyData");
- pContext->coreaudio.AudioObjectGetPropertyDataSize = ma_dlsym(pContext->coreaudio.hCoreAudio, "AudioObjectGetPropertyDataSize");
- pContext->coreaudio.AudioObjectSetPropertyData = ma_dlsym(pContext->coreaudio.hCoreAudio, "AudioObjectSetPropertyData");
- pContext->coreaudio.AudioObjectAddPropertyListener = ma_dlsym(pContext->coreaudio.hCoreAudio, "AudioObjectAddPropertyListener");
+ pContext->coreaudio.AudioObjectGetPropertyData = ma_dlsym(pContext, pContext->coreaudio.hCoreAudio, "AudioObjectGetPropertyData");
+ pContext->coreaudio.AudioObjectGetPropertyDataSize = ma_dlsym(pContext, pContext->coreaudio.hCoreAudio, "AudioObjectGetPropertyDataSize");
+ pContext->coreaudio.AudioObjectSetPropertyData = ma_dlsym(pContext, pContext->coreaudio.hCoreAudio, "AudioObjectSetPropertyData");
+ pContext->coreaudio.AudioObjectAddPropertyListener = ma_dlsym(pContext, pContext->coreaudio.hCoreAudio, "AudioObjectAddPropertyListener");
/*
It looks like Apple has moved some APIs from AudioUnit into AudioToolbox on more recent versions of macOS. They are still
@@ -18849,35 +19011,35 @@ ma_result ma_context_init__coreaudio(const ma_context_config* pConfig, ma_contex
The way it'll work is that it'll first try AudioUnit, and if the required symbols are not present there we'll fall back to
AudioToolbox.
*/
- pContext->coreaudio.hAudioUnit = ma_dlopen("AudioUnit.framework/AudioUnit");
+ pContext->coreaudio.hAudioUnit = ma_dlopen(pContext, "AudioUnit.framework/AudioUnit");
if (pContext->coreaudio.hAudioUnit == NULL) {
- ma_dlclose(pContext->coreaudio.hCoreAudio);
- ma_dlclose(pContext->coreaudio.hCoreFoundation);
+ ma_dlclose(pContext, pContext->coreaudio.hCoreAudio);
+ ma_dlclose(pContext, pContext->coreaudio.hCoreFoundation);
return MA_API_NOT_FOUND;
}
- if (ma_dlsym(pContext->coreaudio.hAudioUnit, "AudioComponentFindNext") == NULL) {
+ if (ma_dlsym(pContext, pContext->coreaudio.hAudioUnit, "AudioComponentFindNext") == NULL) {
/* Couldn't find the required symbols in AudioUnit, so fall back to AudioToolbox. */
- ma_dlclose(pContext->coreaudio.hAudioUnit);
- pContext->coreaudio.hAudioUnit = ma_dlopen("AudioToolbox.framework/AudioToolbox");
+ ma_dlclose(pContext, pContext->coreaudio.hAudioUnit);
+ pContext->coreaudio.hAudioUnit = ma_dlopen(pContext, "AudioToolbox.framework/AudioToolbox");
if (pContext->coreaudio.hAudioUnit == NULL) {
- ma_dlclose(pContext->coreaudio.hCoreAudio);
- ma_dlclose(pContext->coreaudio.hCoreFoundation);
+ ma_dlclose(pContext, pContext->coreaudio.hCoreAudio);
+ ma_dlclose(pContext, pContext->coreaudio.hCoreFoundation);
return MA_API_NOT_FOUND;
}
}
- pContext->coreaudio.AudioComponentFindNext = ma_dlsym(pContext->coreaudio.hAudioUnit, "AudioComponentFindNext");
- pContext->coreaudio.AudioComponentInstanceDispose = ma_dlsym(pContext->coreaudio.hAudioUnit, "AudioComponentInstanceDispose");
- pContext->coreaudio.AudioComponentInstanceNew = ma_dlsym(pContext->coreaudio.hAudioUnit, "AudioComponentInstanceNew");
- pContext->coreaudio.AudioOutputUnitStart = ma_dlsym(pContext->coreaudio.hAudioUnit, "AudioOutputUnitStart");
- pContext->coreaudio.AudioOutputUnitStop = ma_dlsym(pContext->coreaudio.hAudioUnit, "AudioOutputUnitStop");
- pContext->coreaudio.AudioUnitAddPropertyListener = ma_dlsym(pContext->coreaudio.hAudioUnit, "AudioUnitAddPropertyListener");
- pContext->coreaudio.AudioUnitGetPropertyInfo = ma_dlsym(pContext->coreaudio.hAudioUnit, "AudioUnitGetPropertyInfo");
- pContext->coreaudio.AudioUnitGetProperty = ma_dlsym(pContext->coreaudio.hAudioUnit, "AudioUnitGetProperty");
- pContext->coreaudio.AudioUnitSetProperty = ma_dlsym(pContext->coreaudio.hAudioUnit, "AudioUnitSetProperty");
- pContext->coreaudio.AudioUnitInitialize = ma_dlsym(pContext->coreaudio.hAudioUnit, "AudioUnitInitialize");
- pContext->coreaudio.AudioUnitRender = ma_dlsym(pContext->coreaudio.hAudioUnit, "AudioUnitRender");
+ pContext->coreaudio.AudioComponentFindNext = ma_dlsym(pContext, pContext->coreaudio.hAudioUnit, "AudioComponentFindNext");
+ pContext->coreaudio.AudioComponentInstanceDispose = ma_dlsym(pContext, pContext->coreaudio.hAudioUnit, "AudioComponentInstanceDispose");
+ pContext->coreaudio.AudioComponentInstanceNew = ma_dlsym(pContext, pContext->coreaudio.hAudioUnit, "AudioComponentInstanceNew");
+ pContext->coreaudio.AudioOutputUnitStart = ma_dlsym(pContext, pContext->coreaudio.hAudioUnit, "AudioOutputUnitStart");
+ pContext->coreaudio.AudioOutputUnitStop = ma_dlsym(pContext, pContext->coreaudio.hAudioUnit, "AudioOutputUnitStop");
+ pContext->coreaudio.AudioUnitAddPropertyListener = ma_dlsym(pContext, pContext->coreaudio.hAudioUnit, "AudioUnitAddPropertyListener");
+ pContext->coreaudio.AudioUnitGetPropertyInfo = ma_dlsym(pContext, pContext->coreaudio.hAudioUnit, "AudioUnitGetPropertyInfo");
+ pContext->coreaudio.AudioUnitGetProperty = ma_dlsym(pContext, pContext->coreaudio.hAudioUnit, "AudioUnitGetProperty");
+ pContext->coreaudio.AudioUnitSetProperty = ma_dlsym(pContext, pContext->coreaudio.hAudioUnit, "AudioUnitSetProperty");
+ pContext->coreaudio.AudioUnitInitialize = ma_dlsym(pContext, pContext->coreaudio.hAudioUnit, "AudioUnitInitialize");
+ pContext->coreaudio.AudioUnitRender = ma_dlsym(pContext, pContext->coreaudio.hAudioUnit, "AudioUnitRender");
#else
pContext->coreaudio.CFStringGetCString = (ma_proc)CFStringGetCString;
@@ -18928,9 +19090,9 @@ ma_result ma_context_init__coreaudio(const ma_context_config* pConfig, ma_contex
pContext->coreaudio.component = ((ma_AudioComponentFindNext_proc)pContext->coreaudio.AudioComponentFindNext)(NULL, &desc);
if (pContext->coreaudio.component == NULL) {
#if !defined(MA_NO_RUNTIME_LINKING) && !defined(MA_APPLE_MOBILE)
- ma_dlclose(pContext->coreaudio.hAudioUnit);
- ma_dlclose(pContext->coreaudio.hCoreAudio);
- ma_dlclose(pContext->coreaudio.hCoreFoundation);
+ ma_dlclose(pContext, pContext->coreaudio.hAudioUnit);
+ ma_dlclose(pContext, pContext->coreaudio.hCoreAudio);
+ ma_dlclose(pContext, pContext->coreaudio.hCoreFoundation);
#endif
return MA_FAILED_TO_INIT_BACKEND;
}
@@ -19734,7 +19896,7 @@ ma_result ma_context_init__sndio(const ma_context_config* pConfig, ma_context* p
size_t i;
for (i = 0; i < ma_countof(libsndioNames); ++i) {
- pContext->sndio.sndioSO = ma_dlopen(libsndioNames[i]);
+ pContext->sndio.sndioSO = ma_dlopen(pContext, libsndioNames[i]);
if (pContext->sndio.sndioSO != NULL) {
break;
}
@@ -19744,16 +19906,16 @@ ma_result ma_context_init__sndio(const ma_context_config* pConfig, ma_context* p
return MA_NO_BACKEND;
}
- pContext->sndio.sio_open = (ma_proc)ma_dlsym(pContext->sndio.sndioSO, "sio_open");
- pContext->sndio.sio_close = (ma_proc)ma_dlsym(pContext->sndio.sndioSO, "sio_close");
- pContext->sndio.sio_setpar = (ma_proc)ma_dlsym(pContext->sndio.sndioSO, "sio_setpar");
- pContext->sndio.sio_getpar = (ma_proc)ma_dlsym(pContext->sndio.sndioSO, "sio_getpar");
- pContext->sndio.sio_getcap = (ma_proc)ma_dlsym(pContext->sndio.sndioSO, "sio_getcap");
- pContext->sndio.sio_write = (ma_proc)ma_dlsym(pContext->sndio.sndioSO, "sio_write");
- pContext->sndio.sio_read = (ma_proc)ma_dlsym(pContext->sndio.sndioSO, "sio_read");
- pContext->sndio.sio_start = (ma_proc)ma_dlsym(pContext->sndio.sndioSO, "sio_start");
- pContext->sndio.sio_stop = (ma_proc)ma_dlsym(pContext->sndio.sndioSO, "sio_stop");
- pContext->sndio.sio_initpar = (ma_proc)ma_dlsym(pContext->sndio.sndioSO, "sio_initpar");
+ pContext->sndio.sio_open = (ma_proc)ma_dlsym(pContext, pContext->sndio.sndioSO, "sio_open");
+ pContext->sndio.sio_close = (ma_proc)ma_dlsym(pContext, pContext->sndio.sndioSO, "sio_close");
+ pContext->sndio.sio_setpar = (ma_proc)ma_dlsym(pContext, pContext->sndio.sndioSO, "sio_setpar");
+ pContext->sndio.sio_getpar = (ma_proc)ma_dlsym(pContext, pContext->sndio.sndioSO, "sio_getpar");
+ pContext->sndio.sio_getcap = (ma_proc)ma_dlsym(pContext, pContext->sndio.sndioSO, "sio_getcap");
+ pContext->sndio.sio_write = (ma_proc)ma_dlsym(pContext, pContext->sndio.sndioSO, "sio_write");
+ pContext->sndio.sio_read = (ma_proc)ma_dlsym(pContext, pContext->sndio.sndioSO, "sio_read");
+ pContext->sndio.sio_start = (ma_proc)ma_dlsym(pContext, pContext->sndio.sndioSO, "sio_start");
+ pContext->sndio.sio_stop = (ma_proc)ma_dlsym(pContext, pContext->sndio.sndioSO, "sio_stop");
+ pContext->sndio.sio_initpar = (ma_proc)ma_dlsym(pContext, pContext->sndio.sndioSO, "sio_initpar");
#else
pContext->sndio.sio_open = sio_open;
pContext->sndio.sio_close = sio_close;
@@ -21625,7 +21787,7 @@ ma_result ma_context_uninit__aaudio(ma_context* pContext)
ma_assert(pContext != NULL);
ma_assert(pContext->backend == ma_backend_aaudio);
- ma_dlclose(pContext->aaudio.hAAudio);
+ ma_dlclose(pContext, pContext->aaudio.hAAudio);
pContext->aaudio.hAAudio = NULL;
return MA_SUCCESS;
@@ -21639,7 +21801,7 @@ ma_result ma_context_init__aaudio(const ma_context_config* pConfig, ma_context*
size_t i;
for (i = 0; i < ma_countof(libNames); ++i) {
- pContext->aaudio.hAAudio = ma_dlopen(libNames[i]);
+ pContext->aaudio.hAAudio = ma_dlopen(pContext, libNames[i]);
if (pContext->aaudio.hAAudio != NULL) {
break;
}
@@ -21649,30 +21811,30 @@ ma_result ma_context_init__aaudio(const ma_context_config* pConfig, ma_context*
return MA_FAILED_TO_INIT_BACKEND;
}
- pContext->aaudio.AAudio_createStreamBuilder = (ma_proc)ma_dlsym(pContext->aaudio.hAAudio, "AAudio_createStreamBuilder");
- pContext->aaudio.AAudioStreamBuilder_delete = (ma_proc)ma_dlsym(pContext->aaudio.hAAudio, "AAudioStreamBuilder_delete");
- pContext->aaudio.AAudioStreamBuilder_setDeviceId = (ma_proc)ma_dlsym(pContext->aaudio.hAAudio, "AAudioStreamBuilder_setDeviceId");
- pContext->aaudio.AAudioStreamBuilder_setDirection = (ma_proc)ma_dlsym(pContext->aaudio.hAAudio, "AAudioStreamBuilder_setDirection");
- pContext->aaudio.AAudioStreamBuilder_setSharingMode = (ma_proc)ma_dlsym(pContext->aaudio.hAAudio, "AAudioStreamBuilder_setSharingMode");
- pContext->aaudio.AAudioStreamBuilder_setFormat = (ma_proc)ma_dlsym(pContext->aaudio.hAAudio, "AAudioStreamBuilder_setFormat");
- pContext->aaudio.AAudioStreamBuilder_setChannelCount = (ma_proc)ma_dlsym(pContext->aaudio.hAAudio, "AAudioStreamBuilder_setChannelCount");
- pContext->aaudio.AAudioStreamBuilder_setSampleRate = (ma_proc)ma_dlsym(pContext->aaudio.hAAudio, "AAudioStreamBuilder_setSampleRate");
- pContext->aaudio.AAudioStreamBuilder_setBufferCapacityInFrames = (ma_proc)ma_dlsym(pContext->aaudio.hAAudio, "AAudioStreamBuilder_setBufferCapacityInFrames");
- pContext->aaudio.AAudioStreamBuilder_setFramesPerDataCallback = (ma_proc)ma_dlsym(pContext->aaudio.hAAudio, "AAudioStreamBuilder_setFramesPerDataCallback");
- pContext->aaudio.AAudioStreamBuilder_setDataCallback = (ma_proc)ma_dlsym(pContext->aaudio.hAAudio, "AAudioStreamBuilder_setDataCallback");
- pContext->aaudio.AAudioStreamBuilder_setPerformanceMode = (ma_proc)ma_dlsym(pContext->aaudio.hAAudio, "AAudioStreamBuilder_setPerformanceMode");
- pContext->aaudio.AAudioStreamBuilder_openStream = (ma_proc)ma_dlsym(pContext->aaudio.hAAudio, "AAudioStreamBuilder_openStream");
- pContext->aaudio.AAudioStream_close = (ma_proc)ma_dlsym(pContext->aaudio.hAAudio, "AAudioStream_close");
- pContext->aaudio.AAudioStream_getState = (ma_proc)ma_dlsym(pContext->aaudio.hAAudio, "AAudioStream_getState");
- pContext->aaudio.AAudioStream_waitForStateChange = (ma_proc)ma_dlsym(pContext->aaudio.hAAudio, "AAudioStream_waitForStateChange");
- pContext->aaudio.AAudioStream_getFormat = (ma_proc)ma_dlsym(pContext->aaudio.hAAudio, "AAudioStream_getFormat");
- pContext->aaudio.AAudioStream_getChannelCount = (ma_proc)ma_dlsym(pContext->aaudio.hAAudio, "AAudioStream_getChannelCount");
- pContext->aaudio.AAudioStream_getSampleRate = (ma_proc)ma_dlsym(pContext->aaudio.hAAudio, "AAudioStream_getSampleRate");
- pContext->aaudio.AAudioStream_getBufferCapacityInFrames = (ma_proc)ma_dlsym(pContext->aaudio.hAAudio, "AAudioStream_getBufferCapacityInFrames");
- pContext->aaudio.AAudioStream_getFramesPerDataCallback = (ma_proc)ma_dlsym(pContext->aaudio.hAAudio, "AAudioStream_getFramesPerDataCallback");
- pContext->aaudio.AAudioStream_getFramesPerBurst = (ma_proc)ma_dlsym(pContext->aaudio.hAAudio, "AAudioStream_getFramesPerBurst");
- pContext->aaudio.AAudioStream_requestStart = (ma_proc)ma_dlsym(pContext->aaudio.hAAudio, "AAudioStream_requestStart");
- pContext->aaudio.AAudioStream_requestStop = (ma_proc)ma_dlsym(pContext->aaudio.hAAudio, "AAudioStream_requestStop");
+ pContext->aaudio.AAudio_createStreamBuilder = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudio_createStreamBuilder");
+ pContext->aaudio.AAudioStreamBuilder_delete = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStreamBuilder_delete");
+ pContext->aaudio.AAudioStreamBuilder_setDeviceId = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStreamBuilder_setDeviceId");
+ pContext->aaudio.AAudioStreamBuilder_setDirection = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStreamBuilder_setDirection");
+ pContext->aaudio.AAudioStreamBuilder_setSharingMode = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStreamBuilder_setSharingMode");
+ pContext->aaudio.AAudioStreamBuilder_setFormat = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStreamBuilder_setFormat");
+ pContext->aaudio.AAudioStreamBuilder_setChannelCount = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStreamBuilder_setChannelCount");
+ pContext->aaudio.AAudioStreamBuilder_setSampleRate = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStreamBuilder_setSampleRate");
+ pContext->aaudio.AAudioStreamBuilder_setBufferCapacityInFrames = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStreamBuilder_setBufferCapacityInFrames");
+ pContext->aaudio.AAudioStreamBuilder_setFramesPerDataCallback = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStreamBuilder_setFramesPerDataCallback");
+ pContext->aaudio.AAudioStreamBuilder_setDataCallback = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStreamBuilder_setDataCallback");
+ pContext->aaudio.AAudioStreamBuilder_setPerformanceMode = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStreamBuilder_setPerformanceMode");
+ pContext->aaudio.AAudioStreamBuilder_openStream = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStreamBuilder_openStream");
+ pContext->aaudio.AAudioStream_close = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStream_close");
+ pContext->aaudio.AAudioStream_getState = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStream_getState");
+ pContext->aaudio.AAudioStream_waitForStateChange = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStream_waitForStateChange");
+ pContext->aaudio.AAudioStream_getFormat = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStream_getFormat");
+ pContext->aaudio.AAudioStream_getChannelCount = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStream_getChannelCount");
+ pContext->aaudio.AAudioStream_getSampleRate = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStream_getSampleRate");
+ pContext->aaudio.AAudioStream_getBufferCapacityInFrames = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStream_getBufferCapacityInFrames");
+ pContext->aaudio.AAudioStream_getFramesPerDataCallback = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStream_getFramesPerDataCallback");
+ pContext->aaudio.AAudioStream_getFramesPerBurst = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStream_getFramesPerBurst");
+ pContext->aaudio.AAudioStream_requestStart = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStream_requestStart");
+ pContext->aaudio.AAudioStream_requestStop = (ma_proc)ma_dlsym(pContext, pContext->aaudio.hAAudio, "AAudioStream_requestStop");
pContext->isBackendAsynchronous = MA_TRUE;
@@ -22522,7 +22684,7 @@ ma_result ma_device_start__opensl(ma_device* pDevice)
periodSizeInBytes = (pDevice->capture.internalBufferSizeInFrames / pDevice->capture.internalPeriods) * ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels);
for (iPeriod = 0; iPeriod < pDevice->capture.internalPeriods; ++iPeriod) {
- resultSL = MA_OPENSL_BUFFERQUEUE(pDevice->opensl.pBufferQueuePlayback)->Enqueue((SLAndroidSimpleBufferQueueItf)pDevice->opensl.pBufferQueueCapture, pDevice->opensl.pBufferCapture + (periodSizeInBytes * iPeriod), periodSizeInBytes);
+ resultSL = MA_OPENSL_BUFFERQUEUE(pDevice->opensl.pBufferQueueCapture)->Enqueue((SLAndroidSimpleBufferQueueItf)pDevice->opensl.pBufferQueueCapture, pDevice->opensl.pBufferCapture + (periodSizeInBytes * iPeriod), periodSizeInBytes);
if (resultSL != SL_RESULT_SUCCESS) {
MA_OPENSL_RECORD(pDevice->opensl.pAudioRecorder)->SetRecordState((SLRecordItf)pDevice->opensl.pAudioRecorder, SL_RECORDSTATE_STOPPED);
return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[OpenSL] Failed to enqueue buffer for capture device.", MA_FAILED_TO_START_BACKEND_DEVICE);
@@ -23594,9 +23756,9 @@ ma_bool32 ma_device__is_initialized(ma_device* pDevice)
ma_result ma_context_uninit_backend_apis__win32(ma_context* pContext)
{
ma_CoUninitialize(pContext);
- ma_dlclose(pContext->win32.hUser32DLL);
- ma_dlclose(pContext->win32.hOle32DLL);
- ma_dlclose(pContext->win32.hAdvapi32DLL);
+ ma_dlclose(pContext, pContext->win32.hUser32DLL);
+ ma_dlclose(pContext, pContext->win32.hOle32DLL);
+ ma_dlclose(pContext, pContext->win32.hAdvapi32DLL);
return MA_SUCCESS;
}
@@ -23605,38 +23767,38 @@ ma_result ma_context_init_backend_apis__win32(ma_context* pContext)
{
#ifdef MA_WIN32_DESKTOP
/* Ole32.dll */
- pContext->win32.hOle32DLL = ma_dlopen("ole32.dll");
+ pContext->win32.hOle32DLL = ma_dlopen(pContext, "ole32.dll");
if (pContext->win32.hOle32DLL == NULL) {
return MA_FAILED_TO_INIT_BACKEND;
}
- pContext->win32.CoInitializeEx = (ma_proc)ma_dlsym(pContext->win32.hOle32DLL, "CoInitializeEx");
- pContext->win32.CoUninitialize = (ma_proc)ma_dlsym(pContext->win32.hOle32DLL, "CoUninitialize");
- pContext->win32.CoCreateInstance = (ma_proc)ma_dlsym(pContext->win32.hOle32DLL, "CoCreateInstance");
- pContext->win32.CoTaskMemFree = (ma_proc)ma_dlsym(pContext->win32.hOle32DLL, "CoTaskMemFree");
- pContext->win32.PropVariantClear = (ma_proc)ma_dlsym(pContext->win32.hOle32DLL, "PropVariantClear");
- pContext->win32.StringFromGUID2 = (ma_proc)ma_dlsym(pContext->win32.hOle32DLL, "StringFromGUID2");
+ pContext->win32.CoInitializeEx = (ma_proc)ma_dlsym(pContext, pContext->win32.hOle32DLL, "CoInitializeEx");
+ pContext->win32.CoUninitialize = (ma_proc)ma_dlsym(pContext, pContext->win32.hOle32DLL, "CoUninitialize");
+ pContext->win32.CoCreateInstance = (ma_proc)ma_dlsym(pContext, pContext->win32.hOle32DLL, "CoCreateInstance");
+ pContext->win32.CoTaskMemFree = (ma_proc)ma_dlsym(pContext, pContext->win32.hOle32DLL, "CoTaskMemFree");
+ pContext->win32.PropVariantClear = (ma_proc)ma_dlsym(pContext, pContext->win32.hOle32DLL, "PropVariantClear");
+ pContext->win32.StringFromGUID2 = (ma_proc)ma_dlsym(pContext, pContext->win32.hOle32DLL, "StringFromGUID2");
/* User32.dll */
- pContext->win32.hUser32DLL = ma_dlopen("user32.dll");
+ pContext->win32.hUser32DLL = ma_dlopen(pContext, "user32.dll");
if (pContext->win32.hUser32DLL == NULL) {
return MA_FAILED_TO_INIT_BACKEND;
}
- pContext->win32.GetForegroundWindow = (ma_proc)ma_dlsym(pContext->win32.hUser32DLL, "GetForegroundWindow");
- pContext->win32.GetDesktopWindow = (ma_proc)ma_dlsym(pContext->win32.hUser32DLL, "GetDesktopWindow");
+ pContext->win32.GetForegroundWindow = (ma_proc)ma_dlsym(pContext, pContext->win32.hUser32DLL, "GetForegroundWindow");
+ pContext->win32.GetDesktopWindow = (ma_proc)ma_dlsym(pContext, pContext->win32.hUser32DLL, "GetDesktopWindow");
/* Advapi32.dll */
- pContext->win32.hAdvapi32DLL = ma_dlopen("advapi32.dll");
+ pContext->win32.hAdvapi32DLL = ma_dlopen(pContext, "advapi32.dll");
if (pContext->win32.hAdvapi32DLL == NULL) {
return MA_FAILED_TO_INIT_BACKEND;
}
- pContext->win32.RegOpenKeyExA = (ma_proc)ma_dlsym(pContext->win32.hAdvapi32DLL, "RegOpenKeyExA");
- pContext->win32.RegCloseKey = (ma_proc)ma_dlsym(pContext->win32.hAdvapi32DLL, "RegCloseKey");
- pContext->win32.RegQueryValueExA = (ma_proc)ma_dlsym(pContext->win32.hAdvapi32DLL, "RegQueryValueExA");
+ pContext->win32.RegOpenKeyExA = (ma_proc)ma_dlsym(pContext, pContext->win32.hAdvapi32DLL, "RegOpenKeyExA");
+ pContext->win32.RegCloseKey = (ma_proc)ma_dlsym(pContext, pContext->win32.hAdvapi32DLL, "RegCloseKey");
+ pContext->win32.RegQueryValueExA = (ma_proc)ma_dlsym(pContext, pContext->win32.hAdvapi32DLL, "RegQueryValueExA");
#endif
ma_CoInitializeEx(pContext, NULL, MA_COINIT_VALUE);
@@ -23646,7 +23808,7 @@ ma_result ma_context_init_backend_apis__win32(ma_context* pContext)
ma_result ma_context_uninit_backend_apis__nix(ma_context* pContext)
{
#if defined(MA_USE_RUNTIME_LINKING_FOR_PTHREAD) && !defined(MA_NO_RUNTIME_LINKING)
- ma_dlclose(pContext->posix.pthreadSO);
+ ma_dlclose(pContext, pContext->posix.pthreadSO);
#else
(void)pContext;
#endif
@@ -23666,7 +23828,7 @@ ma_result ma_context_init_backend_apis__nix(ma_context* pContext)
size_t i;
for (i = 0; i < sizeof(libpthreadFileNames) / sizeof(libpthreadFileNames[0]); ++i) {
- pContext->posix.pthreadSO = ma_dlopen(libpthreadFileNames[i]);
+ pContext->posix.pthreadSO = ma_dlopen(pContext, libpthreadFileNames[i]);
if (pContext->posix.pthreadSO != NULL) {
break;
}
@@ -23676,21 +23838,21 @@ ma_result ma_context_init_backend_apis__nix(ma_context* pContext)
return MA_FAILED_TO_INIT_BACKEND;
}
- pContext->posix.pthread_create = (ma_proc)ma_dlsym(pContext->posix.pthreadSO, "pthread_create");
- pContext->posix.pthread_join = (ma_proc)ma_dlsym(pContext->posix.pthreadSO, "pthread_join");
- pContext->posix.pthread_mutex_init = (ma_proc)ma_dlsym(pContext->posix.pthreadSO, "pthread_mutex_init");
- pContext->posix.pthread_mutex_destroy = (ma_proc)ma_dlsym(pContext->posix.pthreadSO, "pthread_mutex_destroy");
- pContext->posix.pthread_mutex_lock = (ma_proc)ma_dlsym(pContext->posix.pthreadSO, "pthread_mutex_lock");
- pContext->posix.pthread_mutex_unlock = (ma_proc)ma_dlsym(pContext->posix.pthreadSO, "pthread_mutex_unlock");
- pContext->posix.pthread_cond_init = (ma_proc)ma_dlsym(pContext->posix.pthreadSO, "pthread_cond_init");
- pContext->posix.pthread_cond_destroy = (ma_proc)ma_dlsym(pContext->posix.pthreadSO, "pthread_cond_destroy");
- pContext->posix.pthread_cond_wait = (ma_proc)ma_dlsym(pContext->posix.pthreadSO, "pthread_cond_wait");
- pContext->posix.pthread_cond_signal = (ma_proc)ma_dlsym(pContext->posix.pthreadSO, "pthread_cond_signal");
- pContext->posix.pthread_attr_init = (ma_proc)ma_dlsym(pContext->posix.pthreadSO, "pthread_attr_init");
- pContext->posix.pthread_attr_destroy = (ma_proc)ma_dlsym(pContext->posix.pthreadSO, "pthread_attr_destroy");
- pContext->posix.pthread_attr_setschedpolicy = (ma_proc)ma_dlsym(pContext->posix.pthreadSO, "pthread_attr_setschedpolicy");
- pContext->posix.pthread_attr_getschedparam = (ma_proc)ma_dlsym(pContext->posix.pthreadSO, "pthread_attr_getschedparam");
- pContext->posix.pthread_attr_setschedparam = (ma_proc)ma_dlsym(pContext->posix.pthreadSO, "pthread_attr_setschedparam");
+ pContext->posix.pthread_create = (ma_proc)ma_dlsym(pContext, pContext->posix.pthreadSO, "pthread_create");
+ pContext->posix.pthread_join = (ma_proc)ma_dlsym(pContext, pContext->posix.pthreadSO, "pthread_join");
+ pContext->posix.pthread_mutex_init = (ma_proc)ma_dlsym(pContext, pContext->posix.pthreadSO, "pthread_mutex_init");
+ pContext->posix.pthread_mutex_destroy = (ma_proc)ma_dlsym(pContext, pContext->posix.pthreadSO, "pthread_mutex_destroy");
+ pContext->posix.pthread_mutex_lock = (ma_proc)ma_dlsym(pContext, pContext->posix.pthreadSO, "pthread_mutex_lock");
+ pContext->posix.pthread_mutex_unlock = (ma_proc)ma_dlsym(pContext, pContext->posix.pthreadSO, "pthread_mutex_unlock");
+ pContext->posix.pthread_cond_init = (ma_proc)ma_dlsym(pContext, pContext->posix.pthreadSO, "pthread_cond_init");
+ pContext->posix.pthread_cond_destroy = (ma_proc)ma_dlsym(pContext, pContext->posix.pthreadSO, "pthread_cond_destroy");
+ pContext->posix.pthread_cond_wait = (ma_proc)ma_dlsym(pContext, pContext->posix.pthreadSO, "pthread_cond_wait");
+ pContext->posix.pthread_cond_signal = (ma_proc)ma_dlsym(pContext, pContext->posix.pthreadSO, "pthread_cond_signal");
+ pContext->posix.pthread_attr_init = (ma_proc)ma_dlsym(pContext, pContext->posix.pthreadSO, "pthread_attr_init");
+ pContext->posix.pthread_attr_destroy = (ma_proc)ma_dlsym(pContext, pContext->posix.pthreadSO, "pthread_attr_destroy");
+ pContext->posix.pthread_attr_setschedpolicy = (ma_proc)ma_dlsym(pContext, pContext->posix.pthreadSO, "pthread_attr_setschedpolicy");
+ pContext->posix.pthread_attr_getschedparam = (ma_proc)ma_dlsym(pContext, pContext->posix.pthreadSO, "pthread_attr_getschedparam");
+ pContext->posix.pthread_attr_setschedparam = (ma_proc)ma_dlsym(pContext, pContext->posix.pthreadSO, "pthread_attr_setschedparam");
#else
pContext->posix.pthread_create = (ma_proc)pthread_create;
pContext->posix.pthread_join = (ma_proc)pthread_join;
@@ -24431,13 +24593,8 @@ ma_result ma_device_start(ma_device* pDevice)
return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "ma_device_start() called for an uninitialized device.", MA_DEVICE_NOT_INITIALIZED);
}
- /*
- Starting the device doesn't do anything in synchronous mode because in that case it's started automatically with
- ma_device_write() and ma_device_read(). It's best to return an error so that the application can be aware that
- it's not doing it right.
- */
- if (!ma_device__is_async(pDevice)) {
- return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "ma_device_start() called in synchronous mode. This should only be used in asynchronous/callback mode.", MA_DEVICE_NOT_INITIALIZED);
+ if (ma_device__get_state(pDevice) == MA_STATE_STARTED) {
+ return ma_post_error(pDevice, MA_LOG_LEVEL_WARNING, "ma_device_start() called when the device is already started.", MA_INVALID_OPERATION); /* Already started. Returning an error to let the application know because it probably means they're doing something wrong. */
}
result = MA_ERROR;
@@ -24486,14 +24643,8 @@ ma_result ma_device_stop(ma_device* pDevice)
return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "ma_device_stop() called for an uninitialized device.", MA_DEVICE_NOT_INITIALIZED);
}
- /*
- Stopping is slightly different for synchronous mode. In this case it just tells the driver to stop the internal processing of the device. Also,
- stopping in synchronous mode does not require state checking.
- */
- if (!ma_device__is_async(pDevice)) {
- if (pDevice->pContext->onDeviceStop) {
- return pDevice->pContext->onDeviceStop(pDevice);
- }
+ if (ma_device__get_state(pDevice) == MA_STATE_STOPPED) {
+ return ma_post_error(pDevice, MA_LOG_LEVEL_WARNING, "ma_device_stop() called when the device is already stopped.", MA_INVALID_OPERATION); /* Already stopped. Returning an error to let the application know because it probably means they're doing something wrong. */
}
result = MA_ERROR;
@@ -29347,8 +29498,8 @@ static MA_INLINE float32x4_t ma_src_sinc__interpolation_factor__neon(const ma_sr
{
float32x4_t xabs;
int32x4_t ixabs;
- float32x4_t a;
- float32x4_t r;
+ float32x4_t a
+ float32x4_t r
int* ixabsv;
float lo[4];
float hi[4];
@@ -30470,7 +30621,7 @@ ma_uint64 ma_convert_frames_ex(void* pOut, ma_format formatOut, ma_uint32 channe
*/
totalFramesRead = ma_pcm_converter_read(&converter, pOut, frameCountOut);
if (totalFramesRead < frameCountOut) {
- ma_uint32 bpf = ma_get_bytes_per_frame(formatIn, channelsIn);
+ ma_uint32 bpfOut = ma_get_bytes_per_frame(formatOut, channelsOut);
data.isFeedingZeros = MA_TRUE;
data.totalFrameCount = ((ma_uint64)0xFFFFFFFF << 32) | 0xFFFFFFFF; /* C89 does not support 64-bit constants so need to instead construct it like this. Annoying... */ /*data.totalFrameCount = 0xFFFFFFFFFFFFFFFF;*/
@@ -30483,7 +30634,7 @@ ma_uint64 ma_convert_frames_ex(void* pOut, ma_format formatOut, ma_uint32 channe
framesToRead = (frameCountOut - totalFramesRead);
ma_assert(framesToRead > 0);
- framesJustRead = ma_pcm_converter_read(&converter, ma_offset_ptr(pOut, totalFramesRead * bpf), framesToRead);
+ framesJustRead = ma_pcm_converter_read(&converter, ma_offset_ptr(pOut, totalFramesRead * bpfOut), framesToRead);
totalFramesRead += framesJustRead;
if (framesJustRead < framesToRead) {
@@ -30493,7 +30644,7 @@ ma_uint64 ma_convert_frames_ex(void* pOut, ma_format formatOut, ma_uint32 channe
/* At this point we should have output every sample, but just to be super duper sure, just fill the rest with zeros. */
if (totalFramesRead < frameCountOut) {
- ma_zero_memory_64(ma_offset_ptr(pOut, totalFramesRead * bpf), ((frameCountOut - totalFramesRead) * bpf));
+ ma_zero_memory_64(ma_offset_ptr(pOut, totalFramesRead * bpfOut), ((frameCountOut - totalFramesRead) * bpfOut));
totalFramesRead = frameCountOut;
}
}
@@ -31395,6 +31546,11 @@ ma_result ma_decoder_internal_on_uninit__wav(ma_decoder* pDecoder)
return MA_SUCCESS;
}
+ma_uint64 ma_decoder_internal_on_get_length_in_pcm_frames__wav(ma_decoder* pDecoder)
+{
+ return ((drwav*)pDecoder->pInternalDecoder)->totalPCMFrameCount;
+}
+
ma_result ma_decoder_init_wav__internal(const ma_decoder_config* pConfig, ma_decoder* pDecoder)
{
drwav* pWav;
@@ -31412,6 +31568,7 @@ ma_result ma_decoder_init_wav__internal(const ma_decoder_config* pConfig, ma_dec
/* If we get here it means we successfully initialized the WAV decoder. We can now initialize the rest of the ma_decoder. */
pDecoder->onSeekToPCMFrame = ma_decoder_internal_on_seek_to_pcm_frame__wav;
pDecoder->onUninit = ma_decoder_internal_on_uninit__wav;
+ pDecoder->onGetLengthInPCMFrames = ma_decoder_internal_on_get_length_in_pcm_frames__wav;
pDecoder->pInternalDecoder = pWav;
/* Try to be as optimal as possible for the internal format. If miniaudio does not support a format we will fall back to f32. */
@@ -31529,6 +31686,11 @@ ma_result ma_decoder_internal_on_uninit__flac(ma_decoder* pDecoder)
return MA_SUCCESS;
}
+ma_uint64 ma_decoder_internal_on_get_length_in_pcm_frames__flac(ma_decoder* pDecoder)
+{
+ return ((drflac*)pDecoder->pInternalDecoder)->totalPCMFrameCount;
+}
+
ma_result ma_decoder_init_flac__internal(const ma_decoder_config* pConfig, ma_decoder* pDecoder)
{
drflac* pFlac;
@@ -31546,6 +31708,7 @@ ma_result ma_decoder_init_flac__internal(const ma_decoder_config* pConfig, ma_de
/* If we get here it means we successfully initialized the FLAC decoder. We can now initialize the rest of the ma_decoder. */
pDecoder->onSeekToPCMFrame = ma_decoder_internal_on_seek_to_pcm_frame__flac;
pDecoder->onUninit = ma_decoder_internal_on_uninit__flac;
+ pDecoder->onGetLengthInPCMFrames = ma_decoder_internal_on_get_length_in_pcm_frames__flac;
pDecoder->pInternalDecoder = pFlac;
/*
@@ -31754,6 +31917,13 @@ ma_uint32 ma_decoder_internal_on_read_pcm_frames__vorbis(ma_pcm_converter* pDSP,
return ma_vorbis_decoder_read_pcm_frames(pVorbis, pDecoder, pSamplesOut, frameCount);
}
+ma_uint64 ma_decoder_internal_on_get_length_in_pcm_frames__vorbis(ma_decoder* pDecoder)
+{
+ /* No good way to do this with Vorbis. */
+ (void)pDecoder;
+ return 0;
+}
+
ma_result ma_decoder_init_vorbis__internal(const ma_decoder_config* pConfig, ma_decoder* pDecoder)
{
ma_result result;
@@ -31847,6 +32017,7 @@ ma_result ma_decoder_init_vorbis__internal(const ma_decoder_config* pConfig, ma_
pDecoder->onSeekToPCMFrame = ma_decoder_internal_on_seek_to_pcm_frame__vorbis;
pDecoder->onUninit = ma_decoder_internal_on_uninit__vorbis;
+ pDecoder->onGetLengthInPCMFrames = ma_decoder_internal_on_get_length_in_pcm_frames__vorbis;
pDecoder->pInternalDecoder = pVorbis;
/* The internal format is always f32. */
@@ -31927,6 +32098,11 @@ ma_result ma_decoder_internal_on_uninit__mp3(ma_decoder* pDecoder)
return MA_SUCCESS;
}
+ma_uint64 ma_decoder_internal_on_get_length_in_pcm_frames__mp3(ma_decoder* pDecoder)
+{
+ return drmp3_get_pcm_frame_count((drmp3*)pDecoder->pInternalDecoder);
+}
+
ma_result ma_decoder_init_mp3__internal(const ma_decoder_config* pConfig, ma_decoder* pDecoder)
{
drmp3* pMP3;
@@ -31962,6 +32138,7 @@ ma_result ma_decoder_init_mp3__internal(const ma_decoder_config* pConfig, ma_dec
/* If we get here it means we successfully initialized the MP3 decoder. We can now initialize the rest of the ma_decoder. */
pDecoder->onSeekToPCMFrame = ma_decoder_internal_on_seek_to_pcm_frame__mp3;
pDecoder->onUninit = ma_decoder_internal_on_uninit__mp3;
+ pDecoder->onGetLengthInPCMFrames = ma_decoder_internal_on_get_length_in_pcm_frames__mp3;
pDecoder->pInternalDecoder = pMP3;
/* Internal format. */
@@ -32047,6 +32224,12 @@ ma_result ma_decoder_internal_on_uninit__raw(ma_decoder* pDecoder)
return MA_SUCCESS;
}
+ma_uint64 ma_decoder_internal_on_get_length_in_pcm_frames__raw(ma_decoder* pDecoder)
+{
+ (void)pDecoder;
+ return 0;
+}
+
ma_result ma_decoder_init_raw__internal(const ma_decoder_config* pConfigIn, const ma_decoder_config* pConfigOut, ma_decoder* pDecoder)
{
ma_result result;
@@ -32057,6 +32240,7 @@ ma_result ma_decoder_init_raw__internal(const ma_decoder_config* pConfigIn, cons
pDecoder->onSeekToPCMFrame = ma_decoder_internal_on_seek_to_pcm_frame__raw;
pDecoder->onUninit = ma_decoder_internal_on_uninit__raw;
+ pDecoder->onGetLengthInPCMFrames = ma_decoder_internal_on_get_length_in_pcm_frames__raw;
/* Internal format. */
pDecoder->internalFormat = pConfigIn->format;
@@ -32431,6 +32615,7 @@ ma_result ma_decoder_init_memory_raw(const void* pData, size_t dataSize, const m
#include <stdio.h>
#if !defined(_MSC_VER) && !defined(__DMC__)
#include <strings.h> /* For strcasecmp(). */
+#include <wchar.h> /* For wcsrtombs() */
#endif
const char* ma_path_file_name(const char* path)
@@ -32460,6 +32645,34 @@ const char* ma_path_file_name(const char* path)
return fileName;
}
+const wchar_t* ma_path_file_name_w(const wchar_t* path)
+{
+ const wchar_t* fileName;
+
+ if (path == NULL) {
+ return NULL;
+ }
+
+ fileName = path;
+
+ /* We just loop through the path until we find the last slash. */
+ while (path[0] != '\0') {
+ if (path[0] == '/' || path[0] == '\\') {
+ fileName = path;
+ }
+
+ path += 1;
+ }
+
+ /* At this point the file name is sitting on a slash, so just move forward. */
+ while (fileName[0] != '\0' && (fileName[0] == '/' || fileName[0] == '\\')) {
+ fileName += 1;
+ }
+
+ return fileName;
+}
+
+
const char* ma_path_extension(const char* path)
{
const char* extension;
@@ -32485,6 +32698,32 @@ const char* ma_path_extension(const char* path)
return (lastOccurance != NULL) ? lastOccurance : extension;
}
+const wchar_t* ma_path_extension_w(const wchar_t* path)
+{
+ const wchar_t* extension;
+ const wchar_t* lastOccurance;
+
+ if (path == NULL) {
+ path = L"";
+ }
+
+ extension = ma_path_file_name_w(path);
+ lastOccurance = NULL;
+
+ /* Just find the last '.' and return. */
+ while (extension[0] != '\0') {
+ if (extension[0] == '.') {
+ extension += 1;
+ lastOccurance = extension;
+ }
+
+ extension += 1;
+ }
+
+ return (lastOccurance != NULL) ? lastOccurance : extension;
+}
+
+
ma_bool32 ma_path_extension_equal(const char* path, const char* extension)
{
const char* ext1;
@@ -32504,6 +32743,49 @@ ma_bool32 ma_path_extension_equal(const char* path, const char* extension)
#endif
}
+ma_bool32 ma_path_extension_equal_w(const wchar_t* path, const wchar_t* extension)
+{
+ const wchar_t* ext1;
+ const wchar_t* ext2;
+
+ if (path == NULL || extension == NULL) {
+ return MA_FALSE;
+ }
+
+ ext1 = extension;
+ ext2 = ma_path_extension_w(path);
+
+#if defined(_MSC_VER) || defined(__DMC__)
+ return _wcsicmp(ext1, ext2) == 0;
+#else
+ /*
+ I'm not aware of a wide character version of strcasecmp(). I'm therefore converting the extensions to multibyte strings and comparing those. This
+ isn't the most efficient way to do it, but it should work OK.
+ */
+ {
+ char ext1MB[4096];
+ char ext2MB[4096];
+ const wchar_t* pext1 = ext1;
+ const wchar_t* pext2 = ext2;
+ mbstate_t mbs1;
+ mbstate_t mbs2;
+
+ ma_zero_object(&mbs1);
+ ma_zero_object(&mbs2);
+
+ if (wcsrtombs(ext1MB, &pext1, sizeof(ext1MB), &mbs1) == (size_t)-1) {
+ return MA_FALSE;
+ }
+ if (wcsrtombs(ext2MB, &pext2, sizeof(ext2MB), &mbs2) == (size_t)-1) {
+ return MA_FALSE;
+ }
+
+ return strcasecmp(ext1MB, ext2MB) == 0;
+ }
+#endif
+}
+
+
size_t ma_decoder__on_read_stdio(ma_decoder* pDecoder, void* pBufferOut, size_t bytesToRead)
{
return fread(pBufferOut, 1, bytesToRead, (FILE*)pDecoder->pUserData);
@@ -32546,6 +32828,77 @@ ma_result ma_decoder__preinit_file(const char* pFilePath, const ma_decoder_confi
return MA_SUCCESS;
}
+ma_result ma_decoder__preinit_file_w(const wchar_t* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder)
+{
+ FILE* pFile;
+
+ if (pDecoder == NULL) {
+ return MA_INVALID_ARGS;
+ }
+
+ ma_zero_object(pDecoder);
+
+ if (pFilePath == NULL || pFilePath[0] == '\0') {
+ return MA_INVALID_ARGS;
+ }
+
+#if defined(_WIN32)
+ /* Use _wfopen() on Windows. */
+ #if defined(_MSC_VER) && _MSC_VER >= 1400
+ if (_wfopen_s(&pFile, pFilePath, L"rb") != 0) {
+ return MA_ERROR;
+ }
+ #else
+ pFile = _wfopen(pFilePath, L"rb");
+ if (pFile == NULL) {
+ return MA_ERROR;
+ }
+ #endif
+#else
+ /*
+ Use fopen() on anything other than Windows. Requires a conversion. This is annoying because fopen() is locale specific. The only real way I can
+ think of to do this is with wcsrtombs(). Note that wcstombs() is apparently not thread-safe because it uses a static global mbstate_t object for
+ maintaining state. I've checked this with -std=c89 and it works, but if somebody get's a compiler error I'll look into improving compatibility.
+ */
+ {
+ mbstate_t mbs;
+ size_t lenMB;
+ const wchar_t* pFilePathTemp = pFilePath;
+ char* pFilePathMB = NULL;
+
+ /* Get the length first. */
+ ma_zero_object(&mbs);
+ lenMB = wcsrtombs(NULL, &pFilePathTemp, 0, &mbs);
+ if (lenMB == (size_t)-1) {
+ return MA_ERROR;
+ }
+
+ pFilePathMB = (char*)MA_MALLOC(lenMB + 1);
+ if (pFilePathMB == NULL) {
+ return MA_OUT_OF_MEMORY;
+ }
+
+ pFilePathTemp = pFilePath;
+ ma_zero_object(&mbs);
+ wcsrtombs(pFilePathMB, &pFilePathTemp, lenMB + 1, &mbs);
+
+ pFile = fopen(pFilePathMB, "rb");
+
+ MA_FREE(pFilePathMB);
+ }
+
+ if (pFile == NULL) {
+ return MA_ERROR;
+ }
+#endif
+
+ /* We need to manually set the user data so the calls to ma_decoder__on_seek_stdio() succeed. */
+ pDecoder->pUserData = pFile;
+
+ (void)pConfig;
+ return MA_SUCCESS;
+}
+
ma_result ma_decoder_init_file(const char* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder)
{
ma_result result = ma_decoder__preinit_file(pFilePath, pConfig, pDecoder); /* This sets pDecoder->pUserData to a FILE*. */
@@ -32626,6 +32979,88 @@ ma_result ma_decoder_init_file_mp3(const char* pFilePath, const ma_decoder_confi
return ma_decoder_init_mp3(ma_decoder__on_read_stdio, ma_decoder__on_seek_stdio, pDecoder->pUserData, pConfig, pDecoder);
}
+
+
+ma_result ma_decoder_init_file_w(const wchar_t* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder)
+{
+ ma_result result = ma_decoder__preinit_file_w(pFilePath, pConfig, pDecoder); /* This sets pDecoder->pUserData to a FILE*. */
+ if (result != MA_SUCCESS) {
+ return result;
+ }
+
+ /* WAV */
+ if (ma_path_extension_equal_w(pFilePath, L"wav")) {
+ result = ma_decoder_init_wav(ma_decoder__on_read_stdio, ma_decoder__on_seek_stdio, pDecoder->pUserData, pConfig, pDecoder);
+ if (result == MA_SUCCESS) {
+ return MA_SUCCESS;
+ }
+
+ ma_decoder__on_seek_stdio(pDecoder, 0, ma_seek_origin_start);
+ }
+
+ /* FLAC */
+ if (ma_path_extension_equal_w(pFilePath, L"flac")) {
+ result = ma_decoder_init_flac(ma_decoder__on_read_stdio, ma_decoder__on_seek_stdio, pDecoder->pUserData, pConfig, pDecoder);
+ if (result == MA_SUCCESS) {
+ return MA_SUCCESS;
+ }
+
+ ma_decoder__on_seek_stdio(pDecoder, 0, ma_seek_origin_start);
+ }
+
+ /* MP3 */
+ if (ma_path_extension_equal_w(pFilePath, L"mp3")) {
+ result = ma_decoder_init_mp3(ma_decoder__on_read_stdio, ma_decoder__on_seek_stdio, pDecoder->pUserData, pConfig, pDecoder);
+ if (result == MA_SUCCESS) {
+ return MA_SUCCESS;
+ }
+
+ ma_decoder__on_seek_stdio(pDecoder, 0, ma_seek_origin_start);
+ }
+
+ /* Trial and error. */
+ return ma_decoder_init(ma_decoder__on_read_stdio, ma_decoder__on_seek_stdio, pDecoder->pUserData, pConfig, pDecoder);
+}
+
+ma_result ma_decoder_init_file_wav_w(const wchar_t* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder)
+{
+ ma_result result = ma_decoder__preinit_file_w(pFilePath, pConfig, pDecoder);
+ if (result != MA_SUCCESS) {
+ return result;
+ }
+
+ return ma_decoder_init_wav(ma_decoder__on_read_stdio, ma_decoder__on_seek_stdio, pDecoder->pUserData, pConfig, pDecoder);
+}
+
+ma_result ma_decoder_init_file_flac_w(const wchar_t* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder)
+{
+ ma_result result = ma_decoder__preinit_file_w(pFilePath, pConfig, pDecoder);
+ if (result != MA_SUCCESS) {
+ return result;
+ }
+
+ return ma_decoder_init_flac(ma_decoder__on_read_stdio, ma_decoder__on_seek_stdio, pDecoder->pUserData, pConfig, pDecoder);
+}
+
+ma_result ma_decoder_init_file_vorbis_w(const wchar_t* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder)
+{
+ ma_result result = ma_decoder__preinit_file_w(pFilePath, pConfig, pDecoder);
+ if (result != MA_SUCCESS) {
+ return result;
+ }
+
+ return ma_decoder_init_vorbis(ma_decoder__on_read_stdio, ma_decoder__on_seek_stdio, pDecoder->pUserData, pConfig, pDecoder);
+}
+
+ma_result ma_decoder_init_file_mp3_w(const wchar_t* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder)
+{
+ ma_result result = ma_decoder__preinit_file_w(pFilePath, pConfig, pDecoder);
+ if (result != MA_SUCCESS) {
+ return result;
+ }
+
+ return ma_decoder_init_mp3(ma_decoder__on_read_stdio, ma_decoder__on_seek_stdio, pDecoder->pUserData, pConfig, pDecoder);
+}
#endif
ma_result ma_decoder_uninit(ma_decoder* pDecoder)
@@ -32648,6 +33083,19 @@ ma_result ma_decoder_uninit(ma_decoder* pDecoder)
return MA_SUCCESS;
}
+ma_uint64 ma_decoder_get_length_in_pcm_frames(ma_decoder* pDecoder)
+{
+ if (pDecoder == NULL) {
+ return 0;
+ }
+
+ if (pDecoder->onGetLengthInPCMFrames) {
+ return pDecoder->onGetLengthInPCMFrames(pDecoder);
+ }
+
+ return 0;
+}
+
ma_uint64 ma_decoder_read_pcm_frames(ma_decoder* pDecoder, void* pFramesOut, ma_uint64 frameCount)
{
if (pDecoder == NULL) {
@@ -32913,6 +33361,21 @@ Device
/*
REVISION HISTORY
================
+v0.9.6 - 2019-xx-xx
+ - Add support for loading decoders using a wchar_t string for file paths.
+ - Don't trigger an assert when ma_device_start() is called on a device that is already started. This will now log a warning
+ and return MA_INVALID_OPERATION. The same applies for ma_device_stop().
+ - Try fixing an issue with PulseAudio taking a long time to start playback.
+ - Fix a bug in ma_convert_frames() and ma_convert_frames_ex().
+ - Fix memory leaks in the WASAPI backend.
+ - Fix a compilation error with Visual Studio 2010.
+
+v0.9.5 - 2019-05-21
+ - Add logging to ma_dlopen() and ma_dlsym().
+ - Add ma_decoder_get_length_in_pcm_frames().
+ - Fix a bug with capture on the OpenSL|ES backend.
+ - Fix a bug with the ALSA backend where a device would not restart after being stopped.
+
v0.9.4 - 2019-05-06
- Add support for C89. With this change, miniaudio should compile clean with GCC/Clang with "-std=c89 -ansi -pedantic" and
Microsoft compilers back to VC6. Other compilers should also work, but have not been tested.