diff options
Diffstat (limited to 'src/mixer')
| -rw-r--r-- | src/mixer/audio_miniaudio.c | 14 | ||||
| -rw-r--r-- | src/mixer/mixer.c | 24 | ||||
| -rw-r--r-- | src/mixer/mixer.h | 4 |
3 files changed, 27 insertions, 15 deletions
diff --git a/src/mixer/audio_miniaudio.c b/src/mixer/audio_miniaudio.c index 13f4b8f..30a5b6b 100644 --- a/src/mixer/audio_miniaudio.c +++ b/src/mixer/audio_miniaudio.c @@ -91,10 +91,10 @@ static bool audio_miniaudio_init(struct camu_audio *audio, str *name) return false; } ma->selected_device = NULL; + /* if (ma_context_get_devices(&ma->context, &ma->infos, &ma->info_count, NULL, NULL) != MA_SUCCESS) { return false; } - /* for (u32 i = 0; i < ma->info_count; i++) { ma_device_info *info = &ma->infos[i]; if (strcmp(info->id.alsa, "front:CARD=D10,DEV=0") == 0) { @@ -154,8 +154,15 @@ static void data_callback(ma_device *device, void *output, const void *input, u3 ma->a.data_callback(ma->a.userdata, output, frame_count, &silence); } +//#define MINIAUDIO_LOW_LATENCY + +#ifdef MINIAUDIO_LOW_LATENCY +#define DEFAULT_PERIODS 2 +#define DEFAULT_PERIOD_SIZE_IN_MILLISECONDS 8 +#else #define DEFAULT_PERIODS 3 #define DEFAULT_PERIOD_SIZE_IN_MILLISECONDS 48 +#endif static bool audio_miniaudio_configure_stream(struct camu_audio *audio, void *opaque) { @@ -166,9 +173,14 @@ static bool audio_miniaudio_configure_stream(struct camu_audio *audio, void *opa if (ma->selected_device) { ma->config.playback.pDeviceID = &ma->selected_device->id; } +#ifdef MINIAUDIO_LOW_LATENCY + ma->config.performanceProfile = ma_performance_profile_low_latency; +#else ma->config.performanceProfile = ma_performance_profile_conservative; +#endif ma->config.periods = DEFAULT_PERIODS; ma->config.periodSizeInMilliseconds = DEFAULT_PERIOD_SIZE_IN_MILLISECONDS; + ma->config.periodSizeInFrames = 0; // Derive from periodSizeInMilliseconds. ma->config.playback.format = ma_format_unknown; ma->config.playback.channels = 2; ma->config.sampleRate = 0; diff --git a/src/mixer/mixer.c b/src/mixer/mixer.c index aad0877..079b582 100644 --- a/src/mixer/mixer.c +++ b/src/mixer/mixer.c @@ -3,7 +3,7 @@ #include "mixer.h" #include "audio.h" -// Should an initial read inside of start() be marked as silence or not. +// Should an initial read from within start() be marked as silence or not. #define MIXER_WANT_INITIAL_SILENCE 1 // Number of silent frames to append before signaling MIXER_EMPTY. @@ -14,7 +14,7 @@ static s32 data_callback(void *userdata, u8 *data, s32 frame_count, bool *silenc struct camu_mixer *mixer = (struct camu_mixer *)userdata; ptrdiff_t req = (ptrdiff_t)camu_audio_format_samples_to_bytes(&mixer->fmt.req, (size_t)frame_count); #ifdef CAMU_MIXER_THREADED_START_STOP - if (UNLIKELY(mixer->paused)) { + if (UNLIKELY(al_atomic_load(bool)(&mixer->paused, AL_ATOMIC_SEQ_CST))) { al_memset(data, 0, req); *silence = MIXER_WANT_INITIAL_SILENCE; } else { @@ -73,7 +73,7 @@ bool camu_mixer_init(struct camu_mixer *mixer, struct camu_audio *audio) mixer->audio->userdata = mixer; mixer->audio->init(mixer->audio, &al_str_c("cmv")); mixer->volume = 1.f; - mixer->paused = true; + al_atomic_store(bool)(&mixer->paused, true, AL_ATOMIC_RELAXED); mixer->empty_after = 0; al_array_init(mixer->buffers); #ifdef CAMU_MIXER_THREADED @@ -233,7 +233,7 @@ void camu_mixer_remove_buffer(struct camu_mixer *mixer, struct camu_audio_buffer } al_array_push(mixer->rem_queue, buf); al_atomic_store(u8)(&mixer->queued, 1, AL_ATOMIC_RELAXED); - if (mixer->paused) { + if (al_atomic_load(bool)(&mixer->paused, AL_ATOMIC_RELAXED)) { run_queue_internal(mixer); } nn_mutex_unlock(&mixer->mutex); @@ -267,9 +267,9 @@ void camu_mixer_pause(struct camu_mixer *mixer) #ifdef CAMU_MIXER_THREADED_START_STOP nn_mutex_lock(&mixer->mutex); #endif - if (!mixer->paused) { + if (!al_atomic_load(bool)(&mixer->paused, AL_ATOMIC_ACQUIRE)) { mixer->audio->stop(mixer->audio); - mixer->paused = true; + al_atomic_store(bool)(&mixer->paused, true, AL_ATOMIC_RELEASE); } #ifdef CAMU_MIXER_THREADED // This assumes stop() blocks until the output actually stops. @@ -286,13 +286,13 @@ void camu_mixer_resume(struct camu_mixer *mixer) #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, 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. + if (al_atomic_load(bool)(&mixer->paused, AL_ATOMIC_ACQUIRE)) { + // audio->start() can internally call data_callback() or possibly start a thread which + // can call data_callback() before we have a chance to set paused to false. + // MIXER_THREADED_START_STOP: If paused is true in data_callback(), immediately return silence. + // This will avoid a deadlock in the first case described above. mixer->audio->start(mixer->audio); - mixer->paused = false; + al_atomic_store(bool)(&mixer->paused, false, AL_ATOMIC_RELEASE); } #ifdef CAMU_MIXER_THREADED_START_STOP nn_mutex_unlock(&mixer->mutex); diff --git a/src/mixer/mixer.h b/src/mixer/mixer.h index 802d1b5..8c14ea1 100644 --- a/src/mixer/mixer.h +++ b/src/mixer/mixer.h @@ -2,8 +2,8 @@ #include <al/types.h> #include <al/array.h> -#ifdef CAMU_MIXER_THREADED #include <al/atomic.h> +#ifdef CAMU_MIXER_THREADED #include <nnwt/thread.h> #endif @@ -25,7 +25,7 @@ struct camu_mixer { struct camu_audio *audio; f32 volume; struct camu_resampler_format fmt; - bool paused; + atomic(bool) paused; u8 empty_after; array(struct camu_audio_buffer *) buffers; #ifdef CAMU_MIXER_THREADED |