(Audio) Some cleanups

This commit is contained in:
libretroadmin 2025-05-28 16:40:56 +02:00
parent 4e30df6392
commit 13790a0fad
6 changed files with 56 additions and 76 deletions

View File

@ -21,8 +21,6 @@
RETRO_BEGIN_DECLS RETRO_BEGIN_DECLS
#define AUDIO_CHUNK_SIZE_BLOCKING 512
/* So we don't get complete line-noise when fast-forwarding audio. */ /* So we don't get complete line-noise when fast-forwarding audio. */
#define AUDIO_CHUNK_SIZE_NONBLOCKING 2048 #define AUDIO_CHUNK_SIZE_NONBLOCKING 2048
@ -33,11 +31,7 @@ RETRO_BEGIN_DECLS
#define AUDIO_MIXER_MAX_SYSTEM_STREAMS (AUDIO_MIXER_MAX_STREAMS + 8) #define AUDIO_MIXER_MAX_SYSTEM_STREAMS (AUDIO_MIXER_MAX_STREAMS + 8)
/* Fastforward timing calculations running average samples. Helps with a /* Do not define more than (MAX_SYSTEM_STREAMS - MAX_STREAMS) */
consistent pitch when fast-forwarding. */
#define AUDIO_FF_EXP_AVG_SAMPLES 16
/* do not define more than (MAX_SYSTEM_STREAMS - MAX_STREAMS) */
enum audio_mixer_system_slot enum audio_mixer_system_slot
{ {
AUDIO_MIXER_SYSTEM_SLOT_OK = AUDIO_MIXER_MAX_STREAMS, AUDIO_MIXER_SYSTEM_SLOT_OK = AUDIO_MIXER_MAX_STREAMS,

View File

@ -59,6 +59,12 @@
#include "../tasks/task_content.h" #include "../tasks/task_content.h"
#include "../verbosity.h" #include "../verbosity.h"
#define AUDIO_CHUNK_SIZE_BLOCKING 512
/* Fastforward timing calculations running average samples. Helps with
* a consistent pitch when fast-forwarding. */
#define AUDIO_FF_EXP_AVG_SAMPLES 16
#define MENU_SOUND_FORMATS "ogg|mod|xm|s3m|mp3|flac|wav" #define MENU_SOUND_FORMATS "ogg|mod|xm|s3m|mp3|flac|wav"
/* Converts decibels to voltage gain. returns voltage gain value. */ /* Converts decibels to voltage gain. returns voltage gain value. */
@ -199,20 +205,13 @@ const char *config_get_audio_driver_options(void)
return char_list_new_special(STRING_LIST_AUDIO_DRIVERS, NULL); return char_list_new_special(STRING_LIST_AUDIO_DRIVERS, NULL);
} }
unsigned audio_driver_get_sample_size(void)
{
audio_driver_state_t *audio_st = &audio_driver_st;
return (audio_st->flags & AUDIO_FLAG_USE_FLOAT) ? sizeof(float) : sizeof(int16_t);
}
#ifdef HAVE_TRANSLATE #ifdef HAVE_TRANSLATE
/* TODO/FIXME - Doesn't currently work. Fix this. */ /* TODO/FIXME - Doesn't currently work. Fix this. */
bool audio_driver_is_ai_service_speech_running(void) bool audio_driver_is_ai_service_speech_running(void)
{ {
#ifdef HAVE_AUDIOMIXER #ifdef HAVE_AUDIOMIXER
enum audio_mixer_state res = audio_driver_mixer_get_stream_state(10); enum audio_mixer_state res = audio_driver_mixer_get_stream_state(10);
bool ret = (res == AUDIO_STREAM_STATE_NONE) || (res == AUDIO_STREAM_STATE_STOPPED); if (!((res == AUDIO_STREAM_STATE_NONE) || (res == AUDIO_STREAM_STATE_STOPPED)))
if (!ret)
return true; return true;
#endif #endif
return false; return false;
@ -235,7 +234,7 @@ static bool audio_driver_free_devices_list(void)
} }
#ifdef DEBUG #ifdef DEBUG
static void report_audio_buffer_statistics(void) static void audio_driver_report_audio_buffer_statistics(void)
{ {
audio_statistics_t audio_stats; audio_statistics_t audio_stats;
audio_stats.samples = 0; audio_stats.samples = 0;
@ -269,7 +268,6 @@ static void audio_driver_deinit_resampler(void)
audio_st->resampler_quality = RESAMPLER_QUALITY_DONTCARE; audio_st->resampler_quality = RESAMPLER_QUALITY_DONTCARE;
} }
static bool audio_driver_deinit_internal(bool audio_enable) static bool audio_driver_deinit_internal(bool audio_enable)
{ {
audio_driver_state_t *audio_st = &audio_driver_st; audio_driver_state_t *audio_st = &audio_driver_st;
@ -314,7 +312,7 @@ static bool audio_driver_deinit_internal(bool audio_enable)
audio_driver_dsp_filter_free(); audio_driver_dsp_filter_free();
#endif #endif
#ifdef DEBUG #ifdef DEBUG
report_audio_buffer_statistics(); audio_driver_report_audio_buffer_statistics();
#endif #endif
return true; return true;
@ -392,8 +390,7 @@ bool audio_driver_find_driver(const char *audio_drv,
* @param is_slowmotion True if the core is currently running in slow motion. * @param is_slowmotion True if the core is currently running in slow motion.
* @param is_fastmotion True if the core is currently running in fast-forward. * @param is_fastmotion True if the core is currently running in fast-forward.
**/ **/
static void audio_driver_flush( static void audio_driver_flush(audio_driver_state_t *audio_st,
audio_driver_state_t *audio_st,
float slowmotion_ratio, float slowmotion_ratio,
const int16_t *data, size_t samples, const int16_t *data, size_t samples,
bool is_slowmotion, bool is_fastforward) bool is_slowmotion, bool is_fastforward)
@ -410,41 +407,46 @@ static void audio_driver_flush(
convert_s16_to_float(audio_st->input_data, data, samples, convert_s16_to_float(audio_st->input_data, data, samples,
audio_volume_gain); audio_volume_gain);
/* The resampler operates on floating-point frames,
* so we gotta convert the input first */
/* The resampler operates on floating-point frames,
* so we have to convert the input first */
src_data.data_in = audio_st->input_data; src_data.data_in = audio_st->input_data;
src_data.input_frames = samples >> 1; src_data.input_frames = samples >> 1;
/* Remember, we allocated buffers that are twice as big as needed. /* Remember, we allocated buffers that are twice as big as needed.
* (see audio_driver_init) */ * (see audio_driver_init) */
#ifdef HAVE_DSP_FILTER #ifdef HAVE_DSP_FILTER
/* If we want to process our audio for reasons besides resampling... */
if (audio_st->dsp) if (audio_st->dsp)
{ /* If we want to process our audio for reasons besides resampling... */ {
struct retro_dsp_data dsp_data; struct retro_dsp_data dsp_data;
dsp_data.input = audio_st->input_data; dsp_data.input = audio_st->input_data;
dsp_data.input_frames = (unsigned)(samples >> 1); dsp_data.input_frames = (unsigned)(samples >> 1);
dsp_data.output = NULL; dsp_data.output = NULL;
dsp_data.output_frames = 0; dsp_data.output_frames = 0;
/* Initialize the DSP input/output. /* Initialize the DSP input/output.
* Our DSP implementations generally operate directly on the input buffer, * Our DSP implementations generally operate directly on the
* so the output/output_frames attributes here are zero; * input buffer, so the output/output_frames attributes here are zero;
* the DSP filter will set them to useful values, * the DSP filter will set them to useful values, most likely to be
* most likely to be the same as the inputs. */ * the same as the inputs. */
retro_dsp_filter_process(audio_st->dsp, &dsp_data); retro_dsp_filter_process(audio_st->dsp, &dsp_data);
/* If the DSP filter succeeded... */
if (dsp_data.output) if (dsp_data.output)
{ /* If the DSP filter succeeded... */ {
/* Then let's pass the DSP's output to the resampler's input */
src_data.data_in = dsp_data.output; src_data.data_in = dsp_data.output;
src_data.input_frames = dsp_data.output_frames; src_data.input_frames = dsp_data.output_frames;
/* Then let's pass the DSP's output to the resampler's input */
} }
} }
#endif #endif
src_data.data_out = audio_st->output_samples_buf; src_data.data_out = audio_st->output_samples_buf;
/* Now the resampler will write to the driver state's scratch buffer */ /* Now the resampler will write to the driver state's scratch buffer */
/* Count samples. */ /* Count samples. */
@ -462,10 +464,8 @@ static void audio_driver_flush(
double direction = (double)delta_mid / half_size; double direction = (double)delta_mid / half_size;
double adjust = 1.0 + audio_st->rate_control_delta * direction; double adjust = 1.0 + audio_st->rate_control_delta * direction;
audio_st->free_samples_buf[write_idx] audio_st->free_samples_buf[write_idx] = avail;
= avail; audio_st->src_ratio_curr = audio_st->src_ratio_orig * adjust;
audio_st->source_ratio_current
= audio_st->source_ratio_original * adjust;
#if 0 #if 0
if (verbosity_is_enabled()) if (verbosity_is_enabled())
@ -474,14 +474,14 @@ static void audio_driver_flush(
(unsigned)(100 - (avail * 100) / (unsigned)(100 - (avail * 100) /
audio_st->buffer_size)); audio_st->buffer_size));
RARCH_LOG_OUTPUT("[Audio]: New rate: %lf, Orig rate: %lf\n", RARCH_LOG_OUTPUT("[Audio]: New rate: %lf, Orig rate: %lf\n",
audio_st->source_ratio_current, audio_st->src_ratio_curr,
audio_st->source_ratio_original); audio_st->src_ratio_orig);
} }
#endif #endif
} }
} }
src_data.ratio = audio_st->source_ratio_current; src_data.ratio = audio_st->src_ratio_curr;
if (is_slowmotion) if (is_slowmotion)
src_data.ratio *= slowmotion_ratio; src_data.ratio *= slowmotion_ratio;
@ -520,8 +520,7 @@ static void audio_driver_flush(
audio_st->last_flush_time = flush_time; audio_st->last_flush_time = flush_time;
} }
audio_st->resampler->process( audio_st->resampler->process(audio_st->resampler_data, &src_data);
audio_st->resampler_data, &src_data);
#ifdef HAVE_AUDIOMIXER #ifdef HAVE_AUDIOMIXER
if (audio_st->flags & AUDIO_FLAG_MIXER_ACTIVE) if (audio_st->flags & AUDIO_FLAG_MIXER_ACTIVE)
@ -722,8 +721,8 @@ bool audio_driver_init_internal(void *settings_data, bool audio_cb_inited)
audio_driver_st.input = settings->uints.audio_output_sample_rate; audio_driver_st.input = settings->uints.audio_output_sample_rate;
} }
audio_driver_st.source_ratio_original = audio_driver_st.src_ratio_orig =
audio_driver_st.source_ratio_current = audio_driver_st.src_ratio_curr =
(double)settings->uints.audio_output_sample_rate / audio_driver_st.input; (double)settings->uints.audio_output_sample_rate / audio_driver_st.input;
if (!string_is_empty(settings->arrays.audio_resampler)) if (!string_is_empty(settings->arrays.audio_resampler))
@ -740,7 +739,7 @@ bool audio_driver_init_internal(void *settings_data, bool audio_cb_inited)
&audio_driver_st.resampler, &audio_driver_st.resampler,
audio_driver_st.resampler_ident, audio_driver_st.resampler_ident,
audio_driver_st.resampler_quality, audio_driver_st.resampler_quality,
audio_driver_st.source_ratio_original)) audio_driver_st.src_ratio_orig))
{ {
RARCH_ERR("Failed to initialize resampler \"%s\".\n", RARCH_ERR("Failed to initialize resampler \"%s\".\n",
audio_driver_st.resampler_ident); audio_driver_st.resampler_ident);

View File

@ -169,8 +169,8 @@ typedef struct audio_driver
typedef struct typedef struct
{ {
double source_ratio_original; double src_ratio_orig;
double source_ratio_current; double src_ratio_curr;
uint64_t free_samples_count; uint64_t free_samples_count;
@ -320,17 +320,6 @@ bool audio_driver_start(bool is_shutdown);
bool audio_driver_stop(void); bool audio_driver_stop(void);
/**
* If you need to query the size of audio samples,
* use this function instead of checking the flags directly.
*
* @return The size of a single audio sample in bytes,
* as determined by the presence of the \c AUDIO_FLAG_USE_FLOAT flag.
* Will currently return either 2 (for \c uint16_t) or 4 (for \c float),
* although this may change if we add support for more sample types.
*/
unsigned audio_driver_get_sample_size(void);
#ifdef HAVE_TRANSLATE #ifdef HAVE_TRANSLATE
/* TODO/FIXME - Doesn't currently work. Fix this. */ /* TODO/FIXME - Doesn't currently work. Fix this. */
bool audio_driver_is_ai_service_speech_running(void); bool audio_driver_is_ai_service_speech_running(void);
@ -344,9 +333,7 @@ bool audio_driver_is_ai_service_speech_running(void);
**/ **/
bool audio_compute_buffer_statistics(audio_statistics_t *stats); bool audio_compute_buffer_statistics(audio_statistics_t *stats);
bool audio_driver_init_internal( bool audio_driver_init_internal(void *data, bool audio_cb_inited);
void *settings_data,
bool audio_cb_inited);
bool audio_driver_deinit(void); bool audio_driver_deinit(void);

View File

@ -79,11 +79,12 @@ bool microphone_driver_start(void)
microphone_driver_state_t *mic_st = &mic_driver_st; microphone_driver_state_t *mic_st = &mic_driver_st;
retro_microphone_t *microphone = &mic_st->microphone; retro_microphone_t *microphone = &mic_st->microphone;
/* If there's an opened microphone that the core turned on... */
if (microphone->flags & MICROPHONE_FLAG_ACTIVE) if (microphone->flags & MICROPHONE_FLAG_ACTIVE)
{ /* If there's an opened microphone that the core turned on... */ {
/* If this microphone was requested before the driver was ready...*/
if (microphone->flags & MICROPHONE_FLAG_PENDING) if (microphone->flags & MICROPHONE_FLAG_PENDING)
{ /* If this microphone was requested before the driver was ready...*/ {
retro_assert(microphone->microphone_context == NULL); retro_assert(microphone->microphone_context == NULL);
/* The microphone context shouldn't have been created yet */ /* The microphone context shouldn't have been created yet */
@ -102,8 +103,9 @@ bool microphone_driver_start(void)
* what if the player just unplugged their mic? */ * what if the player just unplugged their mic? */
} }
} }
/* The microphone was already created, so let's just unpause it */
else else
{ /* The mic was already created, so let's just unpause it */ {
microphone_driver_set_mic_state(microphone, true); microphone_driver_set_mic_state(microphone, true);
RARCH_DBG("[Microphone]: Started a microphone that was enabled when the driver was last stopped.\n"); RARCH_DBG("[Microphone]: Started a microphone that was enabled when the driver was last stopped.\n");
@ -117,18 +119,16 @@ bool microphone_driver_stop(void)
{ {
microphone_driver_state_t *mic_st = &mic_driver_st; microphone_driver_state_t *mic_st = &mic_driver_st;
retro_microphone_t *microphone = &mic_st->microphone; retro_microphone_t *microphone = &mic_st->microphone;
bool result = true;
if ((microphone->flags & MICROPHONE_FLAG_ACTIVE) /* If there's an opened microphone that the core
&& (microphone->flags & MICROPHONE_FLAG_ENABLED) * turned on and received... */
if ( (microphone->flags & MICROPHONE_FLAG_ACTIVE)
&& (microphone->flags & MICROPHONE_FLAG_ENABLED)
&& !(microphone->flags & MICROPHONE_FLAG_PENDING)) && !(microphone->flags & MICROPHONE_FLAG_PENDING))
{ /* If there's an opened microphone that the core turned on and received... */ return mic_st->driver->stop_mic(mic_st->driver_context,
microphone->microphone_context);
result = mic_st->driver->stop_mic(mic_st->driver_context, microphone->microphone_context);
}
/* If the mic is pending, then we don't need to do anything. */ /* If the mic is pending, then we don't need to do anything. */
return true;
return result;
} }
/** /**
@ -388,14 +388,14 @@ static bool mic_driver_open_mic_internal(retro_microphone_t* microphone)
&& mic_driver->mic_use_float(mic_st->driver_context, microphone->microphone_context)) && mic_driver->mic_use_float(mic_st->driver_context, microphone->microphone_context))
microphone->flags |= MICROPHONE_FLAG_USE_FLOAT; microphone->flags |= MICROPHONE_FLAG_USE_FLOAT;
microphone->original_ratio = (double)microphone->effective_params.rate / microphone->actual_params.rate; microphone->orig_ratio = (double)microphone->effective_params.rate / microphone->actual_params.rate;
if (!retro_resampler_realloc( if (!retro_resampler_realloc(
&microphone->resampler_data, &microphone->resampler_data,
&microphone->resampler, &microphone->resampler,
mic_st->resampler_ident, mic_st->resampler_ident,
mic_st->resampler_quality, mic_st->resampler_quality,
microphone->original_ratio)) microphone->orig_ratio))
{ {
RARCH_ERR("[Microphone]: Failed to initialize resampler \"%s\".\n", mic_st->resampler_ident); RARCH_ERR("[Microphone]: Failed to initialize resampler \"%s\".\n", mic_st->resampler_ident);
goto error; goto error;

View File

@ -190,7 +190,7 @@ struct retro_microphone
* The ratio of the core-requested sample rate to the device's opened sample rate. * The ratio of the core-requested sample rate to the device's opened sample rate.
* If this is (almost) equal to 1, then resampling will be skipped. * If this is (almost) equal to 1, then resampling will be skipped.
*/ */
double original_ratio; double orig_ratio;
}; };
/** /**

View File

@ -2,7 +2,7 @@
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2021 - Daniel De Matteis * Copyright (C) 2011-2021 - Daniel De Matteis
* Copyright (C) 2012-2015 - Michael Lelli * Copyright (C) 2012-2015 - Michael Lelli
* Copyright (C) 2014-2017 - Jean-Andr<EFBFBD> Santoni * Copyright (C) 2014-2017 - Jean-Andr Santoni
* Copyright (C) 2016-2019 - Brad Parker * Copyright (C) 2016-2019 - Brad Parker
* *
* RetroArch is free software: you can redistribute it and/or modify it under the terms * RetroArch is free software: you can redistribute it and/or modify it under the terms
@ -1979,8 +1979,8 @@ bool driver_ctl(enum driver_ctl_state state, void *data)
video_monitor_set_refresh_rate(*hz); video_monitor_set_refresh_rate(*hz);
/* Sets audio monitor rate to new value. */ /* Sets audio monitor rate to new value. */
audio_st->source_ratio_original = audio_st->src_ratio_orig =
audio_st->source_ratio_current = audio_st->src_ratio_curr =
(double)audio_output_sample_rate / audio_st->input; (double)audio_output_sample_rate / audio_st->input;
driver_adjust_system_rates(runloop_st, video_st, settings); driver_adjust_system_rates(runloop_st, video_st, settings);