diff options
| author | 2024-01-20 18:45:29 -0500 | |
|---|---|---|
| committer | 2024-01-20 18:45:29 -0500 | |
| commit | 88ea5bdca85fc0954d1dd64309a308199c1af4a8 (patch) | |
| tree | ef9dc778b9c42ab2fecce8810f777ccc133cebef /src/mixer | |
| parent | b79f074a86525ece1394af7bc5870516a8c38ba9 (diff) | |
| download | camu-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.c | 106 | ||||
| -rw-r--r-- | src/mixer/meson.build | 1 | ||||
| -rw-r--r-- | src/mixer/mixer.c | 15 |
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 |