From 0eb86ea1daa75deafb273e841854bf9ec9f80201 Mon Sep 17 00:00:00 2001 From: David Reid Date: Fri, 1 Mar 2024 09:58:27 +1000 Subject: [PATCH] Fix a bug where sounds loaded with `MA_SOUND_FLAG_DECODE` do not loop. --- CHANGES.md | 1 + miniaudio.h | 33 ++++++++++++++++++++------------- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index d50b2ffe..2526c56c 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -3,6 +3,7 @@ v0.11.22 - TBD * Add `MA_SOUND_FLAG_LOOPING` and `MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_LOOPING` flags. These can be used to initialize sounds and resource managed data sources to loop by default. This is the recommended way to enable looping for streams. The `isLooping` config option in `ma_sound_config` and `ma_resource_manager_data_source_config` has been deprecated. If you are using those, you should switch to the new flag or else you'll get compiler errors when upgrading to a future version. * Fix a bug relating to node detachment. * Fix a bug where amplification with `ma_device_set_master_volume()` does not work. +* Fix a bug where sounds loaded with `MA_SOUND_FLAG_DECODE` do not loop. * ALSA: Fix some warnings relating to unhandled return value of `read()`. * DirectSound: Add support for specifying an explicit window handle for SetCooperativeLevel(). * Web: Fix ScriptProcessorNode path when compiling with `--closure=1`. Note that the Audio Worklets path is not currently working due to the callback specified in `emscripten_create_wasm_audio_worklet_processor_async` never getting fired. diff --git a/miniaudio.h b/miniaudio.h index aa32dc43..208df04a 100644 --- a/miniaudio.h +++ b/miniaudio.h @@ -69210,22 +69210,29 @@ MA_API ma_result ma_resource_manager_data_buffer_read_pcm_frames(ma_resource_man isDecodedBufferBusy = (ma_resource_manager_data_buffer_node_result(pDataBuffer->pNode) == MA_BUSY); if (ma_resource_manager_data_buffer_get_available_frames(pDataBuffer, &availableFrames) == MA_SUCCESS) { - /* Don't try reading more than the available frame count. */ - if (frameCount > availableFrames) { - frameCount = availableFrames; + /* Don't try reading more than the available frame count if the data buffer node is still loading. */ + if (isDecodedBufferBusy) { + if (frameCount > availableFrames) { + frameCount = availableFrames; - /* - If there's no frames available we want to set the status to MA_AT_END. The logic below - will check if the node is busy, and if so, change it to MA_BUSY. The reason we do this - is because we don't want to call `ma_data_source_read_pcm_frames()` if the frame count - is 0 because that'll result in a situation where it's possible MA_AT_END won't get - returned. - */ - if (frameCount == 0) { - result = MA_AT_END; + /* + If there's no frames available we want to set the status to MA_AT_END. The logic below + will check if the node is busy, and if so, change it to MA_BUSY. The reason we do this + is because we don't want to call `ma_data_source_read_pcm_frames()` if the frame count + is 0 because that'll result in a situation where it's possible MA_AT_END won't get + returned. + */ + if (frameCount == 0) { + result = MA_AT_END; + } + } else { + isDecodedBufferBusy = MA_FALSE; /* We have enough frames available in the buffer to avoid a MA_BUSY status. */ } } else { - isDecodedBufferBusy = MA_FALSE; /* We have enough frames available in the buffer to avoid a MA_BUSY status. */ + /* + Getting here means the buffer has been fully loaded. We can just pass the frame count straight + into ma_data_source_read_pcm_frames() below and let ma_data_source handle it. + */ } } }