Commit 7bd319d9 authored by David Reid's avatar David Reid

Fix a bug relating to changing the range of a data source.

The issue here is that the code is trying to maintain the absolute
position of the loop point. The problem with this is that the absolute
position of the loop points could fall outside the new range which
would then result in no audio being read.

This becomes an issue because it would effect data sources even when
the loop point was never actually explicitly set. From these users
perspective, changing the range completely breaks their audio.

The new system simply resets the loop points. This works for users who
are using the default loop points (the majority of cases). For those
who are explicitly setting a loop point, they simply need to reset
their loop points after changing the range. This is not really an
issue, because loop points are relative to the range, which means a
change in the range would most likely warrant a change in the loop
point anyway.
parent 49a95a32
......@@ -5,6 +5,7 @@ v0.11.12 - TBD
* Fix a crash with some backends when rerouting the playback side of a duplex device.
* Fix some bugs with initialization of POSIX threads.
* Fix a bug where sounds are not resampled when `MA_SOUND_NO_PITCH` is used.
* Fix a bug where changing the range of a data source would result in no audio being read.
* Fix some Wimplicit-fallthrough warnings.
* Optimizations to the high level API.
* Remove the old runtime linking system for pthread. The `MA_USE_RUNTIME_LINKING_FOR_PTHREAD` option is no longer used.
......
......@@ -56586,9 +56586,9 @@ MA_API ma_result ma_data_source_set_range_in_pcm_frames(ma_data_source* pDataSou
{
ma_data_source_base* pDataSourceBase = (ma_data_source_base*)pDataSource;
ma_result result;
ma_uint64 cursor;
ma_uint64 loopBegAbsolute;
ma_uint64 loopEndAbsolute;
ma_uint64 relativeCursor;
ma_uint64 absoluteCursor;
ma_bool32 doSeekAdjustment = MA_FALSE;
if (pDataSource == NULL) {
return MA_INVALID_ARGS;
......@@ -56599,51 +56599,51 @@ MA_API ma_result ma_data_source_set_range_in_pcm_frames(ma_data_source* pDataSou
}
/*
The loop points need to be updated. We'll be storing the loop points relative to the range. We'll update
these so that they maintain their absolute positioning. The loop points will then be clamped to the range.
We may need to adjust the position of the cursor to ensure it's clamped to the range. Grab it now
so we can calculate it's absolute position before we change the range.
*/
loopBegAbsolute = pDataSourceBase->loopBegInFrames + pDataSourceBase->rangeBegInFrames;
loopEndAbsolute = pDataSourceBase->loopEndInFrames + ((pDataSourceBase->loopEndInFrames != ~((ma_uint64)0)) ? pDataSourceBase->rangeBegInFrames : 0);
pDataSourceBase->rangeBegInFrames = rangeBegInFrames;
pDataSourceBase->rangeEndInFrames = rangeEndInFrames;
/* Make the loop points relative again, and make sure they're clamped to within the range. */
if (loopBegAbsolute > pDataSourceBase->rangeBegInFrames) {
pDataSourceBase->loopBegInFrames = loopBegAbsolute - pDataSourceBase->rangeBegInFrames;
result = ma_data_source_get_cursor_in_pcm_frames(pDataSource, &relativeCursor);
if (result == MA_SUCCESS) {
doSeekAdjustment = MA_TRUE;
absoluteCursor = relativeCursor + pDataSourceBase->rangeBegInFrames;
} else {
pDataSourceBase->loopBegInFrames = 0;
}
if (pDataSourceBase->loopBegInFrames > pDataSourceBase->rangeEndInFrames) {
pDataSourceBase->loopBegInFrames = pDataSourceBase->rangeEndInFrames;
/*
We couldn't get the position of the cursor. It probably means the data source has no notion
of a cursor. We'll just leave it at position 0. Don't treat this as an error.
*/
doSeekAdjustment = MA_FALSE;
relativeCursor = 0;
absoluteCursor = 0;
}
/* Only need to update the loop end point if it's not -1. */
if (loopEndAbsolute != ~((ma_uint64)0)) {
if (loopEndAbsolute > pDataSourceBase->rangeBegInFrames) {
pDataSourceBase->loopEndInFrames = loopEndAbsolute - pDataSourceBase->rangeBegInFrames;
} else {
pDataSourceBase->loopEndInFrames = 0;
}
pDataSourceBase->rangeBegInFrames = rangeBegInFrames;
pDataSourceBase->rangeEndInFrames = rangeEndInFrames;
if (pDataSourceBase->loopEndInFrames > pDataSourceBase->rangeEndInFrames && pDataSourceBase->loopEndInFrames) {
pDataSourceBase->loopEndInFrames = pDataSourceBase->rangeEndInFrames;
}
}
/*
The commented out logic below was intended to maintain loop points in response to a change in the
range. However, this is not useful because it results in the sound breaking when you move the range
outside of the old loop points. I'm simplifying this by simply resetting the loop points. The
caller is expected to update their loop points if they change the range.
In practice this should be mostly a non-issue because the majority of the time the range will be
set once right after initialization.
*/
pDataSourceBase->loopBegInFrames = 0;
pDataSourceBase->loopEndInFrames = ~((ma_uint64)0);
/* If the new range is past the current cursor position we need to seek to it. */
result = ma_data_source_get_cursor_in_pcm_frames(pDataSource, &cursor);
if (result == MA_SUCCESS) {
/* Seek to within range. Note that our seek positions here are relative to the new range. */
if (cursor < rangeBegInFrames) {
/*
Seek to within range. Note that our seek positions here are relative to the new range. We don't want
do do this if we failed to retrieve the cursor earlier on because it probably means the data source
has no notion of a cursor. In practice the seek would probably fail (which we silently ignore), but
I'm just not even going to attempt it.
*/
if (doSeekAdjustment) {
if (absoluteCursor < rangeBegInFrames) {
ma_data_source_seek_to_pcm_frame(pDataSource, 0);
} else if (cursor > rangeEndInFrames) {
} else if (absoluteCursor > rangeEndInFrames) {
ma_data_source_seek_to_pcm_frame(pDataSource, rangeEndInFrames - rangeBegInFrames);
}
} else {
/* We failed to get the cursor position. Probably means the data source has no notion of a cursor such a noise data source. Just pretend the seeking worked. */
}
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