summaryrefslogtreecommitdiff
path: root/src/mixer
diff options
context:
space:
mode:
authorAndrew Opalach <andrew@akon.city> 2024-12-07 23:47:36 -0500
committerAndrew Opalach <andrew@akon.city> 2024-12-07 23:47:36 -0500
commitd81c406f62e996840d86333b81c41d0ae4aff347 (patch)
tree9e6baf260ec56d14e8931b61936b0d043cb49847 /src/mixer
parentd4da3d8a644156b9f24b560eba58a87b912c1fef (diff)
downloadcamu-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.c46
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) {