summaryrefslogtreecommitdiff
path: root/src/mixer
diff options
context:
space:
mode:
authorAndrew Opalach <andrew@akon.city> 2024-04-09 11:24:01 -0400
committerAndrew Opalach <andrew@akon.city> 2024-04-09 11:24:01 -0400
commit02f3d3565602146bbbfce85b2719246f24036cb9 (patch)
treec6588ffe297b777e36260effa4fa42b958ca6ba3 /src/mixer
parentbbf3314165182e402ff25acccddc004a87f81ef0 (diff)
downloadcamu-02f3d3565602146bbbfce85b2719246f24036cb9.tar.gz
camu-02f3d3565602146bbbfce85b2719246f24036cb9.tar.bz2
camu-02f3d3565602146bbbfce85b2719246f24036cb9.zip
Massive restructure and many changes
- The server-side list concept is still a wip Signed-off-by: Andrew Opalach <andrew@akon.city>
Diffstat (limited to 'src/mixer')
-rw-r--r--src/mixer/audio.h25
-rw-r--r--src/mixer/audio_miniaudio.c16
-rw-r--r--src/mixer/meson.build1
-rw-r--r--src/mixer/mixer.c69
-rw-r--r--src/mixer/mixer.h6
5 files changed, 62 insertions, 55 deletions
diff --git a/src/mixer/audio.h b/src/mixer/audio.h
index e460536..0e8e105 100644
--- a/src/mixer/audio.h
+++ b/src/mixer/audio.h
@@ -2,30 +2,12 @@
#include <al/str.h>
-#include "../codec/libav/resampler.h"
-
-enum {
- // Not initialized.
- CAMU_AUDIO_STATE_NULL = 0,
- // Context created, waiting for stream.
- CAMU_AUDIO_STATE_INITIALIZED,
- // Stream created, and running.
- CAMU_AUDIO_STATE_STARTED,
- // Error occured, no data will be requested.
- CAMU_AUDIO_STATE_ERROR,
- // Not built.
- CAMU_AUDIO_STATE_UNSUPPORTED
-};
+#include "../codec/ffmpeg/resampler.h"
struct camu_audio {
- u8 state;
-
- s32 (*data_callback)(void *, u8 *, s32);
- void *userdata;
-
bool (*init)(struct camu_audio *, str *);
- void (*pick_format)(struct camu_audio *, struct camu_lav_resample_fmt *);
+ void (*pick_format)(struct camu_audio *, struct camu_ff_resample_fmt *);
bool (*configure_stream)(struct camu_audio *, void *);
u64 (*get_latency)(struct camu_audio *);
@@ -34,4 +16,7 @@ struct camu_audio {
void (*stop)(struct camu_audio *);
void (*free)(struct camu_audio **);
+
+ s32 (*data_callback)(void *, u8 *, s32);
+ void *userdata;
};
diff --git a/src/mixer/audio_miniaudio.c b/src/mixer/audio_miniaudio.c
index dde742a..a7a1889 100644
--- a/src/mixer/audio_miniaudio.c
+++ b/src/mixer/audio_miniaudio.c
@@ -7,7 +7,6 @@ static ma_backend backends[] = {
ma_backend_pulseaudio,
#else
ma_backend_wasapi
-// ma_backend_dsound
#endif
};
@@ -42,7 +41,7 @@ static void miniaudio_log_callback(void *userdata, u32 level, const char *messag
if (level < MA_LOG_LEVEL_WARNING) {
al_log_debug("audio_miniaudio", message);
} else {
- al_log_warn("audio_miniaudio", message);
+ al_log_debug("audio_miniaudio", message);
}
}
@@ -103,7 +102,7 @@ static enum AVSampleFormat av_sample_fmt_from_miniaudio(s32 fmt)
}
}
-static void audio_miniaudio_pick_format(struct camu_audio *audio, struct camu_lav_resample_fmt *fmt)
+static void audio_miniaudio_pick_format(struct camu_audio *audio, struct camu_ff_resample_fmt *fmt)
{
struct camu_audio_miniaudio *ma = (struct camu_audio_miniaudio *)audio;
fmt->req_format = av_sample_fmt_from_miniaudio(ma->device.playback.internalFormat);
@@ -119,12 +118,12 @@ static void data_callback(ma_device *device, void *output, const void *input, u3
}
#define DEFAULT_PERIODS 3
-#define DEFAULT_PERIOD_SIZE_IN_MILLISECONDS 100
+#define DEFAULT_PERIOD_SIZE_IN_MILLISECONDS 75
static bool audio_miniaudio_configure_stream(struct camu_audio *audio, void *opaque)
{
struct camu_audio_miniaudio *ma = (struct camu_audio_miniaudio *)audio;
- struct camu_lav_resample_fmt *fmt = (struct camu_lav_resample_fmt *)opaque;
+ struct camu_ff_resample_fmt *fmt = (struct camu_ff_resample_fmt *)opaque;
(void)fmt;
ma->config = ma_device_config_init(ma_device_type_playback);
//ma->config.playback.pDeviceID = &ma->selected_device->id;
@@ -190,16 +189,15 @@ static void audio_miniaudio_free(struct camu_audio **audio)
struct camu_audio_miniaudio audio_plugin_miniaudio = {
.a = {
- .state = CAMU_AUDIO_STATE_NULL,
- .data_callback = NULL,
- .userdata = NULL,
.init = audio_miniaudio_init,
.pick_format = audio_miniaudio_pick_format,
.configure_stream = audio_miniaudio_configure_stream,
.get_latency = audio_miniaudio_get_latency,
.start = audio_miniaudio_start,
.stop = audio_miniaudio_stop,
- .free = audio_miniaudio_free
+ .free = audio_miniaudio_free,
+ .data_callback = NULL,
+ .userdata = NULL
},
.log = { },
.context_config = { 0 },
diff --git a/src/mixer/meson.build b/src/mixer/meson.build
index ab14b6f..71c003b 100644
--- a/src/mixer/meson.build
+++ b/src/mixer/meson.build
@@ -21,7 +21,6 @@ if not is_windows
miniaudio_args += ['-DMA_ENABLE_PULSEAUDIO', '-DMA_NO_RUNTIME_LINKING']
else
miniaudio_args += ['-DMA_ENABLE_WASAPI']
- #miniaudio_args += ['-DMA_ENABLE_DSOUND']
endif
mixer = declare_dependency(sources: mixer_src, dependencies: mixer_deps,
diff --git a/src/mixer/mixer.c b/src/mixer/mixer.c
index a4c0ef5..31a67b0 100644
--- a/src/mixer/mixer.c
+++ b/src/mixer/mixer.c
@@ -6,31 +6,35 @@
static s32 data_callback(void *userdata, u8 *data, s32 frame_count)
{
struct camu_mixer *mixer = (struct camu_mixer *)userdata;
+ size_t req = camu_ff_resample_fmt_samples_to_bytes(&mixer->fmt, (size_t)frame_count);
+ if (UNLIKELY(mixer->paused)) {
+ al_memset(data, 0, req);
+ } else {
#ifdef CAMU_MIXER_THREADED
- if (al_atomic_bool_load(&mixer->queued, AL_ATOMIC_RELAXED)) {
- camu_mixer_run_queue(mixer);
- }
+ if (al_atomic_bool_load(&mixer->queued, AL_ATOMIC_RELAXED)) {
+ camu_mixer_run_queue(mixer);
+ }
#endif
- size_t req = camu_lav_resample_fmt_samples_to_bytes(&mixer->fmt, (size_t)frame_count);
- do {
- if (mixer->buffers.size == 0) {
- al_memset(data, 0, req);
- } else {
- struct camu_audio_buffer *buf = al_array_last(mixer->buffers);
- size_t signal;
- if ((signal = camu_audio_buffer_read(buf, data, req)) < req) {
+ do {
+ if (mixer->buffers.size == 0) {
+ al_memset(data, 0, req);
+ } else {
+ struct camu_audio_buffer *buf = al_array_last(mixer->buffers);
+ size_t signal;
+ if ((signal = camu_audio_buffer_read(buf, data, req)) < req) {
#ifdef CAMU_MIXER_THREADED
- if (al_atomic_bool_load(&mixer->queued, AL_ATOMIC_RELAXED)) {
- camu_mixer_run_queue(mixer);
- }
+ if (al_atomic_bool_load(&mixer->queued, AL_ATOMIC_RELAXED)) {
+ camu_mixer_run_queue(mixer);
+ }
#endif
- data += signal;
- req = req - signal;
- continue;
+ data += signal;
+ req = req - signal;
+ continue;
+ }
}
- }
- break;
- } while (1);
+ break;
+ } while (1);
+ }
return frame_count;
}
@@ -55,7 +59,7 @@ bool camu_mixer_init(struct camu_mixer *mixer, struct camu_audio *audio)
return true;
}
-void camu_mixer_pick_format(struct camu_mixer *mixer, struct camu_lav_resample_fmt *fmt)
+void camu_mixer_pick_format(struct camu_mixer *mixer, struct camu_ff_resample_fmt *fmt)
{
mixer->audio->pick_format(mixer->audio, fmt);
av_channel_layout_default(&fmt->req_channel_layout, fmt->req_channel_count);
@@ -63,7 +67,6 @@ void camu_mixer_pick_format(struct camu_mixer *mixer, struct camu_lav_resample_f
f64 camu_mixer_get_latency(struct camu_mixer *mixer)
{
- if (!mixer->audio) return 0;
return mixer->audio->get_latency(mixer->audio) / 1000000.0;
}
@@ -144,18 +147,40 @@ void camu_mixer_run_queue(struct camu_mixer *mixer)
void camu_mixer_pause(struct camu_mixer *mixer)
{
+#ifdef CAMU_MIXER_THREADED
+ aki_mutex_lock(&mixer->mutex);
+#endif
if (!mixer->paused) {
mixer->audio->stop(mixer->audio);
mixer->paused = true;
}
+#ifdef CAMU_MIXER_THREADED
+ aki_mutex_unlock(&mixer->mutex);
+#endif
}
void camu_mixer_resume(struct camu_mixer *mixer)
{
+#ifdef CAMU_MIXER_THREADED
+ aki_mutex_lock(&mixer->mutex);
+#endif
if (mixer->paused) {
+//#ifdef CAMU_MIXER_THREADED
+// bool queued = al_atomic_bool_load(&mixer->queued, AL_ATOMIC_RELAXED);
+// // Disable queue when starting audio in case start() directly calls data_callback().
+// // Locking here is necessary to 100% know the state of the audio backend at
+// // any time. This allows us to act on the value of paused, like in remove_buffer().
+// if (queued) al_atomic_bool_store(&mixer->queued, false, AL_ATOMIC_RELAXED);
+//#endif
mixer->audio->start(mixer->audio);
+//#ifdef CAMU_MIXER_THREADED
+// if (queued) al_atomic_bool_store(&mixer->queued, true, AL_ATOMIC_RELAXED);
+//#endif
mixer->paused = false;
}
+#ifdef CAMU_MIXER_THREADED
+ aki_mutex_unlock(&mixer->mutex);
+#endif
}
void camu_mixer_close(struct camu_mixer *mixer)
diff --git a/src/mixer/mixer.h b/src/mixer/mixer.h
index 464431e..113db62 100644
--- a/src/mixer/mixer.h
+++ b/src/mixer/mixer.h
@@ -9,12 +9,12 @@
#include <aki/thread.h>
#endif
-#include "../codec/libav/resampler.h"
+#include "../codec/ffmpeg/resampler.h"
struct camu_mixer {
struct camu_audio *audio;
bool paused;
- struct camu_lav_resample_fmt fmt;
+ struct camu_ff_resample_fmt fmt;
array(struct camu_audio_buffer *) buffers;
#ifdef CAMU_MIXER_THREADED
array(struct camu_audio_buffer *) add_queue;
@@ -25,7 +25,7 @@ struct camu_mixer {
};
bool camu_mixer_init(struct camu_mixer *mixer, struct camu_audio *audio);
-void camu_mixer_pick_format(struct camu_mixer *mixer, struct camu_lav_resample_fmt *fmt);
+void camu_mixer_pick_format(struct camu_mixer *mixer, struct camu_ff_resample_fmt *fmt);
f64 camu_mixer_get_latency(struct camu_mixer *mixer);
void camu_mixer_add_buffer(struct camu_mixer *mixer, struct camu_audio_buffer *buf);
void camu_mixer_remove_buffer(struct camu_mixer *mixer, struct camu_audio_buffer *buf);