From d81c406f62e996840d86333b81c41d0ae4aff347 Mon Sep 17 00:00:00 2001 From: Andrew Opalach Date: Sat, 7 Dec 2024 23:47:36 -0500 Subject: 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 --- src/mixer/mixer.c | 46 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 5 deletions(-) (limited to 'src/mixer') 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) { -- cgit v1.2.3-101-g0448