Commit 27202300 authored by David Reid's avatar David Reid

Version 0.10.11

parent 23166964
/*
Audio playback and capture library. Choice of public domain or MIT-0. See license statements at the end of this file.
miniaudio - v0.10.10 - 26-06-2020
miniaudio - v0.10.11 - 28-06-2020
David Reid - davidreidsoftware@gmail.com
......@@ -26,8 +26,10 @@ GitHub: https://github.com/dr-soft/miniaudio
#ifdef MA_WIN32
#include <windows.h>
#else
#include <stdlib.h> /* For malloc(), free(), wcstombs(). */
#include <string.h> /* For memset() */
#include <stdlib.h> /* For malloc(), free(), wcstombs(). */
#include <string.h> /* For memset() */
#include <sched.h>
#include <sys/time.h> /* select() (used for ma_sleep()). */
#endif
#include <sys/stat.h> /* For fstat(), etc. */
......@@ -464,6 +466,75 @@ static MA_INLINE ma_uint32 ma_swap_endian_uint32(ma_uint32 n)
}
#if !defined(MA_EMSCRIPTEN)
#ifdef MA_WIN32
static void ma_sleep__win32(ma_uint32 milliseconds)
{
Sleep((DWORD)milliseconds);
}
#endif
#ifdef MA_POSIX
static void ma_sleep__posix(ma_uint32 milliseconds)
{
#ifdef MA_EMSCRIPTEN
(void)milliseconds;
MA_ASSERT(MA_FALSE); /* The Emscripten build should never sleep. */
#else
#if _POSIX_C_SOURCE >= 199309L
struct timespec ts;
ts.tv_sec = milliseconds / 1000;
ts.tv_nsec = milliseconds % 1000 * 1000000;
nanosleep(&ts, NULL);
#else
struct timeval tv;
tv.tv_sec = milliseconds / 1000;
tv.tv_usec = milliseconds % 1000 * 1000;
select(0, NULL, NULL, NULL, &tv);
#endif
#endif
}
#endif
static void ma_sleep(ma_uint32 milliseconds)
{
#ifdef MA_WIN32
ma_sleep__win32(milliseconds);
#endif
#ifdef MA_POSIX
ma_sleep__posix(milliseconds);
#endif
}
#endif
#if !defined(MA_EMSCRIPTEN)
static MA_INLINE void ma_yield()
{
#if defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64)
/* x86/x64 */
#if defined(_MSC_VER) && !defined(__clang__)
#if _MSC_VER >= 1400
_mm_pause();
#else
__asm pause;
#endif
#else
__asm__ __volatile__ ("pause");
#endif
#elif (defined(__arm__) && defined(__ARM_ARCH) && __ARM_ARCH >= 6) || (defined(_M_ARM) && _M_ARM >= 6)
/* ARM */
#if defined(_MSC_VER)
/* Apparently there is a __yield() intrinsic that's compatible with ARM, but I cannot find documentation for it nor can I find where it's declared. */
__yield();
#else
__asm__ __volatile__ ("yield");
#endif
#else
/* Unknown or unsupported architecture. No-op. */
#endif
}
#endif
#ifndef MA_COINIT_VALUE
#define MA_COINIT_VALUE 0 /* 0 = COINIT_MULTITHREADED */
......@@ -2599,6 +2670,51 @@ c89atomic_bool c89atomic_compare_exchange_strong_explicit_64(volatile c89atomic_
/* c89atomic.h end */
typedef unsigned char ma_spinlock;
static MA_INLINE ma_result ma_spinlock_lock_ex(ma_spinlock* pSpinlock, ma_bool32 yield)
{
if (pSpinlock == NULL) {
return MA_INVALID_ARGS;
}
for (;;) {
if (c89atomic_flag_test_and_set_explicit(pSpinlock, c89atomic_memory_order_acquire) == 0) {
break;
}
while (c89atomic_load_explicit_8(pSpinlock, c89atomic_memory_order_relaxed) == 1) {
if (yield) {
ma_yield();
}
}
}
return MA_SUCCESS;
}
static ma_result ma_spinlock_lock(ma_spinlock* pSpinlock)
{
return ma_spinlock_lock_ex(pSpinlock, MA_TRUE);
}
static ma_result ma_spinlock_lock_noyield(ma_spinlock* pSpinlock)
{
return ma_spinlock_lock_ex(pSpinlock, MA_FALSE);
}
static ma_result ma_spinlock_unlock(ma_spinlock* pSpinlock)
{
if (pSpinlock == NULL) {
return MA_INVALID_ARGS;
}
c89atomic_flag_clear_explicit(pSpinlock, c89atomic_memory_order_release);
return MA_SUCCESS;
}
static void* ma__malloc_default(size_t sz, void* pUserData)
{
(void)pUserData;
......@@ -2823,11 +2939,6 @@ static void ma_thread_wait__win32(ma_thread* pThread)
WaitForSingleObject((HANDLE)*pThread, INFINITE);
}
static void ma_sleep__win32(ma_uint32 milliseconds)
{
Sleep((DWORD)milliseconds);
}
static ma_result ma_mutex_init__win32(ma_mutex* pMutex)
{
......@@ -2937,9 +3048,6 @@ static ma_result ma_semaphore_release__win32(ma_semaphore* pSemaphore)
#ifdef MA_POSIX
#include <sched.h>
#include <sys/time.h>
static ma_result ma_thread_create__posix(ma_thread* pThread, ma_thread_priority priority, size_t stackSize, ma_thread_entry_proc entryProc, void* pData)
{
int result;
......@@ -3016,28 +3124,6 @@ static void ma_thread_wait__posix(ma_thread* pThread)
pthread_join(*pThread, NULL);
}
#if !defined(MA_EMSCRIPTEN)
static void ma_sleep__posix(ma_uint32 milliseconds)
{
#ifdef MA_EMSCRIPTEN
(void)milliseconds;
MA_ASSERT(MA_FALSE); /* The Emscripten build should never sleep. */
#else
#if _POSIX_C_SOURCE >= 199309L
struct timespec ts;
ts.tv_sec = milliseconds / 1000;
ts.tv_nsec = milliseconds % 1000 * 1000000;
nanosleep(&ts, NULL);
#else
struct timeval tv;
tv.tv_sec = milliseconds / 1000;
tv.tv_usec = milliseconds % 1000 * 1000;
select(0, NULL, NULL, NULL, &tv);
#endif
#endif
}
#endif /* MA_EMSCRIPTEN */
static ma_result ma_mutex_init__posix(ma_mutex* pMutex)
{
......@@ -3216,46 +3302,6 @@ static void ma_thread_wait(ma_thread* pThread)
#endif
}
#if !defined(MA_EMSCRIPTEN)
static void ma_sleep(ma_uint32 milliseconds)
{
#ifdef MA_WIN32
ma_sleep__win32(milliseconds);
#endif
#ifdef MA_POSIX
ma_sleep__posix(milliseconds);
#endif
}
#endif
#if !defined(MA_EMSCRIPTEN)
static MA_INLINE void ma_yield()
{
#if defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64)
/* x86/x64 */
#if defined(_MSC_VER) && !defined(__clang__)
#if _MSC_VER >= 1400
_mm_pause();
#else
__asm pause;
#endif
#else
__asm__ __volatile__ ("pause");
#endif
#elif (defined(__arm__) && defined(__ARM_ARCH) && __ARM_ARCH >= 6) || (defined(_M_ARM) && _M_ARM >= 6)
/* ARM */
#if defined(_MSC_VER)
/* Apparently there is a __yield() intrinsic that's compatible with ARM, but I cannot find documentation for it nor can I find where it's declared. */
__yield();
#else
__asm__ __volatile__ ("yield");
#endif
#else
/* Unknown or unsupported architecture. No-op. */
#endif
}
#endif
MA_API ma_result ma_mutex_init(ma_mutex* pMutex)
{
......@@ -18414,6 +18460,7 @@ static void on_start_stop__coreaudio(void* pUserData, AudioUnit audioUnit, Audio
}
#if defined(MA_APPLE_DESKTOP)
static ma_spinlock g_DeviceTrackingInitLock_CoreAudio = 0; /* A spinlock for mutal exclusion of the init/uninit of the global tracking data. Initialization to 0 is what we need. */
static ma_uint32 g_DeviceTrackingInitCounter_CoreAudio = 0;
static ma_mutex g_DeviceTrackingMutex_CoreAudio;
static ma_device** g_ppTrackedDevices_CoreAudio = NULL;
......@@ -18497,7 +18544,8 @@ static ma_result ma_context__init_device_tracking__coreaudio(ma_context* pContex
{
MA_ASSERT(pContext != NULL);
if (c89atomic_fetch_add_32(&g_DeviceTrackingInitCounter_CoreAudio, 1) == 0) {
ma_spinlock_lock(&g_DeviceTrackingInitLock_CoreAudio);
{
AudioObjectPropertyAddress propAddress;
propAddress.mScope = kAudioObjectPropertyScopeGlobal;
propAddress.mElement = kAudioObjectPropertyElementMaster;
......@@ -18510,7 +18558,8 @@ static ma_result ma_context__init_device_tracking__coreaudio(ma_context* pContex
propAddress.mSelector = kAudioHardwarePropertyDefaultOutputDevice;
((ma_AudioObjectAddPropertyListener_proc)pContext->coreaudio.AudioObjectAddPropertyListener)(kAudioObjectSystemObject, &propAddress, &ma_default_device_changed__coreaudio, NULL);
}
ma_spinlock_unlock(&g_DeviceTrackingInitLock_CoreAudio);
return MA_SUCCESS;
}
......@@ -18518,7 +18567,8 @@ static ma_result ma_context__uninit_device_tracking__coreaudio(ma_context* pCont
{
MA_ASSERT(pContext != NULL);
if (c89atomic_fetch_sub_32(&g_DeviceTrackingInitCounter_CoreAudio, 1) == 1) {
ma_spinlock_lock(&g_DeviceTrackingInitLock_CoreAudio);
{
AudioObjectPropertyAddress propAddress;
propAddress.mScope = kAudioObjectPropertyScopeGlobal;
propAddress.mElement = kAudioObjectPropertyElementMaster;
......@@ -18535,21 +18585,15 @@ static ma_result ma_context__uninit_device_tracking__coreaudio(ma_context* pCont
ma_mutex_uninit(&g_DeviceTrackingMutex_CoreAudio);
}
ma_spinlock_unlock(&g_DeviceTrackingInitLock_CoreAudio);
return MA_SUCCESS;
}
static ma_result ma_device__track__coreaudio(ma_device* pDevice)
{
ma_result result;
MA_ASSERT(pDevice != NULL);
result = ma_context__init_device_tracking__coreaudio(pDevice->pContext);
if (result != MA_SUCCESS) {
return result;
}
ma_mutex_lock(&g_DeviceTrackingMutex_CoreAudio);
{
/* Allocate memory if required. */
......@@ -18584,8 +18628,6 @@ static ma_result ma_device__track__coreaudio(ma_device* pDevice)
static ma_result ma_device__untrack__coreaudio(ma_device* pDevice)
{
ma_result result;
MA_ASSERT(pDevice != NULL);
ma_mutex_lock(&g_DeviceTrackingMutex_CoreAudio);
......@@ -18614,11 +18656,6 @@ static ma_result ma_device__untrack__coreaudio(ma_device* pDevice)
}
ma_mutex_unlock(&g_DeviceTrackingMutex_CoreAudio);
result = ma_context__uninit_device_tracking__coreaudio(pDevice->pContext);
if (result != MA_SUCCESS) {
return result;
}
return MA_SUCCESS;
}
#endif
......@@ -19461,6 +19498,8 @@ static ma_result ma_context_uninit__coreaudio(ma_context* pContext)
ma_dlclose(pContext, pContext->coreaudio.hCoreFoundation);
#endif
ma_context__init_device_tracking__coreaudio(pContext);
(void)pContext;
return MA_SUCCESS;
}
......@@ -19488,6 +19527,8 @@ static AVAudioSessionCategory ma_to_AVAudioSessionCategory(ma_ios_session_catego
static ma_result ma_context_init__coreaudio(const ma_context_config* pConfig, ma_context* pContext)
{
ma_result result;
MA_ASSERT(pConfig != NULL);
MA_ASSERT(pContext != NULL);
......@@ -19642,6 +19683,16 @@ static ma_result ma_context_init__coreaudio(const ma_context_config* pConfig, ma
return MA_FAILED_TO_INIT_BACKEND;
}
}
result = ma_context__init_device_tracking__coreaudio(pContext);
if (result != MA_SUCCESS) {
#if !defined(MA_NO_RUNTIME_LINKING) && !defined(MA_APPLE_MOBILE)
ma_dlclose(pContext, pContext->coreaudio.hAudioUnit);
ma_dlclose(pContext, pContext->coreaudio.hCoreAudio);
ma_dlclose(pContext, pContext->coreaudio.hCoreFoundation);
#endif
return result;
}
return MA_SUCCESS;
}
/*
Audio playback and capture library. Choice of public domain or MIT-0. See license statements at the end of this file.
miniaudio - v0.10.10 - 26-06-2020
miniaudio - v0.10.11 - 28-06-2020
David Reid - davidreidsoftware@gmail.com
......@@ -19,7 +19,7 @@ extern "C" {
#define MA_VERSION_MAJOR 0
#define MA_VERSION_MINOR 10
#define MA_VERSION_REVISION 10
#define MA_VERSION_REVISION 11
#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__)
......
......@@ -25267,11 +25267,11 @@ static ma_result ma_context_init__coreaudio(const ma_context_config* pConfig, ma
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)
#if !defined(MA_NO_RUNTIME_LINKING) && !defined(MA_APPLE_MOBILE)
ma_dlclose(pContext, pContext->coreaudio.hAudioUnit);
ma_dlclose(pContext, pContext->coreaudio.hCoreAudio);
ma_dlclose(pContext, pContext->coreaudio.hCoreFoundation);
#endif
#endif
return MA_FAILED_TO_INIT_BACKEND;
}
}
......@@ -25279,9 +25279,9 @@ static ma_result ma_context_init__coreaudio(const ma_context_config* pConfig, ma
result = ma_context__init_device_tracking__coreaudio(pContext);
if (result != MA_SUCCESS) {
#if !defined(MA_NO_RUNTIME_LINKING) && !defined(MA_APPLE_MOBILE)
ma_dlclose(pContext, pContext->coreaudio.hAudioUnit);
ma_dlclose(pContext, pContext->coreaudio.hCoreAudio);
ma_dlclose(pContext, pContext->coreaudio.hCoreFoundation);
ma_dlclose(pContext, pContext->coreaudio.hAudioUnit);
ma_dlclose(pContext, pContext->coreaudio.hCoreAudio);
ma_dlclose(pContext, pContext->coreaudio.hCoreFoundation);
#endif
return result;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment