Commit 3387e888 authored by David Reid's avatar David Reid

API CHANGE: Add support for custom memory allocators.

This commit changes the following APIs to add an additional parameter
called pAllocationCallbacks. This is a pointer to a
ma_allocation_callbacks structure which is used to perform the actual
allocation/free.

Allocation callbacks can be set in ma_context_config for contexts and
ma_decoder_config for decoders. If it's left unset it will use
MA_MALLOC(), MA_REALLOC() and MA_FREE().
parent 71fe5ec5
...@@ -834,6 +834,14 @@ typedef enum ...@@ -834,6 +834,14 @@ typedef enum
} ma_performance_profile; } ma_performance_profile;
typedef struct
{
void* pUserData;
void* (* onMalloc)(size_t sz, void* pUserData);
void* (* onRealloc)(void* p, size_t sz, void* pUserData);
void (* onFree)(void* p, void* pUserData);
} ma_allocation_callbacks;
/************************************************************************************************************************************************************** /**************************************************************************************************************************************************************
...@@ -1668,10 +1676,11 @@ typedef struct ...@@ -1668,10 +1676,11 @@ typedef struct
volatile ma_uint32 encodedWriteOffset; /* Most significant bit is the loop flag. Lower 31 bits contains the actual offset in bytes. */ volatile ma_uint32 encodedWriteOffset; /* Most significant bit is the loop flag. Lower 31 bits contains the actual offset in bytes. */
ma_bool32 ownsBuffer : 1; /* Used to know whether or not miniaudio is responsible for free()-ing the buffer. */ ma_bool32 ownsBuffer : 1; /* Used to know whether or not miniaudio is responsible for free()-ing the buffer. */
ma_bool32 clearOnWriteAcquire : 1; /* When set, clears the acquired write buffer before returning from ma_rb_acquire_write(). */ ma_bool32 clearOnWriteAcquire : 1; /* When set, clears the acquired write buffer before returning from ma_rb_acquire_write(). */
ma_allocation_callbacks allocationCallbacks;
} ma_rb; } ma_rb;
ma_result ma_rb_init_ex(size_t subbufferSizeInBytes, size_t subbufferCount, size_t subbufferStrideInBytes, void* pOptionalPreallocatedBuffer, ma_rb* pRB); ma_result ma_rb_init_ex(size_t subbufferSizeInBytes, size_t subbufferCount, size_t subbufferStrideInBytes, void* pOptionalPreallocatedBuffer, const ma_allocation_callbacks* pAllocationCallbacks, ma_rb* pRB);
ma_result ma_rb_init(size_t bufferSizeInBytes, void* pOptionalPreallocatedBuffer, ma_rb* pRB); ma_result ma_rb_init(size_t bufferSizeInBytes, void* pOptionalPreallocatedBuffer, const ma_allocation_callbacks* pAllocationCallbacks, ma_rb* pRB);
void ma_rb_uninit(ma_rb* pRB); void ma_rb_uninit(ma_rb* pRB);
void ma_rb_reset(ma_rb* pRB); void ma_rb_reset(ma_rb* pRB);
ma_result ma_rb_acquire_read(ma_rb* pRB, size_t* pSizeInBytes, void** ppBufferOut); ma_result ma_rb_acquire_read(ma_rb* pRB, size_t* pSizeInBytes, void** ppBufferOut);
...@@ -1696,8 +1705,8 @@ typedef struct ...@@ -1696,8 +1705,8 @@ typedef struct
ma_uint32 channels; ma_uint32 channels;
} ma_pcm_rb; } ma_pcm_rb;
ma_result ma_pcm_rb_init_ex(ma_format format, ma_uint32 channels, ma_uint32 subbufferSizeInFrames, ma_uint32 subbufferCount, ma_uint32 subbufferStrideInFrames, void* pOptionalPreallocatedBuffer, ma_pcm_rb* pRB); ma_result ma_pcm_rb_init_ex(ma_format format, ma_uint32 channels, ma_uint32 subbufferSizeInFrames, ma_uint32 subbufferCount, ma_uint32 subbufferStrideInFrames, void* pOptionalPreallocatedBuffer, const ma_allocation_callbacks* pAllocationCallbacks, ma_pcm_rb* pRB);
ma_result ma_pcm_rb_init(ma_format format, ma_uint32 channels, ma_uint32 bufferSizeInFrames, void* pOptionalPreallocatedBuffer, ma_pcm_rb* pRB); ma_result ma_pcm_rb_init(ma_format format, ma_uint32 channels, ma_uint32 bufferSizeInFrames, void* pOptionalPreallocatedBuffer, const ma_allocation_callbacks* pAllocationCallbacks, ma_pcm_rb* pRB);
void ma_pcm_rb_uninit(ma_pcm_rb* pRB); void ma_pcm_rb_uninit(ma_pcm_rb* pRB);
void ma_pcm_rb_reset(ma_pcm_rb* pRB); void ma_pcm_rb_reset(ma_pcm_rb* pRB);
ma_result ma_pcm_rb_acquire_read(ma_pcm_rb* pRB, ma_uint32* pSizeInFrames, void** ppBufferOut); ma_result ma_pcm_rb_acquire_read(ma_pcm_rb* pRB, ma_uint32* pSizeInFrames, void** ppBufferOut);
...@@ -1724,27 +1733,27 @@ Miscellaneous Helpers ...@@ -1724,27 +1733,27 @@ Miscellaneous Helpers
/* /*
malloc(). Calls MA_MALLOC(). malloc(). Calls MA_MALLOC().
*/ */
void* ma_malloc(size_t sz); void* ma_malloc(size_t sz, const ma_allocation_callbacks* pAllocationCallbacks);
/* /*
realloc(). Calls MA_REALLOC(). realloc(). Calls MA_REALLOC().
*/ */
void* ma_realloc(void* p, size_t sz); void* ma_realloc(void* p, size_t sz, const ma_allocation_callbacks* pAllocationCallbacks);
/* /*
free(). Calls MA_FREE(). free(). Calls MA_FREE().
*/ */
void ma_free(void* p); void ma_free(void* p, const ma_allocation_callbacks* pAllocationCallbacks);
/* /*
Performs an aligned malloc, with the assumption that the alignment is a power of 2. Performs an aligned malloc, with the assumption that the alignment is a power of 2.
*/ */
void* ma_aligned_malloc(size_t sz, size_t alignment); void* ma_aligned_malloc(size_t sz, size_t alignment, const ma_allocation_callbacks* pAllocationCallbacks);
/* /*
Free's an aligned malloc'd buffer. Free's an aligned malloc'd buffer.
*/ */
void ma_aligned_free(void* p); void ma_aligned_free(void* p, const ma_allocation_callbacks* pAllocationCallbacks);
/* /*
Retrieves a friendly name for a format. Retrieves a friendly name for a format.
...@@ -2202,7 +2211,7 @@ typedef struct ...@@ -2202,7 +2211,7 @@ typedef struct
ma_log_proc logCallback; ma_log_proc logCallback;
ma_thread_priority threadPriority; ma_thread_priority threadPriority;
void* pUserData; void* pUserData;
ma_allocation_callbacks allocationCallbacks;
struct struct
{ {
ma_bool32 useVerboseDeviceEnumeration; ma_bool32 useVerboseDeviceEnumeration;
...@@ -2233,6 +2242,7 @@ struct ma_context ...@@ -2233,6 +2242,7 @@ struct ma_context
ma_log_proc logCallback; ma_log_proc logCallback;
ma_thread_priority threadPriority; ma_thread_priority threadPriority;
void* pUserData; void* pUserData;
ma_allocation_callbacks allocationCallbacks;
ma_mutex deviceEnumLock; /* Used to make ma_context_get_devices() thread safe. */ ma_mutex deviceEnumLock; /* Used to make ma_context_get_devices() thread safe. */
ma_mutex deviceInfoLock; /* Used to make ma_context_get_device_info() thread safe. */ ma_mutex deviceInfoLock; /* Used to make ma_context_get_device_info() thread safe. */
ma_uint32 deviceInfoCapacity; /* Total capacity of pDeviceInfos. */ ma_uint32 deviceInfoCapacity; /* Total capacity of pDeviceInfos. */
...@@ -3438,6 +3448,7 @@ typedef struct ...@@ -3438,6 +3448,7 @@ typedef struct
int quality; int quality;
} speex; } speex;
} resampling; } resampling;
ma_allocation_callbacks allocationCallbacks;
} ma_decoder_config; } ma_decoder_config;
struct ma_decoder struct ma_decoder
...@@ -3455,6 +3466,7 @@ struct ma_decoder ...@@ -3455,6 +3466,7 @@ struct ma_decoder
ma_uint32 outputSampleRate; ma_uint32 outputSampleRate;
ma_channel outputChannelMap[MA_MAX_CHANNELS]; ma_channel outputChannelMap[MA_MAX_CHANNELS];
ma_data_converter converter; /* <-- Data conversion is achieved by running frames through this. */ ma_data_converter converter; /* <-- Data conversion is achieved by running frames through this. */
ma_allocation_callbacks allocationCallbacks;
ma_decoder_read_pcm_frames_proc onReadPCMFrames; ma_decoder_read_pcm_frames_proc onReadPCMFrames;
ma_decoder_seek_to_pcm_frame_proc onSeekToPCMFrame; ma_decoder_seek_to_pcm_frame_proc onSeekToPCMFrame;
ma_decoder_uninit_proc onUninit; ma_decoder_uninit_proc onUninit;
...@@ -4399,10 +4411,10 @@ int ma_strappend(char* dst, size_t dstSize, const char* srcA, const char* srcB) ...@@ -4399,10 +4411,10 @@ int ma_strappend(char* dst, size_t dstSize, const char* srcA, const char* srcB)
return result; return result;
} }
char* ma_copy_string(const char* src) char* ma_copy_string(const char* src, const ma_allocation_callbacks* pAllocationCallbacks)
{ {
size_t sz = strlen(src)+1; size_t sz = strlen(src)+1;
char* dst = (char*)ma_malloc(sz); char* dst = (char*)ma_malloc(sz, pAllocationCallbacks);
if (dst == NULL) { if (dst == NULL) {
return NULL; return NULL;
} }
...@@ -4724,6 +4736,129 @@ Atomics ...@@ -4724,6 +4736,129 @@ Atomics
#endif #endif
static void* ma__malloc_default(size_t sz, void* pUserData)
{
(void)pUserData;
return MA_MALLOC(sz);
}
static void* ma__realloc_default(void* p, size_t sz, void* pUserData)
{
(void)pUserData;
return MA_REALLOC(p, sz);
}
static void ma__free_default(void* p, void* pUserData)
{
(void)pUserData;
MA_FREE(p);
}
static void* ma__malloc_from_callbacks(size_t sz, const ma_allocation_callbacks* pAllocationCallbacks)
{
if (pAllocationCallbacks == NULL) {
return NULL;
}
if (pAllocationCallbacks->onMalloc != NULL) {
return pAllocationCallbacks->onMalloc(sz, pAllocationCallbacks->pUserData);
}
/* Try using realloc(). */
if (pAllocationCallbacks->onRealloc != NULL) {
return pAllocationCallbacks->onRealloc(NULL, sz, pAllocationCallbacks->pUserData);
}
return NULL;
}
static void* ma__realloc_from_callbacks(void* p, size_t szNew, size_t szOld, const ma_allocation_callbacks* pAllocationCallbacks)
{
if (pAllocationCallbacks == NULL) {
return NULL;
}
if (pAllocationCallbacks->onRealloc != NULL) {
return pAllocationCallbacks->onRealloc(p, szNew, pAllocationCallbacks->pUserData);
}
/* Try emulating realloc() in terms of malloc()/free(). */
if (pAllocationCallbacks->onMalloc != NULL && pAllocationCallbacks->onFree != NULL) {
void* p2;
p2 = pAllocationCallbacks->onMalloc(szNew, pAllocationCallbacks->pUserData);
if (p2 == NULL) {
return NULL;
}
if (p != NULL) {
MA_COPY_MEMORY(p2, p, szOld);
pAllocationCallbacks->onFree(p, pAllocationCallbacks->pUserData);
}
return p2;
}
return NULL;
}
static void* ma__calloc_from_callbacks(size_t sz, const ma_allocation_callbacks* pAllocationCallbacks)
{
void* p = ma__malloc_from_callbacks(sz, pAllocationCallbacks);
if (p != NULL) {
MA_ZERO_MEMORY(p, sz);
}
return p;
}
static void ma__free_from_callbacks(void* p, const ma_allocation_callbacks* pAllocationCallbacks)
{
if (p == NULL || pAllocationCallbacks == NULL) {
return;
}
if (pAllocationCallbacks->onFree != NULL) {
pAllocationCallbacks->onFree(p, pAllocationCallbacks->pUserData);
}
}
static ma_allocation_callbacks ma_allocation_callbacks_init_default()
{
ma_allocation_callbacks callbacks;
callbacks.pUserData = NULL;
callbacks.onMalloc = ma__malloc_default;
callbacks.onRealloc = ma__realloc_default;
callbacks.onFree = ma__free_default;
return callbacks;
}
static ma_result ma_allocation_callbacks_init_copy(ma_allocation_callbacks* pDst, const ma_allocation_callbacks* pSrc)
{
if (pDst == NULL) {
return MA_INVALID_ARGS;
}
if (pSrc == NULL) {
*pDst = ma_allocation_callbacks_init_default();
} else {
if (pSrc->pUserData == NULL && pSrc->onFree == NULL && pSrc->onMalloc == NULL && pSrc->onRealloc == NULL) {
*pDst = ma_allocation_callbacks_init_default();
} else {
if (pSrc->onFree == NULL || (pSrc->onMalloc == NULL && pSrc->onRealloc == NULL)) {
return MA_INVALID_ARGS; /* Invalid allocation callbacks. */
} else {
*pDst = *pSrc;
}
}
}
return MA_SUCCESS;
}
ma_uint64 ma_calculate_frame_count_after_src(ma_uint32 sampleRateOut, ma_uint32 sampleRateIn, ma_uint64 frameCountIn) ma_uint64 ma_calculate_frame_count_after_src(ma_uint32 sampleRateOut, ma_uint32 sampleRateIn, ma_uint64 frameCountIn)
{ {
double srcRatio = (double)sampleRateOut / sampleRateIn; double srcRatio = (double)sampleRateOut / sampleRateIn;
...@@ -12293,7 +12428,7 @@ static void ma_device_uninit__winmm(ma_device* pDevice) ...@@ -12293,7 +12428,7 @@ static void ma_device_uninit__winmm(ma_device* pDevice)
CloseHandle((HANDLE)pDevice->winmm.hEventPlayback); CloseHandle((HANDLE)pDevice->winmm.hEventPlayback);
} }
ma_free(pDevice->winmm._pHeapData); ma__free_from_callbacks(pDevice->winmm._pHeapData, &pDevice->pContext->allocationCallbacks);
MA_ZERO_OBJECT(&pDevice->winmm); /* Safety. */ MA_ZERO_OBJECT(&pDevice->winmm); /* Safety. */
} }
...@@ -12433,7 +12568,7 @@ static ma_result ma_device_init__winmm(ma_context* pContext, const ma_device_con ...@@ -12433,7 +12568,7 @@ static ma_result ma_device_init__winmm(ma_context* pContext, const ma_device_con
heapSize += sizeof(WAVEHDR)*pDevice->playback.internalPeriods + (pDevice->playback.internalBufferSizeInFrames*ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels)); heapSize += sizeof(WAVEHDR)*pDevice->playback.internalPeriods + (pDevice->playback.internalBufferSizeInFrames*ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels));
} }
pDevice->winmm._pHeapData = (ma_uint8*)ma_malloc(heapSize); pDevice->winmm._pHeapData = (ma_uint8*)ma__calloc_from_callbacks(heapSize, &pContext->allocationCallbacks);
if (pDevice->winmm._pHeapData == NULL) { if (pDevice->winmm._pHeapData == NULL) {
errorMsg = "[WinMM] Failed to allocate memory for the intermediary buffer.", errorCode = MA_OUT_OF_MEMORY; errorMsg = "[WinMM] Failed to allocate memory for the intermediary buffer.", errorCode = MA_OUT_OF_MEMORY;
goto on_error; goto on_error;
...@@ -12523,7 +12658,7 @@ on_error: ...@@ -12523,7 +12658,7 @@ on_error:
((MA_PFN_waveOutClose)pContext->winmm.waveOutClose)((HWAVEOUT)pDevice->winmm.hDevicePlayback); ((MA_PFN_waveOutClose)pContext->winmm.waveOutClose)((HWAVEOUT)pDevice->winmm.hDevicePlayback);
} }
ma_free(pDevice->winmm._pHeapData); ma__free_from_callbacks(pDevice->winmm._pHeapData, &pContext->allocationCallbacks);
return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, errorMsg, errorCode); return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, errorMsg, errorCode);
} }
...@@ -13772,7 +13907,9 @@ static ma_result ma_context_enumerate_devices__alsa(ma_context* pContext, ma_enu ...@@ -13772,7 +13907,9 @@ static ma_result ma_context_enumerate_devices__alsa(ma_context* pContext, ma_enu
goto next_device; /* The device has already been enumerated. Move on to the next one. */ goto next_device; /* The device has already been enumerated. Move on to the next one. */
} else { } else {
/* The device has not yet been enumerated. Make sure it's added to our list so that it's not enumerated again. */ /* The device has not yet been enumerated. Make sure it's added to our list so that it's not enumerated again. */
ma_device_id* pNewUniqueIDs = (ma_device_id*)ma_realloc(pUniqueIDs, sizeof(*pUniqueIDs) * (uniqueIDCount + 1)); size_t oldCapacity = sizeof(*pUniqueIDs) * uniqueIDCount;
size_t newCapacity = sizeof(*pUniqueIDs) * (uniqueIDCount + 1);
ma_device_id* pNewUniqueIDs = (ma_device_id*)ma__realloc_from_callbacks(pUniqueIDs, newCapacity, oldCapacity, &pContext->allocationCallbacks);
if (pNewUniqueIDs == NULL) { if (pNewUniqueIDs == NULL) {
goto next_device; /* Failed to allocate memory. */ goto next_device; /* Failed to allocate memory. */
} }
...@@ -13860,7 +13997,7 @@ static ma_result ma_context_enumerate_devices__alsa(ma_context* pContext, ma_enu ...@@ -13860,7 +13997,7 @@ static ma_result ma_context_enumerate_devices__alsa(ma_context* pContext, ma_enu
} }
} }
ma_free(pUniqueIDs); ma__free_from_callbacks(pUniqueIDs, &pContext->allocationCallbacks);
((ma_snd_device_name_free_hint_proc)pContext->alsa.snd_device_name_free_hint)((void**)ppDeviceHints); ((ma_snd_device_name_free_hint_proc)pContext->alsa.snd_device_name_free_hint)((void**)ppDeviceHints);
ma_mutex_unlock(&pContext->alsa.internalDeviceEnumLock); ma_mutex_unlock(&pContext->alsa.internalDeviceEnumLock);
...@@ -13930,7 +14067,7 @@ static ma_result ma_context_get_device_info__alsa(ma_context* pContext, ma_devic ...@@ -13930,7 +14067,7 @@ static ma_result ma_context_get_device_info__alsa(ma_context* pContext, ma_devic
} }
/* We need to initialize a HW parameters object in order to know what formats are supported. */ /* We need to initialize a HW parameters object in order to know what formats are supported. */
pHWParams = (ma_snd_pcm_hw_params_t*)calloc(1, ((ma_snd_pcm_hw_params_sizeof_proc)pContext->alsa.snd_pcm_hw_params_sizeof)()); pHWParams = (ma_snd_pcm_hw_params_t*)ma__calloc_from_callbacks(((ma_snd_pcm_hw_params_sizeof_proc)pContext->alsa.snd_pcm_hw_params_sizeof)(), &pContext->allocationCallbacks);
if (pHWParams == NULL) { if (pHWParams == NULL) {
return MA_OUT_OF_MEMORY; return MA_OUT_OF_MEMORY;
} }
...@@ -13945,7 +14082,7 @@ static ma_result ma_context_get_device_info__alsa(ma_context* pContext, ma_devic ...@@ -13945,7 +14082,7 @@ static ma_result ma_context_get_device_info__alsa(ma_context* pContext, ma_devic
((ma_snd_pcm_hw_params_get_rate_max_proc)pContext->alsa.snd_pcm_hw_params_get_rate_max)(pHWParams, &pDeviceInfo->maxSampleRate, &sampleRateDir); ((ma_snd_pcm_hw_params_get_rate_max_proc)pContext->alsa.snd_pcm_hw_params_get_rate_max)(pHWParams, &pDeviceInfo->maxSampleRate, &sampleRateDir);
/* Formats. */ /* Formats. */
pFormatMask = (ma_snd_pcm_format_mask_t*)calloc(1, ((ma_snd_pcm_format_mask_sizeof_proc)pContext->alsa.snd_pcm_format_mask_sizeof)()); pFormatMask = (ma_snd_pcm_format_mask_t*)ma__calloc_from_callbacks(((ma_snd_pcm_format_mask_sizeof_proc)pContext->alsa.snd_pcm_format_mask_sizeof)(), &pContext->allocationCallbacks);
if (pFormatMask == NULL) { if (pFormatMask == NULL) {
return MA_OUT_OF_MEMORY; return MA_OUT_OF_MEMORY;
} }
...@@ -13969,8 +14106,8 @@ static ma_result ma_context_get_device_info__alsa(ma_context* pContext, ma_devic ...@@ -13969,8 +14106,8 @@ static ma_result ma_context_get_device_info__alsa(ma_context* pContext, ma_devic
pDeviceInfo->formats[pDeviceInfo->formatCount++] = ma_format_f32; pDeviceInfo->formats[pDeviceInfo->formatCount++] = ma_format_f32;
} }
ma_free(pFormatMask); ma__free_from_callbacks(pFormatMask, &pContext->allocationCallbacks);
ma_free(pHWParams); ma__free_from_callbacks(pHWParams, &pContext->allocationCallbacks);
((ma_snd_pcm_close_proc)pContext->alsa.snd_pcm_close)(pPCM); ((ma_snd_pcm_close_proc)pContext->alsa.snd_pcm_close)(pPCM);
return MA_SUCCESS; return MA_SUCCESS;
...@@ -14293,7 +14430,7 @@ static ma_result ma_device_init_by_type__alsa(ma_context* pContext, const ma_dev ...@@ -14293,7 +14430,7 @@ static ma_result ma_device_init_by_type__alsa(ma_context* pContext, const ma_dev
/* If using the default buffer size we may want to apply some device-specific scaling for known devices that have peculiar latency characteristics */ /* If using the default buffer size we may want to apply some device-specific scaling for known devices that have peculiar latency characteristics */
bufferSizeScaleFactor = 1; bufferSizeScaleFactor = 1;
if (pDevice->usingDefaultBufferSize) { if (pDevice->usingDefaultBufferSize) {
ma_snd_pcm_info_t* pInfo = (ma_snd_pcm_info_t*)calloc(1, ((ma_snd_pcm_info_sizeof_proc)pContext->alsa.snd_pcm_info_sizeof)()); ma_snd_pcm_info_t* pInfo = (ma_snd_pcm_info_t*)ma__calloc_from_callbacks(((ma_snd_pcm_info_sizeof_proc)pContext->alsa.snd_pcm_info_sizeof)(), &pContext->allocationCallbacks);
if (pInfo == NULL) { if (pInfo == NULL) {
return MA_OUT_OF_MEMORY; return MA_OUT_OF_MEMORY;
} }
...@@ -14308,7 +14445,7 @@ static ma_result ma_device_init_by_type__alsa(ma_context* pContext, const ma_dev ...@@ -14308,7 +14445,7 @@ static ma_result ma_device_init_by_type__alsa(ma_context* pContext, const ma_dev
/* It's the default device. We need to use DESC from snd_device_name_hint(). */ /* It's the default device. We need to use DESC from snd_device_name_hint(). */
if (((ma_snd_device_name_hint_proc)pContext->alsa.snd_device_name_hint)(-1, "pcm", (void***)&ppDeviceHints) < 0) { if (((ma_snd_device_name_hint_proc)pContext->alsa.snd_device_name_hint)(-1, "pcm", (void***)&ppDeviceHints) < 0) {
ma_free(pInfo); ma__free_from_callbacks(pInfo, &pContext->allocationCallbacks);
return MA_NO_BACKEND; return MA_NO_BACKEND;
} }
...@@ -14344,18 +14481,18 @@ static ma_result ma_device_init_by_type__alsa(ma_context* pContext, const ma_dev ...@@ -14344,18 +14481,18 @@ static ma_result ma_device_init_by_type__alsa(ma_context* pContext, const ma_dev
} }
} }
ma_free(pInfo); ma__free_from_callbacks(pInfo, &pContext->allocationCallbacks);
} }
/* Hardware parameters. */ /* Hardware parameters. */
pHWParams = (ma_snd_pcm_hw_params_t*)calloc(1, ((ma_snd_pcm_hw_params_sizeof_proc)pContext->alsa.snd_pcm_hw_params_sizeof)()); pHWParams = (ma_snd_pcm_hw_params_t*)ma__calloc_from_callbacks(((ma_snd_pcm_hw_params_sizeof_proc)pContext->alsa.snd_pcm_hw_params_sizeof)(), &pContext->allocationCallbacks);
if (pHWParams == NULL) { if (pHWParams == NULL) {
return MA_OUT_OF_MEMORY; return MA_OUT_OF_MEMORY;
} }
if (((ma_snd_pcm_hw_params_any_proc)pContext->alsa.snd_pcm_hw_params_any)(pPCM, pHWParams) < 0) { if (((ma_snd_pcm_hw_params_any_proc)pContext->alsa.snd_pcm_hw_params_any)(pPCM, pHWParams) < 0) {
ma_free(pHWParams); ma__free_from_callbacks(pHWParams, &pContext->allocationCallbacks);
((ma_snd_pcm_close_proc)pDevice->pContext->alsa.snd_pcm_close)(pPCM); ((ma_snd_pcm_close_proc)pDevice->pContext->alsa.snd_pcm_close)(pPCM);
return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[ALSA] Failed to initialize hardware parameters. snd_pcm_hw_params_any() failed.", MA_FAILED_TO_CONFIGURE_BACKEND_DEVICE); return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[ALSA] Failed to initialize hardware parameters. snd_pcm_hw_params_any() failed.", MA_FAILED_TO_CONFIGURE_BACKEND_DEVICE);
} }
...@@ -14374,7 +14511,7 @@ static ma_result ma_device_init_by_type__alsa(ma_context* pContext, const ma_dev ...@@ -14374,7 +14511,7 @@ static ma_result ma_device_init_by_type__alsa(ma_context* pContext, const ma_dev
if (!isUsingMMap) { if (!isUsingMMap) {
if (((ma_snd_pcm_hw_params_set_access_proc)pContext->alsa.snd_pcm_hw_params_set_access)(pPCM, pHWParams, MA_SND_PCM_ACCESS_RW_INTERLEAVED) < 0) { if (((ma_snd_pcm_hw_params_set_access_proc)pContext->alsa.snd_pcm_hw_params_set_access)(pPCM, pHWParams, MA_SND_PCM_ACCESS_RW_INTERLEAVED) < 0) {
ma_free(pHWParams); ma__free_from_callbacks(pHWParams, &pContext->allocationCallbacks);
((ma_snd_pcm_close_proc)pDevice->pContext->alsa.snd_pcm_close)(pPCM); ((ma_snd_pcm_close_proc)pDevice->pContext->alsa.snd_pcm_close)(pPCM);
return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[ALSA] Failed to set access mode to neither SND_PCM_ACCESS_MMAP_INTERLEAVED nor SND_PCM_ACCESS_RW_INTERLEAVED. snd_pcm_hw_params_set_access() failed.", MA_FORMAT_NOT_SUPPORTED); return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[ALSA] Failed to set access mode to neither SND_PCM_ACCESS_MMAP_INTERLEAVED nor SND_PCM_ACCESS_RW_INTERLEAVED. snd_pcm_hw_params_set_access() failed.", MA_FORMAT_NOT_SUPPORTED);
} }
...@@ -14390,9 +14527,9 @@ static ma_result ma_device_init_by_type__alsa(ma_context* pContext, const ma_dev ...@@ -14390,9 +14527,9 @@ static ma_result ma_device_init_by_type__alsa(ma_context* pContext, const ma_dev
ma_snd_pcm_format_mask_t* pFormatMask; ma_snd_pcm_format_mask_t* pFormatMask;
/* Try getting every supported format first. */ /* Try getting every supported format first. */
pFormatMask = (ma_snd_pcm_format_mask_t*)calloc(1, ((ma_snd_pcm_format_mask_sizeof_proc)pContext->alsa.snd_pcm_format_mask_sizeof)()); pFormatMask = (ma_snd_pcm_format_mask_t*)ma__calloc_from_callbacks(((ma_snd_pcm_format_mask_sizeof_proc)pContext->alsa.snd_pcm_format_mask_sizeof)(), &pContext->allocationCallbacks);
if (pFormatMask == NULL) { if (pFormatMask == NULL) {
ma_free(pHWParams); ma__free_from_callbacks(pHWParams, &pContext->allocationCallbacks);
((ma_snd_pcm_close_proc)pDevice->pContext->alsa.snd_pcm_close)(pPCM); ((ma_snd_pcm_close_proc)pDevice->pContext->alsa.snd_pcm_close)(pPCM);
return MA_OUT_OF_MEMORY; return MA_OUT_OF_MEMORY;
} }
...@@ -14432,24 +14569,24 @@ static ma_result ma_device_init_by_type__alsa(ma_context* pContext, const ma_dev ...@@ -14432,24 +14569,24 @@ static ma_result ma_device_init_by_type__alsa(ma_context* pContext, const ma_dev
} }
if (formatALSA == MA_SND_PCM_FORMAT_UNKNOWN) { if (formatALSA == MA_SND_PCM_FORMAT_UNKNOWN) {
ma_free(pHWParams); ma__free_from_callbacks(pHWParams, &pContext->allocationCallbacks);
((ma_snd_pcm_close_proc)pDevice->pContext->alsa.snd_pcm_close)(pPCM); ((ma_snd_pcm_close_proc)pDevice->pContext->alsa.snd_pcm_close)(pPCM);
return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[ALSA] Format not supported. The device does not support any miniaudio formats.", MA_FORMAT_NOT_SUPPORTED); return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[ALSA] Format not supported. The device does not support any miniaudio formats.", MA_FORMAT_NOT_SUPPORTED);
} }
} }
ma_free(pFormatMask); ma__free_from_callbacks(pFormatMask, &pContext->allocationCallbacks);
pFormatMask = NULL; pFormatMask = NULL;
if (((ma_snd_pcm_hw_params_set_format_proc)pContext->alsa.snd_pcm_hw_params_set_format)(pPCM, pHWParams, formatALSA) < 0) { if (((ma_snd_pcm_hw_params_set_format_proc)pContext->alsa.snd_pcm_hw_params_set_format)(pPCM, pHWParams, formatALSA) < 0) {
ma_free(pHWParams); ma__free_from_callbacks(pHWParams, &pContext->allocationCallbacks);
((ma_snd_pcm_close_proc)pDevice->pContext->alsa.snd_pcm_close)(pPCM); ((ma_snd_pcm_close_proc)pDevice->pContext->alsa.snd_pcm_close)(pPCM);
return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[ALSA] Format not supported. snd_pcm_hw_params_set_format() failed.", MA_FORMAT_NOT_SUPPORTED); return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[ALSA] Format not supported. snd_pcm_hw_params_set_format() failed.", MA_FORMAT_NOT_SUPPORTED);
} }
internalFormat = ma_format_from_alsa(formatALSA); internalFormat = ma_format_from_alsa(formatALSA);
if (internalFormat == ma_format_unknown) { if (internalFormat == ma_format_unknown) {
ma_free(pHWParams); ma__free_from_callbacks(pHWParams, &pContext->allocationCallbacks);
((ma_snd_pcm_close_proc)pDevice->pContext->alsa.snd_pcm_close)(pPCM); ((ma_snd_pcm_close_proc)pDevice->pContext->alsa.snd_pcm_close)(pPCM);
return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[ALSA] The chosen format is not supported by miniaudio.", MA_FORMAT_NOT_SUPPORTED); return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[ALSA] The chosen format is not supported by miniaudio.", MA_FORMAT_NOT_SUPPORTED);
} }
...@@ -14459,7 +14596,7 @@ static ma_result ma_device_init_by_type__alsa(ma_context* pContext, const ma_dev ...@@ -14459,7 +14596,7 @@ static ma_result ma_device_init_by_type__alsa(ma_context* pContext, const ma_dev
{ {
unsigned int channels = (deviceType == ma_device_type_capture) ? pConfig->capture.channels : pConfig->playback.channels; unsigned int channels = (deviceType == ma_device_type_capture) ? pConfig->capture.channels : pConfig->playback.channels;
if (((ma_snd_pcm_hw_params_set_channels_near_proc)pContext->alsa.snd_pcm_hw_params_set_channels_near)(pPCM, pHWParams, &channels) < 0) { if (((ma_snd_pcm_hw_params_set_channels_near_proc)pContext->alsa.snd_pcm_hw_params_set_channels_near)(pPCM, pHWParams, &channels) < 0) {
ma_free(pHWParams); ma__free_from_callbacks(pHWParams, &pContext->allocationCallbacks);
((ma_snd_pcm_close_proc)pDevice->pContext->alsa.snd_pcm_close)(pPCM); ((ma_snd_pcm_close_proc)pDevice->pContext->alsa.snd_pcm_close)(pPCM);
return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[ALSA] Failed to set channel count. snd_pcm_hw_params_set_channels_near() failed.", MA_FORMAT_NOT_SUPPORTED); return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[ALSA] Failed to set channel count. snd_pcm_hw_params_set_channels_near() failed.", MA_FORMAT_NOT_SUPPORTED);
} }
...@@ -14491,7 +14628,7 @@ static ma_result ma_device_init_by_type__alsa(ma_context* pContext, const ma_dev ...@@ -14491,7 +14628,7 @@ static ma_result ma_device_init_by_type__alsa(ma_context* pContext, const ma_dev
sampleRate = pConfig->sampleRate; sampleRate = pConfig->sampleRate;
if (((ma_snd_pcm_hw_params_set_rate_near_proc)pContext->alsa.snd_pcm_hw_params_set_rate_near)(pPCM, pHWParams, &sampleRate, 0) < 0) { if (((ma_snd_pcm_hw_params_set_rate_near_proc)pContext->alsa.snd_pcm_hw_params_set_rate_near)(pPCM, pHWParams, &sampleRate, 0) < 0) {
ma_free(pHWParams); ma__free_from_callbacks(pHWParams, &pContext->allocationCallbacks);
((ma_snd_pcm_close_proc)pDevice->pContext->alsa.snd_pcm_close)(pPCM); ((ma_snd_pcm_close_proc)pDevice->pContext->alsa.snd_pcm_close)(pPCM);
return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[ALSA] Sample rate not supported. snd_pcm_hw_params_set_rate_near() failed.", MA_FORMAT_NOT_SUPPORTED); return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[ALSA] Sample rate not supported. snd_pcm_hw_params_set_rate_near() failed.", MA_FORMAT_NOT_SUPPORTED);
} }
...@@ -14506,7 +14643,7 @@ static ma_result ma_device_init_by_type__alsa(ma_context* pContext, const ma_dev ...@@ -14506,7 +14643,7 @@ static ma_result ma_device_init_by_type__alsa(ma_context* pContext, const ma_dev
} }
if (((ma_snd_pcm_hw_params_set_buffer_size_near_proc)pContext->alsa.snd_pcm_hw_params_set_buffer_size_near)(pPCM, pHWParams, &actualBufferSizeInFrames) < 0) { if (((ma_snd_pcm_hw_params_set_buffer_size_near_proc)pContext->alsa.snd_pcm_hw_params_set_buffer_size_near)(pPCM, pHWParams, &actualBufferSizeInFrames) < 0) {
ma_free(pHWParams); ma__free_from_callbacks(pHWParams, &pContext->allocationCallbacks);
((ma_snd_pcm_close_proc)pDevice->pContext->alsa.snd_pcm_close)(pPCM); ((ma_snd_pcm_close_proc)pDevice->pContext->alsa.snd_pcm_close)(pPCM);
return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[ALSA] Failed to set buffer size for device. snd_pcm_hw_params_set_buffer_size() failed.", MA_FORMAT_NOT_SUPPORTED); return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[ALSA] Failed to set buffer size for device. snd_pcm_hw_params_set_buffer_size() failed.", MA_FORMAT_NOT_SUPPORTED);
} }
...@@ -14517,7 +14654,7 @@ static ma_result ma_device_init_by_type__alsa(ma_context* pContext, const ma_dev ...@@ -14517,7 +14654,7 @@ static ma_result ma_device_init_by_type__alsa(ma_context* pContext, const ma_dev
{ {
ma_uint32 periods = pConfig->periods; ma_uint32 periods = pConfig->periods;
if (((ma_snd_pcm_hw_params_set_periods_near_proc)pContext->alsa.snd_pcm_hw_params_set_periods_near)(pPCM, pHWParams, &periods, NULL) < 0) { if (((ma_snd_pcm_hw_params_set_periods_near_proc)pContext->alsa.snd_pcm_hw_params_set_periods_near)(pPCM, pHWParams, &periods, NULL) < 0) {
ma_free(pHWParams); ma__free_from_callbacks(pHWParams, &pContext->allocationCallbacks);
((ma_snd_pcm_close_proc)pDevice->pContext->alsa.snd_pcm_close)(pPCM); ((ma_snd_pcm_close_proc)pDevice->pContext->alsa.snd_pcm_close)(pPCM);
return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[ALSA] Failed to set period count. snd_pcm_hw_params_set_periods_near() failed.", MA_FORMAT_NOT_SUPPORTED); return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[ALSA] Failed to set period count. snd_pcm_hw_params_set_periods_near() failed.", MA_FORMAT_NOT_SUPPORTED);
} }
...@@ -14526,30 +14663,30 @@ static ma_result ma_device_init_by_type__alsa(ma_context* pContext, const ma_dev ...@@ -14526,30 +14663,30 @@ static ma_result ma_device_init_by_type__alsa(ma_context* pContext, const ma_dev
/* Apply hardware parameters. */ /* Apply hardware parameters. */
if (((ma_snd_pcm_hw_params_proc)pContext->alsa.snd_pcm_hw_params)(pPCM, pHWParams) < 0) { if (((ma_snd_pcm_hw_params_proc)pContext->alsa.snd_pcm_hw_params)(pPCM, pHWParams) < 0) {
ma_free(pHWParams); ma__free_from_callbacks(pHWParams, &pContext->allocationCallbacks);
((ma_snd_pcm_close_proc)pDevice->pContext->alsa.snd_pcm_close)(pPCM); ((ma_snd_pcm_close_proc)pDevice->pContext->alsa.snd_pcm_close)(pPCM);
return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[ALSA] Failed to set hardware parameters. snd_pcm_hw_params() failed.", MA_FAILED_TO_CONFIGURE_BACKEND_DEVICE); return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[ALSA] Failed to set hardware parameters. snd_pcm_hw_params() failed.", MA_FAILED_TO_CONFIGURE_BACKEND_DEVICE);
} }
ma_free(pHWParams); ma__free_from_callbacks(pHWParams, &pContext->allocationCallbacks);
pHWParams = NULL; pHWParams = NULL;
/* Software parameters. */ /* Software parameters. */
pSWParams = (ma_snd_pcm_sw_params_t*)calloc(1, ((ma_snd_pcm_sw_params_sizeof_proc)pContext->alsa.snd_pcm_sw_params_sizeof)()); pSWParams = (ma_snd_pcm_sw_params_t*)ma__calloc_from_callbacks(((ma_snd_pcm_sw_params_sizeof_proc)pContext->alsa.snd_pcm_sw_params_sizeof)(), &pContext->allocationCallbacks);
if (pSWParams == NULL) { if (pSWParams == NULL) {
((ma_snd_pcm_close_proc)pDevice->pContext->alsa.snd_pcm_close)(pPCM); ((ma_snd_pcm_close_proc)pDevice->pContext->alsa.snd_pcm_close)(pPCM);
return MA_OUT_OF_MEMORY; return MA_OUT_OF_MEMORY;
} }
if (((ma_snd_pcm_sw_params_current_proc)pContext->alsa.snd_pcm_sw_params_current)(pPCM, pSWParams) != 0) { if (((ma_snd_pcm_sw_params_current_proc)pContext->alsa.snd_pcm_sw_params_current)(pPCM, pSWParams) != 0) {
ma_free(pSWParams); ma__free_from_callbacks(pSWParams, &pContext->allocationCallbacks);
((ma_snd_pcm_close_proc)pDevice->pContext->alsa.snd_pcm_close)(pPCM); ((ma_snd_pcm_close_proc)pDevice->pContext->alsa.snd_pcm_close)(pPCM);
return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[ALSA] Failed to initialize software parameters. snd_pcm_sw_params_current() failed.", MA_FAILED_TO_CONFIGURE_BACKEND_DEVICE); return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[ALSA] Failed to initialize software parameters. snd_pcm_sw_params_current() failed.", MA_FAILED_TO_CONFIGURE_BACKEND_DEVICE);
} }
if (((ma_snd_pcm_sw_params_set_avail_min_proc)pContext->alsa.snd_pcm_sw_params_set_avail_min)(pPCM, pSWParams, ma_prev_power_of_2(internalBufferSizeInFrames/internalPeriods)) != 0) { if (((ma_snd_pcm_sw_params_set_avail_min_proc)pContext->alsa.snd_pcm_sw_params_set_avail_min)(pPCM, pSWParams, ma_prev_power_of_2(internalBufferSizeInFrames/internalPeriods)) != 0) {
ma_free(pSWParams); ma__free_from_callbacks(pSWParams, &pContext->allocationCallbacks);
((ma_snd_pcm_close_proc)pDevice->pContext->alsa.snd_pcm_close)(pPCM); ((ma_snd_pcm_close_proc)pDevice->pContext->alsa.snd_pcm_close)(pPCM);
return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[ALSA] snd_pcm_sw_params_set_avail_min() failed.", MA_FORMAT_NOT_SUPPORTED); return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[ALSA] snd_pcm_sw_params_set_avail_min() failed.", MA_FORMAT_NOT_SUPPORTED);
} }
...@@ -14566,24 +14703,24 @@ static ma_result ma_device_init_by_type__alsa(ma_context* pContext, const ma_dev ...@@ -14566,24 +14703,24 @@ static ma_result ma_device_init_by_type__alsa(ma_context* pContext, const ma_dev
the size of a period. But for full-duplex we need to set it such that it is at least two periods. the size of a period. But for full-duplex we need to set it such that it is at least two periods.
*/ */
if (((ma_snd_pcm_sw_params_set_start_threshold_proc)pContext->alsa.snd_pcm_sw_params_set_start_threshold)(pPCM, pSWParams, (internalBufferSizeInFrames/internalPeriods)*2) != 0) { if (((ma_snd_pcm_sw_params_set_start_threshold_proc)pContext->alsa.snd_pcm_sw_params_set_start_threshold)(pPCM, pSWParams, (internalBufferSizeInFrames/internalPeriods)*2) != 0) {
ma_free(pSWParams); ma__free_from_callbacks(pSWParams, &pContext->allocationCallbacks);
((ma_snd_pcm_close_proc)pDevice->pContext->alsa.snd_pcm_close)(pPCM); ((ma_snd_pcm_close_proc)pDevice->pContext->alsa.snd_pcm_close)(pPCM);
return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[ALSA] Failed to set start threshold for playback device. snd_pcm_sw_params_set_start_threshold() failed.", MA_FAILED_TO_CONFIGURE_BACKEND_DEVICE); return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[ALSA] Failed to set start threshold for playback device. snd_pcm_sw_params_set_start_threshold() failed.", MA_FAILED_TO_CONFIGURE_BACKEND_DEVICE);
} }
if (((ma_snd_pcm_sw_params_set_stop_threshold_proc)pContext->alsa.snd_pcm_sw_params_set_stop_threshold)(pPCM, pSWParams, bufferBoundary) != 0) { /* Set to boundary to loop instead of stop in the event of an xrun. */ if (((ma_snd_pcm_sw_params_set_stop_threshold_proc)pContext->alsa.snd_pcm_sw_params_set_stop_threshold)(pPCM, pSWParams, bufferBoundary) != 0) { /* Set to boundary to loop instead of stop in the event of an xrun. */
ma_free(pSWParams); ma__free_from_callbacks(pSWParams, &pContext->allocationCallbacks);
((ma_snd_pcm_close_proc)pDevice->pContext->alsa.snd_pcm_close)(pPCM); ((ma_snd_pcm_close_proc)pDevice->pContext->alsa.snd_pcm_close)(pPCM);
return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[ALSA] Failed to set stop threshold for playback device. snd_pcm_sw_params_set_stop_threshold() failed.", MA_FAILED_TO_CONFIGURE_BACKEND_DEVICE); return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[ALSA] Failed to set stop threshold for playback device. snd_pcm_sw_params_set_stop_threshold() failed.", MA_FAILED_TO_CONFIGURE_BACKEND_DEVICE);
} }
} }
if (((ma_snd_pcm_sw_params_proc)pContext->alsa.snd_pcm_sw_params)(pPCM, pSWParams) != 0) { if (((ma_snd_pcm_sw_params_proc)pContext->alsa.snd_pcm_sw_params)(pPCM, pSWParams) != 0) {
ma_free(pSWParams); ma__free_from_callbacks(pSWParams, &pContext->allocationCallbacks);
((ma_snd_pcm_close_proc)pDevice->pContext->alsa.snd_pcm_close)(pPCM); ((ma_snd_pcm_close_proc)pDevice->pContext->alsa.snd_pcm_close)(pPCM);
return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[ALSA] Failed to set software parameters. snd_pcm_sw_params() failed.", MA_FAILED_TO_CONFIGURE_BACKEND_DEVICE); return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[ALSA] Failed to set software parameters. snd_pcm_sw_params() failed.", MA_FAILED_TO_CONFIGURE_BACKEND_DEVICE);
} }
ma_free(pSWParams); ma__free_from_callbacks(pSWParams, &pContext->allocationCallbacks);
pSWParams = NULL; pSWParams = NULL;
...@@ -17285,10 +17422,10 @@ static ma_result ma_context_uninit__pulse(ma_context* pContext) ...@@ -17285,10 +17422,10 @@ static ma_result ma_context_uninit__pulse(ma_context* pContext)
MA_ASSERT(pContext != NULL); MA_ASSERT(pContext != NULL);
MA_ASSERT(pContext->backend == ma_backend_pulseaudio); MA_ASSERT(pContext->backend == ma_backend_pulseaudio);
ma_free(pContext->pulse.pServerName); ma_free(pContext->pulse.pServerName, &pContext->allocationCallbacks);
pContext->pulse.pServerName = NULL; pContext->pulse.pServerName = NULL;
ma_free(pContext->pulse.pApplicationName); ma_free(pContext->pulse.pApplicationName, &pContext->allocationCallbacks);
pContext->pulse.pApplicationName = NULL; pContext->pulse.pApplicationName = NULL;
#ifndef MA_NO_RUNTIME_LINKING #ifndef MA_NO_RUNTIME_LINKING
...@@ -17466,10 +17603,10 @@ static ma_result ma_context_init__pulse(const ma_context_config* pConfig, ma_con ...@@ -17466,10 +17603,10 @@ static ma_result ma_context_init__pulse(const ma_context_config* pConfig, ma_con
pContext->onDeviceMainLoop = ma_device_main_loop__pulse; pContext->onDeviceMainLoop = ma_device_main_loop__pulse;
if (pConfig->pulse.pApplicationName) { if (pConfig->pulse.pApplicationName) {
pContext->pulse.pApplicationName = ma_copy_string(pConfig->pulse.pApplicationName); pContext->pulse.pApplicationName = ma_copy_string(pConfig->pulse.pApplicationName, &pContext->allocationCallbacks);
} }
if (pConfig->pulse.pServerName) { if (pConfig->pulse.pServerName) {
pContext->pulse.pServerName = ma_copy_string(pConfig->pulse.pServerName); pContext->pulse.pServerName = ma_copy_string(pConfig->pulse.pServerName, &pContext->allocationCallbacks);
} }
pContext->pulse.tryAutoSpawn = pConfig->pulse.tryAutoSpawn; pContext->pulse.tryAutoSpawn = pConfig->pulse.tryAutoSpawn;
...@@ -17485,8 +17622,8 @@ static ma_result ma_context_init__pulse(const ma_context_config* pConfig, ma_con ...@@ -17485,8 +17622,8 @@ static ma_result ma_context_init__pulse(const ma_context_config* pConfig, ma_con
pMainLoop = ((ma_pa_mainloop_new_proc)pContext->pulse.pa_mainloop_new)(); pMainLoop = ((ma_pa_mainloop_new_proc)pContext->pulse.pa_mainloop_new)();
if (pMainLoop == NULL) { if (pMainLoop == NULL) {
ma_free(pContext->pulse.pServerName); ma_free(pContext->pulse.pServerName, &pContext->allocationCallbacks);
ma_free(pContext->pulse.pApplicationName); ma_free(pContext->pulse.pApplicationName, &pContext->allocationCallbacks);
#ifndef MA_NO_RUNTIME_LINKING #ifndef MA_NO_RUNTIME_LINKING
ma_dlclose(pContext, pContext->pulse.pulseSO); ma_dlclose(pContext, pContext->pulse.pulseSO);
#endif #endif
...@@ -17495,8 +17632,8 @@ static ma_result ma_context_init__pulse(const ma_context_config* pConfig, ma_con ...@@ -17495,8 +17632,8 @@ static ma_result ma_context_init__pulse(const ma_context_config* pConfig, ma_con
pAPI = ((ma_pa_mainloop_get_api_proc)pContext->pulse.pa_mainloop_get_api)(pMainLoop); pAPI = ((ma_pa_mainloop_get_api_proc)pContext->pulse.pa_mainloop_get_api)(pMainLoop);
if (pAPI == NULL) { if (pAPI == NULL) {
ma_free(pContext->pulse.pServerName); ma_free(pContext->pulse.pServerName, &pContext->allocationCallbacks);
ma_free(pContext->pulse.pApplicationName); ma_free(pContext->pulse.pApplicationName, &pContext->allocationCallbacks);
((ma_pa_mainloop_free_proc)pContext->pulse.pa_mainloop_free)(pMainLoop); ((ma_pa_mainloop_free_proc)pContext->pulse.pa_mainloop_free)(pMainLoop);
#ifndef MA_NO_RUNTIME_LINKING #ifndef MA_NO_RUNTIME_LINKING
ma_dlclose(pContext, pContext->pulse.pulseSO); ma_dlclose(pContext, pContext->pulse.pulseSO);
...@@ -17506,8 +17643,8 @@ static ma_result ma_context_init__pulse(const ma_context_config* pConfig, ma_con ...@@ -17506,8 +17643,8 @@ static ma_result ma_context_init__pulse(const ma_context_config* pConfig, ma_con
pPulseContext = ((ma_pa_context_new_proc)pContext->pulse.pa_context_new)(pAPI, pContext->pulse.pApplicationName); pPulseContext = ((ma_pa_context_new_proc)pContext->pulse.pa_context_new)(pAPI, pContext->pulse.pApplicationName);
if (pPulseContext == NULL) { if (pPulseContext == NULL) {
ma_free(pContext->pulse.pServerName); ma_free(pContext->pulse.pServerName, &pContext->allocationCallbacks);
ma_free(pContext->pulse.pApplicationName); ma_free(pContext->pulse.pApplicationName, &pContext->allocationCallbacks);
((ma_pa_mainloop_free_proc)pContext->pulse.pa_mainloop_free)(pMainLoop); ((ma_pa_mainloop_free_proc)pContext->pulse.pa_mainloop_free)(pMainLoop);
#ifndef MA_NO_RUNTIME_LINKING #ifndef MA_NO_RUNTIME_LINKING
ma_dlclose(pContext, pContext->pulse.pulseSO); ma_dlclose(pContext, pContext->pulse.pulseSO);
...@@ -17517,8 +17654,8 @@ static ma_result ma_context_init__pulse(const ma_context_config* pConfig, ma_con ...@@ -17517,8 +17654,8 @@ static ma_result ma_context_init__pulse(const ma_context_config* pConfig, ma_con
error = ((ma_pa_context_connect_proc)pContext->pulse.pa_context_connect)(pPulseContext, pContext->pulse.pServerName, 0, NULL); error = ((ma_pa_context_connect_proc)pContext->pulse.pa_context_connect)(pPulseContext, pContext->pulse.pServerName, 0, NULL);
if (error != MA_PA_OK) { if (error != MA_PA_OK) {
ma_free(pContext->pulse.pServerName); ma_free(pContext->pulse.pServerName, &pContext->allocationCallbacks);
ma_free(pContext->pulse.pApplicationName); ma_free(pContext->pulse.pApplicationName, &pContext->allocationCallbacks);
((ma_pa_context_unref_proc)pContext->pulse.pa_context_unref)(pPulseContext); ((ma_pa_context_unref_proc)pContext->pulse.pa_context_unref)(pPulseContext);
((ma_pa_mainloop_free_proc)pContext->pulse.pa_mainloop_free)(pMainLoop); ((ma_pa_mainloop_free_proc)pContext->pulse.pa_mainloop_free)(pMainLoop);
#ifndef MA_NO_RUNTIME_LINKING #ifndef MA_NO_RUNTIME_LINKING
...@@ -17732,11 +17869,11 @@ static void ma_device_uninit__jack(ma_device* pDevice) ...@@ -17732,11 +17869,11 @@ static void ma_device_uninit__jack(ma_device* pDevice)
} }
if (pDevice->type == ma_device_type_capture || pDevice->type == ma_device_type_duplex) { if (pDevice->type == ma_device_type_capture || pDevice->type == ma_device_type_duplex) {
ma_free(pDevice->jack.pIntermediaryBufferCapture); ma__free_from_callbacks(pDevice->jack.pIntermediaryBufferCapture, &pDevice->pContext->allocationCallbacks);
} }
if (pDevice->type == ma_device_type_playback || pDevice->type == ma_device_type_duplex) { if (pDevice->type == ma_device_type_playback || pDevice->type == ma_device_type_duplex) {
ma_free(pDevice->jack.pIntermediaryBufferPlayback); ma__free_from_callbacks(pDevice->jack.pIntermediaryBufferPlayback, &pDevice->pContext->allocationCallbacks);
} }
if (pDevice->type == ma_device_type_duplex) { if (pDevice->type == ma_device_type_duplex) {
...@@ -17759,21 +17896,27 @@ static int ma_device__jack_buffer_size_callback(ma_jack_nframes_t frameCount, vo ...@@ -17759,21 +17896,27 @@ static int ma_device__jack_buffer_size_callback(ma_jack_nframes_t frameCount, vo
MA_ASSERT(pDevice != NULL); MA_ASSERT(pDevice != NULL);
if (pDevice->type == ma_device_type_capture || pDevice->type == ma_device_type_duplex) { if (pDevice->type == ma_device_type_capture || pDevice->type == ma_device_type_duplex) {
float* pNewBuffer = (float*)ma_realloc(pDevice->jack.pIntermediaryBufferCapture, frameCount * (pDevice->capture.internalChannels * ma_get_bytes_per_sample(pDevice->capture.internalFormat))); size_t newBufferSize = frameCount * (pDevice->capture.internalChannels * ma_get_bytes_per_sample(pDevice->capture.internalFormat));
float* pNewBuffer = (float*)ma__calloc_from_callbacks(newBufferSize, &pDevice->pContext->allocationCallbacks);
if (pNewBuffer == NULL) { if (pNewBuffer == NULL) {
return MA_OUT_OF_MEMORY; return MA_OUT_OF_MEMORY;
} }
ma__free_from_callbacks(pDevice->jack.pIntermediaryBufferCapture, &pDevice->pContext->allocationCallbacks);
pDevice->jack.pIntermediaryBufferCapture = pNewBuffer; pDevice->jack.pIntermediaryBufferCapture = pNewBuffer;
pDevice->playback.internalBufferSizeInFrames = frameCount * pDevice->capture.internalPeriods; pDevice->playback.internalBufferSizeInFrames = frameCount * pDevice->capture.internalPeriods;
} }
if (pDevice->type == ma_device_type_playback || pDevice->type == ma_device_type_duplex) { if (pDevice->type == ma_device_type_playback || pDevice->type == ma_device_type_duplex) {
float* pNewBuffer = (float*)ma_realloc(pDevice->jack.pIntermediaryBufferPlayback, frameCount * (pDevice->playback.internalChannels * ma_get_bytes_per_sample(pDevice->playback.internalFormat))); size_t newBufferSize = frameCount * (pDevice->playback.internalChannels * ma_get_bytes_per_sample(pDevice->playback.internalFormat));
float* pNewBuffer = (float*)ma__calloc_from_callbacks(newBufferSize, &pDevice->pContext->allocationCallbacks);
if (pNewBuffer == NULL) { if (pNewBuffer == NULL) {
return MA_OUT_OF_MEMORY; return MA_OUT_OF_MEMORY;
} }
ma__free_from_callbacks(pDevice->jack.pIntermediaryBufferPlayback, &pDevice->pContext->allocationCallbacks);
pDevice->jack.pIntermediaryBufferPlayback = pNewBuffer; pDevice->jack.pIntermediaryBufferPlayback = pNewBuffer;
pDevice->playback.internalBufferSizeInFrames = frameCount * pDevice->playback.internalPeriods; pDevice->playback.internalBufferSizeInFrames = frameCount * pDevice->playback.internalPeriods;
} }
...@@ -17922,7 +18065,7 @@ static ma_result ma_device_init__jack(ma_context* pContext, const ma_device_conf ...@@ -17922,7 +18065,7 @@ static ma_result ma_device_init__jack(ma_context* pContext, const ma_device_conf
pDevice->capture.internalBufferSizeInFrames = bufferSizeInFrames; pDevice->capture.internalBufferSizeInFrames = bufferSizeInFrames;
pDevice->capture.internalPeriods = periods; pDevice->capture.internalPeriods = periods;
pDevice->jack.pIntermediaryBufferCapture = (float*)ma_malloc((pDevice->capture.internalBufferSizeInFrames/pDevice->capture.internalPeriods) * (pDevice->capture.internalChannels * ma_get_bytes_per_sample(pDevice->capture.internalFormat))); pDevice->jack.pIntermediaryBufferCapture = (float*)ma__calloc_from_callbacks((pDevice->capture.internalBufferSizeInFrames/pDevice->capture.internalPeriods) * (pDevice->capture.internalChannels * ma_get_bytes_per_sample(pDevice->capture.internalFormat)), &pContext->allocationCallbacks);
if (pDevice->jack.pIntermediaryBufferCapture == NULL) { if (pDevice->jack.pIntermediaryBufferCapture == NULL) {
ma_device_uninit__jack(pDevice); ma_device_uninit__jack(pDevice);
return MA_OUT_OF_MEMORY; return MA_OUT_OF_MEMORY;
...@@ -17962,7 +18105,7 @@ static ma_result ma_device_init__jack(ma_context* pContext, const ma_device_conf ...@@ -17962,7 +18105,7 @@ static ma_result ma_device_init__jack(ma_context* pContext, const ma_device_conf
pDevice->playback.internalBufferSizeInFrames = bufferSizeInFrames; pDevice->playback.internalBufferSizeInFrames = bufferSizeInFrames;
pDevice->playback.internalPeriods = periods; pDevice->playback.internalPeriods = periods;
pDevice->jack.pIntermediaryBufferPlayback = (float*)ma_malloc((pDevice->playback.internalBufferSizeInFrames/pDevice->playback.internalPeriods) * (pDevice->playback.internalChannels * ma_get_bytes_per_sample(pDevice->playback.internalFormat))); pDevice->jack.pIntermediaryBufferPlayback = (float*)ma__calloc_from_callbacks((pDevice->playback.internalBufferSizeInFrames/pDevice->playback.internalPeriods) * (pDevice->playback.internalChannels * ma_get_bytes_per_sample(pDevice->playback.internalFormat)), &pContext->allocationCallbacks);
if (pDevice->jack.pIntermediaryBufferPlayback == NULL) { if (pDevice->jack.pIntermediaryBufferPlayback == NULL) {
ma_device_uninit__jack(pDevice); ma_device_uninit__jack(pDevice);
return MA_OUT_OF_MEMORY; return MA_OUT_OF_MEMORY;
...@@ -17971,7 +18114,7 @@ static ma_result ma_device_init__jack(ma_context* pContext, const ma_device_conf ...@@ -17971,7 +18114,7 @@ static ma_result ma_device_init__jack(ma_context* pContext, const ma_device_conf
if (pDevice->type == ma_device_type_duplex) { if (pDevice->type == ma_device_type_duplex) {
ma_uint32 rbSizeInFrames = (ma_uint32)ma_calculate_frame_count_after_src(pDevice->sampleRate, pDevice->capture.internalSampleRate, pDevice->capture.internalBufferSizeInFrames); ma_uint32 rbSizeInFrames = (ma_uint32)ma_calculate_frame_count_after_src(pDevice->sampleRate, pDevice->capture.internalSampleRate, pDevice->capture.internalBufferSizeInFrames);
result = ma_pcm_rb_init(pDevice->capture.format, pDevice->capture.channels, rbSizeInFrames, NULL, &pDevice->jack.duplexRB); result = ma_pcm_rb_init(pDevice->capture.format, pDevice->capture.channels, rbSizeInFrames, NULL, &pDevice->pContext->allocationCallbacks, &pDevice->jack.duplexRB);
if (result != MA_SUCCESS) { if (result != MA_SUCCESS) {
ma_device_uninit__jack(pDevice); ma_device_uninit__jack(pDevice);
return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[JACK] Failed to initialize ring buffer.", result); return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[JACK] Failed to initialize ring buffer.", result);
...@@ -18074,7 +18217,7 @@ static ma_result ma_context_uninit__jack(ma_context* pContext) ...@@ -18074,7 +18217,7 @@ static ma_result ma_context_uninit__jack(ma_context* pContext)
MA_ASSERT(pContext != NULL); MA_ASSERT(pContext != NULL);
MA_ASSERT(pContext->backend == ma_backend_jack); MA_ASSERT(pContext->backend == ma_backend_jack);
ma_free(pContext->jack.pClientName); ma_free(pContext->jack.pClientName, &pContext->allocationCallbacks);
pContext->jack.pClientName = NULL; pContext->jack.pClientName = NULL;
#ifndef MA_NO_RUNTIME_LINKING #ifndef MA_NO_RUNTIME_LINKING
...@@ -18176,7 +18319,7 @@ static ma_result ma_context_init__jack(const ma_context_config* pConfig, ma_cont ...@@ -18176,7 +18319,7 @@ static ma_result ma_context_init__jack(const ma_context_config* pConfig, ma_cont
pContext->onDeviceStop = ma_device_stop__jack; pContext->onDeviceStop = ma_device_stop__jack;
if (pConfig->jack.pClientName != NULL) { if (pConfig->jack.pClientName != NULL) {
pContext->jack.pClientName = ma_copy_string(pConfig->jack.pClientName); pContext->jack.pClientName = ma_copy_string(pConfig->jack.pClientName, &pContext->allocationCallbacks);
} }
pContext->jack.tryStartServer = pConfig->jack.tryStartServer; pContext->jack.tryStartServer = pConfig->jack.tryStartServer;
...@@ -18188,7 +18331,7 @@ static ma_result ma_context_init__jack(const ma_context_config* pConfig, ma_cont ...@@ -18188,7 +18331,7 @@ static ma_result ma_context_init__jack(const ma_context_config* pConfig, ma_cont
ma_jack_client_t* pDummyClient; ma_jack_client_t* pDummyClient;
ma_result result = ma_context_open_client__jack(pContext, &pDummyClient); ma_result result = ma_context_open_client__jack(pContext, &pDummyClient);
if (result != MA_SUCCESS) { if (result != MA_SUCCESS) {
ma_free(pContext->jack.pClientName); ma_free(pContext->jack.pClientName, &pContext->allocationCallbacks);
#ifndef MA_NO_RUNTIME_LINKING #ifndef MA_NO_RUNTIME_LINKING
ma_dlclose(pContext, pContext->jack.jackSO); ma_dlclose(pContext, pContext->jack.jackSO);
#endif #endif
...@@ -18609,21 +18752,20 @@ static ma_result ma_get_device_object_ids__coreaudio(ma_context* pContext, UInt3 ...@@ -18609,21 +18752,20 @@ static ma_result ma_get_device_object_ids__coreaudio(ma_context* pContext, UInt3
return ma_result_from_OSStatus(status); return ma_result_from_OSStatus(status);
} }
pDeviceObjectIDs = (AudioObjectID*)ma_malloc(deviceObjectsDataSize); pDeviceObjectIDs = (AudioObjectID*)ma_malloc(deviceObjectsDataSize, &pContext->allocationCallbacks);
if (pDeviceObjectIDs == NULL) { if (pDeviceObjectIDs == NULL) {
return MA_OUT_OF_MEMORY; return MA_OUT_OF_MEMORY;
} }
status = ((ma_AudioObjectGetPropertyData_proc)pContext->coreaudio.AudioObjectGetPropertyData)(kAudioObjectSystemObject, &propAddressDevices, 0, NULL, &deviceObjectsDataSize, pDeviceObjectIDs); status = ((ma_AudioObjectGetPropertyData_proc)pContext->coreaudio.AudioObjectGetPropertyData)(kAudioObjectSystemObject, &propAddressDevices, 0, NULL, &deviceObjectsDataSize, pDeviceObjectIDs);
if (status != noErr) { if (status != noErr) {
ma_free(pDeviceObjectIDs); ma_free(pDeviceObjectIDs, &pContext->allocationCallbacks);
return ma_result_from_OSStatus(status); return ma_result_from_OSStatus(status);
} }
*pDeviceCount = deviceObjectsDataSize / sizeof(AudioObjectID); *pDeviceCount = deviceObjectsDataSize / sizeof(AudioObjectID);
*ppDeviceObjectIDs = pDeviceObjectIDs; *ppDeviceObjectIDs = pDeviceObjectIDs;
(void)pContext; /* Unused. */
return MA_SUCCESS; return MA_SUCCESS;
} }
...@@ -18715,14 +18857,14 @@ static ma_bool32 ma_does_AudioObject_support_scope(ma_context* pContext, AudioOb ...@@ -18715,14 +18857,14 @@ static ma_bool32 ma_does_AudioObject_support_scope(ma_context* pContext, AudioOb
return MA_FALSE; return MA_FALSE;
} }
pBufferList = (AudioBufferList*)ma_malloc(dataSize); pBufferList = (AudioBufferList*)ma__malloc_from_callbacks(dataSize, &pContext->allocationCallbacks);
if (pBufferList == NULL) { if (pBufferList == NULL) {
return MA_FALSE; /* Out of memory. */ return MA_FALSE; /* Out of memory. */
} }
status = ((ma_AudioObjectGetPropertyData_proc)pContext->coreaudio.AudioObjectGetPropertyData)(deviceObjectID, &propAddress, 0, NULL, &dataSize, pBufferList); status = ((ma_AudioObjectGetPropertyData_proc)pContext->coreaudio.AudioObjectGetPropertyData)(deviceObjectID, &propAddress, 0, NULL, &dataSize, pBufferList);
if (status != noErr) { if (status != noErr) {
ma_free(pBufferList); ma__free_from_callbacks(pBufferList, &pContext->allocationCallbacks);
return MA_FALSE; return MA_FALSE;
} }
...@@ -18731,7 +18873,7 @@ static ma_bool32 ma_does_AudioObject_support_scope(ma_context* pContext, AudioOb ...@@ -18731,7 +18873,7 @@ static ma_bool32 ma_does_AudioObject_support_scope(ma_context* pContext, AudioOb
isSupported = MA_TRUE; isSupported = MA_TRUE;
} }
ma_free(pBufferList); ma__free_from_callbacks(pBufferList, &pContext->allocationCallbacks);
return isSupported; return isSupported;
} }
...@@ -18770,14 +18912,14 @@ static ma_result ma_get_AudioObject_stream_descriptions(ma_context* pContext, Au ...@@ -18770,14 +18912,14 @@ static ma_result ma_get_AudioObject_stream_descriptions(ma_context* pContext, Au
return ma_result_from_OSStatus(status); return ma_result_from_OSStatus(status);
} }
pDescriptions = (AudioStreamRangedDescription*)ma_malloc(dataSize); pDescriptions = (AudioStreamRangedDescription*)ma_malloc(dataSize, &pContext->allocationCallbacks);
if (pDescriptions == NULL) { if (pDescriptions == NULL) {
return MA_OUT_OF_MEMORY; return MA_OUT_OF_MEMORY;
} }
status = ((ma_AudioObjectGetPropertyData_proc)pContext->coreaudio.AudioObjectGetPropertyData)(deviceObjectID, &propAddress, 0, NULL, &dataSize, pDescriptions); status = ((ma_AudioObjectGetPropertyData_proc)pContext->coreaudio.AudioObjectGetPropertyData)(deviceObjectID, &propAddress, 0, NULL, &dataSize, pDescriptions);
if (status != noErr) { if (status != noErr) {
ma_free(pDescriptions); ma_free(pDescriptions, &pContext->allocationCallbacks);
return ma_result_from_OSStatus(status); return ma_result_from_OSStatus(status);
} }
...@@ -18808,14 +18950,14 @@ static ma_result ma_get_AudioObject_channel_layout(ma_context* pContext, AudioOb ...@@ -18808,14 +18950,14 @@ static ma_result ma_get_AudioObject_channel_layout(ma_context* pContext, AudioOb
return ma_result_from_OSStatus(status); return ma_result_from_OSStatus(status);
} }
pChannelLayout = (AudioChannelLayout*)ma_malloc(dataSize); pChannelLayout = (AudioChannelLayout*)ma_malloc(dataSize, &pContext->allocationCallbacks);
if (pChannelLayout == NULL) { if (pChannelLayout == NULL) {
return MA_OUT_OF_MEMORY; return MA_OUT_OF_MEMORY;
} }
status = ((ma_AudioObjectGetPropertyData_proc)pContext->coreaudio.AudioObjectGetPropertyData)(deviceObjectID, &propAddress, 0, NULL, &dataSize, pChannelLayout); status = ((ma_AudioObjectGetPropertyData_proc)pContext->coreaudio.AudioObjectGetPropertyData)(deviceObjectID, &propAddress, 0, NULL, &dataSize, pChannelLayout);
if (status != noErr) { if (status != noErr) {
ma_free(pChannelLayout); ma_free(pChannelLayout, &pContext->allocationCallbacks);
return ma_result_from_OSStatus(status); return ma_result_from_OSStatus(status);
} }
...@@ -18846,7 +18988,7 @@ static ma_result ma_get_AudioObject_channel_count(ma_context* pContext, AudioObj ...@@ -18846,7 +18988,7 @@ static ma_result ma_get_AudioObject_channel_count(ma_context* pContext, AudioObj
*pChannelCount = AudioChannelLayoutTag_GetNumberOfChannels(pChannelLayout->mChannelLayoutTag); *pChannelCount = AudioChannelLayoutTag_GetNumberOfChannels(pChannelLayout->mChannelLayoutTag);
} }
ma_free(pChannelLayout); ma_free(pChannelLayout, &pContext->allocationCallbacks);
return MA_SUCCESS; return MA_SUCCESS;
} }
...@@ -18864,11 +19006,11 @@ static ma_result ma_get_AudioObject_channel_map(ma_context* pContext, AudioObjec ...@@ -18864,11 +19006,11 @@ static ma_result ma_get_AudioObject_channel_map(ma_context* pContext, AudioObjec
result = ma_get_channel_map_from_AudioChannelLayout(pChannelLayout, channelMap); result = ma_get_channel_map_from_AudioChannelLayout(pChannelLayout, channelMap);
if (result != MA_SUCCESS) { if (result != MA_SUCCESS) {
ma_free(pChannelLayout); ma_free(pChannelLayout, &pContext->allocationCallbacks);
return result; return result;
} }
ma_free(pChannelLayout); ma_free(pChannelLayout, &pContext->allocationCallbacks);
return result; return result;
} }
...@@ -18896,14 +19038,14 @@ static ma_result ma_get_AudioObject_sample_rates(ma_context* pContext, AudioObje ...@@ -18896,14 +19038,14 @@ static ma_result ma_get_AudioObject_sample_rates(ma_context* pContext, AudioObje
return ma_result_from_OSStatus(status); return ma_result_from_OSStatus(status);
} }
pSampleRateRanges = (AudioValueRange*)ma_malloc(dataSize); pSampleRateRanges = (AudioValueRange*)ma_malloc(dataSize, &pContext->allocationCallbacks);
if (pSampleRateRanges == NULL) { if (pSampleRateRanges == NULL) {
return MA_OUT_OF_MEMORY; return MA_OUT_OF_MEMORY;
} }
status = ((ma_AudioObjectGetPropertyData_proc)pContext->coreaudio.AudioObjectGetPropertyData)(deviceObjectID, &propAddress, 0, NULL, &dataSize, pSampleRateRanges); status = ((ma_AudioObjectGetPropertyData_proc)pContext->coreaudio.AudioObjectGetPropertyData)(deviceObjectID, &propAddress, 0, NULL, &dataSize, pSampleRateRanges);
if (status != noErr) { if (status != noErr) {
ma_free(pSampleRateRanges); ma_free(pSampleRateRanges, &pContext->allocationCallbacks);
return ma_result_from_OSStatus(status); return ma_result_from_OSStatus(status);
} }
...@@ -18929,7 +19071,7 @@ static ma_result ma_get_AudioObject_get_closest_sample_rate(ma_context* pContext ...@@ -18929,7 +19071,7 @@ static ma_result ma_get_AudioObject_get_closest_sample_rate(ma_context* pContext
} }
if (sampleRateRangeCount == 0) { if (sampleRateRangeCount == 0) {
ma_free(pSampleRateRanges); ma_free(pSampleRateRanges, &pContext->allocationCallbacks);
return MA_ERROR; /* Should never hit this case should we? */ return MA_ERROR; /* Should never hit this case should we? */
} }
...@@ -18943,7 +19085,7 @@ static ma_result ma_get_AudioObject_get_closest_sample_rate(ma_context* pContext ...@@ -18943,7 +19085,7 @@ static ma_result ma_get_AudioObject_get_closest_sample_rate(ma_context* pContext
AudioValueRange caSampleRate = pSampleRateRanges[iCASampleRate]; AudioValueRange caSampleRate = pSampleRateRanges[iCASampleRate];
if (caSampleRate.mMinimum <= malSampleRate && caSampleRate.mMaximum >= malSampleRate) { if (caSampleRate.mMinimum <= malSampleRate && caSampleRate.mMaximum >= malSampleRate) {
*pSampleRateOut = malSampleRate; *pSampleRateOut = malSampleRate;
ma_free(pSampleRateRanges); ma_free(pSampleRateRanges, &pContext->allocationCallbacks);
return MA_SUCCESS; return MA_SUCCESS;
} }
} }
...@@ -18956,7 +19098,7 @@ static ma_result ma_get_AudioObject_get_closest_sample_rate(ma_context* pContext ...@@ -18956,7 +19098,7 @@ static ma_result ma_get_AudioObject_get_closest_sample_rate(ma_context* pContext
MA_ASSERT(sampleRateRangeCount > 0); MA_ASSERT(sampleRateRangeCount > 0);
*pSampleRateOut = pSampleRateRanges[0].mMinimum; *pSampleRateOut = pSampleRateRanges[0].mMinimum;
ma_free(pSampleRateRanges); ma_free(pSampleRateRanges, &pContext->allocationCallbacks);
return MA_SUCCESS; return MA_SUCCESS;
} else { } else {
/* Find the closest match to this sample rate. */ /* Find the closest match to this sample rate. */
...@@ -18966,7 +19108,7 @@ static ma_result ma_get_AudioObject_get_closest_sample_rate(ma_context* pContext ...@@ -18966,7 +19108,7 @@ static ma_result ma_get_AudioObject_get_closest_sample_rate(ma_context* pContext
for (iRange = 0; iRange < sampleRateRangeCount; ++iRange) { for (iRange = 0; iRange < sampleRateRangeCount; ++iRange) {
if (pSampleRateRanges[iRange].mMinimum <= sampleRateIn && pSampleRateRanges[iRange].mMaximum >= sampleRateIn) { if (pSampleRateRanges[iRange].mMinimum <= sampleRateIn && pSampleRateRanges[iRange].mMaximum >= sampleRateIn) {
*pSampleRateOut = sampleRateIn; *pSampleRateOut = sampleRateIn;
ma_free(pSampleRateRanges); ma_free(pSampleRateRanges, &pContext->allocationCallbacks);
return MA_SUCCESS; return MA_SUCCESS;
} else { } else {
UInt32 absoluteDifference; UInt32 absoluteDifference;
...@@ -18986,12 +19128,12 @@ static ma_result ma_get_AudioObject_get_closest_sample_rate(ma_context* pContext ...@@ -18986,12 +19128,12 @@ static ma_result ma_get_AudioObject_get_closest_sample_rate(ma_context* pContext
MA_ASSERT(iCurrentClosestRange != (UInt32)-1); MA_ASSERT(iCurrentClosestRange != (UInt32)-1);
*pSampleRateOut = pSampleRateRanges[iCurrentClosestRange].mMinimum; *pSampleRateOut = pSampleRateRanges[iCurrentClosestRange].mMinimum;
ma_free(pSampleRateRanges); ma_free(pSampleRateRanges, &pContext->allocationCallbacks);
return MA_SUCCESS; return MA_SUCCESS;
} }
/* Should never get here, but it would mean we weren't able to find any suitable sample rates. */ /* Should never get here, but it would mean we weren't able to find any suitable sample rates. */
/*ma_free(pSampleRateRanges);*/ /*ma_free(pSampleRateRanges, &pContext->allocationCallbacks);*/
/*return MA_ERROR;*/ /*return MA_ERROR;*/
} }
...@@ -19117,7 +19259,7 @@ static ma_result ma_find_AudioObjectID(ma_context* pContext, ma_device_type devi ...@@ -19117,7 +19259,7 @@ static ma_result ma_find_AudioObjectID(ma_context* pContext, ma_device_type devi
if (ma_does_AudioObject_support_playback(pContext, deviceObjectID)) { if (ma_does_AudioObject_support_playback(pContext, deviceObjectID)) {
if (strcmp(uid, pDeviceID->coreaudio) == 0) { if (strcmp(uid, pDeviceID->coreaudio) == 0) {
*pDeviceObjectID = deviceObjectID; *pDeviceObjectID = deviceObjectID;
ma_free(pDeviceObjectIDs); ma_free(pDeviceObjectIDs, &pContext->allocationCallbacks);
return MA_SUCCESS; return MA_SUCCESS;
} }
} }
...@@ -19125,14 +19267,14 @@ static ma_result ma_find_AudioObjectID(ma_context* pContext, ma_device_type devi ...@@ -19125,14 +19267,14 @@ static ma_result ma_find_AudioObjectID(ma_context* pContext, ma_device_type devi
if (ma_does_AudioObject_support_capture(pContext, deviceObjectID)) { if (ma_does_AudioObject_support_capture(pContext, deviceObjectID)) {
if (strcmp(uid, pDeviceID->coreaudio) == 0) { if (strcmp(uid, pDeviceID->coreaudio) == 0) {
*pDeviceObjectID = deviceObjectID; *pDeviceObjectID = deviceObjectID;
ma_free(pDeviceObjectIDs); ma_free(pDeviceObjectIDs, &pContext->allocationCallbacks);
return MA_SUCCESS; return MA_SUCCESS;
} }
} }
} }
} }
ma_free(pDeviceObjectIDs); ma_free(pDeviceObjectIDs, &pContext->allocationCallbacks);
} }
/* If we get here it means we couldn't find the device. */ /* If we get here it means we couldn't find the device. */
...@@ -19213,7 +19355,7 @@ static ma_result ma_find_best_format__coreaudio(ma_context* pContext, AudioObjec ...@@ -19213,7 +19355,7 @@ static ma_result ma_find_best_format__coreaudio(ma_context* pContext, AudioObjec
} }
if (!hasSupportedFormat) { if (!hasSupportedFormat) {
ma_free(pDeviceFormatDescriptions); ma_free(pDeviceFormatDescriptions, &pContext->allocationCallbacks);
return MA_FORMAT_NOT_SUPPORTED; return MA_FORMAT_NOT_SUPPORTED;
} }
...@@ -19336,7 +19478,7 @@ static ma_result ma_find_best_format__coreaudio(ma_context* pContext, AudioObjec ...@@ -19336,7 +19478,7 @@ static ma_result ma_find_best_format__coreaudio(ma_context* pContext, AudioObjec
*pFormat = bestDeviceFormatSoFar; *pFormat = bestDeviceFormatSoFar;
ma_free(pDeviceFormatDescriptions); ma_free(pDeviceFormatDescriptions, &pContext->allocationCallbacks);
return MA_SUCCESS; return MA_SUCCESS;
} }
#endif #endif
...@@ -19365,24 +19507,24 @@ static ma_result ma_get_AudioUnit_channel_map(ma_context* pContext, AudioUnit au ...@@ -19365,24 +19507,24 @@ static ma_result ma_get_AudioUnit_channel_map(ma_context* pContext, AudioUnit au
return ma_result_from_OSStatus(status); return ma_result_from_OSStatus(status);
} }
pChannelLayout = (AudioChannelLayout*)ma_malloc(channelLayoutSize); pChannelLayout = (AudioChannelLayout*)ma__malloc_from_callbacks(channelLayoutSize, &pContext->allocationCallbacks);
if (pChannelLayout == NULL) { if (pChannelLayout == NULL) {
return MA_OUT_OF_MEMORY; return MA_OUT_OF_MEMORY;
} }
status = ((ma_AudioUnitGetProperty_proc)pContext->coreaudio.AudioUnitGetProperty)(audioUnit, kAudioUnitProperty_AudioChannelLayout, deviceScope, deviceBus, pChannelLayout, &channelLayoutSize); status = ((ma_AudioUnitGetProperty_proc)pContext->coreaudio.AudioUnitGetProperty)(audioUnit, kAudioUnitProperty_AudioChannelLayout, deviceScope, deviceBus, pChannelLayout, &channelLayoutSize);
if (status != noErr) { if (status != noErr) {
ma_free(pChannelLayout); ma__free_from_callbacks(pChannelLayout, &pContext->allocationCallbacks);
return ma_result_from_OSStatus(status); return ma_result_from_OSStatus(status);
} }
result = ma_get_channel_map_from_AudioChannelLayout(pChannelLayout, channelMap); result = ma_get_channel_map_from_AudioChannelLayout(pChannelLayout, channelMap);
if (result != MA_SUCCESS) { if (result != MA_SUCCESS) {
ma_free(pChannelLayout); ma__free_from_callbacks(pChannelLayout, &pContext->allocationCallbacks);
return result; return result;
} }
ma_free(pChannelLayout); ma__free_from_callbacks(pChannelLayout, &pContext->allocationCallbacks);
return MA_SUCCESS; return MA_SUCCESS;
} }
...@@ -19433,7 +19575,7 @@ static ma_result ma_context_enumerate_devices__coreaudio(ma_context* pContext, m ...@@ -19433,7 +19575,7 @@ static ma_result ma_context_enumerate_devices__coreaudio(ma_context* pContext, m
} }
} }
ma_free(pDeviceObjectIDs); ma_free(pDeviceObjectIDs, &pContext->allocationCallbacks);
#else #else
/* Only supporting default devices on non-Desktop platforms. */ /* Only supporting default devices on non-Desktop platforms. */
ma_device_info info; ma_device_info info;
...@@ -19521,7 +19663,7 @@ static ma_result ma_context_get_device_info__coreaudio(ma_context* pContext, ma_ ...@@ -19521,7 +19663,7 @@ static ma_result ma_context_get_device_info__coreaudio(ma_context* pContext, ma_
} }
} }
ma_free(pStreamDescriptions); ma_free(pStreamDescriptions, &pContext->allocationCallbacks);
/* Channels. */ /* Channels. */
...@@ -20057,15 +20199,17 @@ static ma_result ma_device__track__coreaudio(ma_device* pDevice) ...@@ -20057,15 +20199,17 @@ static ma_result ma_device__track__coreaudio(ma_device* pDevice)
{ {
/* Allocate memory if required. */ /* Allocate memory if required. */
if (g_TrackedDeviceCap_CoreAudio <= g_TrackedDeviceCount_CoreAudio) { if (g_TrackedDeviceCap_CoreAudio <= g_TrackedDeviceCount_CoreAudio) {
ma_uint32 oldCap;
ma_uint32 newCap; ma_uint32 newCap;
ma_device** ppNewDevices; ma_device** ppNewDevices;
oldCap = g_TrackedDeviceCap_CoreAudio;
newCap = g_TrackedDeviceCap_CoreAudio * 2; newCap = g_TrackedDeviceCap_CoreAudio * 2;
if (newCap == 0) { if (newCap == 0) {
newCap = 1; newCap = 1;
} }
ppNewDevices = (ma_device**)ma_realloc(g_ppTrackedDevices_CoreAudio, sizeof(*g_ppTrackedDevices_CoreAudio) * newCap); ppNewDevices = (ma_device**)ma__realloc_from_callbacks(g_ppTrackedDevices_CoreAudio, sizeof(*g_ppTrackedDevices_CoreAudio)*newCap, sizeof(*g_ppTrackedDevices_CoreAudio)*oldCap, &pDevice->pContext->allocationCallbacks);
if (ppNewDevices == NULL) { if (ppNewDevices == NULL) {
ma_mutex_unlock(&g_DeviceTrackingMutex_CoreAudio); ma_mutex_unlock(&g_DeviceTrackingMutex_CoreAudio);
return MA_OUT_OF_MEMORY; return MA_OUT_OF_MEMORY;
...@@ -20104,7 +20248,7 @@ static ma_result ma_device__untrack__coreaudio(ma_device* pDevice) ...@@ -20104,7 +20248,7 @@ static ma_result ma_device__untrack__coreaudio(ma_device* pDevice)
/* If there's nothing else in the list we need to free memory. */ /* If there's nothing else in the list we need to free memory. */
if (g_TrackedDeviceCount_CoreAudio == 0) { if (g_TrackedDeviceCount_CoreAudio == 0) {
ma_free(g_ppTrackedDevices_CoreAudio); ma__free_from_callbacks(g_ppTrackedDevices_CoreAudio, &pDevice->pContext->allocationCallbacks);
g_ppTrackedDevices_CoreAudio = NULL; g_ppTrackedDevices_CoreAudio = NULL;
g_TrackedDeviceCap_CoreAudio = 0; g_TrackedDeviceCap_CoreAudio = 0;
} }
...@@ -20250,7 +20394,7 @@ static void ma_device_uninit__coreaudio(ma_device* pDevice) ...@@ -20250,7 +20394,7 @@ static void ma_device_uninit__coreaudio(ma_device* pDevice)
} }
if (pDevice->coreaudio.pAudioBufferList) { if (pDevice->coreaudio.pAudioBufferList) {
ma_free(pDevice->coreaudio.pAudioBufferList); ma__free_from_callbacks(pDevice->coreaudio.pAudioBufferList, &pDevice->pContext->allocationCallbacks);
} }
if (pDevice->type == ma_device_type_duplex) { if (pDevice->type == ma_device_type_duplex) {
...@@ -20564,7 +20708,7 @@ static ma_result ma_device_init_internal__coreaudio(ma_context* pContext, ma_dev ...@@ -20564,7 +20708,7 @@ static ma_result ma_device_init_internal__coreaudio(ma_context* pContext, ma_dev
allocationSize += actualBufferSizeInFrames * ma_get_bytes_per_sample(pData->formatOut) * pData->channelsOut; allocationSize += actualBufferSizeInFrames * ma_get_bytes_per_sample(pData->formatOut) * pData->channelsOut;
} }
pBufferList = (AudioBufferList*)ma_malloc(allocationSize); pBufferList = (AudioBufferList*)ma__malloc_from_callbacks(allocationSize, &pContext->allocationCallbacks);
if (pBufferList == NULL) { if (pBufferList == NULL) {
((ma_AudioComponentInstanceDispose_proc)pContext->coreaudio.AudioComponentInstanceDispose)(pData->audioUnit); ((ma_AudioComponentInstanceDispose_proc)pContext->coreaudio.AudioComponentInstanceDispose)(pData->audioUnit);
return MA_OUT_OF_MEMORY; return MA_OUT_OF_MEMORY;
...@@ -20618,7 +20762,7 @@ static ma_result ma_device_init_internal__coreaudio(ma_context* pContext, ma_dev ...@@ -20618,7 +20762,7 @@ static ma_result ma_device_init_internal__coreaudio(ma_context* pContext, ma_dev
/* Initialize the audio unit. */ /* Initialize the audio unit. */
status = ((ma_AudioUnitInitialize_proc)pContext->coreaudio.AudioUnitInitialize)(pData->audioUnit); status = ((ma_AudioUnitInitialize_proc)pContext->coreaudio.AudioUnitInitialize)(pData->audioUnit);
if (status != noErr) { if (status != noErr) {
ma_free(pData->pAudioBufferList); ma__free_from_callbacks(pData->pAudioBufferList, &pContext->allocationCallbacks);
pData->pAudioBufferList = NULL; pData->pAudioBufferList = NULL;
((ma_AudioComponentInstanceDispose_proc)pContext->coreaudio.AudioComponentInstanceDispose)(pData->audioUnit); ((ma_AudioComponentInstanceDispose_proc)pContext->coreaudio.AudioComponentInstanceDispose)(pData->audioUnit);
return ma_result_from_OSStatus(status); return ma_result_from_OSStatus(status);
...@@ -20665,7 +20809,7 @@ static ma_result ma_device_reinit_internal__coreaudio(ma_device* pDevice, ma_dev ...@@ -20665,7 +20809,7 @@ static ma_result ma_device_reinit_internal__coreaudio(ma_device* pDevice, ma_dev
((ma_AudioComponentInstanceDispose_proc)pDevice->pContext->coreaudio.AudioComponentInstanceDispose)((AudioUnit)pDevice->coreaudio.audioUnitCapture); ((ma_AudioComponentInstanceDispose_proc)pDevice->pContext->coreaudio.AudioComponentInstanceDispose)((AudioUnit)pDevice->coreaudio.audioUnitCapture);
} }
if (pDevice->coreaudio.pAudioBufferList) { if (pDevice->coreaudio.pAudioBufferList) {
ma_free(pDevice->coreaudio.pAudioBufferList); ma__free_from_callbacks(pDevice->coreaudio.pAudioBufferList, &pDevice->pContext->allocationCallbacks);
} }
} else if (deviceType == ma_device_type_playback) { } else if (deviceType == ma_device_type_playback) {
data.formatIn = pDevice->playback.format; data.formatIn = pDevice->playback.format;
...@@ -20829,7 +20973,7 @@ static ma_result ma_device_init__coreaudio(ma_context* pContext, const ma_device ...@@ -20829,7 +20973,7 @@ static ma_result ma_device_init__coreaudio(ma_context* pContext, const ma_device
if (pConfig->deviceType == ma_device_type_duplex) { if (pConfig->deviceType == ma_device_type_duplex) {
((ma_AudioComponentInstanceDispose_proc)pDevice->pContext->coreaudio.AudioComponentInstanceDispose)((AudioUnit)pDevice->coreaudio.audioUnitCapture); ((ma_AudioComponentInstanceDispose_proc)pDevice->pContext->coreaudio.AudioComponentInstanceDispose)((AudioUnit)pDevice->coreaudio.audioUnitCapture);
if (pDevice->coreaudio.pAudioBufferList) { if (pDevice->coreaudio.pAudioBufferList) {
ma_free(pDevice->coreaudio.pAudioBufferList); ma__free_from_callbacks(pDevice->coreaudio.pAudioBufferList, &pDevice->pContext->allocationCallbacks);
} }
} }
return result; return result;
...@@ -20872,7 +21016,7 @@ static ma_result ma_device_init__coreaudio(ma_context* pContext, const ma_device ...@@ -20872,7 +21016,7 @@ static ma_result ma_device_init__coreaudio(ma_context* pContext, const ma_device
/* Need a ring buffer for duplex mode. */ /* Need a ring buffer for duplex mode. */
if (pConfig->deviceType == ma_device_type_duplex) { if (pConfig->deviceType == ma_device_type_duplex) {
ma_uint32 rbSizeInFrames = (ma_uint32)ma_calculate_frame_count_after_src(pDevice->sampleRate, pDevice->capture.internalSampleRate, pDevice->capture.internalBufferSizeInFrames); ma_uint32 rbSizeInFrames = (ma_uint32)ma_calculate_frame_count_after_src(pDevice->sampleRate, pDevice->capture.internalSampleRate, pDevice->capture.internalBufferSizeInFrames);
ma_result result = ma_pcm_rb_init(pDevice->capture.format, pDevice->capture.channels, rbSizeInFrames, NULL, &pDevice->coreaudio.duplexRB); ma_result result = ma_pcm_rb_init(pDevice->capture.format, pDevice->capture.channels, rbSizeInFrames, NULL, &pDevice->pContext->allocationCallbacks, &pDevice->coreaudio.duplexRB);
if (result != MA_SUCCESS) { if (result != MA_SUCCESS) {
return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[Core Audio] Failed to initialize ring buffer.", result); return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[Core Audio] Failed to initialize ring buffer.", result);
} }
...@@ -24289,7 +24433,7 @@ static ma_result ma_device_init__aaudio(ma_context* pContext, const ma_device_co ...@@ -24289,7 +24433,7 @@ static ma_result ma_device_init__aaudio(ma_context* pContext, const ma_device_co
if (pConfig->deviceType == ma_device_type_duplex) { if (pConfig->deviceType == ma_device_type_duplex) {
ma_uint32 rbSizeInFrames = (ma_uint32)ma_calculate_frame_count_after_src(pDevice->sampleRate, pDevice->capture.internalSampleRate, pDevice->capture.internalBufferSizeInFrames); ma_uint32 rbSizeInFrames = (ma_uint32)ma_calculate_frame_count_after_src(pDevice->sampleRate, pDevice->capture.internalSampleRate, pDevice->capture.internalBufferSizeInFrames);
ma_result result = ma_pcm_rb_init(pDevice->capture.format, pDevice->capture.channels, rbSizeInFrames, NULL, &pDevice->aaudio.duplexRB); ma_result result = ma_pcm_rb_init(pDevice->capture.format, pDevice->capture.channels, rbSizeInFrames, NULL, &pDevice->pContext->allocationCallbacks, &pDevice->aaudio.duplexRB);
if (result != MA_SUCCESS) { if (result != MA_SUCCESS) {
if (pDevice->type == ma_device_type_capture || pDevice->type == ma_device_type_duplex) { if (pDevice->type == ma_device_type_capture || pDevice->type == ma_device_type_duplex) {
ma_close_stream__aaudio(pDevice->pContext, (ma_AAudioStream*)pDevice->aaudio.pStreamCapture); ma_close_stream__aaudio(pDevice->pContext, (ma_AAudioStream*)pDevice->aaudio.pStreamCapture);
...@@ -24972,7 +25116,7 @@ static void ma_device_uninit__opensl(ma_device* pDevice) ...@@ -24972,7 +25116,7 @@ static void ma_device_uninit__opensl(ma_device* pDevice)
MA_OPENSL_OBJ(pDevice->opensl.pAudioRecorderObj)->Destroy((SLObjectItf)pDevice->opensl.pAudioRecorderObj); MA_OPENSL_OBJ(pDevice->opensl.pAudioRecorderObj)->Destroy((SLObjectItf)pDevice->opensl.pAudioRecorderObj);
} }
ma_free(pDevice->opensl.pBufferCapture); ma__free_from_callbacks(pDevice->opensl.pBufferCapture, &pDevice->pContext->allocationCallbacks);
} }
if (pDevice->type == ma_device_type_playback || pDevice->type == ma_device_type_duplex) { if (pDevice->type == ma_device_type_playback || pDevice->type == ma_device_type_duplex) {
...@@ -24983,7 +25127,7 @@ static void ma_device_uninit__opensl(ma_device* pDevice) ...@@ -24983,7 +25127,7 @@ static void ma_device_uninit__opensl(ma_device* pDevice)
MA_OPENSL_OBJ(pDevice->opensl.pOutputMixObj)->Destroy((SLObjectItf)pDevice->opensl.pOutputMixObj); MA_OPENSL_OBJ(pDevice->opensl.pOutputMixObj)->Destroy((SLObjectItf)pDevice->opensl.pOutputMixObj);
} }
ma_free(pDevice->opensl.pBufferPlayback); ma__free_from_callbacks(pDevice->opensl.pBufferPlayback, &pDevice->pContext->allocationCallbacks);
} }
if (pDevice->type == ma_device_type_duplex) { if (pDevice->type == ma_device_type_duplex) {
...@@ -25196,7 +25340,7 @@ static ma_result ma_device_init__opensl(ma_context* pContext, const ma_device_co ...@@ -25196,7 +25340,7 @@ static ma_result ma_device_init__opensl(ma_context* pContext, const ma_device_co
pDevice->opensl.currentBufferIndexCapture = 0; pDevice->opensl.currentBufferIndexCapture = 0;
bufferSizeInBytes = pDevice->capture.internalBufferSizeInFrames * ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels); bufferSizeInBytes = pDevice->capture.internalBufferSizeInFrames * ma_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels);
pDevice->opensl.pBufferCapture = (ma_uint8*)ma_malloc(bufferSizeInBytes); pDevice->opensl.pBufferCapture = (ma_uint8*)ma__calloc_from_callbacks(bufferSizeInBytes, &pContext->allocationCallbacks);
if (pDevice->opensl.pBufferCapture == NULL) { if (pDevice->opensl.pBufferCapture == NULL) {
ma_device_uninit__opensl(pDevice); ma_device_uninit__opensl(pDevice);
return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[OpenSL] Failed to allocate memory for data buffer.", MA_OUT_OF_MEMORY); return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[OpenSL] Failed to allocate memory for data buffer.", MA_OUT_OF_MEMORY);
...@@ -25293,7 +25437,7 @@ static ma_result ma_device_init__opensl(ma_context* pContext, const ma_device_co ...@@ -25293,7 +25437,7 @@ static ma_result ma_device_init__opensl(ma_context* pContext, const ma_device_co
pDevice->opensl.currentBufferIndexPlayback = 0; pDevice->opensl.currentBufferIndexPlayback = 0;
bufferSizeInBytes = pDevice->playback.internalBufferSizeInFrames * ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels); bufferSizeInBytes = pDevice->playback.internalBufferSizeInFrames * ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels);
pDevice->opensl.pBufferPlayback = (ma_uint8*)ma_malloc(bufferSizeInBytes); pDevice->opensl.pBufferPlayback = (ma_uint8*)ma__calloc_from_callbacks(bufferSizeInBytes, &pContext->allocationCallbacks);
if (pDevice->opensl.pBufferPlayback == NULL) { if (pDevice->opensl.pBufferPlayback == NULL) {
ma_device_uninit__opensl(pDevice); ma_device_uninit__opensl(pDevice);
return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[OpenSL] Failed to allocate memory for data buffer.", MA_OUT_OF_MEMORY); return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[OpenSL] Failed to allocate memory for data buffer.", MA_OUT_OF_MEMORY);
...@@ -25303,7 +25447,7 @@ static ma_result ma_device_init__opensl(ma_context* pContext, const ma_device_co ...@@ -25303,7 +25447,7 @@ static ma_result ma_device_init__opensl(ma_context* pContext, const ma_device_co
if (pConfig->deviceType == ma_device_type_duplex) { if (pConfig->deviceType == ma_device_type_duplex) {
ma_uint32 rbSizeInFrames = (ma_uint32)ma_calculate_frame_count_after_src(pDevice->sampleRate, pDevice->capture.internalSampleRate, pDevice->capture.internalBufferSizeInFrames); ma_uint32 rbSizeInFrames = (ma_uint32)ma_calculate_frame_count_after_src(pDevice->sampleRate, pDevice->capture.internalSampleRate, pDevice->capture.internalBufferSizeInFrames);
ma_result result = ma_pcm_rb_init(pDevice->capture.format, pDevice->capture.channels, rbSizeInFrames, NULL, &pDevice->opensl.duplexRB); ma_result result = ma_pcm_rb_init(pDevice->capture.format, pDevice->capture.channels, rbSizeInFrames, NULL, &pDevice->pContext->allocationCallbacks, &pDevice->opensl.duplexRB);
if (result != MA_SUCCESS) { if (result != MA_SUCCESS) {
ma_device_uninit__opensl(pDevice); ma_device_uninit__opensl(pDevice);
return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[OpenSL] Failed to initialize ring buffer.", result); return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[OpenSL] Failed to initialize ring buffer.", result);
...@@ -25914,7 +26058,7 @@ static ma_result ma_device_init__webaudio(ma_context* pContext, const ma_device_ ...@@ -25914,7 +26058,7 @@ static ma_result ma_device_init__webaudio(ma_context* pContext, const ma_device_
*/ */
if (pConfig->deviceType == ma_device_type_duplex) { if (pConfig->deviceType == ma_device_type_duplex) {
ma_uint32 rbSizeInFrames = (ma_uint32)ma_calculate_frame_count_after_src(pDevice->sampleRate, pDevice->capture.internalSampleRate, pDevice->capture.internalBufferSizeInFrames) * 2; ma_uint32 rbSizeInFrames = (ma_uint32)ma_calculate_frame_count_after_src(pDevice->sampleRate, pDevice->capture.internalSampleRate, pDevice->capture.internalBufferSizeInFrames) * 2;
result = ma_pcm_rb_init(pDevice->capture.format, pDevice->capture.channels, rbSizeInFrames, NULL, &pDevice->webaudio.duplexRB); result = ma_pcm_rb_init(pDevice->capture.format, pDevice->capture.channels, rbSizeInFrames, NULL, &pDevice->pContext->allocationCallbacks, &pDevice->webaudio.duplexRB);
if (result != MA_SUCCESS) { if (result != MA_SUCCESS) {
if (pDevice->type == ma_device_type_capture || pDevice->type == ma_device_type_duplex) { if (pDevice->type == ma_device_type_capture || pDevice->type == ma_device_type_duplex) {
ma_device_uninit_by_index__webaudio(pDevice, ma_device_type_capture, pDevice->webaudio.indexCapture); ma_device_uninit_by_index__webaudio(pDevice, ma_device_type_capture, pDevice->webaudio.indexCapture);
...@@ -26477,6 +26621,11 @@ ma_result ma_context_init(const ma_backend backends[], ma_uint32 backendCount, c ...@@ -26477,6 +26621,11 @@ ma_result ma_context_init(const ma_backend backends[], ma_uint32 backendCount, c
pContext->threadPriority = config.threadPriority; pContext->threadPriority = config.threadPriority;
pContext->pUserData = config.pUserData; pContext->pUserData = config.pUserData;
result = ma_allocation_callbacks_init_copy(&pContext->allocationCallbacks, &config.allocationCallbacks);
if (result != MA_SUCCESS) {
return result;
}
/* Backend APIs need to be initialized first. This is where external libraries will be loaded and linked. */ /* Backend APIs need to be initialized first. This is where external libraries will be loaded and linked. */
result = ma_context_init_backend_apis(pContext); result = ma_context_init_backend_apis(pContext);
if (result != MA_SUCCESS) { if (result != MA_SUCCESS) {
...@@ -26628,7 +26777,7 @@ ma_result ma_context_uninit(ma_context* pContext) ...@@ -26628,7 +26777,7 @@ ma_result ma_context_uninit(ma_context* pContext)
ma_mutex_uninit(&pContext->deviceEnumLock); ma_mutex_uninit(&pContext->deviceEnumLock);
ma_mutex_uninit(&pContext->deviceInfoLock); ma_mutex_uninit(&pContext->deviceInfoLock);
ma_free(pContext->pDeviceInfos); ma__free_from_callbacks(pContext->pDeviceInfos, &pContext->allocationCallbacks);
ma_context_uninit_backend_apis(pContext); ma_context_uninit_backend_apis(pContext);
return MA_SUCCESS; return MA_SUCCESS;
...@@ -26668,8 +26817,9 @@ static ma_bool32 ma_context_get_devices__enum_callback(ma_context* pContext, ma_ ...@@ -26668,8 +26817,9 @@ static ma_bool32 ma_context_get_devices__enum_callback(ma_context* pContext, ma_
const ma_uint32 totalDeviceInfoCount = pContext->playbackDeviceInfoCount + pContext->captureDeviceInfoCount; const ma_uint32 totalDeviceInfoCount = pContext->playbackDeviceInfoCount + pContext->captureDeviceInfoCount;
if (pContext->deviceInfoCapacity >= totalDeviceInfoCount) { if (pContext->deviceInfoCapacity >= totalDeviceInfoCount) {
ma_uint32 newCapacity = totalDeviceInfoCount + bufferExpansionCount; ma_uint32 oldCapacity = pContext->deviceInfoCapacity;
ma_device_info* pNewInfos = (ma_device_info*)ma_realloc(pContext->pDeviceInfos, sizeof(*pContext->pDeviceInfos)*newCapacity); ma_uint32 newCapacity = oldCapacity + bufferExpansionCount;
ma_device_info* pNewInfos = (ma_device_info*)ma__realloc_from_callbacks(pContext->pDeviceInfos, sizeof(*pContext->pDeviceInfos)*newCapacity, sizeof(*pContext->pDeviceInfos)*oldCapacity, &pContext->allocationCallbacks);
if (pNewInfos == NULL) { if (pNewInfos == NULL) {
return MA_FALSE; /* Out of memory. */ return MA_FALSE; /* Out of memory. */
} }
...@@ -27051,12 +27201,23 @@ ma_result ma_device_init_ex(const ma_backend backends[], ma_uint32 backendCount, ...@@ -27051,12 +27201,23 @@ ma_result ma_device_init_ex(const ma_backend backends[], ma_uint32 backendCount,
ma_uint32 iBackend; ma_uint32 iBackend;
ma_backend* pBackendsToIterate; ma_backend* pBackendsToIterate;
ma_uint32 backendsToIterateCount; ma_uint32 backendsToIterateCount;
ma_allocation_callbacks allocationCallbacks;
if (pConfig == NULL) { if (pConfig == NULL) {
return MA_INVALID_ARGS; return MA_INVALID_ARGS;
} }
pContext = (ma_context*)ma_malloc(sizeof(*pContext)); if (pContextConfig != NULL) {
result = ma_allocation_callbacks_init_copy(&allocationCallbacks, &pContextConfig->allocationCallbacks);
if (result != MA_SUCCESS) {
return result;
}
} else {
allocationCallbacks = ma_allocation_callbacks_init_default();
}
pContext = (ma_context*)ma__malloc_from_callbacks(sizeof(*pContext), &allocationCallbacks);
if (pContext == NULL) { if (pContext == NULL) {
return MA_OUT_OF_MEMORY; return MA_OUT_OF_MEMORY;
} }
...@@ -27087,7 +27248,7 @@ ma_result ma_device_init_ex(const ma_backend backends[], ma_uint32 backendCount, ...@@ -27087,7 +27248,7 @@ ma_result ma_device_init_ex(const ma_backend backends[], ma_uint32 backendCount,
} }
if (result != MA_SUCCESS) { if (result != MA_SUCCESS) {
ma_free(pContext); ma__free_from_callbacks(pContext, &allocationCallbacks);
return result; return result;
} }
...@@ -27123,8 +27284,10 @@ void ma_device_uninit(ma_device* pDevice) ...@@ -27123,8 +27284,10 @@ void ma_device_uninit(ma_device* pDevice)
ma_mutex_uninit(&pDevice->lock); ma_mutex_uninit(&pDevice->lock);
if (pDevice->isOwnerOfContext) { if (pDevice->isOwnerOfContext) {
ma_allocation_callbacks allocationCallbacks = pDevice->pContext->allocationCallbacks;
ma_context_uninit(pDevice->pContext); ma_context_uninit(pDevice->pContext);
ma_free(pDevice->pContext); ma__free_from_callbacks(pDevice->pContext, &allocationCallbacks);
} }
MA_ZERO_OBJECT(pDevice); MA_ZERO_OBJECT(pDevice);
...@@ -33519,8 +33682,9 @@ MA_INLINE void ma_rb__deconstruct_offset(ma_uint32 encodedOffset, ma_uint32* pOf ...@@ -33519,8 +33682,9 @@ MA_INLINE void ma_rb__deconstruct_offset(ma_uint32 encodedOffset, ma_uint32* pOf
} }
ma_result ma_rb_init_ex(size_t subbufferSizeInBytes, size_t subbufferCount, size_t subbufferStrideInBytes, void* pOptionalPreallocatedBuffer, ma_rb* pRB) ma_result ma_rb_init_ex(size_t subbufferSizeInBytes, size_t subbufferCount, size_t subbufferStrideInBytes, void* pOptionalPreallocatedBuffer, const ma_allocation_callbacks* pAllocationCallbacks, ma_rb* pRB)
{ {
ma_result result;
const ma_uint32 maxSubBufferSize = 0x7FFFFFFF - (MA_SIMD_ALIGNMENT-1); const ma_uint32 maxSubBufferSize = 0x7FFFFFFF - (MA_SIMD_ALIGNMENT-1);
if (pRB == NULL) { if (pRB == NULL) {
...@@ -33537,6 +33701,12 @@ ma_result ma_rb_init_ex(size_t subbufferSizeInBytes, size_t subbufferCount, size ...@@ -33537,6 +33701,12 @@ ma_result ma_rb_init_ex(size_t subbufferSizeInBytes, size_t subbufferCount, size
MA_ZERO_OBJECT(pRB); MA_ZERO_OBJECT(pRB);
result = ma_allocation_callbacks_init_copy(&pRB->allocationCallbacks, pAllocationCallbacks);
if (result != MA_SUCCESS) {
return result;
}
pRB->subbufferSizeInBytes = (ma_uint32)subbufferSizeInBytes; pRB->subbufferSizeInBytes = (ma_uint32)subbufferSizeInBytes;
pRB->subbufferCount = (ma_uint32)subbufferCount; pRB->subbufferCount = (ma_uint32)subbufferCount;
...@@ -33553,7 +33723,7 @@ ma_result ma_rb_init_ex(size_t subbufferSizeInBytes, size_t subbufferCount, size ...@@ -33553,7 +33723,7 @@ ma_result ma_rb_init_ex(size_t subbufferSizeInBytes, size_t subbufferCount, size
pRB->subbufferStrideInBytes = (pRB->subbufferSizeInBytes + (MA_SIMD_ALIGNMENT-1)) & ~MA_SIMD_ALIGNMENT; pRB->subbufferStrideInBytes = (pRB->subbufferSizeInBytes + (MA_SIMD_ALIGNMENT-1)) & ~MA_SIMD_ALIGNMENT;
bufferSizeInBytes = (size_t)pRB->subbufferCount*pRB->subbufferStrideInBytes; bufferSizeInBytes = (size_t)pRB->subbufferCount*pRB->subbufferStrideInBytes;
pRB->pBuffer = ma_aligned_malloc(bufferSizeInBytes, MA_SIMD_ALIGNMENT); pRB->pBuffer = ma_aligned_malloc(bufferSizeInBytes, MA_SIMD_ALIGNMENT, &pRB->allocationCallbacks);
if (pRB->pBuffer == NULL) { if (pRB->pBuffer == NULL) {
return MA_OUT_OF_MEMORY; return MA_OUT_OF_MEMORY;
} }
...@@ -33565,9 +33735,9 @@ ma_result ma_rb_init_ex(size_t subbufferSizeInBytes, size_t subbufferCount, size ...@@ -33565,9 +33735,9 @@ ma_result ma_rb_init_ex(size_t subbufferSizeInBytes, size_t subbufferCount, size
return MA_SUCCESS; return MA_SUCCESS;
} }
ma_result ma_rb_init(size_t bufferSizeInBytes, void* pOptionalPreallocatedBuffer, ma_rb* pRB) ma_result ma_rb_init(size_t bufferSizeInBytes, void* pOptionalPreallocatedBuffer, const ma_allocation_callbacks* pAllocationCallbacks, ma_rb* pRB)
{ {
return ma_rb_init_ex(bufferSizeInBytes, 1, 0, pOptionalPreallocatedBuffer, pRB); return ma_rb_init_ex(bufferSizeInBytes, 1, 0, pOptionalPreallocatedBuffer, pAllocationCallbacks, pRB);
} }
void ma_rb_uninit(ma_rb* pRB) void ma_rb_uninit(ma_rb* pRB)
...@@ -33577,7 +33747,7 @@ void ma_rb_uninit(ma_rb* pRB) ...@@ -33577,7 +33747,7 @@ void ma_rb_uninit(ma_rb* pRB)
} }
if (pRB->ownsBuffer) { if (pRB->ownsBuffer) {
ma_aligned_free(pRB->pBuffer); ma_aligned_free(pRB->pBuffer, &pRB->allocationCallbacks);
} }
} }
...@@ -33946,7 +34116,7 @@ static MA_INLINE ma_uint32 ma_pcm_rb_get_bpf(ma_pcm_rb* pRB) ...@@ -33946,7 +34116,7 @@ static MA_INLINE ma_uint32 ma_pcm_rb_get_bpf(ma_pcm_rb* pRB)
return ma_get_bytes_per_frame(pRB->format, pRB->channels); return ma_get_bytes_per_frame(pRB->format, pRB->channels);
} }
ma_result ma_pcm_rb_init_ex(ma_format format, ma_uint32 channels, ma_uint32 subbufferSizeInFrames, ma_uint32 subbufferCount, ma_uint32 subbufferStrideInFrames, void* pOptionalPreallocatedBuffer, ma_pcm_rb* pRB) ma_result ma_pcm_rb_init_ex(ma_format format, ma_uint32 channels, ma_uint32 subbufferSizeInFrames, ma_uint32 subbufferCount, ma_uint32 subbufferStrideInFrames, void* pOptionalPreallocatedBuffer, const ma_allocation_callbacks* pAllocationCallbacks, ma_pcm_rb* pRB)
{ {
ma_uint32 bpf; ma_uint32 bpf;
ma_result result; ma_result result;
...@@ -33962,7 +34132,7 @@ ma_result ma_pcm_rb_init_ex(ma_format format, ma_uint32 channels, ma_uint32 subb ...@@ -33962,7 +34132,7 @@ ma_result ma_pcm_rb_init_ex(ma_format format, ma_uint32 channels, ma_uint32 subb
return MA_INVALID_ARGS; return MA_INVALID_ARGS;
} }
result = ma_rb_init_ex(subbufferSizeInFrames*bpf, subbufferCount, subbufferStrideInFrames*bpf, pOptionalPreallocatedBuffer, &pRB->rb); result = ma_rb_init_ex(subbufferSizeInFrames*bpf, subbufferCount, subbufferStrideInFrames*bpf, pOptionalPreallocatedBuffer, pAllocationCallbacks, &pRB->rb);
if (result != MA_SUCCESS) { if (result != MA_SUCCESS) {
return result; return result;
} }
...@@ -33973,9 +34143,9 @@ ma_result ma_pcm_rb_init_ex(ma_format format, ma_uint32 channels, ma_uint32 subb ...@@ -33973,9 +34143,9 @@ ma_result ma_pcm_rb_init_ex(ma_format format, ma_uint32 channels, ma_uint32 subb
return MA_SUCCESS; return MA_SUCCESS;
} }
ma_result ma_pcm_rb_init(ma_format format, ma_uint32 channels, ma_uint32 bufferSizeInFrames, void* pOptionalPreallocatedBuffer, ma_pcm_rb* pRB) ma_result ma_pcm_rb_init(ma_format format, ma_uint32 channels, ma_uint32 bufferSizeInFrames, void* pOptionalPreallocatedBuffer, const ma_allocation_callbacks* pAllocationCallbacks, ma_pcm_rb* pRB)
{ {
return ma_pcm_rb_init_ex(format, channels, bufferSizeInFrames, 1, 0, pOptionalPreallocatedBuffer, pRB); return ma_pcm_rb_init_ex(format, channels, bufferSizeInFrames, 1, 0, pOptionalPreallocatedBuffer, pAllocationCallbacks, pRB);
} }
void ma_pcm_rb_uninit(ma_pcm_rb* pRB) void ma_pcm_rb_uninit(ma_pcm_rb* pRB)
...@@ -34142,22 +34312,38 @@ void* ma_pcm_rb_get_subbuffer_ptr(ma_pcm_rb* pRB, ma_uint32 subbufferIndex, void ...@@ -34142,22 +34312,38 @@ void* ma_pcm_rb_get_subbuffer_ptr(ma_pcm_rb* pRB, ma_uint32 subbufferIndex, void
Miscellaneous Helpers Miscellaneous Helpers
**************************************************************************************************************************************************************/ **************************************************************************************************************************************************************/
void* ma_malloc(size_t sz) void* ma_malloc(size_t sz, const ma_allocation_callbacks* pAllocationCallbacks)
{ {
return MA_MALLOC(sz); if (pAllocationCallbacks != NULL) {
return ma__malloc_from_callbacks(sz, pAllocationCallbacks);
} else {
return ma__malloc_default(sz, NULL);
}
} }
void* ma_realloc(void* p, size_t sz) void* ma_realloc(void* p, size_t sz, const ma_allocation_callbacks* pAllocationCallbacks)
{ {
return MA_REALLOC(p, sz); if (pAllocationCallbacks != NULL) {
if (pAllocationCallbacks->onRealloc != NULL) {
return pAllocationCallbacks->onRealloc(p, sz, pAllocationCallbacks->pUserData);
} else {
return NULL; /* This requires a native implementation of realloc(). */
}
} else {
return ma__realloc_default(p, sz, NULL);
}
} }
void ma_free(void* p) void ma_free(void* p, const ma_allocation_callbacks* pAllocationCallbacks)
{ {
MA_FREE(p); if (pAllocationCallbacks != NULL) {
ma__free_from_callbacks(p, pAllocationCallbacks);
} else {
ma__free_default(p, NULL);
}
} }
void* ma_aligned_malloc(size_t sz, size_t alignment) void* ma_aligned_malloc(size_t sz, size_t alignment, const ma_allocation_callbacks* pAllocationCallbacks)
{ {
size_t extraBytes; size_t extraBytes;
void* pUnaligned; void* pUnaligned;
...@@ -34169,7 +34355,7 @@ void* ma_aligned_malloc(size_t sz, size_t alignment) ...@@ -34169,7 +34355,7 @@ void* ma_aligned_malloc(size_t sz, size_t alignment)
extraBytes = alignment-1 + sizeof(void*); extraBytes = alignment-1 + sizeof(void*);
pUnaligned = ma_malloc(sz + extraBytes); pUnaligned = ma_malloc(sz + extraBytes, pAllocationCallbacks);
if (pUnaligned == NULL) { if (pUnaligned == NULL) {
return NULL; return NULL;
} }
...@@ -34180,9 +34366,9 @@ void* ma_aligned_malloc(size_t sz, size_t alignment) ...@@ -34180,9 +34366,9 @@ void* ma_aligned_malloc(size_t sz, size_t alignment)
return pAligned; return pAligned;
} }
void ma_aligned_free(void* p) void ma_aligned_free(void* p, const ma_allocation_callbacks* pAllocationCallbacks)
{ {
ma_free(((void**)p)[-1]); ma_free(((void**)p)[-1], pAllocationCallbacks);
} }
const char* ma_get_format_name(ma_format format) const char* ma_get_format_name(ma_format format)
...@@ -34398,7 +34584,7 @@ static ma_result ma_decoder_internal_on_seek_to_pcm_frame__wav(ma_decoder* pDeco ...@@ -34398,7 +34584,7 @@ static ma_result ma_decoder_internal_on_seek_to_pcm_frame__wav(ma_decoder* pDeco
static ma_result ma_decoder_internal_on_uninit__wav(ma_decoder* pDecoder) static ma_result ma_decoder_internal_on_uninit__wav(ma_decoder* pDecoder)
{ {
drwav_uninit((drwav*)pDecoder->pInternalDecoder); drwav_uninit((drwav*)pDecoder->pInternalDecoder);
ma_free(pDecoder->pInternalDecoder); ma__free_from_callbacks(pDecoder->pInternalDecoder, &pDecoder->allocationCallbacks);
return MA_SUCCESS; return MA_SUCCESS;
} }
...@@ -34410,18 +34596,24 @@ static ma_uint64 ma_decoder_internal_on_get_length_in_pcm_frames__wav(ma_decoder ...@@ -34410,18 +34596,24 @@ static ma_uint64 ma_decoder_internal_on_get_length_in_pcm_frames__wav(ma_decoder
static ma_result ma_decoder_init_wav__internal(const ma_decoder_config* pConfig, ma_decoder* pDecoder) static ma_result ma_decoder_init_wav__internal(const ma_decoder_config* pConfig, ma_decoder* pDecoder)
{ {
drwav* pWav; drwav* pWav;
drwav_allocation_callbacks allocationCallbacks;
MA_ASSERT(pConfig != NULL); MA_ASSERT(pConfig != NULL);
MA_ASSERT(pDecoder != NULL); MA_ASSERT(pDecoder != NULL);
pWav = (drwav*)ma_malloc(sizeof(*pWav)); pWav = (drwav*)ma__malloc_from_callbacks(sizeof(*pWav), &pDecoder->allocationCallbacks);
if (pWav == NULL) { if (pWav == NULL) {
return MA_OUT_OF_MEMORY; return MA_OUT_OF_MEMORY;
} }
allocationCallbacks.pUserData = pDecoder->allocationCallbacks.pUserData;
allocationCallbacks.onMalloc = pDecoder->allocationCallbacks.onMalloc;
allocationCallbacks.onRealloc = pDecoder->allocationCallbacks.onRealloc;
allocationCallbacks.onFree = pDecoder->allocationCallbacks.onFree;
/* Try opening the decoder first. */ /* Try opening the decoder first. */
if (!drwav_init(pWav, ma_decoder_internal_on_read__wav, ma_decoder_internal_on_seek__wav, pDecoder, NULL)) { if (!drwav_init(pWav, ma_decoder_internal_on_read__wav, ma_decoder_internal_on_seek__wav, pDecoder, &allocationCallbacks)) {
ma_free(pWav); ma__free_from_callbacks(pWav, &pDecoder->allocationCallbacks);
return MA_ERROR; return MA_ERROR;
} }
...@@ -34546,12 +34738,18 @@ static ma_uint64 ma_decoder_internal_on_get_length_in_pcm_frames__flac(ma_decode ...@@ -34546,12 +34738,18 @@ static ma_uint64 ma_decoder_internal_on_get_length_in_pcm_frames__flac(ma_decode
static ma_result ma_decoder_init_flac__internal(const ma_decoder_config* pConfig, ma_decoder* pDecoder) static ma_result ma_decoder_init_flac__internal(const ma_decoder_config* pConfig, ma_decoder* pDecoder)
{ {
drflac* pFlac; drflac* pFlac;
drflac_allocation_callbacks allocationCallbacks;
MA_ASSERT(pConfig != NULL); MA_ASSERT(pConfig != NULL);
MA_ASSERT(pDecoder != NULL); MA_ASSERT(pDecoder != NULL);
allocationCallbacks.pUserData = pDecoder->allocationCallbacks.pUserData;
allocationCallbacks.onMalloc = pDecoder->allocationCallbacks.onMalloc;
allocationCallbacks.onRealloc = pDecoder->allocationCallbacks.onRealloc;
allocationCallbacks.onFree = pDecoder->allocationCallbacks.onFree;
/* Try opening the decoder first. */ /* Try opening the decoder first. */
pFlac = drflac_open(ma_decoder_internal_on_read__flac, ma_decoder_internal_on_seek__flac, pDecoder, NULL); pFlac = drflac_open(ma_decoder_internal_on_read__flac, ma_decoder_internal_on_seek__flac, pDecoder, &allocationCallbacks);
if (pFlac == NULL) { if (pFlac == NULL) {
return MA_ERROR; return MA_ERROR;
} }
...@@ -34660,10 +34858,11 @@ static ma_uint64 ma_vorbis_decoder_read_pcm_frames(ma_vorbis_decoder* pVorbis, m ...@@ -34660,10 +34858,11 @@ static ma_uint64 ma_vorbis_decoder_read_pcm_frames(ma_vorbis_decoder* pVorbis, m
size_t bytesRead; size_t bytesRead;
if (pVorbis->dataCapacity == pVorbis->dataSize) { if (pVorbis->dataCapacity == pVorbis->dataSize) {
/* No room. Expand. */ /* No room. Expand. */
size_t oldCap = pVorbis->dataCapacity;
size_t newCap = pVorbis->dataCapacity + MA_VORBIS_DATA_CHUNK_SIZE; size_t newCap = pVorbis->dataCapacity + MA_VORBIS_DATA_CHUNK_SIZE;
ma_uint8* pNewData; ma_uint8* pNewData;
pNewData = (ma_uint8*)ma_realloc(pVorbis->pData, newCap); pNewData = (ma_uint8*)ma__realloc_from_callbacks(pVorbis->pData, newCap, oldCap, &pDecoder->allocationCallbacks);
if (pNewData == NULL) { if (pNewData == NULL) {
return totalFramesRead; /* Out of memory. */ return totalFramesRead; /* Out of memory. */
} }
...@@ -34740,8 +34939,8 @@ static ma_result ma_decoder_internal_on_uninit__vorbis(ma_decoder* pDecoder) ...@@ -34740,8 +34939,8 @@ static ma_result ma_decoder_internal_on_uninit__vorbis(ma_decoder* pDecoder)
MA_ASSERT(pVorbis != NULL); MA_ASSERT(pVorbis != NULL);
stb_vorbis_close(pVorbis->pInternalVorbis); stb_vorbis_close(pVorbis->pInternalVorbis);
ma_free(pVorbis->pData); ma__free_from_callbacks(pVorbis->pData, &pDecoder->allocationCallbacks);
ma_free(pVorbis); ma__free_from_callbacks(pVorbis, &pDecoder->allocationCallbacks);
return MA_SUCCESS; return MA_SUCCESS;
} }
...@@ -34788,11 +34987,12 @@ static ma_result ma_decoder_init_vorbis__internal(const ma_decoder_config* pConf ...@@ -34788,11 +34987,12 @@ static ma_result ma_decoder_init_vorbis__internal(const ma_decoder_config* pConf
size_t bytesRead; size_t bytesRead;
int vorbisError = 0; int vorbisError = 0;
int consumedDataSize = 0; int consumedDataSize = 0;
size_t oldCapacity = dataCapacity;
dataCapacity += MA_VORBIS_DATA_CHUNK_SIZE; dataCapacity += MA_VORBIS_DATA_CHUNK_SIZE;
pNewData = (ma_uint8*)ma_realloc(pData, dataCapacity); pNewData = (ma_uint8*)ma__realloc_from_callbacks(pData, dataCapacity, oldCapacity, &pDecoder->allocationCallbacks);
if (pNewData == NULL) { if (pNewData == NULL) {
ma_free(pData); ma__free_from_callbacks(pData, &pDecoder->allocationCallbacks);
return MA_OUT_OF_MEMORY; return MA_OUT_OF_MEMORY;
} }
...@@ -34839,15 +35039,15 @@ static ma_result ma_decoder_init_vorbis__internal(const ma_decoder_config* pConf ...@@ -34839,15 +35039,15 @@ static ma_result ma_decoder_init_vorbis__internal(const ma_decoder_config* pConf
/* Don't allow more than MA_MAX_CHANNELS channels. */ /* Don't allow more than MA_MAX_CHANNELS channels. */
if (vorbisInfo.channels > MA_MAX_CHANNELS) { if (vorbisInfo.channels > MA_MAX_CHANNELS) {
stb_vorbis_close(pInternalVorbis); stb_vorbis_close(pInternalVorbis);
ma_free(pData); ma__free_from_callbacks(pData, &pDecoder->allocationCallbacks);
return MA_ERROR; /* Too many channels. */ return MA_ERROR; /* Too many channels. */
} }
vorbisDataSize = sizeof(ma_vorbis_decoder) + sizeof(float)*vorbisInfo.max_frame_size; vorbisDataSize = sizeof(ma_vorbis_decoder) + sizeof(float)*vorbisInfo.max_frame_size;
pVorbis = (ma_vorbis_decoder*)ma_malloc(vorbisDataSize); pVorbis = (ma_vorbis_decoder*)ma__malloc_from_callbacks(vorbisDataSize, &pDecoder->allocationCallbacks);
if (pVorbis == NULL) { if (pVorbis == NULL) {
stb_vorbis_close(pInternalVorbis); stb_vorbis_close(pInternalVorbis);
ma_free(pData); ma__free_from_callbacks(pData, &pDecoder->allocationCallbacks);
return MA_OUT_OF_MEMORY; return MA_OUT_OF_MEMORY;
} }
...@@ -34926,7 +35126,7 @@ static ma_result ma_decoder_internal_on_seek_to_pcm_frame__mp3(ma_decoder* pDeco ...@@ -34926,7 +35126,7 @@ static ma_result ma_decoder_internal_on_seek_to_pcm_frame__mp3(ma_decoder* pDeco
static ma_result ma_decoder_internal_on_uninit__mp3(ma_decoder* pDecoder) static ma_result ma_decoder_internal_on_uninit__mp3(ma_decoder* pDecoder)
{ {
drmp3_uninit((drmp3*)pDecoder->pInternalDecoder); drmp3_uninit((drmp3*)pDecoder->pInternalDecoder);
ma_free(pDecoder->pInternalDecoder); ma__free_from_callbacks(pDecoder->pInternalDecoder, &pDecoder->allocationCallbacks);
return MA_SUCCESS; return MA_SUCCESS;
} }
...@@ -34939,15 +35139,21 @@ static ma_result ma_decoder_init_mp3__internal(const ma_decoder_config* pConfig, ...@@ -34939,15 +35139,21 @@ static ma_result ma_decoder_init_mp3__internal(const ma_decoder_config* pConfig,
{ {
drmp3* pMP3; drmp3* pMP3;
drmp3_config mp3Config; drmp3_config mp3Config;
drmp3_allocation_callbacks allocationCallbacks;
MA_ASSERT(pConfig != NULL); MA_ASSERT(pConfig != NULL);
MA_ASSERT(pDecoder != NULL); MA_ASSERT(pDecoder != NULL);
pMP3 = (drmp3*)ma_malloc(sizeof(*pMP3)); pMP3 = (drmp3*)ma__malloc_from_callbacks(sizeof(*pMP3), &pDecoder->allocationCallbacks);
if (pMP3 == NULL) { if (pMP3 == NULL) {
return MA_OUT_OF_MEMORY; return MA_OUT_OF_MEMORY;
} }
allocationCallbacks.pUserData = pDecoder->allocationCallbacks.pUserData;
allocationCallbacks.onMalloc = pDecoder->allocationCallbacks.onMalloc;
allocationCallbacks.onRealloc = pDecoder->allocationCallbacks.onRealloc;
allocationCallbacks.onFree = pDecoder->allocationCallbacks.onFree;
/* /*
Try opening the decoder first. MP3 can have variable sample rates (it's per frame/packet). We therefore need Try opening the decoder first. MP3 can have variable sample rates (it's per frame/packet). We therefore need
to use some smarts to determine the most appropriate internal sample rate. These are the rules we're going to use some smarts to determine the most appropriate internal sample rate. These are the rules we're going
...@@ -34962,8 +35168,8 @@ static ma_result ma_decoder_init_mp3__internal(const ma_decoder_config* pConfig, ...@@ -34962,8 +35168,8 @@ static ma_result ma_decoder_init_mp3__internal(const ma_decoder_config* pConfig,
MA_ZERO_OBJECT(&mp3Config); MA_ZERO_OBJECT(&mp3Config);
mp3Config.outputChannels = 2; mp3Config.outputChannels = 2;
mp3Config.outputSampleRate = (pConfig->sampleRate != 0) ? pConfig->sampleRate : 44100; mp3Config.outputSampleRate = (pConfig->sampleRate != 0) ? pConfig->sampleRate : 44100;
if (!drmp3_init(pMP3, ma_decoder_internal_on_read__mp3, ma_decoder_internal_on_seek__mp3, pDecoder, &mp3Config, NULL)) { if (!drmp3_init(pMP3, ma_decoder_internal_on_read__mp3, ma_decoder_internal_on_seek__mp3, pDecoder, &mp3Config, &allocationCallbacks)) {
ma_free(pMP3); ma__free_from_callbacks(pMP3, &pDecoder->allocationCallbacks);
return MA_ERROR; return MA_ERROR;
} }
...@@ -35098,8 +35304,22 @@ static ma_result ma_decoder_init_raw__internal(const ma_decoder_config* pConfigI ...@@ -35098,8 +35304,22 @@ static ma_result ma_decoder_init_raw__internal(const ma_decoder_config* pConfigI
return MA_SUCCESS; return MA_SUCCESS;
} }
static ma_result ma_decoder__init_allocation_callbacks(const ma_decoder_config* pConfig, ma_decoder* pDecoder)
{
MA_ASSERT(pDecoder != NULL);
if (pConfig != NULL) {
return ma_allocation_callbacks_init_copy(&pDecoder->allocationCallbacks, &pConfig->allocationCallbacks);
} else {
pDecoder->allocationCallbacks = ma_allocation_callbacks_init_default();
return MA_SUCCESS;
}
}
static ma_result ma_decoder__preinit(ma_decoder_read_proc onRead, ma_decoder_seek_proc onSeek, void* pUserData, const ma_decoder_config* pConfig, ma_decoder* pDecoder) static ma_result ma_decoder__preinit(ma_decoder_read_proc onRead, ma_decoder_seek_proc onSeek, void* pUserData, const ma_decoder_config* pConfig, ma_decoder* pDecoder)
{ {
ma_result result;
MA_ASSERT(pConfig != NULL); MA_ASSERT(pConfig != NULL);
if (pDecoder == NULL) { if (pDecoder == NULL) {
...@@ -35116,7 +35336,11 @@ static ma_result ma_decoder__preinit(ma_decoder_read_proc onRead, ma_decoder_see ...@@ -35116,7 +35336,11 @@ static ma_result ma_decoder__preinit(ma_decoder_read_proc onRead, ma_decoder_see
pDecoder->onSeek = onSeek; pDecoder->onSeek = onSeek;
pDecoder->pUserData = pUserData; pDecoder->pUserData = pUserData;
(void)pConfig; result = ma_decoder__init_allocation_callbacks(pConfig, pDecoder);
if (result != MA_SUCCESS) {
return result;
}
return MA_SUCCESS; return MA_SUCCESS;
} }
...@@ -35696,6 +35920,7 @@ static ma_bool32 ma_decoder__on_seek_stdio(ma_decoder* pDecoder, int byteOffset, ...@@ -35696,6 +35920,7 @@ static ma_bool32 ma_decoder__on_seek_stdio(ma_decoder* pDecoder, int byteOffset,
static ma_result ma_decoder__preinit_file(const char* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder) static ma_result ma_decoder__preinit_file(const char* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder)
{ {
ma_result result;
FILE* pFile; FILE* pFile;
if (pDecoder == NULL) { if (pDecoder == NULL) {
...@@ -35708,6 +35933,11 @@ static ma_result ma_decoder__preinit_file(const char* pFilePath, const ma_decode ...@@ -35708,6 +35933,11 @@ static ma_result ma_decoder__preinit_file(const char* pFilePath, const ma_decode
return MA_INVALID_ARGS; return MA_INVALID_ARGS;
} }
result = ma_decoder__init_allocation_callbacks(pConfig, pDecoder);
if (result != MA_SUCCESS) {
return result;
}
#if defined(_MSC_VER) && _MSC_VER >= 1400 #if defined(_MSC_VER) && _MSC_VER >= 1400
if (fopen_s(&pFile, pFilePath, "rb") != 0) { if (fopen_s(&pFile, pFilePath, "rb") != 0) {
return MA_ERROR; return MA_ERROR;
...@@ -35722,7 +35952,6 @@ static ma_result ma_decoder__preinit_file(const char* pFilePath, const ma_decode ...@@ -35722,7 +35952,6 @@ static ma_result ma_decoder__preinit_file(const char* pFilePath, const ma_decode
/* We need to manually set the user data so the calls to ma_decoder__on_seek_stdio() succeed. */ /* We need to manually set the user data so the calls to ma_decoder__on_seek_stdio() succeed. */
pDecoder->pUserData = pFile; pDecoder->pUserData = pFile;
(void)pConfig;
return MA_SUCCESS; return MA_SUCCESS;
} }
...@@ -35745,6 +35974,7 @@ fallback, so if you notice your compiler not detecting this properly I'm happy t ...@@ -35745,6 +35974,7 @@ fallback, so if you notice your compiler not detecting this properly I'm happy t
static ma_result ma_decoder__preinit_file_w(const wchar_t* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder) static ma_result ma_decoder__preinit_file_w(const wchar_t* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder)
{ {
ma_result result;
FILE* pFile; FILE* pFile;
if (pDecoder == NULL) { if (pDecoder == NULL) {
...@@ -35757,6 +35987,11 @@ static ma_result ma_decoder__preinit_file_w(const wchar_t* pFilePath, const ma_d ...@@ -35757,6 +35987,11 @@ static ma_result ma_decoder__preinit_file_w(const wchar_t* pFilePath, const ma_d
return MA_INVALID_ARGS; return MA_INVALID_ARGS;
} }
result = ma_decoder__init_allocation_callbacks(pConfig, pDecoder);
if (result != MA_SUCCESS) {
return result;
}
#if defined(MA_HAS_WFOPEN) #if defined(MA_HAS_WFOPEN)
/* Use _wfopen() on Windows. */ /* Use _wfopen() on Windows. */
#if defined(_MSC_VER) && _MSC_VER >= 1400 #if defined(_MSC_VER) && _MSC_VER >= 1400
...@@ -35788,7 +36023,7 @@ static ma_result ma_decoder__preinit_file_w(const wchar_t* pFilePath, const ma_d ...@@ -35788,7 +36023,7 @@ static ma_result ma_decoder__preinit_file_w(const wchar_t* pFilePath, const ma_d
return MA_ERROR; return MA_ERROR;
} }
pFilePathMB = (char*)MA_MALLOC(lenMB + 1); pFilePathMB = (char*)ma__malloc_from_callbacks(lenMB + 1, &pDecoder->allocationCallbacks);
if (pFilePathMB == NULL) { if (pFilePathMB == NULL) {
return MA_OUT_OF_MEMORY; return MA_OUT_OF_MEMORY;
} }
...@@ -35799,7 +36034,7 @@ static ma_result ma_decoder__preinit_file_w(const wchar_t* pFilePath, const ma_d ...@@ -35799,7 +36034,7 @@ static ma_result ma_decoder__preinit_file_w(const wchar_t* pFilePath, const ma_d
pFile = fopen(pFilePathMB, "rb"); pFile = fopen(pFilePathMB, "rb");
MA_FREE(pFilePathMB); ma__free_from_callbacks(pFilePathMB, &pDecoder->allocationCallbacks);
} }
if (pFile == NULL) { if (pFile == NULL) {
...@@ -36121,20 +36356,21 @@ static ma_result ma_decoder__full_decode_and_uninit(ma_decoder* pDecoder, ma_dec ...@@ -36121,20 +36356,21 @@ static ma_result ma_decoder__full_decode_and_uninit(ma_decoder* pDecoder, ma_dec
/* Make room if there's not enough. */ /* Make room if there's not enough. */
if (totalFrameCount == dataCapInFrames) { if (totalFrameCount == dataCapInFrames) {
void* pNewPCMFramesOut; void* pNewPCMFramesOut;
ma_uint64 oldDataCapInFrames = dataCapInFrames;
ma_uint64 newDataCapInFrames = dataCapInFrames*2; ma_uint64 newDataCapInFrames = dataCapInFrames*2;
if (newDataCapInFrames == 0) { if (newDataCapInFrames == 0) {
newDataCapInFrames = 4096; newDataCapInFrames = 4096;
} }
if ((newDataCapInFrames * bpf) > MA_SIZE_MAX) { if ((newDataCapInFrames * bpf) > MA_SIZE_MAX) {
ma_free(pPCMFramesOut); ma__free_from_callbacks(pPCMFramesOut, &pDecoder->allocationCallbacks);
return MA_TOO_LARGE; return MA_TOO_LARGE;
} }
pNewPCMFramesOut = (void*)ma_realloc(pPCMFramesOut, (size_t)(newDataCapInFrames * bpf)); pNewPCMFramesOut = (void*)ma__realloc_from_callbacks(pPCMFramesOut, (size_t)(newDataCapInFrames * bpf), (size_t)(oldDataCapInFrames * bpf), &pDecoder->allocationCallbacks);
if (pNewPCMFramesOut == NULL) { if (pNewPCMFramesOut == NULL) {
ma_free(pPCMFramesOut); ma__free_from_callbacks(pPCMFramesOut, &pDecoder->allocationCallbacks);
return MA_OUT_OF_MEMORY; return MA_OUT_OF_MEMORY;
} }
...@@ -36164,7 +36400,7 @@ static ma_result ma_decoder__full_decode_and_uninit(ma_decoder* pDecoder, ma_dec ...@@ -36164,7 +36400,7 @@ static ma_result ma_decoder__full_decode_and_uninit(ma_decoder* pDecoder, ma_dec
if (ppPCMFramesOut != NULL) { if (ppPCMFramesOut != NULL) {
*ppPCMFramesOut = pPCMFramesOut; *ppPCMFramesOut = pPCMFramesOut;
} else { } else {
ma_free(pPCMFramesOut); ma__free_from_callbacks(pPCMFramesOut, &pDecoder->allocationCallbacks);
} }
if (pFrameCountOut != NULL) { if (pFrameCountOut != NULL) {
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