summaryrefslogtreecommitdiff
path: root/src/mixer
diff options
context:
space:
mode:
Diffstat (limited to 'src/mixer')
-rw-r--r--src/mixer/mixer.c18
-rw-r--r--src/mixer/mixer.h8
2 files changed, 21 insertions, 5 deletions
diff --git a/src/mixer/mixer.c b/src/mixer/mixer.c
index 5a21b19..1360934 100644
--- a/src/mixer/mixer.c
+++ b/src/mixer/mixer.c
@@ -13,10 +13,12 @@ static s32 data_callback(void *userdata, u8 *data, s32 frame_count, bool *silenc
{
struct camu_mixer *mixer = (struct camu_mixer *)userdata;
size_t req = camu_audio_format_samples_to_bytes(&mixer->fmt.req, (size_t)frame_count);
+#ifdef CAMU_MIXER_THREADED_START_STOP
if (UNLIKELY(mixer->paused)) {
al_memset(data, 0, req);
*silence = MIXER_WANT_INITIAL_SILENCE;
} else {
+#endif
#ifdef CAMU_MIXER_THREADED
if (al_atomic_load(u8)(&mixer->queued, AL_ATOMIC_RELAXED)) {
camu_mixer_run_queue(mixer);
@@ -58,7 +60,9 @@ static s32 data_callback(void *userdata, u8 *data, s32 frame_count, bool *silenc
}
break;
}
+#ifdef CAMU_MIXER_THREADED_START_STOP
}
+#endif
return frame_count;
}
@@ -260,7 +264,7 @@ void camu_mixer_clear(struct camu_mixer *mixer)
void camu_mixer_pause(struct camu_mixer *mixer)
{
-#ifdef CAMU_MIXER_THREADED
+#ifdef CAMU_MIXER_THREADED_START_STOP
nn_mutex_lock(&mixer->mutex);
#endif
if (!mixer->paused) {
@@ -268,25 +272,29 @@ void camu_mixer_pause(struct camu_mixer *mixer)
mixer->paused = true;
}
#ifdef CAMU_MIXER_THREADED
+ // This assumes stop() blocks until the output actually stops.
+ // That may not be the behavior we want to require.
run_queue_internal(mixer);
+#endif
+#ifdef CAMU_MIXER_THREADED_START_STOP
nn_mutex_unlock(&mixer->mutex);
#endif
}
void camu_mixer_resume(struct camu_mixer *mixer)
{
-#ifdef CAMU_MIXER_THREADED
+#ifdef CAMU_MIXER_THREADED_START_STOP
nn_mutex_lock(&mixer->mutex);
#endif
if (mixer->paused) {
// start() can internally call data_callback once before returning.
- // In that call mixer->paused will still be true. So, we have a special case to
- // immediately return silence and avoid any possible locking.
+ // In that call mixer->paused will still be true. So, if MIXER_THREADED_START_STOP
+ // is defined, we have a special case to immediately return silence to avoid a deadlock.
// Outputs can treat that silence as part of the stream with MIXER_WANT_INITIAL_SILENCE.
mixer->audio->start(mixer->audio);
mixer->paused = false;
}
-#ifdef CAMU_MIXER_THREADED
+#ifdef CAMU_MIXER_THREADED_START_STOP
nn_mutex_unlock(&mixer->mutex);
#endif
}
diff --git a/src/mixer/mixer.h b/src/mixer/mixer.h
index 16ec924..802d1b5 100644
--- a/src/mixer/mixer.h
+++ b/src/mixer/mixer.h
@@ -9,6 +9,14 @@
#include "../codec/codec.h"
+#ifdef CAMU_MIXER_THREADED
+// Do we need to lock in order to synchronize the mixers paused state.
+// Disabling this is a very specific optimization to allow the audio device to
+// buffer data during start(). It requires pause(), resume(), and remove_buffer()
+// to all come from the same thread.
+//#define CAMU_MIXER_THREADED_START_STOP
+#endif
+
enum {
CAMU_MIXER_EMPTY = 0
};