From 019959a0124cad79efd2260a1c8c945c8c10f657 Mon Sep 17 00:00:00 2001 From: Themaister Date: Fri, 18 Jan 2013 10:38:43 +0100 Subject: [PATCH 1/2] Add audio buffer statistics measurement. --- driver.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ general.h | 4 ++++ retroarch.c | 3 +++ 3 files changed, 55 insertions(+) diff --git a/driver.c b/driver.c index 6f1a387b87..28a360c2cf 100644 --- a/driver.c +++ b/driver.c @@ -434,6 +434,52 @@ void init_audio(void) #ifdef HAVE_DYLIB init_dsp_plugin(); #endif + + g_extern.audio_data.buffer_free_samples_count = 0; +} + +static void compute_audio_buffer_statistics(void) +{ + unsigned samples = min(g_extern.audio_data.buffer_free_samples_count, AUDIO_BUFFER_FREE_SAMPLES_COUNT); + if (!samples) + return; + + uint64_t accum = 0; + for (unsigned i = 0; i < samples; i++) + accum += g_extern.audio_data.buffer_free_samples[i]; + + int avg = accum / samples; + + uint64_t accum_var = 0; + for (unsigned i = 0; i < samples; i++) + { + int diff = avg - g_extern.audio_data.buffer_free_samples[i]; + accum_var += diff * diff; + } + + unsigned stddev = (unsigned)sqrtf((float)accum_var / samples); + + float avg_filled = 1.0f - (float)avg / g_extern.audio_data.driver_buffer_size; + float deviation = (float)stddev / g_extern.audio_data.driver_buffer_size; + + unsigned low_water_size = g_extern.audio_data.driver_buffer_size * 3 / 4; + unsigned high_water_size = g_extern.audio_data.driver_buffer_size / 4; + + unsigned low_water_count = 0; + unsigned high_water_count = 0; + for (unsigned i = 0; i < samples; i++) + { + if (g_extern.audio_data.buffer_free_samples[i] >= low_water_size) + low_water_count++; + else if (g_extern.audio_data.buffer_free_samples[i] <= high_water_size) + high_water_count++; + } + + RARCH_LOG("Average audio buffer saturation: %.2f %%, standard deviation (percentage points): %.2f %%.\n", + avg_filled * 100.0, deviation * 100.0); + RARCH_LOG("Amount of time spent close to underrun: %.2f %%. Close to blocking: %.2f %%.\n", + (100.0 * low_water_count) / samples, + (100.0 * high_water_count) / samples); } void uninit_audio(void) @@ -466,6 +512,8 @@ void uninit_audio(void) #ifdef HAVE_DYLIB deinit_dsp_plugin(); #endif + + compute_audio_buffer_statistics(); } #ifdef HAVE_DYLIB diff --git a/general.h b/general.h index d456a76592..38275bb9c3 100644 --- a/general.h +++ b/general.h @@ -401,6 +401,10 @@ struct global float volume_db; float volume_gain; + +#define AUDIO_BUFFER_FREE_SAMPLES_COUNT (8 * 1024) + unsigned buffer_free_samples[AUDIO_BUFFER_FREE_SAMPLES_COUNT]; + uint64_t buffer_free_samples_count; } audio_data; struct diff --git a/retroarch.c b/retroarch.c index f1c40397fa..fbf78512b8 100644 --- a/retroarch.c +++ b/retroarch.c @@ -182,6 +182,9 @@ static void readjust_audio_input_rate(void) //RARCH_LOG_OUTPUT("Audio buffer is %u%% full\n", // (unsigned)(100 - (avail * 100) / g_extern.audio_data.driver_buffer_size)); + unsigned write_index = (g_extern.audio_data.buffer_free_samples_count++) & (AUDIO_BUFFER_FREE_SAMPLES_COUNT - 1); + g_extern.audio_data.buffer_free_samples[write_index] = avail; + int half_size = g_extern.audio_data.driver_buffer_size / 2; int delta_mid = avail - half_size; double direction = (double)delta_mid / half_size; From b7b569d4eaf26f79dd22c71e4a17919874a209bb Mon Sep 17 00:00:00 2001 From: Themaister Date: Fri, 18 Jan 2013 11:14:38 +0100 Subject: [PATCH 2/2] Actually use POT size in SL. --- audio/opensl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/audio/opensl.c b/audio/opensl.c index 4be267542e..c2ab6bea2a 100644 --- a/audio/opensl.c +++ b/audio/opensl.c @@ -34,7 +34,7 @@ #define SLPlayItf_SetPlayState(a, ...) ((*(a))->SetPlayState(a, __VA_ARGS__)) // TODO: Are these sane? -#define BUFFER_SIZE 8092 +#define BUFFER_SIZE 8192 #define BUFFER_COUNT 4 typedef struct sl