Commit fcddfe62 authored by David Reid's avatar David Reid

Update ma_pcm_rb data source implementation.

The data source implementation of a ma_pcm_rb could possibly return a
frame count of 0 which would in turn result in
ma_data_source_read_pcm_frames() returning MA_AT_END which does not
make sense for a ring buffer since it has no notion of an end.
parent 547ef1c9
...@@ -2,6 +2,7 @@ v0.11.22 - TBD ...@@ -2,6 +2,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. * 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.
* `ma_rb_commit_read()`, `ma_rb_commit_write()`, `ma_pcm_rb_commit_read()` and `ma_pcm_rb_commit_write()` no longer return `MA_AT_END`. The reason for this change is that there's no real notion of an "end" in a ring buffer which makes this result code confusing. In addition, it's possible for these functions to return something other than `MA_SUCCESS` when the operation completed successfully which adds to the confusion. The correct way to check if there is any more room in the ring buffer is to look at the frame count returned by `*rb_acquire_read/write()`. * `ma_rb_commit_read()`, `ma_rb_commit_write()`, `ma_pcm_rb_commit_read()` and `ma_pcm_rb_commit_write()` no longer return `MA_AT_END`. The reason for this change is that there's no real notion of an "end" in a ring buffer which makes this result code confusing. In addition, it's possible for these functions to return something other than `MA_SUCCESS` when the operation completed successfully which adds to the confusion. The correct way to check if there is any more room in the ring buffer is to look at the frame count returned by `*rb_acquire_read/write()`.
* The `ma_pcm_rb` data source implementation has been modified to pad output data with silence if there is not enough data in the ring buffer to fill the request. What this means is `ma_data_source_read_pcm_frames()` should no longer return a frame count of less than what you requested, and will therefore never return `MA_AT_END` which does not make sense for a ring buffer since it does not have the notion of an end.
* Fix a bug relating to node detachment. * 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 amplification with `ma_device_set_master_volume()` does not work.
* Fix a bug where sounds loaded with `MA_SOUND_FLAG_DECODE` do not loop. * Fix a bug where sounds loaded with `MA_SOUND_FLAG_DECODE` do not loop.
......
...@@ -125,9 +125,6 @@ int main(int argc, char** argv) ...@@ -125,9 +125,6 @@ int main(int argc, char** argv)
return -1; return -1;
} }
/* Make sure the sound is set to looping or else it'll stop if the ring buffer runs out of data. */
ma_sound_set_looping(&sound, MA_TRUE);
/* Link the starting of the device and sound together. */ /* Link the starting of the device and sound together. */
ma_device_start(&device); ma_device_start(&device);
ma_sound_start(&sound); ma_sound_start(&sound);
......
...@@ -56897,6 +56897,16 @@ static ma_result ma_pcm_rb_data_source__on_read(ma_data_source* pDataSource, voi ...@@ -56897,6 +56897,16 @@ static ma_result ma_pcm_rb_data_source__on_read(ma_data_source* pDataSource, voi
totalFramesRead += mappedFrameCount; totalFramesRead += mappedFrameCount;
} }
/*
There is no notion of an "end" in a ring buffer. If we didn't have enough data to fill the requested frame
count we'll need to pad with silence. If we don't do this, totalFramesRead might equal 0 which will result
in the data source layer at a higher level translating this to MA_AT_END which is incorrect for a ring buffer.
*/
if (totalFramesRead < frameCount) {
ma_silence_pcm_frames(ma_offset_pcm_frames_ptr(pFramesOut, totalFramesRead, pRB->format, pRB->channels), (frameCount - totalFramesRead), pRB->format, pRB->channels);
totalFramesRead = frameCount;
}
*pFramesRead = totalFramesRead; *pFramesRead = totalFramesRead;
return MA_SUCCESS; return MA_SUCCESS;
} }
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