(audio_driver.c) Uniquely namespace static variables

This commit is contained in:
twinaphex 2015-11-30 07:33:15 +01:00
parent d1486464fe
commit 1ed467f4e7
1 changed files with 160 additions and 159 deletions

View File

@ -63,15 +63,6 @@ typedef struct audio_driver_input_data
uint64_t buffer_free_samples_count; uint64_t buffer_free_samples_count;
} audio_driver_input_data_t; } audio_driver_input_data_t;
static bool audio_active;
static bool audio_data_own;
static const rarch_resampler_t *audio_resampler;
static void *audio_resampler_data;
static const audio_driver_t *current_audio;
static void *context_audio_data;
static audio_driver_input_data_t audio_data;
static const audio_driver_t *audio_drivers[] = { static const audio_driver_t *audio_drivers[] = {
#ifdef HAVE_ALSA #ifdef HAVE_ALSA
&audio_alsa, &audio_alsa,
@ -135,6 +126,15 @@ static const audio_driver_t *audio_drivers[] = {
NULL, NULL,
}; };
static bool audio_driver_active;
static bool audio_driver_data_own;
static const rarch_resampler_t *audio_driver_resampler;
static void *audio_driver_resampler_data;
static const audio_driver_t *current_audio;
static void *audio_driver_context_audio_data;
static audio_driver_input_data_t audio_driver_data;
/** /**
* compute_audio_buffer_statistics: * compute_audio_buffer_statistics:
* *
@ -147,35 +147,35 @@ static void compute_audio_buffer_statistics(void)
float avg_filled, deviation; float avg_filled, deviation;
uint64_t accum = 0, accum_var = 0; uint64_t accum = 0, accum_var = 0;
unsigned low_water_count = 0, high_water_count = 0; unsigned low_water_count = 0, high_water_count = 0;
unsigned samples = min(audio_data.buffer_free_samples_count, unsigned samples = min(audio_driver_data.buffer_free_samples_count,
AUDIO_BUFFER_FREE_SAMPLES_COUNT); AUDIO_BUFFER_FREE_SAMPLES_COUNT);
if (samples < 3) if (samples < 3)
return; return;
for (i = 1; i < samples; i++) for (i = 1; i < samples; i++)
accum += audio_data.buffer_free_samples[i]; accum += audio_driver_data.buffer_free_samples[i];
avg = accum / (samples - 1); avg = accum / (samples - 1);
for (i = 1; i < samples; i++) for (i = 1; i < samples; i++)
{ {
int diff = avg - audio_data.buffer_free_samples[i]; int diff = avg - audio_driver_data.buffer_free_samples[i];
accum_var += diff * diff; accum_var += diff * diff;
} }
stddev = (unsigned)sqrt((double)accum_var / (samples - 2)); stddev = (unsigned)sqrt((double)accum_var / (samples - 2));
avg_filled = 1.0f - (float)avg / audio_data.driver_buffer_size; avg_filled = 1.0f - (float)avg / audio_driver_data.driver_buffer_size;
deviation = (float)stddev / audio_data.driver_buffer_size; deviation = (float)stddev / audio_driver_data.driver_buffer_size;
low_water_size = audio_data.driver_buffer_size * 3 / 4; low_water_size = audio_driver_data.driver_buffer_size * 3 / 4;
high_water_size = audio_data.driver_buffer_size / 4; high_water_size = audio_driver_data.driver_buffer_size / 4;
for (i = 1; i < samples; i++) for (i = 1; i < samples; i++)
{ {
if (audio_data.buffer_free_samples[i] >= low_water_size) if (audio_driver_data.buffer_free_samples[i] >= low_water_size)
low_water_count++; low_water_count++;
else if (audio_data.buffer_free_samples[i] <= high_water_size) else if (audio_driver_data.buffer_free_samples[i] <= high_water_size)
high_water_count++; high_water_count++;
} }
@ -233,40 +233,40 @@ static bool uninit_audio(void)
{ {
settings_t *settings = config_get_ptr(); settings_t *settings = config_get_ptr();
if (context_audio_data && current_audio) if (audio_driver_context_audio_data && current_audio)
current_audio->free(context_audio_data); current_audio->free(audio_driver_context_audio_data);
if (audio_data.conv_outsamples) if (audio_driver_data.conv_outsamples)
free(audio_data.conv_outsamples); free(audio_driver_data.conv_outsamples);
audio_data.conv_outsamples = NULL; audio_driver_data.conv_outsamples = NULL;
audio_data.data_ptr = 0; audio_driver_data.data_ptr = 0;
if (audio_data.rewind_buf) if (audio_driver_data.rewind_buf)
free(audio_data.rewind_buf); free(audio_driver_data.rewind_buf);
audio_data.rewind_buf = NULL; audio_driver_data.rewind_buf = NULL;
if (!settings->audio.enable) if (!settings->audio.enable)
{ {
audio_active = false; audio_driver_active = false;
return false; return false;
} }
rarch_resampler_freep(&audio_resampler, rarch_resampler_freep(&audio_driver_resampler,
&audio_resampler_data); &audio_driver_resampler_data);
if (audio_data.audio_callback.callback) if (audio_driver_data.audio_callback.callback)
{ {
audio_data.audio_callback.callback = NULL; audio_driver_data.audio_callback.callback = NULL;
audio_data.audio_callback.set_state = NULL; audio_driver_data.audio_callback.set_state = NULL;
} }
if (audio_data.data) if (audio_driver_data.data)
free(audio_data.data); free(audio_driver_data.data);
audio_data.data = NULL; audio_driver_data.data = NULL;
if (audio_data.outsamples) if (audio_driver_data.outsamples)
free(audio_data.outsamples); free(audio_driver_data.outsamples);
audio_data.outsamples = NULL; audio_driver_data.outsamples = NULL;
event_command(EVENT_CMD_DSP_FILTER_DEINIT); event_command(EVENT_CMD_DSP_FILTER_DEINIT);
@ -274,8 +274,8 @@ static bool uninit_audio(void)
current_audio = NULL; current_audio = NULL;
if (!audio_data_own) if (!audio_driver_data_own)
context_audio_data = NULL; audio_driver_context_audio_data = NULL;
return true; return true;
} }
@ -288,7 +288,7 @@ static bool init_audio(void)
audio_convert_init_simd(); audio_convert_init_simd();
/* Resource leaks will follow if audio is initialized twice. */ /* Resource leaks will follow if audio is initialized twice. */
if (context_audio_data) if (audio_driver_context_audio_data)
return false; return false;
/* Accomodate rewind since at some point we might have two full buffers. */ /* Accomodate rewind since at some point we might have two full buffers. */
@ -296,38 +296,38 @@ static bool init_audio(void)
settings->slowmotion_ratio; settings->slowmotion_ratio;
/* Used for recording even if audio isn't enabled. */ /* Used for recording even if audio isn't enabled. */
retro_assert(audio_data.conv_outsamples = retro_assert(audio_driver_data.conv_outsamples =
(int16_t*)malloc(outsamples_max * sizeof(int16_t))); (int16_t*)malloc(outsamples_max * sizeof(int16_t)));
if (!audio_data.conv_outsamples) if (!audio_driver_data.conv_outsamples)
goto error; goto error;
audio_data.block_chunk_size = AUDIO_CHUNK_SIZE_BLOCKING; audio_driver_data.block_chunk_size = AUDIO_CHUNK_SIZE_BLOCKING;
audio_data.nonblock_chunk_size = AUDIO_CHUNK_SIZE_NONBLOCKING; audio_driver_data.nonblock_chunk_size = AUDIO_CHUNK_SIZE_NONBLOCKING;
audio_data.chunk_size = audio_data.block_chunk_size; audio_driver_data.chunk_size = audio_driver_data.block_chunk_size;
/* Needs to be able to hold full content of a full max_bufsamples /* Needs to be able to hold full content of a full max_bufsamples
* in addition to its own. */ * in addition to its own. */
retro_assert(audio_data.rewind_buf = (int16_t*) retro_assert(audio_driver_data.rewind_buf = (int16_t*)
malloc(max_bufsamples * sizeof(int16_t))); malloc(max_bufsamples * sizeof(int16_t)));
if (!audio_data.rewind_buf) if (!audio_driver_data.rewind_buf)
goto error; goto error;
audio_data.rewind_size = max_bufsamples; audio_driver_data.rewind_size = max_bufsamples;
if (!settings->audio.enable) if (!settings->audio.enable)
{ {
audio_active = false; audio_driver_active = false;
return false; return false;
} }
audio_driver_ctl(RARCH_AUDIO_CTL_FIND_DRIVER, NULL); audio_driver_ctl(RARCH_AUDIO_CTL_FIND_DRIVER, NULL);
#ifdef HAVE_THREADS #ifdef HAVE_THREADS
if (audio_data.audio_callback.callback) if (audio_driver_data.audio_callback.callback)
{ {
RARCH_LOG("Starting threaded audio driver ...\n"); RARCH_LOG("Starting threaded audio driver ...\n");
if (!rarch_threaded_audio_init(&current_audio, &context_audio_data, if (!rarch_threaded_audio_init(&current_audio, &audio_driver_context_audio_data,
*settings->audio.device ? settings->audio.device : NULL, *settings->audio.device ? settings->audio.device : NULL,
settings->audio.out_rate, settings->audio.latency, settings->audio.out_rate, settings->audio.latency,
current_audio)) current_audio))
@ -339,74 +339,74 @@ static bool init_audio(void)
else else
#endif #endif
{ {
context_audio_data = current_audio->init(*settings->audio.device ? audio_driver_context_audio_data = current_audio->init(*settings->audio.device ?
settings->audio.device : NULL, settings->audio.device : NULL,
settings->audio.out_rate, settings->audio.latency); settings->audio.out_rate, settings->audio.latency);
} }
if (!context_audio_data) if (!audio_driver_context_audio_data)
{ {
RARCH_ERR("Failed to initialize audio driver. Will continue without audio.\n"); RARCH_ERR("Failed to initialize audio driver. Will continue without audio.\n");
audio_active = false; audio_driver_active = false;
} }
audio_data.use_float = false; audio_driver_data.use_float = false;
if (audio_active && current_audio->use_float(context_audio_data)) if (audio_driver_active && current_audio->use_float(audio_driver_context_audio_data))
audio_data.use_float = true; audio_driver_data.use_float = true;
if (!settings->audio.sync && audio_active) if (!settings->audio.sync && audio_driver_active)
{ {
event_command(EVENT_CMD_AUDIO_SET_NONBLOCKING_STATE); event_command(EVENT_CMD_AUDIO_SET_NONBLOCKING_STATE);
audio_data.chunk_size = audio_data.nonblock_chunk_size; audio_driver_data.chunk_size = audio_driver_data.nonblock_chunk_size;
} }
if (audio_data.in_rate <= 0.0f) if (audio_driver_data.in_rate <= 0.0f)
{ {
/* Should never happen. */ /* Should never happen. */
RARCH_WARN("Input rate is invalid (%.3f Hz). Using output rate (%u Hz).\n", RARCH_WARN("Input rate is invalid (%.3f Hz). Using output rate (%u Hz).\n",
audio_data.in_rate, settings->audio.out_rate); audio_driver_data.in_rate, settings->audio.out_rate);
audio_data.in_rate = settings->audio.out_rate; audio_driver_data.in_rate = settings->audio.out_rate;
} }
audio_data.orig_src_ratio = audio_data.src_ratio = audio_driver_data.orig_src_ratio = audio_driver_data.src_ratio =
(double)settings->audio.out_rate / audio_data.in_rate; (double)settings->audio.out_rate / audio_driver_data.in_rate;
if (!rarch_resampler_realloc(&audio_resampler_data, if (!rarch_resampler_realloc(&audio_driver_resampler_data,
&audio_resampler, &audio_driver_resampler,
settings->audio.resampler, audio_data.orig_src_ratio)) settings->audio.resampler, audio_driver_data.orig_src_ratio))
{ {
RARCH_ERR("Failed to initialize resampler \"%s\".\n", RARCH_ERR("Failed to initialize resampler \"%s\".\n",
settings->audio.resampler); settings->audio.resampler);
audio_active = false; audio_driver_active = false;
} }
retro_assert(audio_data.data = (float*) retro_assert(audio_driver_data.data = (float*)
malloc(max_bufsamples * sizeof(float))); malloc(max_bufsamples * sizeof(float)));
if (!audio_data.data) if (!audio_driver_data.data)
goto error; goto error;
audio_data.data_ptr = 0; audio_driver_data.data_ptr = 0;
retro_assert(settings->audio.out_rate < retro_assert(settings->audio.out_rate <
audio_data.in_rate * AUDIO_MAX_RATIO); audio_driver_data.in_rate * AUDIO_MAX_RATIO);
retro_assert(audio_data.outsamples = (float*) retro_assert(audio_driver_data.outsamples = (float*)
malloc(outsamples_max * sizeof(float))); malloc(outsamples_max * sizeof(float)));
if (!audio_data.outsamples) if (!audio_driver_data.outsamples)
goto error; goto error;
audio_data.rate_control = false; audio_driver_data.rate_control = false;
if (!audio_data.audio_callback.callback && audio_active && if (!audio_driver_data.audio_callback.callback && audio_driver_active &&
settings->audio.rate_control) settings->audio.rate_control)
{ {
/* Audio rate control requires write_avail /* Audio rate control requires write_avail
* and buffer_size to be implemented. */ * and buffer_size to be implemented. */
if (current_audio->buffer_size) if (current_audio->buffer_size)
{ {
audio_data.driver_buffer_size = audio_driver_data.driver_buffer_size =
current_audio->buffer_size(context_audio_data); current_audio->buffer_size(audio_driver_context_audio_data);
audio_data.rate_control = true; audio_driver_data.rate_control = true;
} }
else else
RARCH_WARN("Audio rate control was desired, but driver does not support needed features.\n"); RARCH_WARN("Audio rate control was desired, but driver does not support needed features.\n");
@ -414,11 +414,11 @@ static bool init_audio(void)
event_command(EVENT_CMD_DSP_FILTER_INIT); event_command(EVENT_CMD_DSP_FILTER_INIT);
audio_data.buffer_free_samples_count = 0; audio_driver_data.buffer_free_samples_count = 0;
/* Threaded driver is initially stopped. */ /* Threaded driver is initially stopped. */
if (audio_active && !settings->audio.mute_enable && if (audio_driver_active && !settings->audio.mute_enable &&
audio_data.audio_callback.callback) audio_driver_data.audio_callback.callback)
audio_driver_ctl(RARCH_AUDIO_CTL_START, NULL); audio_driver_ctl(RARCH_AUDIO_CTL_START, NULL);
return true; return true;
@ -435,37 +435,37 @@ error:
static void audio_driver_readjust_input_rate(void) static void audio_driver_readjust_input_rate(void)
{ {
settings_t *settings = config_get_ptr(); settings_t *settings = config_get_ptr();
unsigned write_idx = audio_data.buffer_free_samples_count++ & unsigned write_idx = audio_driver_data.buffer_free_samples_count++ &
(AUDIO_BUFFER_FREE_SAMPLES_COUNT - 1); (AUDIO_BUFFER_FREE_SAMPLES_COUNT - 1);
int half_size = audio_data.driver_buffer_size / 2; int half_size = audio_driver_data.driver_buffer_size / 2;
int avail = current_audio->write_avail(context_audio_data); int avail = current_audio->write_avail(audio_driver_context_audio_data);
int delta_mid = avail - half_size; int delta_mid = avail - half_size;
double direction = (double)delta_mid / half_size; double direction = (double)delta_mid / half_size;
double adjust = 1.0 + settings->audio.rate_control_delta * direction; double adjust = 1.0 + settings->audio.rate_control_delta * direction;
#if 0 #if 0
RARCH_LOG_OUTPUT("Audio buffer is %u%% full\n", RARCH_LOG_OUTPUT("Audio buffer is %u%% full\n",
(unsigned)(100 - (avail * 100) / audio_data.driver_buffer_size)); (unsigned)(100 - (avail * 100) / audio_driver_data.driver_buffer_size));
#endif #endif
audio_data.buffer_free_samples[write_idx] = avail; audio_driver_data.buffer_free_samples[write_idx] = avail;
audio_data.src_ratio = audio_data.orig_src_ratio * adjust; audio_driver_data.src_ratio = audio_driver_data.orig_src_ratio * adjust;
#if 0 #if 0
RARCH_LOG_OUTPUT("New rate: %lf, Orig rate: %lf\n", RARCH_LOG_OUTPUT("New rate: %lf, Orig rate: %lf\n",
audio_data.src_ratio, audio_data.orig_src_ratio); audio_driver_data.src_ratio, audio_driver_data.orig_src_ratio);
#endif #endif
} }
void audio_driver_set_nonblocking_state(bool enable) void audio_driver_set_nonblocking_state(bool enable)
{ {
settings_t *settings = config_get_ptr(); settings_t *settings = config_get_ptr();
if (audio_active && context_audio_data) if (audio_driver_active && audio_driver_context_audio_data)
current_audio->set_nonblock_state(context_audio_data, current_audio->set_nonblock_state(audio_driver_context_audio_data,
settings->audio.sync ? enable : true); settings->audio.sync ? enable : true);
audio_data.chunk_size = enable ? audio_data.nonblock_chunk_size : audio_driver_data.chunk_size = enable ? audio_driver_data.nonblock_chunk_size :
audio_data.block_chunk_size; audio_driver_data.block_chunk_size;
} }
/** /**
@ -499,26 +499,26 @@ static bool audio_driver_flush(const int16_t *data, size_t samples)
if (is_paused || settings->audio.mute_enable) if (is_paused || settings->audio.mute_enable)
return true; return true;
if (!audio_active || !audio_data.data) if (!audio_driver_active || !audio_driver_data.data)
return false; return false;
rarch_perf_init(&audio_convert_s16, "audio_convert_s16"); rarch_perf_init(&audio_convert_s16, "audio_convert_s16");
retro_perf_start(&audio_convert_s16); retro_perf_start(&audio_convert_s16);
audio_convert_s16_to_float(audio_data.data, data, samples, audio_convert_s16_to_float(audio_driver_data.data, data, samples,
audio_data.volume_gain); audio_driver_data.volume_gain);
retro_perf_stop(&audio_convert_s16); retro_perf_stop(&audio_convert_s16);
src_data.data_in = audio_data.data; src_data.data_in = audio_driver_data.data;
src_data.input_frames = samples >> 1; src_data.input_frames = samples >> 1;
dsp_data.input = audio_data.data; dsp_data.input = audio_driver_data.data;
dsp_data.input_frames = samples >> 1; dsp_data.input_frames = samples >> 1;
if (audio_data.dsp) if (audio_driver_data.dsp)
{ {
rarch_perf_init(&audio_dsp, "audio_dsp"); rarch_perf_init(&audio_dsp, "audio_dsp");
retro_perf_start(&audio_dsp); retro_perf_start(&audio_dsp);
rarch_dsp_filter_process(audio_data.dsp, &dsp_data); rarch_dsp_filter_process(audio_driver_data.dsp, &dsp_data);
retro_perf_stop(&audio_dsp); retro_perf_stop(&audio_dsp);
if (dsp_data.output) if (dsp_data.output)
@ -528,12 +528,12 @@ static bool audio_driver_flush(const int16_t *data, size_t samples)
} }
} }
src_data.data_out = audio_data.outsamples; src_data.data_out = audio_driver_data.outsamples;
if (audio_data.rate_control) if (audio_driver_data.rate_control)
audio_driver_readjust_input_rate(); audio_driver_readjust_input_rate();
src_data.ratio = audio_data.src_ratio; src_data.ratio = audio_driver_data.src_ratio;
rarch_main_ctl(RARCH_MAIN_CTL_IS_SLOWMOTION, &is_slowmotion); rarch_main_ctl(RARCH_MAIN_CTL_IS_SLOWMOTION, &is_slowmotion);
@ -542,27 +542,28 @@ static bool audio_driver_flush(const int16_t *data, size_t samples)
rarch_perf_init(&resampler_proc, "resampler_proc"); rarch_perf_init(&resampler_proc, "resampler_proc");
retro_perf_start(&resampler_proc); retro_perf_start(&resampler_proc);
rarch_resampler_process(audio_resampler, audio_resampler_data, &src_data); rarch_resampler_process(audio_driver_resampler, audio_driver_resampler_data, &src_data);
retro_perf_stop(&resampler_proc); retro_perf_stop(&resampler_proc);
output_data = audio_data.outsamples; output_data = audio_driver_data.outsamples;
output_frames = src_data.output_frames; output_frames = src_data.output_frames;
if (!audio_data.use_float) if (!audio_driver_data.use_float)
{ {
rarch_perf_init(&audio_convert_float, "audio_convert_float"); rarch_perf_init(&audio_convert_float, "audio_convert_float");
retro_perf_start(&audio_convert_float); retro_perf_start(&audio_convert_float);
audio_convert_float_to_s16(audio_data.conv_outsamples, audio_convert_float_to_s16(audio_driver_data.conv_outsamples,
(const float*)output_data, output_frames * 2); (const float*)output_data, output_frames * 2);
retro_perf_stop(&audio_convert_float); retro_perf_stop(&audio_convert_float);
output_data = audio_data.conv_outsamples; output_data = audio_driver_data.conv_outsamples;
output_size = sizeof(int16_t); output_size = sizeof(int16_t);
} }
if (current_audio->write(context_audio_data, output_data, output_frames * output_size * 2) < 0) if (current_audio->write(audio_driver_context_audio_data,
output_data, output_frames * output_size * 2) < 0)
{ {
audio_active = false; audio_driver_active = false;
return false; return false;
} }
@ -578,15 +579,15 @@ static bool audio_driver_flush(const int16_t *data, size_t samples)
**/ **/
void audio_driver_sample(int16_t left, int16_t right) void audio_driver_sample(int16_t left, int16_t right)
{ {
audio_data.conv_outsamples[audio_data.data_ptr++] = left; audio_driver_data.conv_outsamples[audio_driver_data.data_ptr++] = left;
audio_data.conv_outsamples[audio_data.data_ptr++] = right; audio_driver_data.conv_outsamples[audio_driver_data.data_ptr++] = right;
if (audio_data.data_ptr < audio_data.chunk_size) if (audio_driver_data.data_ptr < audio_driver_data.chunk_size)
return; return;
audio_driver_flush(audio_data.conv_outsamples, audio_data.data_ptr); audio_driver_flush(audio_driver_data.conv_outsamples, audio_driver_data.data_ptr);
audio_data.data_ptr = 0; audio_driver_data.data_ptr = 0;
} }
/** /**
@ -619,8 +620,8 @@ size_t audio_driver_sample_batch(const int16_t *data, size_t frames)
**/ **/
void audio_driver_sample_rewind(int16_t left, int16_t right) void audio_driver_sample_rewind(int16_t left, int16_t right)
{ {
audio_data.rewind_buf[--audio_data.rewind_ptr] = right; audio_driver_data.rewind_buf[--audio_driver_data.rewind_ptr] = right;
audio_data.rewind_buf[--audio_data.rewind_ptr] = left; audio_driver_data.rewind_buf[--audio_driver_data.rewind_ptr] = left;
} }
/** /**
@ -640,33 +641,33 @@ size_t audio_driver_sample_batch_rewind(const int16_t *data, size_t frames)
size_t samples = frames << 1; size_t samples = frames << 1;
for (i = 0; i < samples; i++) for (i = 0; i < samples; i++)
audio_data.rewind_buf[--audio_data.rewind_ptr] = data[i]; audio_driver_data.rewind_buf[--audio_driver_data.rewind_ptr] = data[i];
return frames; return frames;
} }
void audio_driver_set_volume_gain(float gain) void audio_driver_set_volume_gain(float gain)
{ {
audio_data.volume_gain = gain; audio_driver_data.volume_gain = gain;
} }
void audio_driver_dsp_filter_free(void) void audio_driver_dsp_filter_free(void)
{ {
if (audio_data.dsp) if (audio_driver_data.dsp)
rarch_dsp_filter_free(audio_data.dsp); rarch_dsp_filter_free(audio_driver_data.dsp);
audio_data.dsp = NULL; audio_driver_data.dsp = NULL;
} }
void audio_driver_dsp_filter_init(const char *device) void audio_driver_dsp_filter_init(const char *device)
{ {
audio_data.dsp = rarch_dsp_filter_new(device, audio_data.in_rate); audio_driver_data.dsp = rarch_dsp_filter_new(device, audio_driver_data.in_rate);
if (!audio_data.dsp) if (!audio_driver_data.dsp)
RARCH_ERR("[DSP]: Failed to initialize DSP filter \"%s\".\n", device); RARCH_ERR("[DSP]: Failed to initialize DSP filter \"%s\".\n", device);
} }
void audio_driver_set_buffer_size(size_t bufsize) void audio_driver_set_buffer_size(size_t bufsize)
{ {
audio_data.driver_buffer_size = bufsize; audio_driver_data.driver_buffer_size = bufsize;
} }
void audio_driver_set_callback(const void *data) void audio_driver_set_callback(const void *data)
@ -675,7 +676,7 @@ void audio_driver_set_callback(const void *data)
(const struct retro_audio_callback*)data; (const struct retro_audio_callback*)data;
if (cb) if (cb)
audio_data.audio_callback = *cb; audio_driver_data.audio_callback = *cb;
} }
void audio_driver_callback_set_state(bool state) void audio_driver_callback_set_state(bool state)
@ -683,8 +684,8 @@ void audio_driver_callback_set_state(bool state)
if (!audio_driver_ctl(RARCH_AUDIO_CTL_HAS_CALLBACK, NULL)) if (!audio_driver_ctl(RARCH_AUDIO_CTL_HAS_CALLBACK, NULL))
return; return;
if (audio_data.audio_callback.set_state) if (audio_driver_data.audio_callback.set_state)
audio_data.audio_callback.set_state(state); audio_driver_data.audio_callback.set_state(state);
} }
static void audio_monitor_adjust_system_rates(void) static void audio_monitor_adjust_system_rates(void)
@ -701,13 +702,13 @@ static void audio_monitor_adjust_system_rates(void)
return; return;
timing_skew = fabs(1.0f - info->fps / settings->video.refresh_rate); timing_skew = fabs(1.0f - info->fps / settings->video.refresh_rate);
audio_data.in_rate = info->sample_rate; audio_driver_data.in_rate = info->sample_rate;
if (timing_skew <= settings->audio.max_timing_skew) if (timing_skew <= settings->audio.max_timing_skew)
audio_data.in_rate *= (settings->video.refresh_rate / info->fps); audio_driver_data.in_rate *= (settings->video.refresh_rate / info->fps);
RARCH_LOG("Set audio input rate to: %.2f Hz.\n", RARCH_LOG("Set audio input rate to: %.2f Hz.\n",
audio_data.in_rate); audio_driver_data.in_rate);
} }
static void audio_driver_setup_rewind(void) static void audio_driver_setup_rewind(void)
@ -715,18 +716,18 @@ static void audio_driver_setup_rewind(void)
unsigned i; unsigned i;
/* Push audio ready to be played. */ /* Push audio ready to be played. */
audio_data.rewind_ptr = audio_data.rewind_size; audio_driver_data.rewind_ptr = audio_driver_data.rewind_size;
for (i = 0; i < audio_data.data_ptr; i += 2) for (i = 0; i < audio_driver_data.data_ptr; i += 2)
{ {
audio_data.rewind_buf[--audio_data.rewind_ptr] = audio_driver_data.rewind_buf[--audio_driver_data.rewind_ptr] =
audio_data.conv_outsamples[i + 1]; audio_driver_data.conv_outsamples[i + 1];
audio_data.rewind_buf[--audio_data.rewind_ptr] = audio_driver_data.rewind_buf[--audio_driver_data.rewind_ptr] =
audio_data.conv_outsamples[i + 0]; audio_driver_data.conv_outsamples[i + 0];
} }
audio_data.data_ptr = 0; audio_driver_data.data_ptr = 0;
} }
static bool find_audio_driver(void) static bool find_audio_driver(void)
@ -772,13 +773,13 @@ bool audio_driver_ctl(enum rarch_audio_ctl_state state, void *data)
audio_driver_setup_rewind(); audio_driver_setup_rewind();
return true; return true;
case RARCH_AUDIO_CTL_HAS_CALLBACK: case RARCH_AUDIO_CTL_HAS_CALLBACK:
return audio_data.audio_callback.callback; return audio_driver_data.audio_callback.callback;
case RARCH_AUDIO_CTL_CALLBACK: case RARCH_AUDIO_CTL_CALLBACK:
if (!audio_driver_ctl(RARCH_AUDIO_CTL_HAS_CALLBACK, NULL)) if (!audio_driver_ctl(RARCH_AUDIO_CTL_HAS_CALLBACK, NULL))
return false; return false;
if (audio_data.audio_callback.callback) if (audio_driver_data.audio_callback.callback)
audio_data.audio_callback.callback(); audio_driver_data.audio_callback.callback();
return true; return true;
case RARCH_AUDIO_CTL_MONITOR_ADJUST_SYSTEM_RATES: case RARCH_AUDIO_CTL_MONITOR_ADJUST_SYSTEM_RATES:
audio_monitor_adjust_system_rates(); audio_monitor_adjust_system_rates();
@ -786,14 +787,14 @@ bool audio_driver_ctl(enum rarch_audio_ctl_state state, void *data)
case RARCH_AUDIO_CTL_MONITOR_SET_REFRESH_RATE: case RARCH_AUDIO_CTL_MONITOR_SET_REFRESH_RATE:
{ {
double new_src_ratio = (double)settings->audio.out_rate / double new_src_ratio = (double)settings->audio.out_rate /
audio_data.in_rate; audio_driver_data.in_rate;
audio_data.orig_src_ratio = new_src_ratio; audio_driver_data.orig_src_ratio = new_src_ratio;
audio_data.src_ratio = new_src_ratio; audio_driver_data.src_ratio = new_src_ratio;
} }
return true; return true;
case RARCH_AUDIO_CTL_MUTE_TOGGLE: case RARCH_AUDIO_CTL_MUTE_TOGGLE:
if (!context_audio_data || !audio_active) if (!audio_driver_context_audio_data || !audio_driver_active)
return false; return false;
settings->audio.mute_enable = !settings->audio.mute_enable; settings->audio.mute_enable = !settings->audio.mute_enable;
@ -802,38 +803,38 @@ bool audio_driver_ctl(enum rarch_audio_ctl_state state, void *data)
event_command(EVENT_CMD_AUDIO_STOP); event_command(EVENT_CMD_AUDIO_STOP);
else if (!event_command(EVENT_CMD_AUDIO_START)) else if (!event_command(EVENT_CMD_AUDIO_START))
{ {
audio_active = false; audio_driver_active = false;
return false; return false;
} }
return true; return true;
case RARCH_AUDIO_CTL_ALIVE: case RARCH_AUDIO_CTL_ALIVE:
if (!context_audio_data) if (!audio_driver_context_audio_data)
return false; return false;
return current_audio->alive(context_audio_data); return current_audio->alive(audio_driver_context_audio_data);
case RARCH_AUDIO_CTL_START: case RARCH_AUDIO_CTL_START:
return current_audio->start(context_audio_data); return current_audio->start(audio_driver_context_audio_data);
case RARCH_AUDIO_CTL_STOP: case RARCH_AUDIO_CTL_STOP:
return current_audio->stop(context_audio_data); return current_audio->stop(audio_driver_context_audio_data);
case RARCH_AUDIO_CTL_FIND_DRIVER: case RARCH_AUDIO_CTL_FIND_DRIVER:
return find_audio_driver(); return find_audio_driver();
case RARCH_AUDIO_CTL_SET_OWN_DRIVER: case RARCH_AUDIO_CTL_SET_OWN_DRIVER:
audio_data_own = true; audio_driver_data_own = true;
break; break;
case RARCH_AUDIO_CTL_UNSET_OWN_DRIVER: case RARCH_AUDIO_CTL_UNSET_OWN_DRIVER:
audio_data_own = false; audio_driver_data_own = false;
break; break;
case RARCH_AUDIO_CTL_OWNS_DRIVER: case RARCH_AUDIO_CTL_OWNS_DRIVER:
return audio_data_own; return audio_driver_data_own;
case RARCH_AUDIO_CTL_SET_ACTIVE: case RARCH_AUDIO_CTL_SET_ACTIVE:
audio_active = true; audio_driver_active = true;
break; break;
case RARCH_AUDIO_CTL_UNSET_ACTIVE: case RARCH_AUDIO_CTL_UNSET_ACTIVE:
audio_active = false; audio_driver_active = false;
break; break;
case RARCH_AUDIO_CTL_FRAME_IS_REVERSE: case RARCH_AUDIO_CTL_FRAME_IS_REVERSE:
/* We just rewound. Flush rewind audio buffer. */ /* We just rewound. Flush rewind audio buffer. */
audio_driver_flush(audio_data.rewind_buf + audio_data.rewind_ptr, audio_driver_flush(audio_driver_data.rewind_buf + audio_driver_data.rewind_ptr,
audio_data.rewind_size - audio_data.rewind_ptr); audio_driver_data.rewind_size - audio_driver_data.rewind_ptr);
return true; return true;
} }