diff options
| author | 2024-12-07 23:47:36 -0500 | |
|---|---|---|
| committer | 2024-12-07 23:47:36 -0500 | |
| commit | d81c406f62e996840d86333b81c41d0ae4aff347 (patch) | |
| tree | 9e6baf260ec56d14e8931b61936b0d043cb49847 /src/mixer | |
| parent | d4da3d8a644156b9f24b560eba58a87b912c1fef (diff) | |
| download | camu-d81c406f62e996840d86333b81c41d0ae4aff347.tar.gz camu-d81c406f62e996840d86333b81c41d0ae4aff347.tar.bz2 camu-d81c406f62e996840d86333b81c41d0ae4aff347.zip | |
Synced list reference 1
This marks a point where the list behavior is at least moderately robust
for the skip operation. It includes fixes for multiple deep-rooted
issues found by testing with input simulation.
Signed-off-by: Andrew Opalach <andrew@akon.city>
Diffstat (limited to 'src/mixer')
| -rw-r--r-- | src/mixer/mixer.c | 46 |
1 files changed, 41 insertions, 5 deletions
diff --git a/src/mixer/mixer.c b/src/mixer/mixer.c index c144c69..46df146 100644 --- a/src/mixer/mixer.c +++ b/src/mixer/mixer.c @@ -151,16 +151,16 @@ static void remove_buffer_internal(struct camu_mixer *mixer, struct camu_audio_b #ifdef CAMU_MIXER_THREADED static void run_queue_internal(struct camu_mixer *mixer) { - al_array_reserve(mixer->buffers, mixer->buffers.size + mixer->add_queue.size); struct camu_audio_buffer *buf; - al_array_foreach(mixer->add_queue, i, buf) { - add_buffer_internal(mixer, buf); - } - mixer->add_queue.size = 0; al_array_foreach(mixer->rem_queue, i, buf) { remove_buffer_internal(mixer, buf); } mixer->rem_queue.size = 0; + al_array_reserve(mixer->buffers, mixer->buffers.size + mixer->add_queue.size); + al_array_foreach(mixer->add_queue, i, buf) { + add_buffer_internal(mixer, buf); + } + mixer->add_queue.size = 0; al_atomic_store(u8)(&mixer->queued, 0, AL_ATOMIC_RELAXED); if (al_array_is_empty(mixer->buffers)) { mixer->empty_after = MIXER_TRAILING_SILENCE; @@ -174,6 +174,24 @@ void camu_mixer_add_buffer(struct camu_mixer *mixer, struct camu_audio_buffer *b { #ifdef CAMU_MIXER_THREADED aki_mutex_lock(&mixer->mutex); + struct camu_audio_buffer *rbuf; + al_array_foreach(mixer->add_queue, i, rbuf) { + if (rbuf == buf) { + aki_mutex_unlock(&mixer->mutex); + return; + } + } + al_array_foreach_rev(mixer->rem_queue, i, rbuf) { + if (rbuf == buf) { + al_array_remove_at(mixer->rem_queue, i); + bool queue_empty = mixer->add_queue.size + mixer->rem_queue.size == 0; + if (queue_empty) { + al_atomic_store(u8)(&mixer->queued, 0, AL_ATOMIC_RELAXED); + } + aki_mutex_unlock(&mixer->mutex); + return; + } + } al_array_push(mixer->add_queue, buf); al_atomic_store(u8)(&mixer->queued, 1, AL_ATOMIC_RELAXED); aki_mutex_unlock(&mixer->mutex); @@ -187,6 +205,24 @@ void camu_mixer_remove_buffer(struct camu_mixer *mixer, struct camu_audio_buffer { #ifdef CAMU_MIXER_THREADED aki_mutex_lock(&mixer->mutex); + struct camu_audio_buffer *rbuf; + al_array_foreach(mixer->rem_queue, i, rbuf) { + if (rbuf == buf) { + aki_mutex_unlock(&mixer->mutex); + return; + } + } + al_array_foreach_rev(mixer->add_queue, i, rbuf) { + if (rbuf == buf) { + al_array_remove_at(mixer->add_queue, i); + bool queue_empty = mixer->add_queue.size + mixer->rem_queue.size == 0; + if (queue_empty) { + al_atomic_store(u8)(&mixer->queued, 0, AL_ATOMIC_RELAXED); + } + aki_mutex_unlock(&mixer->mutex); + return; + } + } al_array_push(mixer->rem_queue, buf); al_atomic_store(u8)(&mixer->queued, 1, AL_ATOMIC_RELAXED); if (mixer->paused) { |