Commit 9c338c58 authored by David Reid's avatar David Reid

Fix a crash when seeking with ma_sound_seek_to_pcm_frame().

parent 09f54c37
v0.11.9 - TBD v0.11.9 - TBD
==================== ====================
* Fix some bugs where looping doesn't work with the resource manager. * Fix some bugs where looping doesn't work with the resource manager.
* Fix a crash when seeking a sound.
* Add a new flag called MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_UNKNOWN_LENGTH for use with resource managed data sources. This flag is used as a hint to the resource manager that the length of the data source is unknown and calling ma_data_source_get_length_in_pcm_frames() should be avoided. * Add a new flag called MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_UNKNOWN_LENGTH for use with resource managed data sources. This flag is used as a hint to the resource manager that the length of the data source is unknown and calling ma_data_source_get_length_in_pcm_frames() should be avoided.
v0.11.8 - 2022-02-12 v0.11.8 - 2022-02-12
==================== ====================
* PulseAudio: Work around bugs in PipeWire: * PulseAudio: Work around bugs in PipeWire:
......
...@@ -10749,7 +10749,7 @@ struct ma_sound ...@@ -10749,7 +10749,7 @@ struct ma_sound
{ {
ma_engine_node engineNode; /* Must be the first member for compatibility with the ma_node API. */ ma_engine_node engineNode; /* Must be the first member for compatibility with the ma_node API. */
ma_data_source* pDataSource; ma_data_source* pDataSource;
ma_uint64 seekTarget; /* The PCM frame index to seek to in the mixing thread. Set to (~(ma_uint64)0) to not perform any seeking. */ MA_ATOMIC(8, ma_uint64) seekTarget; /* The PCM frame index to seek to in the mixing thread. Set to (~(ma_uint64)0) to not perform any seeking. */
MA_ATOMIC(4, ma_bool32) atEnd; MA_ATOMIC(4, ma_bool32) atEnd;
ma_bool8 ownsDataSource; ma_bool8 ownsDataSource;
...@@ -71002,6 +71002,7 @@ static void ma_engine_node_process_pcm_frames__sound(ma_node* pNode, const float ...@@ -71002,6 +71002,7 @@ static void ma_engine_node_process_pcm_frames__sound(ma_node* pNode, const float
ma_uint32 dataSourceChannels; ma_uint32 dataSourceChannels;
ma_uint8 temp[MA_DATA_CONVERTER_STACK_BUFFER_SIZE]; ma_uint8 temp[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
ma_uint32 tempCapInFrames; ma_uint32 tempCapInFrames;
ma_uint64 seekTarget;
/* This is a data source node which means no input buses. */ /* This is a data source node which means no input buses. */
(void)ppFramesIn; (void)ppFramesIn;
...@@ -71015,13 +71016,14 @@ static void ma_engine_node_process_pcm_frames__sound(ma_node* pNode, const float ...@@ -71015,13 +71016,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 we're seeking, do so now before reading. */
if (pSound->seekTarget != MA_SEEK_TARGET_NONE) { seekTarget = c89atomic_load_64(&pSound->seekTarget);
ma_data_source_seek_to_pcm_frame(pSound->pDataSource, 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. */ /* 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);
} }
/* /*
...@@ -73176,24 +73178,8 @@ MA_API ma_result ma_sound_seek_to_pcm_frame(ma_sound* pSound, ma_uint64 frameInd ...@@ -73176,24 +73178,8 @@ MA_API ma_result ma_sound_seek_to_pcm_frame(ma_sound* pSound, ma_uint64 frameInd
return MA_INVALID_OPERATION; return MA_INVALID_OPERATION;
} }
/* /* 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. */
Resource manager data sources are thread safe which means we can just seek immediately. However, we cannot guarantee that other data sources are c89atomic_exchange_64(&pSound->seekTarget, frameIndex);
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;
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