11/*
22Audio playback and capture library. Choice of public domain or MIT-0. See license statements at the end of this file.
3- miniaudio - v0.11.15 - 2023-04-30
3+ miniaudio - v0.11.16 - 2023-05-15
44
5566
@@ -3722,7 +3722,7 @@ extern "C" {
37223722
37233723#define MA_VERSION_MAJOR 0
37243724#define MA_VERSION_MINOR 11
3725- #define MA_VERSION_REVISION 15
3725+ #define MA_VERSION_REVISION 16
37263726#define MA_VERSION_STRING MA_XSTRINGIFY(MA_VERSION_MAJOR) "." MA_XSTRINGIFY(MA_VERSION_MINOR) "." MA_XSTRINGIFY(MA_VERSION_REVISION)
37273727
37283728#if defined(_MSC_VER) && !defined(__clang__)
@@ -18455,22 +18455,22 @@ MA_API ma_handle ma_dlopen(ma_context* pContext, const char* filename)
1845518455
1845618456 ma_log_postf(ma_context_get_log(pContext), MA_LOG_LEVEL_DEBUG, "Loading library: %s\n", filename);
1845718457
18458- #ifdef _WIN32
18459- /* From MSDN: Desktop applications cannot use LoadPackagedLibrary; if a desktop application calls this function it fails with APPMODEL_ERROR_NO_PACKAGE.*/
18460- #if !defined(WINAPI_FAMILY) || (defined(WINAPI_FAMILY) && (defined(WINAPI_FAMILY_DESKTOP_APP) && WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP))
18461- handle = (ma_handle)LoadLibraryA(filename);
18458+ #ifdef MA_WIN32
18459+ /* From MSDN: Desktop applications cannot use LoadPackagedLibrary; if a desktop application calls this function it fails with APPMODEL_ERROR_NO_PACKAGE.*/
18460+ #if !defined(MA_WIN32_UWP)
18461+ handle = (ma_handle)LoadLibraryA(filename);
18462+ #else
18463+ /* *sigh* It appears there is no ANSI version of LoadPackagedLibrary()... */
18464+ WCHAR filenameW[4096];
18465+ if (MultiByteToWideChar(CP_UTF8, 0, filename, -1, filenameW, sizeof(filenameW)) == 0) {
18466+ handle = NULL;
18467+ } else {
18468+ handle = (ma_handle)LoadPackagedLibrary(filenameW, 0);
18469+ }
18470+ #endif
1846218471 #else
18463- /* *sigh* It appears there is no ANSI version of LoadPackagedLibrary()... */
18464- WCHAR filenameW[4096];
18465- if (MultiByteToWideChar(CP_UTF8, 0, filename, -1, filenameW, sizeof(filenameW)) == 0) {
18466- handle = NULL;
18467- } else {
18468- handle = (ma_handle)LoadPackagedLibrary(filenameW, 0);
18469- }
18472+ handle = (ma_handle)dlopen(filename, RTLD_NOW);
1847018473 #endif
18471- #else
18472- handle = (ma_handle)dlopen(filename, RTLD_NOW);
18473- #endif
1847418474
1847518475 /*
1847618476 I'm not considering failure to load a library an error nor a warning because seamlessly falling through to a lower-priority
@@ -18493,11 +18493,11 @@ MA_API ma_handle ma_dlopen(ma_context* pContext, const char* filename)
1849318493MA_API void ma_dlclose(ma_context* pContext, ma_handle handle)
1849418494{
1849518495#ifndef MA_NO_RUNTIME_LINKING
18496- #ifdef _WIN32
18497- FreeLibrary((HMODULE)handle);
18498- #else
18499- dlclose((void*)handle);
18500- #endif
18496+ #ifdef MA_WIN32
18497+ FreeLibrary((HMODULE)handle);
18498+ #else
18499+ dlclose((void*)handle);
18500+ #endif
1850118501
1850218502 (void)pContext;
1850318503#else
@@ -19820,7 +19820,7 @@ WIN32 COMMON
1982019820
1982119821*******************************************************************************/
1982219822#if defined(MA_WIN32)
19823- #if defined(MA_WIN32_DESKTOP)
19823+ #if defined(MA_WIN32_DESKTOP) || defined(MA_WIN32_GDK)
1982419824 #define ma_CoInitializeEx(pContext, pvReserved, dwCoInit) ((pContext->win32.CoInitializeEx) ? ((MA_PFN_CoInitializeEx)pContext->win32.CoInitializeEx)(pvReserved, dwCoInit) : ((MA_PFN_CoInitialize)pContext->win32.CoInitialize)(pvReserved))
1982519825 #define ma_CoUninitialize(pContext) ((MA_PFN_CoUninitialize)pContext->win32.CoUninitialize)()
1982619826 #define ma_CoCreateInstance(pContext, rclsid, pUnkOuter, dwClsContext, riid, ppv) ((MA_PFN_CoCreateInstance)pContext->win32.CoCreateInstance)(rclsid, pUnkOuter, dwClsContext, riid, ppv)
@@ -20880,13 +20880,9 @@ static HRESULT STDMETHODCALLTYPE ma_IMMNotificationClient_OnDefaultDeviceChanged
2088020880 /*ma_log_postf(ma_device_get_log(pThis->pDevice), MA_LOG_LEVEL_DEBUG, "IMMNotificationClient_OnDefaultDeviceChanged(dataFlow=%d, role=%d, pDefaultDeviceID=%S)\n", dataFlow, role, (pDefaultDeviceID != NULL) ? pDefaultDeviceID : L"(NULL)");*/
2088120881#endif
2088220882
20883- /* We only ever use the eConsole role in miniaudio. */
20884- if (role != ma_eConsole) {
20885- ma_log_postf(ma_device_get_log(pThis->pDevice), MA_LOG_LEVEL_DEBUG, "[WASAPI] Stream rerouting: role != eConsole\n");
20886- return S_OK;
20887- }
20883+ (void)role;
2088820884
20889- /* We only care about devices with the same data flow and role as the current device. */
20885+ /* We only care about devices with the same data flow as the current device. */
2089020886 if ((pThis->pDevice->type == ma_device_type_playback && dataFlow != ma_eRender) ||
2089120887 (pThis->pDevice->type == ma_device_type_capture && dataFlow != ma_eCapture) ||
2089220888 (pThis->pDevice->type == ma_device_type_loopback && dataFlow != ma_eRender)) {
@@ -22931,7 +22927,7 @@ static ma_result ma_device_start__wasapi_nolock(ma_device* pDevice)
2293122927 if (pDevice->type == ma_device_type_capture || pDevice->type == ma_device_type_duplex || pDevice->type == ma_device_type_loopback) {
2293222928 hr = ma_IAudioClient_Start((ma_IAudioClient*)pDevice->wasapi.pAudioClientCapture);
2293322929 if (FAILED(hr)) {
22934- ma_log_post (ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to start internal capture device." );
22930+ ma_log_postf (ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to start internal capture device. HRESULT = %d.", (int)hr );
2293522931 return ma_result_from_HRESULT(hr);
2293622932 }
2293722933
@@ -22941,7 +22937,7 @@ static ma_result ma_device_start__wasapi_nolock(ma_device* pDevice)
2294122937 if (pDevice->type == ma_device_type_playback || pDevice->type == ma_device_type_duplex) {
2294222938 hr = ma_IAudioClient_Start((ma_IAudioClient*)pDevice->wasapi.pAudioClientPlayback);
2294322939 if (FAILED(hr)) {
22944- ma_log_post (ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to start internal playback device." );
22940+ ma_log_postf (ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to start internal playback device. HRESULT = %d.", (int)hr );
2294522941 return ma_result_from_HRESULT(hr);
2294622942 }
2294722943
@@ -40972,11 +40968,15 @@ static ma_bool32 ma_device__is_initialized(ma_device* pDevice)
4097240968static ma_result ma_context_uninit_backend_apis__win32(ma_context* pContext)
4097340969{
4097440970 /* For some reason UWP complains when CoUninitialize() is called. I'm just not going to call it on UWP. */
40975- #ifdef MA_WIN32_DESKTOP
40971+ #if defined( MA_WIN32_DESKTOP) || defined(MA_WIN32_GDK)
4097640972 ma_CoUninitialize(pContext);
40977- ma_dlclose(pContext, pContext->win32.hUser32DLL);
40973+
40974+ #if defined(MA_WIN32_DESKTOP)
40975+ ma_dlclose(pContext, pContext->win32.hUser32DLL);
40976+ ma_dlclose(pContext, pContext->win32.hAdvapi32DLL);
40977+ #endif
40978+
4097840979 ma_dlclose(pContext, pContext->win32.hOle32DLL);
40979- ma_dlclose(pContext, pContext->win32.hAdvapi32DLL);
4098040980#else
4098140981 (void)pContext;
4098240982#endif
@@ -40986,7 +40986,29 @@ static ma_result ma_context_uninit_backend_apis__win32(ma_context* pContext)
4098640986
4098740987static ma_result ma_context_init_backend_apis__win32(ma_context* pContext)
4098840988{
40989- #ifdef MA_WIN32_DESKTOP
40989+ #if defined(MA_WIN32_DESKTOP) || defined(MA_WIN32_GDK)
40990+ #if defined(MA_WIN32_DESKTOP)
40991+ /* User32.dll */
40992+ pContext->win32.hUser32DLL = ma_dlopen(pContext, "user32.dll");
40993+ if (pContext->win32.hUser32DLL == NULL) {
40994+ return MA_FAILED_TO_INIT_BACKEND;
40995+ }
40996+
40997+ pContext->win32.GetForegroundWindow = (ma_proc)ma_dlsym(pContext, pContext->win32.hUser32DLL, "GetForegroundWindow");
40998+ pContext->win32.GetDesktopWindow = (ma_proc)ma_dlsym(pContext, pContext->win32.hUser32DLL, "GetDesktopWindow");
40999+
41000+
41001+ /* Advapi32.dll */
41002+ pContext->win32.hAdvapi32DLL = ma_dlopen(pContext, "advapi32.dll");
41003+ if (pContext->win32.hAdvapi32DLL == NULL) {
41004+ return MA_FAILED_TO_INIT_BACKEND;
41005+ }
41006+
41007+ pContext->win32.RegOpenKeyExA = (ma_proc)ma_dlsym(pContext, pContext->win32.hAdvapi32DLL, "RegOpenKeyExA");
41008+ pContext->win32.RegCloseKey = (ma_proc)ma_dlsym(pContext, pContext->win32.hAdvapi32DLL, "RegCloseKey");
41009+ pContext->win32.RegQueryValueExA = (ma_proc)ma_dlsym(pContext, pContext->win32.hAdvapi32DLL, "RegQueryValueExA");
41010+ #endif
41011+
4099041012 /* Ole32.dll */
4099141013 pContext->win32.hOle32DLL = ma_dlopen(pContext, "ole32.dll");
4099241014 if (pContext->win32.hOle32DLL == NULL) {
@@ -41000,27 +41022,6 @@ static ma_result ma_context_init_backend_apis__win32(ma_context* pContext)
4100041022 pContext->win32.CoTaskMemFree = (ma_proc)ma_dlsym(pContext, pContext->win32.hOle32DLL, "CoTaskMemFree");
4100141023 pContext->win32.PropVariantClear = (ma_proc)ma_dlsym(pContext, pContext->win32.hOle32DLL, "PropVariantClear");
4100241024 pContext->win32.StringFromGUID2 = (ma_proc)ma_dlsym(pContext, pContext->win32.hOle32DLL, "StringFromGUID2");
41003-
41004-
41005- /* User32.dll */
41006- pContext->win32.hUser32DLL = ma_dlopen(pContext, "user32.dll");
41007- if (pContext->win32.hUser32DLL == NULL) {
41008- return MA_FAILED_TO_INIT_BACKEND;
41009- }
41010-
41011- pContext->win32.GetForegroundWindow = (ma_proc)ma_dlsym(pContext, pContext->win32.hUser32DLL, "GetForegroundWindow");
41012- pContext->win32.GetDesktopWindow = (ma_proc)ma_dlsym(pContext, pContext->win32.hUser32DLL, "GetDesktopWindow");
41013-
41014-
41015- /* Advapi32.dll */
41016- pContext->win32.hAdvapi32DLL = ma_dlopen(pContext, "advapi32.dll");
41017- if (pContext->win32.hAdvapi32DLL == NULL) {
41018- return MA_FAILED_TO_INIT_BACKEND;
41019- }
41020-
41021- pContext->win32.RegOpenKeyExA = (ma_proc)ma_dlsym(pContext, pContext->win32.hAdvapi32DLL, "RegOpenKeyExA");
41022- pContext->win32.RegCloseKey = (ma_proc)ma_dlsym(pContext, pContext->win32.hAdvapi32DLL, "RegCloseKey");
41023- pContext->win32.RegQueryValueExA = (ma_proc)ma_dlsym(pContext, pContext->win32.hAdvapi32DLL, "RegQueryValueExA");
4102441025#else
4102541026 (void)pContext; /* Unused. */
4102641027#endif
@@ -67937,7 +67938,12 @@ static ma_result ma_resource_manager_data_buffer_node_acquire_critical_section(m
6793767938 job.data.resourceManager.loadDataBufferNode.pInitFence = pInitFence;
6793867939 job.data.resourceManager.loadDataBufferNode.pDoneFence = pDoneFence;
6793967940
67940- result = ma_resource_manager_post_job(pResourceManager, &job);
67941+ if ((flags & MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_WAIT_INIT) != 0) {
67942+ result = ma_job_process(&job);
67943+ } else {
67944+ result = ma_resource_manager_post_job(pResourceManager, &job);
67945+ }
67946+
6794167947 if (result != MA_SUCCESS) {
6794267948 /* Failed to post job. Probably ran out of memory. */
6794367949 ma_log_postf(ma_resource_manager_get_log(pResourceManager), MA_LOG_LEVEL_ERROR, "Failed to post MA_JOB_TYPE_RESOURCE_MANAGER_LOAD_DATA_BUFFER_NODE job. %s.\n", ma_result_description(result));
@@ -67950,12 +67956,13 @@ static ma_result ma_resource_manager_data_buffer_node_acquire_critical_section(m
6795067956 if (pDoneFence != NULL) { ma_fence_release(pDoneFence); }
6795167957
6795267958 if ((flags & MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_WAIT_INIT) != 0) {
67953- ma_resource_manager_inline_notification_init(pResourceManager, pInitNotification);
67959+ ma_resource_manager_inline_notification_uninit(pInitNotification);
67960+ } else {
67961+ /* These will have been freed by the job thread, but with WAIT_INIT they will already have happend sinced the job has already been handled. */
67962+ ma_free(pFilePathCopy, &pResourceManager->config.allocationCallbacks);
67963+ ma_free(pFilePathWCopy, &pResourceManager->config.allocationCallbacks);
6795467964 }
6795567965
67956- ma_free(pFilePathCopy, &pResourceManager->config.allocationCallbacks);
67957- ma_free(pFilePathWCopy, &pResourceManager->config.allocationCallbacks);
67958-
6795967966 ma_resource_manager_data_buffer_node_remove(pResourceManager, pDataBufferNode);
6796067967 ma_free(pDataBufferNode, &pResourceManager->config.allocationCallbacks);
6796167968
@@ -68394,7 +68401,13 @@ static ma_result ma_resource_manager_data_buffer_init_ex_internal(ma_resource_ma
6839468401 job.data.resourceManager.loadDataBuffer.loopPointEndInPCMFrames = pConfig->loopPointEndInPCMFrames;
6839568402 job.data.resourceManager.loadDataBuffer.isLooping = pConfig->isLooping;
6839668403
68397- result = ma_resource_manager_post_job(pResourceManager, &job);
68404+ /* If we need to wait for initialization to complete we can just process the job in place. */
68405+ if ((flags & MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_WAIT_INIT) != 0) {
68406+ result = ma_job_process(&job);
68407+ } else {
68408+ result = ma_resource_manager_post_job(pResourceManager, &job);
68409+ }
68410+
6839868411 if (result != MA_SUCCESS) {
6839968412 /* We failed to post the job. Most likely there isn't enough room in the queue's buffer. */
6840068413 ma_log_postf(ma_resource_manager_get_log(pResourceManager), MA_LOG_LEVEL_ERROR, "Failed to post MA_JOB_TYPE_RESOURCE_MANAGER_LOAD_DATA_BUFFER job. %s.\n", ma_result_description(result));
@@ -70093,6 +70106,12 @@ static ma_result ma_job_process__resource_manager__load_data_buffer_node(ma_job*
7009370106
7009470107 /* Increment the node's execution pointer so that the next jobs can be processed. This is how we keep decoding of pages in-order. */
7009570108 c89atomic_fetch_add_32(&pDataBufferNode->executionPointer, 1);
70109+
70110+ /* A busy result should be considered successful from the point of view of the job system. */
70111+ if (result == MA_BUSY) {
70112+ result = MA_SUCCESS;
70113+ }
70114+
7009670115 return result;
7009770116}
7009870117
@@ -75444,7 +75463,7 @@ MA_API ma_result ma_sound_init_copy(ma_engine* pEngine, const ma_sound* pExistin
7544475463
7544575464 /*
7544675465 We need to make a clone of the data source. If the data source is not a data buffer (i.e. a stream)
75447- the this will fail.
75466+ this will fail.
7544875467 */
7544975468 pSound->pResourceManagerDataSource = (ma_resource_manager_data_source*)ma_malloc(sizeof(*pSound->pResourceManagerDataSource), &pEngine->allocationCallbacks);
7545075469 if (pSound->pResourceManagerDataSource == NULL) {
@@ -75472,6 +75491,9 @@ MA_API ma_result ma_sound_init_copy(ma_engine* pEngine, const ma_sound* pExistin
7547275491 return result;
7547375492 }
7547475493
75494+ /* Make sure the sound is marked as the owner of the data source or else it will never get uninitialized. */
75495+ pSound->ownsDataSource = MA_TRUE;
75496+
7547575497 return MA_SUCCESS;
7547675498}
7547775499#endif
0 commit comments