From eb0ce6f1a56d69835693f53e507f816df18ebf4e Mon Sep 17 00:00:00 2001 From: David Reid Date: Sat, 4 Nov 2023 08:43:16 +1000 Subject: [PATCH 1/3] Fix an error when dynamically linking when forcing the UWP build. This also fixes a possible crash during initialization due to leaving a thread running after early termination of the initialization routine. --- CHANGES.md | 5 ++ miniaudio.h | 74 +++++++++++++------------- tests/test_deviceio/ma_test_deviceio.c | 1 + 3 files changed, 42 insertions(+), 38 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 68adbf5c..9c976563 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,8 @@ +v0.11.20 - TBD +===================== +* Fix an error when dynamically linking libraries when forcing the UWP build on desktop. + + v0.11.19 - 2023-11-04 ===================== * Fix a bug where `ma_decoder_init_file()` can incorrectly return successfully. diff --git a/miniaudio.h b/miniaudio.h index b5a8771f..ca46c50c 100644 --- a/miniaudio.h +++ b/miniaudio.h @@ -1,6 +1,6 @@ /* Audio playback and capture library. Choice of public domain or MIT-0. See license statements at the end of this file. -miniaudio - v0.11.19 - 2023-11-04 +miniaudio - v0.11.20 - TBD David Reid - mackron@gmail.com @@ -3723,7 +3723,7 @@ extern "C" { #define MA_VERSION_MAJOR 0 #define MA_VERSION_MINOR 11 -#define MA_VERSION_REVISION 19 +#define MA_VERSION_REVISION 20 #define MA_VERSION_STRING MA_XSTRINGIFY(MA_VERSION_MAJOR) "." MA_XSTRINGIFY(MA_VERSION_MINOR) "." MA_XSTRINGIFY(MA_VERSION_REVISION) #if defined(_MSC_VER) && !defined(__clang__) @@ -17820,7 +17820,7 @@ MA_API ma_handle ma_dlopen(ma_log* pLog, const char* filename) #ifdef MA_WIN32 /* From MSDN: Desktop applications cannot use LoadPackagedLibrary; if a desktop application calls this function it fails with APPMODEL_ERROR_NO_PACKAGE.*/ - #if !defined(MA_WIN32_UWP) + #if !defined(MA_WIN32_UWP) || !(defined(WINAPI_FAMILY) && ((defined(WINAPI_FAMILY_PHONE_APP) && WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP))) handle = (ma_handle)LoadLibraryA(filename); #else /* *sigh* It appears there is no ANSI version of LoadPackagedLibrary()... */ @@ -23511,6 +23511,39 @@ static ma_result ma_context_init__wasapi(ma_context* pContext, const ma_context_ MA_ZERO_OBJECT(&pContext->wasapi); + + #if defined(MA_WIN32_UWP) + { + /* Link to mmdevapi so we can get access to ActivateAudioInterfaceAsync(). */ + pContext->wasapi.hMMDevapi = ma_dlopen(ma_context_get_log(pContext), "mmdevapi.dll"); + if (pContext->wasapi.hMMDevapi) { + pContext->wasapi.ActivateAudioInterfaceAsync = ma_dlsym(ma_context_get_log(pContext), pContext->wasapi.hMMDevapi, "ActivateAudioInterfaceAsync"); + if (pContext->wasapi.ActivateAudioInterfaceAsync == NULL) { + ma_dlclose(ma_context_get_log(pContext), pContext->wasapi.hMMDevapi); + return MA_NO_BACKEND; /* ActivateAudioInterfaceAsync() could not be loaded. */ + } + } else { + return MA_NO_BACKEND; /* Failed to load mmdevapi.dll which is required for ActivateAudioInterfaceAsync() */ + } + } + #endif + + /* Optionally use the Avrt API to specify the audio thread's latency sensitivity requirements */ + pContext->wasapi.hAvrt = ma_dlopen(ma_context_get_log(pContext), "avrt.dll"); + if (pContext->wasapi.hAvrt) { + pContext->wasapi.AvSetMmThreadCharacteristicsA = ma_dlsym(ma_context_get_log(pContext), pContext->wasapi.hAvrt, "AvSetMmThreadCharacteristicsA"); + pContext->wasapi.AvRevertMmThreadcharacteristics = ma_dlsym(ma_context_get_log(pContext), pContext->wasapi.hAvrt, "AvRevertMmThreadCharacteristics"); + + /* If either function could not be found, disable use of avrt entirely. */ + if (!pContext->wasapi.AvSetMmThreadCharacteristicsA || !pContext->wasapi.AvRevertMmThreadcharacteristics) { + pContext->wasapi.AvSetMmThreadCharacteristicsA = NULL; + pContext->wasapi.AvRevertMmThreadcharacteristics = NULL; + ma_dlclose(ma_context_get_log(pContext), pContext->wasapi.hAvrt); + pContext->wasapi.hAvrt = NULL; + } + } + + /* Annoyingly, WASAPI does not allow you to release an IAudioClient object from a different thread than the one that retrieved it with GetService(). This can result in a deadlock in two @@ -23554,41 +23587,6 @@ static ma_result ma_context_init__wasapi(ma_context* pContext, const ma_context_ ma_mutex_uninit(&pContext->wasapi.commandLock); return result; } - - #if defined(MA_WIN32_UWP) - { - /* Link to mmdevapi so we can get access to ActivateAudioInterfaceAsync(). */ - pContext->wasapi.hMMDevapi = ma_dlopen(ma_context_get_log(pContext), "mmdevapi.dll"); - if (pContext->wasapi.hMMDevapi) { - pContext->wasapi.ActivateAudioInterfaceAsync = ma_dlsym(ma_context_get_log(pContext), pContext->wasapi.hMMDevapi, "ActivateAudioInterfaceAsync"); - if (pContext->wasapi.ActivateAudioInterfaceAsync == NULL) { - ma_semaphore_uninit(&pContext->wasapi.commandSem); - ma_mutex_uninit(&pContext->wasapi.commandLock); - ma_dlclose(ma_context_get_log(pContext), pContext->wasapi.hMMDevapi); - return MA_NO_BACKEND; /* ActivateAudioInterfaceAsync() could not be loaded. */ - } - } else { - ma_semaphore_uninit(&pContext->wasapi.commandSem); - ma_mutex_uninit(&pContext->wasapi.commandLock); - return MA_NO_BACKEND; /* Failed to load mmdevapi.dll which is required for ActivateAudioInterfaceAsync() */ - } - } - #endif - - /* Optionally use the Avrt API to specify the audio thread's latency sensitivity requirements */ - pContext->wasapi.hAvrt = ma_dlopen(ma_context_get_log(pContext), "avrt.dll"); - if (pContext->wasapi.hAvrt) { - pContext->wasapi.AvSetMmThreadCharacteristicsA = ma_dlsym(ma_context_get_log(pContext), pContext->wasapi.hAvrt, "AvSetMmThreadCharacteristicsA"); - pContext->wasapi.AvRevertMmThreadcharacteristics = ma_dlsym(ma_context_get_log(pContext), pContext->wasapi.hAvrt, "AvRevertMmThreadCharacteristics"); - - /* If either function could not be found, disable use of avrt entirely. */ - if (!pContext->wasapi.AvSetMmThreadCharacteristicsA || !pContext->wasapi.AvRevertMmThreadcharacteristics) { - pContext->wasapi.AvSetMmThreadCharacteristicsA = NULL; - pContext->wasapi.AvRevertMmThreadcharacteristics = NULL; - ma_dlclose(ma_context_get_log(pContext), pContext->wasapi.hAvrt); - pContext->wasapi.hAvrt = NULL; - } - } } diff --git a/tests/test_deviceio/ma_test_deviceio.c b/tests/test_deviceio/ma_test_deviceio.c index f7b049b6..6c8ceaf5 100644 --- a/tests/test_deviceio/ma_test_deviceio.c +++ b/tests/test_deviceio/ma_test_deviceio.c @@ -41,6 +41,7 @@ will receive the captured audio. If multiple backends are specified, the priority will be based on the order in which you specify them. If multiple waveform or noise types are specified the last one on the command line will have priority. */ +#define MA_FORCE_UWP #include "../test_common/ma_test_common.c" typedef enum From da0572e6b820465691f4c7de435291774c5e5751 Mon Sep 17 00:00:00 2001 From: David Reid Date: Thu, 9 Nov 2023 15:01:03 +1000 Subject: [PATCH 2/3] Fix a compilation error with iOS. Public issue https://github.com/mackron/miniaudio/issues/770 --- CHANGES.md | 1 + miniaudio.h | 25 ++++++++++++------------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 9c976563..344f76e0 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,7 @@ v0.11.20 - TBD ===================== * Fix an error when dynamically linking libraries when forcing the UWP build on desktop. +* Fix a compilation error with iOS. v0.11.19 - 2023-11-04 diff --git a/miniaudio.h b/miniaudio.h index ca46c50c..f6d01645 100644 --- a/miniaudio.h +++ b/miniaudio.h @@ -18668,19 +18668,6 @@ static void ma_device__on_notification_rerouted(ma_device* pDevice) } #endif -/* Interruptions are only used on some platforms. */ -#if defined(MA_APPLE_MOBILE) -static void ma_device__on_notification_interruption_began(ma_device* pDevice) -{ - ma_device__on_notification(ma_device_notification_init(pDevice, ma_device_notification_type_interruption_began)); -} - -static void ma_device__on_notification_interruption_ended(ma_device* pDevice) -{ - ma_device__on_notification(ma_device_notification_init(pDevice, ma_device_notification_type_interruption_ended)); -} -#endif - static void ma_device__on_data_inner(ma_device* pDevice, void* pFramesOut, const void* pFramesIn, ma_uint32 frameCount) { @@ -31882,6 +31869,18 @@ size, allocate a block of memory of that size and then call AudioObjectGetProper AudioDeviceID's so just do "dataSize/sizeof(AudioDeviceID)" to know the device count. */ +#if defined(MA_APPLE_MOBILE) +static void ma_device__on_notification_interruption_began(ma_device* pDevice) +{ + ma_device__on_notification(ma_device_notification_init(pDevice, ma_device_notification_type_interruption_began)); +} + +static void ma_device__on_notification_interruption_ended(ma_device* pDevice) +{ + ma_device__on_notification(ma_device_notification_init(pDevice, ma_device_notification_type_interruption_ended)); +} +#endif + static ma_result ma_result_from_OSStatus(OSStatus status) { switch (status) From 3b50a854ec16c273a6bafd13cfd1ef159e48ce7e Mon Sep 17 00:00:00 2001 From: David Reid Date: Fri, 10 Nov 2023 07:44:19 +1000 Subject: [PATCH 3/3] Version 0.11.20 --- CHANGES.md | 4 +- extras/miniaudio_split/miniaudio.c | 97 +++++++++++++++--------------- extras/miniaudio_split/miniaudio.h | 4 +- miniaudio.h | 2 +- 4 files changed, 52 insertions(+), 55 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 344f76e0..c38ac947 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,7 +1,7 @@ -v0.11.20 - TBD +v0.11.20 - 2023-11-10 ===================== -* Fix an error when dynamically linking libraries when forcing the UWP build on desktop. * Fix a compilation error with iOS. +* Fix an error when dynamically linking libraries when forcing the UWP build on desktop. v0.11.19 - 2023-11-04 diff --git a/extras/miniaudio_split/miniaudio.c b/extras/miniaudio_split/miniaudio.c index 9438f604..3e185c79 100644 --- a/extras/miniaudio_split/miniaudio.c +++ b/extras/miniaudio_split/miniaudio.c @@ -1,6 +1,6 @@ /* Audio playback and capture library. Choice of public domain or MIT-0. See license statements at the end of this file. -miniaudio - v0.11.19 - 2023-11-04 +miniaudio - v0.11.20 - 2023-11-10 David Reid - mackron@gmail.com @@ -6397,7 +6397,7 @@ MA_API ma_handle ma_dlopen(ma_log* pLog, const char* filename) #ifdef MA_WIN32 /* From MSDN: Desktop applications cannot use LoadPackagedLibrary; if a desktop application calls this function it fails with APPMODEL_ERROR_NO_PACKAGE.*/ - #if !defined(MA_WIN32_UWP) + #if !defined(MA_WIN32_UWP) || !(defined(WINAPI_FAMILY) && ((defined(WINAPI_FAMILY_PHONE_APP) && WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP))) handle = (ma_handle)LoadLibraryA(filename); #else /* *sigh* It appears there is no ANSI version of LoadPackagedLibrary()... */ @@ -7245,19 +7245,6 @@ static void ma_device__on_notification_rerouted(ma_device* pDevice) } #endif -/* Interruptions are only used on some platforms. */ -#if defined(MA_APPLE_MOBILE) -static void ma_device__on_notification_interruption_began(ma_device* pDevice) -{ - ma_device__on_notification(ma_device_notification_init(pDevice, ma_device_notification_type_interruption_began)); -} - -static void ma_device__on_notification_interruption_ended(ma_device* pDevice) -{ - ma_device__on_notification(ma_device_notification_init(pDevice, ma_device_notification_type_interruption_ended)); -} -#endif - static void ma_device__on_data_inner(ma_device* pDevice, void* pFramesOut, const void* pFramesIn, ma_uint32 frameCount) { @@ -12088,6 +12075,39 @@ static ma_result ma_context_init__wasapi(ma_context* pContext, const ma_context_ MA_ZERO_OBJECT(&pContext->wasapi); + + #if defined(MA_WIN32_UWP) + { + /* Link to mmdevapi so we can get access to ActivateAudioInterfaceAsync(). */ + pContext->wasapi.hMMDevapi = ma_dlopen(ma_context_get_log(pContext), "mmdevapi.dll"); + if (pContext->wasapi.hMMDevapi) { + pContext->wasapi.ActivateAudioInterfaceAsync = ma_dlsym(ma_context_get_log(pContext), pContext->wasapi.hMMDevapi, "ActivateAudioInterfaceAsync"); + if (pContext->wasapi.ActivateAudioInterfaceAsync == NULL) { + ma_dlclose(ma_context_get_log(pContext), pContext->wasapi.hMMDevapi); + return MA_NO_BACKEND; /* ActivateAudioInterfaceAsync() could not be loaded. */ + } + } else { + return MA_NO_BACKEND; /* Failed to load mmdevapi.dll which is required for ActivateAudioInterfaceAsync() */ + } + } + #endif + + /* Optionally use the Avrt API to specify the audio thread's latency sensitivity requirements */ + pContext->wasapi.hAvrt = ma_dlopen(ma_context_get_log(pContext), "avrt.dll"); + if (pContext->wasapi.hAvrt) { + pContext->wasapi.AvSetMmThreadCharacteristicsA = ma_dlsym(ma_context_get_log(pContext), pContext->wasapi.hAvrt, "AvSetMmThreadCharacteristicsA"); + pContext->wasapi.AvRevertMmThreadcharacteristics = ma_dlsym(ma_context_get_log(pContext), pContext->wasapi.hAvrt, "AvRevertMmThreadCharacteristics"); + + /* If either function could not be found, disable use of avrt entirely. */ + if (!pContext->wasapi.AvSetMmThreadCharacteristicsA || !pContext->wasapi.AvRevertMmThreadcharacteristics) { + pContext->wasapi.AvSetMmThreadCharacteristicsA = NULL; + pContext->wasapi.AvRevertMmThreadcharacteristics = NULL; + ma_dlclose(ma_context_get_log(pContext), pContext->wasapi.hAvrt); + pContext->wasapi.hAvrt = NULL; + } + } + + /* Annoyingly, WASAPI does not allow you to release an IAudioClient object from a different thread than the one that retrieved it with GetService(). This can result in a deadlock in two @@ -12131,41 +12151,6 @@ static ma_result ma_context_init__wasapi(ma_context* pContext, const ma_context_ ma_mutex_uninit(&pContext->wasapi.commandLock); return result; } - - #if defined(MA_WIN32_UWP) - { - /* Link to mmdevapi so we can get access to ActivateAudioInterfaceAsync(). */ - pContext->wasapi.hMMDevapi = ma_dlopen(ma_context_get_log(pContext), "mmdevapi.dll"); - if (pContext->wasapi.hMMDevapi) { - pContext->wasapi.ActivateAudioInterfaceAsync = ma_dlsym(ma_context_get_log(pContext), pContext->wasapi.hMMDevapi, "ActivateAudioInterfaceAsync"); - if (pContext->wasapi.ActivateAudioInterfaceAsync == NULL) { - ma_semaphore_uninit(&pContext->wasapi.commandSem); - ma_mutex_uninit(&pContext->wasapi.commandLock); - ma_dlclose(ma_context_get_log(pContext), pContext->wasapi.hMMDevapi); - return MA_NO_BACKEND; /* ActivateAudioInterfaceAsync() could not be loaded. */ - } - } else { - ma_semaphore_uninit(&pContext->wasapi.commandSem); - ma_mutex_uninit(&pContext->wasapi.commandLock); - return MA_NO_BACKEND; /* Failed to load mmdevapi.dll which is required for ActivateAudioInterfaceAsync() */ - } - } - #endif - - /* Optionally use the Avrt API to specify the audio thread's latency sensitivity requirements */ - pContext->wasapi.hAvrt = ma_dlopen(ma_context_get_log(pContext), "avrt.dll"); - if (pContext->wasapi.hAvrt) { - pContext->wasapi.AvSetMmThreadCharacteristicsA = ma_dlsym(ma_context_get_log(pContext), pContext->wasapi.hAvrt, "AvSetMmThreadCharacteristicsA"); - pContext->wasapi.AvRevertMmThreadcharacteristics = ma_dlsym(ma_context_get_log(pContext), pContext->wasapi.hAvrt, "AvRevertMmThreadCharacteristics"); - - /* If either function could not be found, disable use of avrt entirely. */ - if (!pContext->wasapi.AvSetMmThreadCharacteristicsA || !pContext->wasapi.AvRevertMmThreadcharacteristics) { - pContext->wasapi.AvSetMmThreadCharacteristicsA = NULL; - pContext->wasapi.AvRevertMmThreadcharacteristics = NULL; - ma_dlclose(ma_context_get_log(pContext), pContext->wasapi.hAvrt); - pContext->wasapi.hAvrt = NULL; - } - } } @@ -20461,6 +20446,18 @@ size, allocate a block of memory of that size and then call AudioObjectGetProper AudioDeviceID's so just do "dataSize/sizeof(AudioDeviceID)" to know the device count. */ +#if defined(MA_APPLE_MOBILE) +static void ma_device__on_notification_interruption_began(ma_device* pDevice) +{ + ma_device__on_notification(ma_device_notification_init(pDevice, ma_device_notification_type_interruption_began)); +} + +static void ma_device__on_notification_interruption_ended(ma_device* pDevice) +{ + ma_device__on_notification(ma_device_notification_init(pDevice, ma_device_notification_type_interruption_ended)); +} +#endif + static ma_result ma_result_from_OSStatus(OSStatus status) { switch (status) diff --git a/extras/miniaudio_split/miniaudio.h b/extras/miniaudio_split/miniaudio.h index 1ab95771..a019ecd8 100644 --- a/extras/miniaudio_split/miniaudio.h +++ b/extras/miniaudio_split/miniaudio.h @@ -1,6 +1,6 @@ /* Audio playback and capture library. Choice of public domain or MIT-0. See license statements at the end of this file. -miniaudio - v0.11.19 - 2023-11-04 +miniaudio - v0.11.20 - 2023-11-10 David Reid - mackron@gmail.com @@ -20,7 +20,7 @@ extern "C" { #define MA_VERSION_MAJOR 0 #define MA_VERSION_MINOR 11 -#define MA_VERSION_REVISION 19 +#define MA_VERSION_REVISION 20 #define MA_VERSION_STRING MA_XSTRINGIFY(MA_VERSION_MAJOR) "." MA_XSTRINGIFY(MA_VERSION_MINOR) "." MA_XSTRINGIFY(MA_VERSION_REVISION) #if defined(_MSC_VER) && !defined(__clang__) diff --git a/miniaudio.h b/miniaudio.h index f6d01645..e0728243 100644 --- a/miniaudio.h +++ b/miniaudio.h @@ -1,6 +1,6 @@ /* Audio playback and capture library. Choice of public domain or MIT-0. See license statements at the end of this file. -miniaudio - v0.11.20 - TBD +miniaudio - v0.11.20 - 2023-11-10 David Reid - mackron@gmail.com