summaryrefslogtreecommitdiff
path: root/src/mixer
diff options
context:
space:
mode:
authorAndrew Opalach <andrew@akon.city> 2024-01-20 18:45:29 -0500
committerAndrew Opalach <andrew@akon.city> 2024-01-20 18:45:29 -0500
commit88ea5bdca85fc0954d1dd64309a308199c1af4a8 (patch)
treeef9dc778b9c42ab2fecce8810f777ccc133cebef /src/mixer
parentb79f074a86525ece1394af7bc5870516a8c38ba9 (diff)
downloadcamu-88ea5bdca85fc0954d1dd64309a308199c1af4a8.tar.gz
camu-88ea5bdca85fc0954d1dd64309a308199c1af4a8.tar.bz2
camu-88ea5bdca85fc0954d1dd64309a308199c1af4a8.zip
wip
Signed-off-by: Andrew Opalach <andrew@akon.city>
Diffstat (limited to 'src/mixer')
-rw-r--r--src/mixer/audio_miniaudio.c106
-rw-r--r--src/mixer/meson.build1
-rw-r--r--src/mixer/mixer.c15
3 files changed, 75 insertions, 47 deletions
diff --git a/src/mixer/audio_miniaudio.c b/src/mixer/audio_miniaudio.c
index 3d6f54b..dde742a 100644
--- a/src/mixer/audio_miniaudio.c
+++ b/src/mixer/audio_miniaudio.c
@@ -7,6 +7,7 @@ static ma_backend backends[] = {
ma_backend_pulseaudio,
#else
ma_backend_wasapi
+// ma_backend_dsound
#endif
};
@@ -38,7 +39,11 @@ static ma_allocation_callbacks alloc_callbacks = {
static void miniaudio_log_callback(void *userdata, u32 level, const char *message)
{
(void)userdata;
- if (level <= MA_LOG_LEVEL_WARNING) al_log_debug("audio_miniaudio", message);
+ if (level < MA_LOG_LEVEL_WARNING) {
+ al_log_debug("audio_miniaudio", message);
+ } else {
+ al_log_warn("audio_miniaudio", message);
+ }
}
static bool audio_miniaudio_init(struct camu_audio *audio, str *name)
@@ -48,53 +53,65 @@ static bool audio_miniaudio_init(struct camu_audio *audio, str *name)
ma_log_register_callback(&ma->log, ma_log_callback_init(miniaudio_log_callback, NULL));
ma->context_config = ma_context_config_init();
ma->context_config.pLog = &ma->log;
- ma->context_config.alsa.useVerboseDeviceEnumeration = true;
+ ma->context_config.alsa.useVerboseDeviceEnumeration = MA_TRUE;
char *c_str = al_str_to_c_str(name);
ma->context_config.pulse.pApplicationName = c_str;
- //ma->context_config.pulse.pServerName = "";
- ma->context_config.pulse.tryAutoSpawn = true;;
+ ma->context_config.pulse.tryAutoSpawn = MA_TRUE;
s32 ret = ma_context_init(backends, AL_ARRAY_SIZE(backends), &ma->context_config, &ma->context);
if (ret != MA_SUCCESS) {
al_log_error("audio_miniaudio", "Failed to initialize context (%d).", ret);
return false;
}
- //if (ma_context_get_devices(&ma->context, &ma->infos, &ma->info_count, NULL, NULL) != MA_SUCCESS) {
- // return false;
- //}
- //ma->selected_device = NULL;
- //for (u32 i = 0; i < ma->info_count; i++) {
- // ma_device_info *info = &ma->infos[i];
- // ma_device_info real_info;
- // ma_context_get_device_info(&ma->context, ma_device_type_playback, &info->id, &real_info);
- // for (u32 j = 0; j < real_info.nativeDataFormatCount; j++) {
- // if (strcmp(real_info.id.alsa, "hw:CARD=D10,DEV=0") == 0) {
- // ma->selected_device = info;
- // break;
- // }
- // /*
- // al_printf("%s\n", real_info.id.alsa);
- // al_printf("%i\n", real_info.nativeDataFormats[j].format);
- // al_printf("%i\n", real_info.nativeDataFormats[j].channels);
- // al_printf("%i\n", real_info.nativeDataFormats[j].sampleRate);
- // */
- // }
- // if (ma->selected_device) break;
- // //al_printf("\n");
- //}
- ////al_printf("%i\n", ma->info_count);
+ /*
+ 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];
+ ma_device_info real_info;
+ ma_context_get_device_info(&ma->context, ma_device_type_playback, &info->id, &real_info);
+ for (u32 j = 0; j < real_info.nativeDataFormatCount; j++) {
+ //al_printf("%s\n", real_info.id.alsa);
+ //al_printf("%s\n", real_info.id.pulse);
+ //al_printf("%i\n", real_info.nativeDataFormats[j].format);
+ //al_printf("%i\n", real_info.nativeDataFormats[j].channels);
+ //al_printf("%i\n", real_info.nativeDataFormats[j].sampleRate);
+ //al_printf("\n");
+ }
+ }
+ //al_printf("%i\n", ma->info_count);
+ */
return true;
}
+static enum AVSampleFormat av_sample_fmt_from_miniaudio(s32 fmt)
+{
+ switch (fmt) {
+ case ma_format_u8:
+ return AV_SAMPLE_FMT_U8;
+ case ma_format_s16:
+ return AV_SAMPLE_FMT_S16;
+ case ma_format_s24:
+ case ma_format_s32:
+ return AV_SAMPLE_FMT_S32;
+ case ma_format_f32:
+ return AV_SAMPLE_FMT_FLT;
+ case ma_format_unknown:
+ default:
+ al_assert(false);
+ return AV_SAMPLE_FMT_NONE;
+ }
+}
+
static void audio_miniaudio_pick_format(struct camu_audio *audio, struct camu_lav_resample_fmt *fmt)
{
struct camu_audio_miniaudio *ma = (struct camu_audio_miniaudio *)audio;
- (void)ma;
- fmt->req_channel_count = 2;
- fmt->req_format = AV_SAMPLE_FMT_S32;
- fmt->req_sample_rate = 44100;
+ fmt->req_format = av_sample_fmt_from_miniaudio(ma->device.playback.internalFormat);
+ fmt->req_channel_count = ma->device.playback.internalChannels;
+ fmt->req_sample_rate = ma->device.playback.internalSampleRate;
}
-static void data_callback(ma_device *device, void *output, const void *input, ma_uint32 frame_count)
+static void data_callback(ma_device *device, void *output, const void *input, u32 frame_count)
{
struct camu_audio_miniaudio *ma = (struct camu_audio_miniaudio *)device->pUserData;
(void)input;
@@ -111,22 +128,29 @@ static bool audio_miniaudio_configure_stream(struct camu_audio *audio, void *opa
(void)fmt;
ma->config = ma_device_config_init(ma_device_type_playback);
//ma->config.playback.pDeviceID = &ma->selected_device->id;
+ //ma->config.performanceProfile = ma_performance_profile_low_latency;
ma->config.performanceProfile = ma_performance_profile_conservative;
ma->config.periods = DEFAULT_PERIODS;
ma->config.periodSizeInMilliseconds = DEFAULT_PERIOD_SIZE_IN_MILLISECONDS;
- ma->config.playback.channels = 2;
- ma->config.playback.format = ma_format_s32;
- ma->config.sampleRate = 44100;
+ ma->config.playback.format = ma_format_unknown;
+ ma->config.playback.channels = 0;
+ ma->config.sampleRate = 0;
ma->config.dataCallback = data_callback;
ma->config.pUserData = ma;
- ma->config.noPreSilencedOutputBuffer = true;
+ ma->config.noPreSilencedOutputBuffer = MA_TRUE;
+ ma->config.noFixedSizedCallback = MA_TRUE;
+ ma->config.noClip = MA_TRUE;
+ ma->config.wasapi.noAutoConvertSRC = MA_FALSE;
+ ma->config.wasapi.noDefaultQualitySRC = MA_FALSE;
s32 ret = ma_device_init(&ma->context, &ma->config, &ma->device);
if (ret != MA_SUCCESS) {
al_log_error("audio_miniaudio", "Failed to initialize device (%d).", ret);
return false;
}
- const char *format_name = av_get_sample_fmt_name(AV_SAMPLE_FMT_S32);
- al_log_info("audio_miniaudio", "Output: %s (%dch) %dHz.", format_name, 2, 44100);
+ enum AVSampleFormat avfmt = av_sample_fmt_from_miniaudio(ma->device.playback.internalFormat);
+ const char *format_name = av_get_sample_fmt_name(avfmt);
+ al_log_info("audio_miniaudio", "Output: %s (%dch) %dHz.", format_name,
+ ma->device.playback.internalChannels, ma->device.playback.internalSampleRate);
return true;
}
@@ -177,9 +201,9 @@ struct camu_audio_miniaudio audio_plugin_miniaudio = {
.stop = audio_miniaudio_stop,
.free = audio_miniaudio_free
},
- .log = { 0 },
+ .log = { },
.context_config = { 0 },
- .context = { 0 },
+ .context = { },
.infos = NULL,
.info_count = 0,
.selected_device = NULL,
diff --git a/src/mixer/meson.build b/src/mixer/meson.build
index 71c003b..ab14b6f 100644
--- a/src/mixer/meson.build
+++ b/src/mixer/meson.build
@@ -21,6 +21,7 @@ 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 663e7aa..a4c0ef5 100644
--- a/src/mixer/mixer.c
+++ b/src/mixer/mixer.c
@@ -1,6 +1,7 @@
#include "../buffer/audio.h"
#include "mixer.h"
+#include "audio.h"
static s32 data_callback(void *userdata, u8 *data, s32 frame_count)
{
@@ -39,8 +40,10 @@ bool camu_mixer_init(struct camu_mixer *mixer, struct camu_audio *audio)
mixer->audio->data_callback = data_callback;
mixer->audio->userdata = mixer;
mixer->audio->init(mixer->audio, al_str_c("camu"));
- mixer->audio->pick_format(mixer->audio, &mixer->fmt);
- av_channel_layout_default(&mixer->fmt.req_channel_layout, mixer->fmt.req_channel_count);
+ if (!mixer->audio->configure_stream(mixer->audio, NULL)) {
+ return false;
+ }
+ camu_mixer_pick_format(mixer, &mixer->fmt);
mixer->paused = true;
al_array_init(mixer->buffers);
#ifdef CAMU_MIXER_THREADED
@@ -55,6 +58,7 @@ 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)
{
mixer->audio->pick_format(mixer->audio, fmt);
+ av_channel_layout_default(&fmt->req_channel_layout, fmt->req_channel_count);
}
f64 camu_mixer_get_latency(struct camu_mixer *mixer)
@@ -90,8 +94,6 @@ void camu_mixer_add_buffer(struct camu_mixer *mixer, struct camu_audio_buffer *b
#ifdef CAMU_MIXER_THREADED
aki_mutex_lock(&mixer->mutex);
al_array_push(mixer->add_queue, buf);
- // Ensure an allocation doesn't happen in data_callback.
- al_array_reserve(mixer->buffers, mixer->buffers.size + mixer->add_queue.size);
al_atomic_bool_store(&mixer->queued, true, AL_ATOMIC_RELAXED);
aki_mutex_unlock(&mixer->mutex);
#else
@@ -102,15 +104,16 @@ void camu_mixer_add_buffer(struct camu_mixer *mixer, struct camu_audio_buffer *b
#ifdef CAMU_MIXER_THREADED
static void run_queue_internal(struct camu_mixer *mixer)
{
+ al_array_reserve(mixer->buffers, mixer->buffers.size + mixer->add_queue.size);
struct camu_audio_buffer *buf;
al_array_foreach(mixer->add_queue, i, buf) {
add_buffer_internal(mixer, buf);
- al_array_remove_at_iter(mixer->add_queue, i);
}
+ mixer->add_queue.size = 0;
al_array_foreach(mixer->rem_queue, i, buf) {
remove_buffer_internal(mixer, buf);
- al_array_remove_at_iter(mixer->rem_queue, i);
}
+ mixer->rem_queue.size = 0;
al_atomic_bool_store(&mixer->queued, false, AL_ATOMIC_RELAXED);
}
#endif