diff options
| author | 2025-01-03 16:53:06 -0500 | |
|---|---|---|
| committer | 2025-01-03 16:53:06 -0500 | |
| commit | d86e3f6dade53d5ca3b23a5c72c550b8f0583f91 (patch) | |
| tree | 2452d09fda386a497a82eb120d8f36ac59dc912f /src/mixer | |
| parent | 298debac881c1e7ca5e3a28834f32ff3e74e45f6 (diff) | |
| download | camu-d86e3f6dade53d5ca3b23a5c72c550b8f0583f91.tar.gz camu-d86e3f6dade53d5ca3b23a5c72c550b8f0583f91.tar.bz2 camu-d86e3f6dade53d5ca3b23a5c72c550b8f0583f91.zip | |
Audio buffer, mixer and sink improvements
Signed-off-by: Andrew Opalach <andrew@akon.city>
Diffstat (limited to 'src/mixer')
| -rw-r--r-- | src/mixer/mixer.c | 18 | ||||
| -rw-r--r-- | src/mixer/mixer.h | 8 |
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 }; |