From 38ec55573c50179a05dfd7012120fd34094e8c08 Mon Sep 17 00:00:00 2001 From: Themaister Date: Sat, 14 Sep 2013 17:26:10 +0200 Subject: [PATCH] Rework SET_AUDIO_CALLBACK. When disabling audio and/or muting, the core has no way of knowing this, causing potential issues in a threaded mixer. This environ is not used by any public core to my knowledge so the old API has been removed and replaced with a change to environment number (20 -> 22). --- audio/thread_wrapper.c | 4 +++- driver.c | 6 +++--- dynamic.c | 2 +- general.h | 3 ++- libretro.h | 11 ++++++++++- retroarch.c | 2 +- 6 files changed, 20 insertions(+), 8 deletions(-) diff --git a/audio/thread_wrapper.c b/audio/thread_wrapper.c index 0c762aa15f..f507ff89ee 100644 --- a/audio/thread_wrapper.c +++ b/audio/thread_wrapper.c @@ -57,7 +57,7 @@ static void audio_thread_loop(void *data) } slock_unlock(thr->lock); - g_extern.system.audio_callback(); + g_extern.system.audio_callback.callback(); } } @@ -98,12 +98,14 @@ static bool audio_thread_stop(void *data) { audio_thread_t *thr = (audio_thread_t*)data; audio_thread_block(thr); + g_extern.system.audio_callback.set_state(false); return true; } static bool audio_thread_start(void *data) { audio_thread_t *thr = (audio_thread_t*)data; + g_extern.system.audio_callback.set_state(true); audio_thread_unblock(thr); return true; } diff --git a/driver.c b/driver.c index 20273357bd..5397b3629b 100644 --- a/driver.c +++ b/driver.c @@ -512,7 +512,7 @@ void init_audio(void) #ifdef HAVE_THREADS find_audio_driver(); - if (g_extern.system.audio_callback) + if (g_extern.system.audio_callback.callback) { RARCH_LOG("Starting threaded audio driver ...\n"); if (!rarch_threaded_audio_init(&driver.audio, &driver.audio_data, @@ -566,7 +566,7 @@ void init_audio(void) rarch_assert(g_extern.audio_data.outsamples = (float*)malloc(outsamples_max * sizeof(float))); g_extern.audio_data.rate_control = false; - if (!g_extern.system.audio_callback && g_extern.audio_active && g_settings.audio.rate_control) + if (!g_extern.system.audio_callback.callback && g_extern.audio_active && g_settings.audio.rate_control) { if (driver.audio->buffer_size && driver.audio->write_avail) { @@ -586,7 +586,7 @@ void init_audio(void) g_extern.measure_data.buffer_free_samples_count = 0; - if (g_extern.audio_active && !g_extern.audio_data.mute && g_extern.system.audio_callback) // Threaded driver is initially stopped. + if (g_extern.audio_active && !g_extern.audio_data.mute && g_extern.system.audio_callback.callback) // Threaded driver is initially stopped. audio_start_func(); } diff --git a/dynamic.c b/dynamic.c index 2f789ee5d6..d1b356e067 100644 --- a/dynamic.c +++ b/dynamic.c @@ -737,7 +737,7 @@ bool rarch_environment_cb(unsigned cmd, void *data) return false; #endif - g_extern.system.audio_callback = info->callback; + g_extern.system.audio_callback = *info; break; } #endif diff --git a/general.h b/general.h index 0d187b688b..5632ba6086 100644 --- a/general.h +++ b/general.h @@ -396,7 +396,8 @@ struct global char valid_extensions[PATH_MAX]; retro_keyboard_event_t key_event; - retro_audio_callback_t audio_callback; + + struct retro_audio_callback audio_callback; struct retro_disk_control_callback disk_control; struct retro_hw_render_callback hw_render_callback; diff --git a/libretro.h b/libretro.h index 7b767fe6eb..8d23356138 100755 --- a/libretro.h +++ b/libretro.h @@ -489,7 +489,10 @@ enum retro_mod // NULL is returned if the libretro was loaded statically (i.e. linked statically to frontend), or if the path cannot be determined. // Mostly useful in cooperation with SET_SUPPORT_NO_GAME as assets can be loaded without ugly hacks. // -#define RETRO_ENVIRONMENT_SET_AUDIO_CALLBACK 20 + // +// Environment 20 was an obsolete version of SET_AUDIO_CALLBACK. It was not used by any known core at the time, +// and was removed from the API. +#define RETRO_ENVIRONMENT_SET_AUDIO_CALLBACK 22 // const struct retro_audio_callback * -- // Sets an interface which is used to notify a libretro core about audio being available for writing. // The callback can be called from any thread, so a core using this must have a thread safe audio implementation. @@ -515,9 +518,15 @@ enum retro_mod // Notifies libretro that audio data should be written. typedef void (*retro_audio_callback_t)(void); + +// True: Audio driver in frontend is active, and callback is expected to be called regularily. +// False: Audio driver in frontend is paused or inactive. Audio callback will not be called until set_state has been called with true. +// Initial state is false (inactive). +typedef void (*retro_audio_set_state_callback_t)(bool enabled); struct retro_audio_callback { retro_audio_callback_t callback; + retro_audio_set_state_callback_t set_state; }; // Notifies a libretro core of time spent since last invocation of retro_run() in microseconds. diff --git a/retroarch.c b/retroarch.c index 2c119948ff..2cc5a7e750 100644 --- a/retroarch.c +++ b/retroarch.c @@ -1434,7 +1434,7 @@ void rarch_init_rewind(void) if (!g_settings.rewind_enable || g_extern.state_manager) return; - if (g_extern.system.audio_callback) + if (g_extern.system.audio_callback.callback) { RARCH_ERR("Implementation uses threaded audio. Cannot use rewind.\n"); return;