summaryrefslogtreecommitdiff
path: root/src/mixer
diff options
context:
space:
mode:
Diffstat (limited to 'src/mixer')
-rw-r--r--src/mixer/audio_miniaudio.c14
-rw-r--r--src/mixer/mixer.c24
-rw-r--r--src/mixer/mixer.h4
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