Version 0.11.9

This commit is contained in:
David Reid
2022-04-20 20:14:51 +10:00
parent c2931a92cc
commit 4dfe7c4c31
3 changed files with 339 additions and 138 deletions
+295 -120
View File
@@ -1,6 +1,6 @@
/*
Audio playback and capture library. Choice of public domain or MIT-0. See license statements at the end of this file.
miniaudio - v0.11.8 - 2022-02-12
miniaudio - v0.11.9 - 2022-04-20
David Reid - mackron@gmail.com
@@ -21389,6 +21389,12 @@ static ma_result ma_device__untrack__coreaudio(ma_device* pDevice)
-(void)dealloc
{
[self remove_handler];
#if defined(__has_feature)
#if !__has_feature(objc_arc)
[super dealloc];
#endif
#endif
}
-(void)remove_handler
@@ -32678,6 +32684,23 @@ MA_API ma_result ma_biquad_reinit(const ma_biquad_config* pConfig, ma_biquad* pB
return MA_SUCCESS;
}
MA_API ma_result ma_biquad_clear_cache(ma_biquad* pBQ)
{
if (pBQ == NULL) {
return MA_INVALID_ARGS;
}
if (pBQ->format == ma_format_f32) {
pBQ->pR1->f32 = 0;
pBQ->pR2->f32 = 0;
} else {
pBQ->pR1->s32 = 0;
pBQ->pR2->s32 = 0;
}
return MA_SUCCESS;
}
static MA_INLINE void ma_biquad_process_pcm_frame_f32__direct_form_2_transposed(ma_biquad* pBQ, float* pY, const float* pX)
{
ma_uint32 c;
@@ -32979,6 +33002,21 @@ MA_API ma_result ma_lpf1_reinit(const ma_lpf1_config* pConfig, ma_lpf1* pLPF)
return MA_SUCCESS;
}
MA_API ma_result ma_lpf1_clear_cache(ma_lpf1* pLPF)
{
if (pLPF == NULL) {
return MA_INVALID_ARGS;
}
if (pLPF->format == ma_format_f32) {
pLPF->a.f32 = 0;
} else {
pLPF->a.s32 = 0;
}
return MA_SUCCESS;
}
static MA_INLINE void ma_lpf1_process_pcm_frame_f32(ma_lpf1* pLPF, float* pY, const float* pX)
{
ma_uint32 c;
@@ -33184,6 +33222,17 @@ MA_API ma_result ma_lpf2_reinit(const ma_lpf2_config* pConfig, ma_lpf2* pLPF)
return MA_SUCCESS;
}
MA_API ma_result ma_lpf2_clear_cache(ma_lpf2* pLPF)
{
if (pLPF == NULL) {
return MA_INVALID_ARGS;
}
ma_biquad_clear_cache(&pLPF->bq);
return MA_SUCCESS;
}
static MA_INLINE void ma_lpf2_process_pcm_frame_s16(ma_lpf2* pLPF, ma_int16* pFrameOut, const ma_int16* pFrameIn)
{
ma_biquad_process_pcm_frame_s16(&pLPF->bq, pFrameOut, pFrameIn);
@@ -33527,6 +33576,26 @@ MA_API ma_result ma_lpf_reinit(const ma_lpf_config* pConfig, ma_lpf* pLPF)
return ma_lpf_reinit__internal(pConfig, NULL, pLPF, /*isNew*/MA_FALSE);
}
MA_API ma_result ma_lpf_clear_cache(ma_lpf* pLPF)
{
ma_uint32 ilpf1;
ma_uint32 ilpf2;
if (pLPF == NULL) {
return MA_INVALID_ARGS;
}
for (ilpf1 = 0; ilpf1 < pLPF->lpf1Count; ilpf1 += 1) {
ma_lpf1_clear_cache(&pLPF->pLPF1[ilpf1]);
}
for (ilpf2 = 0; ilpf2 < pLPF->lpf2Count; ilpf2 += 1) {
ma_lpf2_clear_cache(&pLPF->pLPF2[ilpf2]);
}
return MA_SUCCESS;
}
static MA_INLINE void ma_lpf_process_pcm_frame_f32(ma_lpf* pLPF, float* pY, const void* pX)
{
ma_uint32 ilpf1;
@@ -38701,6 +38770,38 @@ MA_API ma_result ma_linear_resampler_get_expected_output_frame_count(const ma_li
return MA_SUCCESS;
}
MA_API ma_result ma_linear_resampler_reset(ma_linear_resampler* pResampler)
{
ma_uint32 iChannel;
if (pResampler == NULL) {
return MA_INVALID_ARGS;
}
/* Timers need to be cleared back to zero. */
pResampler->inTimeInt = 1; /* Set this to one to force an input sample to always be loaded for the first output frame. */
pResampler->inTimeFrac = 0;
/* Cached samples need to be cleared. */
if (pResampler->config.format == ma_format_f32) {
for (iChannel = 0; iChannel < pResampler->config.channels; iChannel += 1) {
pResampler->x0.f32[iChannel] = 0;
pResampler->x1.f32[iChannel] = 0;
}
} else {
for (iChannel = 0; iChannel < pResampler->config.channels; iChannel += 1) {
pResampler->x0.s16[iChannel] = 0;
pResampler->x1.s16[iChannel] = 0;
}
}
/* The low pass filter needs to have it's cache reset. */
ma_lpf_clear_cache(&pResampler->lpf);
return MA_SUCCESS;
}
/* Linear resampler backend vtable. */
static ma_linear_resampler_config ma_resampling_backend_get_config__linear(const ma_resampler_config* pConfig)
@@ -38793,6 +38894,13 @@ static ma_result ma_resampling_backend_get_expected_output_frame_count__linear(v
return ma_linear_resampler_get_expected_output_frame_count((const ma_linear_resampler*)pBackend, inputFrameCount, pOutputFrameCount);
}
static ma_result ma_resampling_backend_reset__linear(void* pUserData, ma_resampling_backend* pBackend)
{
(void)pUserData;
return ma_linear_resampler_reset((ma_linear_resampler*)pBackend);
}
static ma_resampling_backend_vtable g_ma_linear_resampler_vtable =
{
ma_resampling_backend_get_heap_size__linear,
@@ -38803,7 +38911,8 @@ static ma_resampling_backend_vtable g_ma_linear_resampler_vtable =
ma_resampling_backend_get_input_latency__linear,
ma_resampling_backend_get_output_latency__linear,
ma_resampling_backend_get_required_input_frame_count__linear,
ma_resampling_backend_get_expected_output_frame_count__linear
ma_resampling_backend_get_expected_output_frame_count__linear,
ma_resampling_backend_reset__linear
};
@@ -39104,6 +39213,19 @@ MA_API ma_result ma_resampler_get_expected_output_frame_count(const ma_resampler
return pResampler->pBackendVTable->onGetExpectedOutputFrameCount(pResampler->pBackendUserData, pResampler->pBackend, inputFrameCount, pOutputFrameCount);
}
MA_API ma_result ma_resampler_reset(ma_resampler* pResampler)
{
if (pResampler == NULL) {
return MA_INVALID_ARGS;
}
if (pResampler->pBackendVTable == NULL || pResampler->pBackendVTable->onReset == NULL) {
return MA_NOT_IMPLEMENTED;
}
return pResampler->pBackendVTable->onReset(pResampler->pBackendUserData, pResampler->pBackend);
}
/**************************************************************************************************************************************************************
Channel Conversion
@@ -41644,6 +41766,20 @@ MA_API ma_result ma_data_converter_get_output_channel_map(const ma_data_converte
return MA_SUCCESS;
}
MA_API ma_result ma_data_converter_reset(ma_data_converter* pConverter)
{
if (pConverter == NULL) {
return MA_INVALID_ARGS;
}
/* There's nothing to do if we're not resampling. */
if (pConverter->hasResampler == MA_FALSE) {
return MA_SUCCESS;
}
return ma_resampler_reset(&pConverter->resampler);
}
/**************************************************************************************************************************************************************
@@ -43953,9 +44089,9 @@ MA_API ma_result ma_data_source_set_looping(ma_data_source* pDataSource, ma_bool
return pDataSourceBase->vtable->onSetLooping(pDataSource, isLooping);
}
MA_API ma_bool32 ma_data_source_is_looping(ma_data_source* pDataSource)
MA_API ma_bool32 ma_data_source_is_looping(const ma_data_source* pDataSource)
{
ma_data_source_base* pDataSourceBase = (ma_data_source_base*)pDataSource;
const ma_data_source_base* pDataSourceBase = (const ma_data_source_base*)pDataSource;
if (pDataSource == NULL) {
return MA_FALSE;
@@ -44031,9 +44167,9 @@ MA_API ma_result ma_data_source_set_range_in_pcm_frames(ma_data_source* pDataSou
return MA_SUCCESS;
}
MA_API void ma_data_source_get_range_in_pcm_frames(ma_data_source* pDataSource, ma_uint64* pRangeBegInFrames, ma_uint64* pRangeEndInFrames)
MA_API void ma_data_source_get_range_in_pcm_frames(const ma_data_source* pDataSource, ma_uint64* pRangeBegInFrames, ma_uint64* pRangeEndInFrames)
{
ma_data_source_base* pDataSourceBase = (ma_data_source_base*)pDataSource;
const ma_data_source_base* pDataSourceBase = (const ma_data_source_base*)pDataSource;
if (pDataSource == NULL) {
return;
@@ -44075,9 +44211,9 @@ MA_API ma_result ma_data_source_set_loop_point_in_pcm_frames(ma_data_source* pDa
return MA_SUCCESS;
}
MA_API void ma_data_source_get_loop_point_in_pcm_frames(ma_data_source* pDataSource, ma_uint64* pLoopBegInFrames, ma_uint64* pLoopEndInFrames)
MA_API void ma_data_source_get_loop_point_in_pcm_frames(const ma_data_source* pDataSource, ma_uint64* pLoopBegInFrames, ma_uint64* pLoopEndInFrames)
{
ma_data_source_base* pDataSourceBase = (ma_data_source_base*)pDataSource;
const ma_data_source_base* pDataSourceBase = (const ma_data_source_base*)pDataSource;
if (pDataSource == NULL) {
return;
@@ -44105,9 +44241,9 @@ MA_API ma_result ma_data_source_set_current(ma_data_source* pDataSource, ma_data
return MA_SUCCESS;
}
MA_API ma_data_source* ma_data_source_get_current(ma_data_source* pDataSource)
MA_API ma_data_source* ma_data_source_get_current(const ma_data_source* pDataSource)
{
ma_data_source_base* pDataSourceBase = (ma_data_source_base*)pDataSource;
const ma_data_source_base* pDataSourceBase = (const ma_data_source_base*)pDataSource;
if (pDataSource == NULL) {
return NULL;
@@ -44129,9 +44265,9 @@ MA_API ma_result ma_data_source_set_next(ma_data_source* pDataSource, ma_data_so
return MA_SUCCESS;
}
MA_API ma_data_source* ma_data_source_get_next(ma_data_source* pDataSource)
MA_API ma_data_source* ma_data_source_get_next(const ma_data_source* pDataSource)
{
ma_data_source_base* pDataSourceBase = (ma_data_source_base*)pDataSource;
const ma_data_source_base* pDataSourceBase = (const ma_data_source_base*)pDataSource;
if (pDataSource == NULL) {
return NULL;
@@ -44153,9 +44289,9 @@ MA_API ma_result ma_data_source_set_next_callback(ma_data_source* pDataSource, m
return MA_SUCCESS;
}
MA_API ma_data_source_get_next_proc ma_data_source_get_next_callback(ma_data_source* pDataSource)
MA_API ma_data_source_get_next_proc ma_data_source_get_next_callback(const ma_data_source* pDataSource)
{
ma_data_source_base* pDataSourceBase = (ma_data_source_base*)pDataSource;
const ma_data_source_base* pDataSourceBase = (const ma_data_source_base*)pDataSource;
if (pDataSource == NULL) {
return NULL;
@@ -44192,7 +44328,7 @@ static ma_result ma_audio_buffer_ref__data_source_on_get_data_format(ma_data_sou
*pFormat = pAudioBufferRef->format;
*pChannels = pAudioBufferRef->channels;
*pSampleRate = 0; /* There is no notion of a sample rate with audio buffers. */
*pSampleRate = pAudioBufferRef->sampleRate;
ma_channel_map_init_standard(ma_standard_channel_map_default, pChannelMap, channelMapCap, pAudioBufferRef->channels);
return MA_SUCCESS;
@@ -44248,6 +44384,7 @@ MA_API ma_result ma_audio_buffer_ref_init(ma_format format, ma_uint32 channels,
pAudioBufferRef->format = format;
pAudioBufferRef->channels = channels;
pAudioBufferRef->sampleRate = 0; /* TODO: Version 0.12. Set this to sampleRate. */
pAudioBufferRef->cursor = 0;
pAudioBufferRef->sizeInFrames = sizeInFrames;
pAudioBufferRef->pData = pData;
@@ -44300,7 +44437,7 @@ MA_API ma_uint64 ma_audio_buffer_ref_read_pcm_frames(ma_audio_buffer_ref* pAudio
}
if (pFramesOut != NULL) {
ma_copy_pcm_frames(pFramesOut, ma_offset_ptr(pAudioBufferRef->pData, pAudioBufferRef->cursor * ma_get_bytes_per_frame(pAudioBufferRef->format, pAudioBufferRef->channels)), framesToRead, pAudioBufferRef->format, pAudioBufferRef->channels);
ma_copy_pcm_frames(ma_offset_ptr(pFramesOut, totalFramesRead * ma_get_bytes_per_frame(pAudioBufferRef->format, pAudioBufferRef->channels)), ma_offset_ptr(pAudioBufferRef->pData, pAudioBufferRef->cursor * ma_get_bytes_per_frame(pAudioBufferRef->format, pAudioBufferRef->channels)), framesToRead, pAudioBufferRef->format, pAudioBufferRef->channels);
}
totalFramesRead += framesToRead;
@@ -44458,10 +44595,11 @@ MA_API ma_audio_buffer_config ma_audio_buffer_config_init(ma_format format, ma_u
ma_audio_buffer_config config;
MA_ZERO_OBJECT(&config);
config.format = format;
config.channels = channels;
config.format = format;
config.channels = channels;
config.sampleRate = 0; /* TODO: Version 0.12. Set this to sampleRate. */
config.sizeInFrames = sizeInFrames;
config.pData = pData;
config.pData = pData;
ma_allocation_callbacks_init_copy(&config.allocationCallbacks, pAllocationCallbacks);
return config;
@@ -44490,6 +44628,9 @@ static ma_result ma_audio_buffer_init_ex(const ma_audio_buffer_config* pConfig,
return result;
}
/* TODO: Version 0.12. Set this in ma_audio_buffer_ref_init() instead of here. */
pAudioBuffer->ref.sampleRate = pConfig->sampleRate;
ma_allocation_callbacks_init_copy(&pAudioBuffer->allocationCallbacks, &pConfig->allocationCallbacks);
if (doCopy) {
@@ -46030,7 +46171,7 @@ extern "C" {
#define DRWAV_XSTRINGIFY(x) DRWAV_STRINGIFY(x)
#define DRWAV_VERSION_MAJOR 0
#define DRWAV_VERSION_MINOR 13
#define DRWAV_VERSION_REVISION 5
#define DRWAV_VERSION_REVISION 6
#define DRWAV_VERSION_STRING DRWAV_XSTRINGIFY(DRWAV_VERSION_MAJOR) "." DRWAV_XSTRINGIFY(DRWAV_VERSION_MINOR) "." DRWAV_XSTRINGIFY(DRWAV_VERSION_REVISION)
#include <stddef.h>
typedef signed char drwav_int8;
@@ -46565,7 +46706,7 @@ extern "C" {
#define DRFLAC_XSTRINGIFY(x) DRFLAC_STRINGIFY(x)
#define DRFLAC_VERSION_MAJOR 0
#define DRFLAC_VERSION_MINOR 12
#define DRFLAC_VERSION_REVISION 37
#define DRFLAC_VERSION_REVISION 38
#define DRFLAC_VERSION_STRING DRFLAC_XSTRINGIFY(DRFLAC_VERSION_MAJOR) "." DRFLAC_XSTRINGIFY(DRFLAC_VERSION_MINOR) "." DRFLAC_XSTRINGIFY(DRFLAC_VERSION_REVISION)
#include <stddef.h>
typedef signed char drflac_int8;
@@ -46926,7 +47067,7 @@ extern "C" {
#define DRMP3_XSTRINGIFY(x) DRMP3_STRINGIFY(x)
#define DRMP3_VERSION_MAJOR 0
#define DRMP3_VERSION_MINOR 6
#define DRMP3_VERSION_REVISION 32
#define DRMP3_VERSION_REVISION 33
#define DRMP3_VERSION_STRING DRMP3_XSTRINGIFY(DRMP3_VERSION_MAJOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_MINOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_REVISION)
#include <stddef.h>
typedef signed char drmp3_int8;
@@ -47050,9 +47191,14 @@ typedef drmp3_int32 drmp3_result;
#define DRMP3_INLINE __forceinline
#elif defined(__GNUC__)
#if defined(__STRICT_ANSI__)
#define DRMP3_INLINE __inline__ __attribute__((always_inline))
#define DRMP3_GNUC_INLINE_HINT __inline__
#else
#define DRMP3_INLINE inline __attribute__((always_inline))
#define DRMP3_GNUC_INLINE_HINT inline
#endif
#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 2)) || defined(__clang__)
#define DRMP3_INLINE DRMP3_GNUC_INLINE_HINT __attribute__((always_inline))
#else
#define DRMP3_INLINE DRMP3_GNUC_INLINE_HINT
#endif
#elif defined(__WATCOMC__)
#define DRMP3_INLINE __inline
@@ -51226,6 +51372,7 @@ MA_API ma_result ma_decoder_seek_to_pcm_frame(ma_decoder* pDecoder, ma_uint64 fr
ma_result result;
ma_uint64 internalFrameIndex;
ma_uint32 internalSampleRate;
ma_uint64 currentFrameIndex;
result = ma_data_source_get_data_format(pDecoder->pBackend, NULL, NULL, &internalSampleRate, NULL, 0);
if (result != MA_SUCCESS) {
@@ -51238,9 +51385,16 @@ MA_API ma_result ma_decoder_seek_to_pcm_frame(ma_decoder* pDecoder, ma_uint64 fr
internalFrameIndex = ma_calculate_frame_count_after_resampling(internalSampleRate, pDecoder->outputSampleRate, frameIndex);
}
result = ma_data_source_seek_to_pcm_frame(pDecoder->pBackend, internalFrameIndex);
if (result == MA_SUCCESS) {
pDecoder->readPointerInPCMFrames = frameIndex;
/* Only seek if we're requesting a different frame to what we're currently sitting on. */
ma_data_source_get_cursor_in_pcm_frames(pDecoder->pBackend, &currentFrameIndex);
if (currentFrameIndex != internalFrameIndex) {
result = ma_data_source_seek_to_pcm_frame(pDecoder->pBackend, internalFrameIndex);
if (result == MA_SUCCESS) {
pDecoder->readPointerInPCMFrames = frameIndex;
}
/* Reset the data converter so that any cached data in the resampler is cleared. */
ma_data_converter_reset(&pDecoder->converter);
}
return result;
@@ -53786,11 +53940,12 @@ static ma_data_source* ma_resource_manager_data_buffer_get_connector(ma_resource
};
}
static ma_result ma_resource_manager_data_buffer_init_connector(ma_resource_manager_data_buffer* pDataBuffer, ma_async_notification* pInitNotification, ma_fence* pInitFence)
static ma_result ma_resource_manager_data_buffer_init_connector(ma_resource_manager_data_buffer* pDataBuffer, const ma_resource_manager_data_source_config* pConfig, ma_async_notification* pInitNotification, ma_fence* pInitFence)
{
ma_result result;
MA_ASSERT(pDataBuffer != NULL);
MA_ASSERT(pConfig != NULL);
MA_ASSERT(pDataBuffer->isConnectorInitialized == MA_FALSE);
/* The underlying data buffer must be initialized before we'll be able to know how to initialize the backend. */
@@ -53844,7 +53999,9 @@ static ma_result ma_resource_manager_data_buffer_init_connector(ma_resource_mana
Make sure the looping state is set before returning in order to handle the case where the
loop state was set on the data buffer before the connector was initialized.
*/
ma_data_source_set_looping(ma_resource_manager_data_buffer_get_connector(pDataBuffer), ma_resource_manager_data_buffer_is_looping(pDataBuffer));
ma_data_source_set_range_in_pcm_frames(pDataBuffer, pConfig->rangeBegInPCMFrames, pConfig->rangeEndInPCMFrames);
ma_data_source_set_loop_point_in_pcm_frames(pDataBuffer, pConfig->loopPointBegInPCMFrames, pConfig->loopPointEndInPCMFrames);
ma_data_source_set_looping(pDataBuffer, pConfig->isLooping);
pDataBuffer->isConnectorInitialized = MA_TRUE;
@@ -53930,7 +54087,7 @@ static ma_result ma_resource_manager_data_buffer_node_init_supply_encoded(ma_res
return MA_SUCCESS;
}
static ma_result ma_resource_manager_data_buffer_node_init_supply_decoded(ma_resource_manager* pResourceManager, ma_resource_manager_data_buffer_node* pDataBufferNode, const char* pFilePath, const wchar_t* pFilePathW, ma_decoder** ppDecoder)
static ma_result ma_resource_manager_data_buffer_node_init_supply_decoded(ma_resource_manager* pResourceManager, ma_resource_manager_data_buffer_node* pDataBufferNode, const char* pFilePath, const wchar_t* pFilePathW, ma_uint32 flags, ma_decoder** ppDecoder)
{
ma_result result = MA_SUCCESS;
ma_decoder* pDecoder;
@@ -53960,9 +54117,13 @@ static ma_result ma_resource_manager_data_buffer_node_init_supply_decoded(ma_res
allocated buffer, whereas a paged buffer is a linked list of paged-sized buffers. The latter
is used when the length of a sound is unknown until a full decode has been performed.
*/
result = ma_decoder_get_length_in_pcm_frames(pDecoder, &totalFrameCount);
if (result != MA_SUCCESS) {
return result;
if ((flags & MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_UNKNOWN_LENGTH) == 0) {
result = ma_decoder_get_length_in_pcm_frames(pDecoder, &totalFrameCount);
if (result != MA_SUCCESS) {
return result;
}
} else {
totalFrameCount = 0;
}
if (totalFrameCount > 0) {
@@ -54204,7 +54365,7 @@ static ma_result ma_resource_manager_data_buffer_node_acquire_critical_section(m
job.data.resourceManager.loadDataBufferNode.pDataBufferNode = pDataBufferNode;
job.data.resourceManager.loadDataBufferNode.pFilePath = pFilePathCopy;
job.data.resourceManager.loadDataBufferNode.pFilePathW = pFilePathWCopy;
job.data.resourceManager.loadDataBufferNode.decode = (flags & MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_DECODE ) != 0;
job.data.resourceManager.loadDataBufferNode.flags = flags;
job.data.resourceManager.loadDataBufferNode.pInitNotification = ((flags & MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_WAIT_INIT) != 0) ? pInitNotification : NULL;
job.data.resourceManager.loadDataBufferNode.pDoneNotification = NULL;
job.data.resourceManager.loadDataBufferNode.pInitFence = pInitFence;
@@ -54330,7 +54491,7 @@ static ma_result ma_resource_manager_data_buffer_node_acquire(ma_resource_manage
} else {
/* Decoding. We do this the same way as we do when loading asynchronously. */
ma_decoder* pDecoder;
result = ma_resource_manager_data_buffer_node_init_supply_decoded(pResourceManager, pDataBufferNode, pFilePath, pFilePathW, &pDecoder);
result = ma_resource_manager_data_buffer_node_init_supply_decoded(pResourceManager, pDataBufferNode, pFilePath, pFilePathW, flags, &pDecoder);
if (result != MA_SUCCESS) {
goto done;
}
@@ -54532,7 +54693,15 @@ static ma_result ma_resource_manager_data_buffer_cb__get_length_in_pcm_frames(ma
static ma_result ma_resource_manager_data_buffer_cb__set_looping(ma_data_source* pDataSource, ma_bool32 isLooping)
{
return ma_resource_manager_data_buffer_set_looping((ma_resource_manager_data_buffer*)pDataSource, isLooping);
ma_resource_manager_data_buffer* pDataBuffer = (ma_resource_manager_data_buffer*)pDataSource;
MA_ASSERT(pDataBuffer != NULL);
c89atomic_exchange_32(&pDataBuffer->isLooping, isLooping);
/* The looping state needs to be set on the connector as well or else looping won't work when we read audio data. */
ma_data_source_set_looping(ma_resource_manager_data_buffer_get_connector(pDataBuffer), isLooping);
return MA_SUCCESS;
}
static ma_data_source_vtable g_ma_resource_manager_data_buffer_vtable =
@@ -54622,7 +54791,7 @@ static ma_result ma_resource_manager_data_buffer_init_ex_internal(ma_resource_ma
/* If we're loading asynchronously we need to post a job to the job queue to initialize the connector. */
if (async == MA_FALSE || ma_resource_manager_data_buffer_node_result(pDataBufferNode) == MA_SUCCESS) {
/* Loading synchronously or the data has already been fully loaded. We can just initialize the connector from here without a job. */
result = ma_resource_manager_data_buffer_init_connector(pDataBuffer, NULL, NULL);
result = ma_resource_manager_data_buffer_init_connector(pDataBuffer, pConfig, NULL, NULL);
c89atomic_exchange_i32(&pDataBuffer->result, result);
ma_resource_manager_pipeline_notifications_signal_all_notifications(&notifications);
@@ -54648,11 +54817,16 @@ static ma_result ma_resource_manager_data_buffer_init_ex_internal(ma_resource_ma
job = ma_job_init(MA_JOB_TYPE_RESOURCE_MANAGER_LOAD_DATA_BUFFER);
job.order = ma_resource_manager_data_buffer_next_execution_order(pDataBuffer);
job.data.resourceManager.loadDataBuffer.pDataBuffer = pDataBuffer;
job.data.resourceManager.loadDataBuffer.pInitNotification = ((flags & MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_WAIT_INIT) != 0) ? &initNotification : notifications.init.pNotification;
job.data.resourceManager.loadDataBuffer.pDoneNotification = notifications.done.pNotification;
job.data.resourceManager.loadDataBuffer.pInitFence = notifications.init.pFence;
job.data.resourceManager.loadDataBuffer.pDoneFence = notifications.done.pFence;
job.data.resourceManager.loadDataBuffer.pDataBuffer = pDataBuffer;
job.data.resourceManager.loadDataBuffer.pInitNotification = ((flags & MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_WAIT_INIT) != 0) ? &initNotification : notifications.init.pNotification;
job.data.resourceManager.loadDataBuffer.pDoneNotification = notifications.done.pNotification;
job.data.resourceManager.loadDataBuffer.pInitFence = notifications.init.pFence;
job.data.resourceManager.loadDataBuffer.pDoneFence = notifications.done.pFence;
job.data.resourceManager.loadDataBuffer.rangeBegInPCMFrames = pConfig->rangeBegInPCMFrames;
job.data.resourceManager.loadDataBuffer.rangeEndInPCMFrames = pConfig->rangeEndInPCMFrames;
job.data.resourceManager.loadDataBuffer.loopPointBegInPCMFrames = pConfig->loopPointBegInPCMFrames;
job.data.resourceManager.loadDataBuffer.loopPointEndInPCMFrames = pConfig->loopPointEndInPCMFrames;
job.data.resourceManager.loadDataBuffer.isLooping = pConfig->isLooping;
result = ma_resource_manager_post_job(pResourceManager, &job);
if (result != MA_SUCCESS) {
@@ -55042,25 +55216,12 @@ MA_API ma_result ma_resource_manager_data_buffer_result(const ma_resource_manage
MA_API ma_result ma_resource_manager_data_buffer_set_looping(ma_resource_manager_data_buffer* pDataBuffer, ma_bool32 isLooping)
{
if (pDataBuffer == NULL) {
return MA_INVALID_ARGS;
}
c89atomic_exchange_32(&pDataBuffer->isLooping, isLooping);
/* The looping state needs to be set on the connector as well or else looping won't work when we read audio data. */
ma_data_source_set_looping(ma_resource_manager_data_buffer_get_connector(pDataBuffer), isLooping);
return MA_SUCCESS;
return ma_data_source_set_looping(pDataBuffer, isLooping);
}
MA_API ma_bool32 ma_resource_manager_data_buffer_is_looping(const ma_resource_manager_data_buffer* pDataBuffer)
{
if (pDataBuffer == NULL) {
return MA_FALSE;
}
return c89atomic_load_32((ma_bool32*)&pDataBuffer->isLooping);
return ma_data_source_is_looping(pDataBuffer);
}
MA_API ma_result ma_resource_manager_data_buffer_get_available_frames(ma_resource_manager_data_buffer* pDataBuffer, ma_uint64* pAvailableFrames)
@@ -55246,7 +55407,12 @@ static ma_result ma_resource_manager_data_stream_cb__get_length_in_pcm_frames(ma
static ma_result ma_resource_manager_data_stream_cb__set_looping(ma_data_source* pDataSource, ma_bool32 isLooping)
{
return ma_resource_manager_data_stream_set_looping((ma_resource_manager_data_stream*)pDataSource, isLooping);
ma_resource_manager_data_stream* pDataStream = (ma_resource_manager_data_stream*)pDataSource;
MA_ASSERT(pDataStream != NULL);
c89atomic_exchange_32(&pDataStream->isLooping, isLooping);
return MA_SUCCESS;
}
static ma_data_source_vtable g_ma_resource_manager_data_stream_vtable =
@@ -55715,6 +55881,14 @@ MA_API ma_result ma_resource_manager_data_stream_seek_to_pcm_frame(ma_resource_m
return MA_INVALID_OPERATION;
}
/* If we're not already seeking and we're sitting on the same frame, just make this a no-op. */
if (c89atomic_load_32(&pDataStream->seekCounter) == 0) {
if (c89atomic_load_64(&pDataStream->absoluteCursor) == frameIndex) {
return MA_SUCCESS;
}
}
/* Increment the seek counter first to indicate to read_paged_pcm_frames() and map_paged_pcm_frames() that we are in the middle of a seek and MA_BUSY should be returned. */
c89atomic_fetch_add_32(&pDataStream->seekCounter, 1);
@@ -55859,13 +56033,7 @@ MA_API ma_result ma_resource_manager_data_stream_result(const ma_resource_manage
MA_API ma_result ma_resource_manager_data_stream_set_looping(ma_resource_manager_data_stream* pDataStream, ma_bool32 isLooping)
{
if (pDataStream == NULL) {
return MA_INVALID_ARGS;
}
c89atomic_exchange_32(&pDataStream->isLooping, isLooping);
return MA_SUCCESS;
return ma_data_source_set_looping(pDataStream, isLooping);
}
MA_API ma_bool32 ma_resource_manager_data_stream_is_looping(const ma_resource_manager_data_stream* pDataStream)
@@ -56227,7 +56395,7 @@ static ma_result ma_job_process__resource_manager__load_data_buffer_node(ma_job*
will determine that the node is available for data delivery and the data buffer connectors can be
initialized. Therefore, it's important that it is set after the data supply has been initialized.
*/
if (pJob->data.resourceManager.loadDataBufferNode.decode) {
if ((pJob->data.resourceManager.loadDataBufferNode.flags & MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_DECODE) != 0) {
/*
Decoding. This is the complex case because we're not going to be doing the entire decoding
process here. Instead it's going to be split of multiple jobs and loaded in pages. The
@@ -56246,7 +56414,7 @@ static ma_result ma_job_process__resource_manager__load_data_buffer_node(ma_job*
ma_job pageDataBufferNodeJob;
/* Allocate the decoder by initializing a decoded data supply. */
result = ma_resource_manager_data_buffer_node_init_supply_decoded(pResourceManager, pDataBufferNode, pJob->data.resourceManager.loadDataBufferNode.pFilePath, pJob->data.resourceManager.loadDataBufferNode.pFilePathW, &pDecoder);
result = ma_resource_manager_data_buffer_node_init_supply_decoded(pResourceManager, pDataBufferNode, pJob->data.resourceManager.loadDataBufferNode.pFilePath, pJob->data.resourceManager.loadDataBufferNode.pFilePathW, pJob->data.resourceManager.loadDataBufferNode.flags, &pDecoder);
/*
Don't ever propagate an MA_BUSY result code or else the resource manager will think the
@@ -56492,7 +56660,15 @@ static ma_result ma_job_process__resource_manager__load_data_buffer(ma_job* pJob
if (dataSupplyType != ma_resource_manager_data_supply_type_unknown) {
/* We can now initialize the connector. If this fails, we need to abort. It's very rare for this to fail. */
result = ma_resource_manager_data_buffer_init_connector(pDataBuffer, pJob->data.resourceManager.loadDataBuffer.pInitNotification, pJob->data.resourceManager.loadDataBuffer.pInitFence);
ma_resource_manager_data_source_config dataSourceConfig; /* For setting initial looping state and range. */
dataSourceConfig = ma_resource_manager_data_source_config_init();
dataSourceConfig.rangeBegInPCMFrames = pJob->data.resourceManager.loadDataBuffer.rangeBegInPCMFrames;
dataSourceConfig.rangeEndInPCMFrames = pJob->data.resourceManager.loadDataBuffer.rangeEndInPCMFrames;
dataSourceConfig.loopPointBegInPCMFrames = pJob->data.resourceManager.loadDataBuffer.loopPointBegInPCMFrames;
dataSourceConfig.loopPointEndInPCMFrames = pJob->data.resourceManager.loadDataBuffer.loopPointEndInPCMFrames;
dataSourceConfig.isLooping = pJob->data.resourceManager.loadDataBuffer.isLooping;
result = ma_resource_manager_data_buffer_init_connector(pDataBuffer, &dataSourceConfig, pJob->data.resourceManager.loadDataBuffer.pInitNotification, pJob->data.resourceManager.loadDataBuffer.pInitFence);
if (result != MA_SUCCESS) {
ma_log_postf(ma_resource_manager_get_log(pResourceManager), MA_LOG_LEVEL_ERROR, "Failed to initialize connector for data buffer. %s.\n", ma_result_description(result));
goto done;
@@ -56615,9 +56791,13 @@ static ma_result ma_job_process__resource_manager__load_data_stream(ma_job* pJob
}
/* Retrieve the total length of the file before marking the decoder are loaded. */
result = ma_decoder_get_length_in_pcm_frames(&pDataStream->decoder, &pDataStream->totalLengthInPCMFrames);
if (result != MA_SUCCESS) {
goto done; /* Failed to retrieve the length. */
if ((pDataStream->flags & MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_UNKNOWN_LENGTH) == 0) {
result = ma_decoder_get_length_in_pcm_frames(&pDataStream->decoder, &pDataStream->totalLengthInPCMFrames);
if (result != MA_SUCCESS) {
goto done; /* Failed to retrieve the length. */
}
} else {
pDataStream->totalLengthInPCMFrames = 0;
}
/*
@@ -59976,6 +60156,7 @@ static void ma_engine_node_process_pcm_frames__sound(ma_node* pNode, const float
ma_uint32 dataSourceChannels;
ma_uint8 temp[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
ma_uint32 tempCapInFrames;
ma_uint64 seekTarget;
/* This is a data source node which means no input buses. */
(void)ppFramesIn;
@@ -59989,13 +60170,14 @@ static void ma_engine_node_process_pcm_frames__sound(ma_node* pNode, const float
}
/* If we're seeking, do so now before reading. */
if (pSound->seekTarget != MA_SEEK_TARGET_NONE) {
ma_data_source_seek_to_pcm_frame(pSound->pDataSource, pSound->seekTarget);
seekTarget = c89atomic_load_64(&pSound->seekTarget);
if (seekTarget != MA_SEEK_TARGET_NONE) {
ma_data_source_seek_to_pcm_frame(pSound->pDataSource, seekTarget);
/* Any time-dependant effects need to have their times updated. */
ma_node_set_time(pSound, pSound->seekTarget);
ma_node_set_time(pSound, seekTarget);
pSound->seekTarget = MA_SEEK_TARGET_NONE;
c89atomic_exchange_64(&pSound->seekTarget, MA_SEEK_TARGET_NONE);
}
/*
@@ -62150,24 +62332,8 @@ MA_API ma_result ma_sound_seek_to_pcm_frame(ma_sound* pSound, ma_uint64 frameInd
return MA_INVALID_OPERATION;
}
/*
Resource manager data sources are thread safe which means we can just seek immediately. However, we cannot guarantee that other data sources are
thread safe as well so in that case we'll need to get the mixing thread to seek for us to ensure we don't try seeking at the same time as reading.
*/
#ifndef MA_NO_RESOURCE_MANAGER
if (pSound->pDataSource == pSound->pResourceManagerDataSource) {
ma_result result = ma_resource_manager_data_source_seek_to_pcm_frame(pSound->pResourceManagerDataSource, frameIndex);
if (result != MA_SUCCESS) {
return result;
}
/* Time dependant effects need to have their timers updated. */
return ma_node_set_time(&pSound->engineNode, frameIndex);
}
#endif
/* Getting here means the data source is not a resource manager data source so we'll need to get the mixing thread to do the seeking for us. */
pSound->seekTarget = frameIndex;
/* We can't be seeking while reading at the same time. We just set the seek target and get the mixing thread to do the actual seek. */
c89atomic_exchange_64(&pSound->seekTarget, frameIndex);
return MA_SUCCESS;
}
@@ -62631,9 +62797,14 @@ code below please report the bug to the respective repository for the relevant p
#define DRWAV_INLINE __forceinline
#elif defined(__GNUC__)
#if defined(__STRICT_ANSI__)
#define DRWAV_INLINE __inline__ __attribute__((always_inline))
#define DRWAV_GNUC_INLINE_HINT __inline__
#else
#define DRWAV_INLINE inline __attribute__((always_inline))
#define DRWAV_GNUC_INLINE_HINT inline
#endif
#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 2)) || defined(__clang__)
#define DRWAV_INLINE DRWAV_GNUC_INLINE_HINT __attribute__((always_inline))
#else
#define DRWAV_INLINE DRWAV_GNUC_INLINE_HINT
#endif
#elif defined(__WATCOMC__)
#define DRWAV_INLINE __inline
@@ -63123,7 +63294,7 @@ DRWAV_PRIVATE drwav_bool32 drwav__read_fmt(drwav_read_proc onRead, drwav_seek_pr
fmtOut->extendedSize = 0;
fmtOut->validBitsPerSample = 0;
fmtOut->channelMask = 0;
memset(fmtOut->subFormat, 0, sizeof(fmtOut->subFormat));
DRWAV_ZERO_MEMORY(fmtOut->subFormat, sizeof(fmtOut->subFormat));
if (header.sizeInBytes > 16) {
drwav_uint8 fmt_cbSize[2];
int bytesReadSoFar = 0;
@@ -63256,7 +63427,7 @@ DRWAV_PRIVATE void drwav__metadata_request_extra_memory_for_stage_2(drwav__metad
DRWAV_PRIVATE drwav_result drwav__metadata_alloc(drwav__metadata_parser* pParser, drwav_allocation_callbacks* pAllocationCallbacks)
{
if (pParser->extraCapacity != 0 || pParser->metadataCount != 0) {
free(pParser->pData);
pAllocationCallbacks->onFree(pParser->pData, pAllocationCallbacks->pUserData);
pParser->pData = (drwav_uint8*)pAllocationCallbacks->onMalloc(drwav__metadata_memory_capacity(pParser), pAllocationCallbacks->pUserData);
pParser->pDataCursor = pParser->pData;
if (pParser->pData == NULL) {
@@ -63390,6 +63561,14 @@ DRWAV_PRIVATE drwav_uint64 drwav__read_acid_to_metadata_obj(drwav__metadata_pars
}
return bytesRead;
}
DRWAV_PRIVATE size_t drwav__strlen(const char* str)
{
size_t result = 0;
while (*str++) {
result += 1;
}
return result;
}
DRWAV_PRIVATE size_t drwav__strlen_clamped(const char* str, size_t maxToRead)
{
size_t result = 0;
@@ -63404,7 +63583,7 @@ DRWAV_PRIVATE char* drwav__metadata_copy_string(drwav__metadata_parser* pParser,
if (len) {
char* result = (char*)drwav__metadata_get_memory(pParser, len + 1, 1);
DRWAV_ASSERT(result != NULL);
memcpy(result, str, len);
DRWAV_COPY_MEMORY(result, str, len);
result[len] = '\0';
return result;
} else {
@@ -63534,7 +63713,7 @@ DRWAV_PRIVATE drwav_uint64 drwav__read_bext_to_metadata_obj(drwav__metadata_pars
pMetadata->data.bext.pCodingHistory = (char*)drwav__metadata_get_memory(pParser, extraBytes + 1, 1);
DRWAV_ASSERT(pMetadata->data.bext.pCodingHistory != NULL);
bytesRead += drwav__metadata_parser_read(pParser, pMetadata->data.bext.pCodingHistory, extraBytes, NULL);
pMetadata->data.bext.codingHistorySize = (drwav_uint32)strlen(pMetadata->data.bext.pCodingHistory);
pMetadata->data.bext.codingHistorySize = (drwav_uint32)drwav__strlen(pMetadata->data.bext.pCodingHistory);
} else {
pMetadata->data.bext.pCodingHistory = NULL;
pMetadata->data.bext.codingHistorySize = 0;
@@ -63751,19 +63930,19 @@ DRWAV_PRIVATE drwav_uint64 drwav__metadata_process_chunk(drwav__metadata_parser*
if (bytesJustRead != DRWAV_BEXT_DESCRIPTION_BYTES) {
return bytesRead;
}
allocSizeNeeded += strlen(buffer) + 1;
allocSizeNeeded += drwav__strlen(buffer) + 1;
buffer[DRWAV_BEXT_ORIGINATOR_NAME_BYTES] = '\0';
bytesJustRead = drwav__metadata_parser_read(pParser, buffer, DRWAV_BEXT_ORIGINATOR_NAME_BYTES, &bytesRead);
if (bytesJustRead != DRWAV_BEXT_ORIGINATOR_NAME_BYTES) {
return bytesRead;
}
allocSizeNeeded += strlen(buffer) + 1;
allocSizeNeeded += drwav__strlen(buffer) + 1;
buffer[DRWAV_BEXT_ORIGINATOR_REF_BYTES] = '\0';
bytesJustRead = drwav__metadata_parser_read(pParser, buffer, DRWAV_BEXT_ORIGINATOR_REF_BYTES, &bytesRead);
if (bytesJustRead != DRWAV_BEXT_ORIGINATOR_REF_BYTES) {
return bytesRead;
}
allocSizeNeeded += strlen(buffer) + 1;
allocSizeNeeded += drwav__strlen(buffer) + 1;
allocSizeNeeded += (size_t)pChunkHeader->sizeInBytes - DRWAV_BEXT_BYTES;
drwav__metadata_request_extra_memory_for_stage_2(pParser, allocSizeNeeded, 1);
pParser->metadataCount += 1;
@@ -64030,7 +64209,7 @@ DRWAV_PRIVATE drwav_bool32 drwav_init__internal(drwav* pWav, drwav_chunk_proc on
if (translatedFormatTag == DR_WAVE_FORMAT_EXTENSIBLE) {
translatedFormatTag = drwav_bytes_to_u16(fmt.subFormat + 0);
}
memset(&metadataParser, 0, sizeof(metadataParser));
DRWAV_ZERO_MEMORY(&metadataParser, sizeof(metadataParser));
if (!sequential && pWav->allowedMetadataTypes != drwav_metadata_type_none && (pWav->container == drwav_container_riff || pWav->container == drwav_container_rf64)) {
drwav_uint64 cursorForMetadata = cursor;
metadataParser.onRead = pWav->onRead;
@@ -64462,7 +64641,7 @@ DRWAV_PRIVATE size_t drwav__write_or_count_metadata(drwav* pWav, drwav_metadata*
bytesWritten += drwav__write_or_count_u16ne_to_le(pWav, pMetadata->data.bext.maxTruePeakLevel);
bytesWritten += drwav__write_or_count_u16ne_to_le(pWav, pMetadata->data.bext.maxMomentaryLoudness);
bytesWritten += drwav__write_or_count_u16ne_to_le(pWav, pMetadata->data.bext.maxShortTermLoudness);
memset(reservedBuf, 0, sizeof(reservedBuf));
DRWAV_ZERO_MEMORY(reservedBuf, sizeof(reservedBuf));
bytesWritten += drwav__write_or_count(pWav, reservedBuf, sizeof(reservedBuf));
if (pMetadata->data.bext.codingHistorySize > 0) {
bytesWritten += drwav__write_or_count(pWav, pMetadata->data.bext.pCodingHistory, pMetadata->data.bext.codingHistorySize);
@@ -67693,9 +67872,14 @@ DRWAV_API drwav_bool32 drwav_fourcc_equal(const drwav_uint8* a, const char* b)
#define DRFLAC_INLINE __forceinline
#elif defined(__GNUC__)
#if defined(__STRICT_ANSI__)
#define DRFLAC_INLINE __inline__ __attribute__((always_inline))
#define DRFLAC_GNUC_INLINE_HINT __inline__
#else
#define DRFLAC_INLINE inline __attribute__((always_inline))
#define DRFLAC_GNUC_INLINE_HINT inline
#endif
#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 2)) || defined(__clang__)
#define DRFLAC_INLINE DRFLAC_GNUC_INLINE_HINT __attribute__((always_inline))
#else
#define DRFLAC_INLINE DRFLAC_GNUC_INLINE_HINT
#endif
#elif defined(__WATCOMC__)
#define DRFLAC_INLINE __inline
@@ -72637,7 +72821,7 @@ static drflac* drflac_open_with_metadata_private(drflac_read_proc onRead, drflac
#ifndef DR_FLAC_NO_OGG
if (init.container == drflac_container_ogg) {
drflac_oggbs* pInternalOggbs = (drflac_oggbs*)((drflac_uint8*)pFlac->pDecodedSamples + decodedSamplesAllocationSize + seektableSize);
*pInternalOggbs = oggbs;
DRFLAC_COPY_MEMORY(pInternalOggbs, &oggbs, sizeof(oggbs));
pFlac->bs.onRead = drflac__on_read_ogg;
pFlac->bs.onSeek = drflac__on_seek_ogg;
pFlac->bs.pUserData = (void*)pInternalOggbs;
@@ -77375,7 +77559,11 @@ static void drmp3d_synth(float *xl, drmp3d_sample_t *dstl, int nch, float *lins)
vst1_lane_s16(dstl + (49 + i)*nch, pcmb, 2);
#endif
#else
#if DRMP3_HAVE_SSE
static const drmp3_f4 g_scale = { 1.0f/32768.0f, 1.0f/32768.0f, 1.0f/32768.0f, 1.0f/32768.0f };
#else
const drmp3_f4 g_scale = vdupq_n_f32(1.0f/32768.0f);
#endif
a = DRMP3_VMUL(a, g_scale);
b = DRMP3_VMUL(b, g_scale);
#if DRMP3_HAVE_SSE
@@ -77649,7 +77837,6 @@ DRMP3_API void drmp3dec_f32_to_s16(const float *in, drmp3_int16 *out, size_t num
}
}
}
#include <math.h>
#if defined(SIZE_MAX)
#define DRMP3_SIZE_MAX SIZE_MAX
#else
@@ -77695,18 +77882,6 @@ static DRMP3_INLINE drmp3_uint32 drmp3_gcf_u32(drmp3_uint32 a, drmp3_uint32 b)
}
return a;
}
static DRMP3_INLINE double drmp3_sin(double x)
{
return sin(x);
}
static DRMP3_INLINE double drmp3_exp(double x)
{
return exp(x);
}
static DRMP3_INLINE double drmp3_cos(double x)
{
return drmp3_sin((DRMP3_PI_D*0.5) - x);
}
static void* drmp3__malloc_default(size_t sz, void* pUserData)
{
(void)pUserData;