mirror of
https://github.com/libretro/RetroArch
synced 2025-03-03 13:14:04 +00:00
Create public function compute_audio_buffer_statistics
This commit is contained in:
parent
647f1a48a6
commit
9343eacc0a
@ -146,10 +146,8 @@ static size_t audio_driver_rewind_size = 0;
|
|||||||
static int16_t *audio_driver_rewind_buf = NULL;
|
static int16_t *audio_driver_rewind_buf = NULL;
|
||||||
static int16_t *audio_driver_output_samples_conv_buf = NULL;
|
static int16_t *audio_driver_output_samples_conv_buf = NULL;
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
static unsigned audio_driver_free_samples_buf[AUDIO_BUFFER_FREE_SAMPLES_COUNT];
|
static unsigned audio_driver_free_samples_buf[AUDIO_BUFFER_FREE_SAMPLES_COUNT];
|
||||||
static uint64_t audio_driver_free_samples_count = 0;
|
static uint64_t audio_driver_free_samples_count = 0;
|
||||||
#endif
|
|
||||||
|
|
||||||
static size_t audio_driver_buffer_size = 0;
|
static size_t audio_driver_buffer_size = 0;
|
||||||
static size_t audio_driver_data_ptr = 0;
|
static size_t audio_driver_data_ptr = 0;
|
||||||
@ -195,18 +193,15 @@ enum resampler_quality audio_driver_get_resampler_quality(void)
|
|||||||
return (enum resampler_quality)settings->uints.audio_resampler_quality;
|
return (enum resampler_quality)settings->uints.audio_resampler_quality;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
/**
|
/**
|
||||||
* compute_audio_buffer_statistics:
|
* compute_audio_buffer_statistics:
|
||||||
*
|
*
|
||||||
* Computes audio buffer statistics.
|
* Computes audio buffer statistics.
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
static void compute_audio_buffer_statistics(void)
|
bool compute_audio_buffer_statistics(audio_statistics_t *stats)
|
||||||
{
|
{
|
||||||
unsigned i, low_water_size, high_water_size, avg, stddev;
|
unsigned i, low_water_size, high_water_size, avg, stddev;
|
||||||
float avg_filled = 0.0f;
|
|
||||||
float deviation = 0.0f;
|
|
||||||
uint64_t accum = 0;
|
uint64_t accum = 0;
|
||||||
uint64_t accum_var = 0;
|
uint64_t accum_var = 0;
|
||||||
unsigned low_water_count = 0;
|
unsigned low_water_count = 0;
|
||||||
@ -215,9 +210,21 @@ static void compute_audio_buffer_statistics(void)
|
|||||||
(unsigned)audio_driver_free_samples_count,
|
(unsigned)audio_driver_free_samples_count,
|
||||||
AUDIO_BUFFER_FREE_SAMPLES_COUNT);
|
AUDIO_BUFFER_FREE_SAMPLES_COUNT);
|
||||||
|
|
||||||
if (samples < 3)
|
if (samples < 3 || !stats)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
|
stats->average_buffer_saturation = 0.0;
|
||||||
|
stats->std_deviation_percentage = 0.0f;
|
||||||
|
#ifdef WARPUP
|
||||||
|
/* uint64 to double not implemented, fair chance
|
||||||
|
* signed int64 to double doesn't exist either */
|
||||||
|
/* https://forums.libretro.com/t/unsupported-platform-help/13903/ */
|
||||||
|
(void)stddev;
|
||||||
|
#elif defined(_MSC_VER) && _MSC_VER <= 1200
|
||||||
|
/* FIXME: error C2520: conversion from unsigned __int64
|
||||||
|
* to double not implemented, use signed __int64 */
|
||||||
|
(void)stddev;
|
||||||
|
#else
|
||||||
for (i = 1; i < samples; i++)
|
for (i = 1; i < samples; i++)
|
||||||
accum += audio_driver_free_samples_buf[i];
|
accum += audio_driver_free_samples_buf[i];
|
||||||
|
|
||||||
@ -225,24 +232,17 @@ static void compute_audio_buffer_statistics(void)
|
|||||||
|
|
||||||
for (i = 1; i < samples; i++)
|
for (i = 1; i < samples; i++)
|
||||||
{
|
{
|
||||||
int diff = avg - audio_driver_free_samples_buf[i];
|
int diff = avg - audio_driver_free_samples_buf[i];
|
||||||
accum_var += diff * diff;
|
accum_var += diff * diff;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WARPUP
|
stddev = (unsigned)
|
||||||
/* uint64 to double not implemented, fair chance signed int64 to double doesn't exist either */
|
sqrt((double)accum_var / (samples - 2));
|
||||||
/* https://forums.libretro.com/t/unsupported-platform-help/13903/ */
|
|
||||||
(void)stddev; (void)avg_filled; (void)deviation;
|
|
||||||
#elif defined(_MSC_VER) && _MSC_VER <= 1200
|
|
||||||
/* FIXME: error C2520: conversion from unsigned __int64 to double not implemented, use signed __int64 */
|
|
||||||
(void)stddev; (void)avg_filled; (void)deviation;
|
|
||||||
#else
|
|
||||||
stddev = (unsigned)sqrt((double)accum_var / (samples - 2));
|
|
||||||
avg_filled = 1.0f - (float)avg / audio_driver_buffer_size;
|
|
||||||
deviation = (float)stddev / audio_driver_buffer_size;
|
|
||||||
|
|
||||||
RARCH_LOG("[Audio]: Average audio buffer saturation: %.2f %%, standard deviation (percentage points): %.2f %%.\n",
|
stats->average_buffer_saturation = (1.0f - (float)avg
|
||||||
avg_filled * 100.0, deviation * 100.0);
|
/ audio_driver_buffer_size) * 100.0;
|
||||||
|
stats->std_deviation_percentage = ((float)stddev
|
||||||
|
/ audio_driver_buffer_size) * 100.0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
low_water_size = (unsigned)(audio_driver_buffer_size * 3 / 4);
|
low_water_size = (unsigned)(audio_driver_buffer_size * 3 / 4);
|
||||||
@ -256,11 +256,29 @@ static void compute_audio_buffer_statistics(void)
|
|||||||
high_water_count++;
|
high_water_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
RARCH_LOG("[Audio]: Amount of time spent close to underrun: %.2f %%. Close to blocking: %.2f %%.\n",
|
stats->close_to_underrun = (100.0 * low_water_count) / (samples - 1);
|
||||||
(100.0 * low_water_count) / (samples - 1),
|
stats->close_to_blocking = (100.0 * high_water_count) / (samples - 1);
|
||||||
(100.0 * high_water_count) / (samples - 1));
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void report_audio_buffer_statistics(void)
|
||||||
|
{
|
||||||
|
audio_statistics_t audio_stats;
|
||||||
|
if (!compute_audio_buffer_statistics(&audio_stats))
|
||||||
|
return;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
RARCH_LOG("[Audio]: Average audio buffer saturation: %.2f %%,"
|
||||||
|
" standard deviation (percentage points): %.2f %%.\n"
|
||||||
|
"[Audio]: Amount of time spent close to underrun: %.2f %%."
|
||||||
|
" Close to blocking: %.2f %%.\n",
|
||||||
|
audio_stats.average_buffer_saturation,
|
||||||
|
audio_stats.std_deviation_percentage,
|
||||||
|
audio_stats.close_to_underrun,
|
||||||
|
audio_stats.close_to_blocking);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* audio_driver_find_handle:
|
* audio_driver_find_handle:
|
||||||
@ -345,9 +363,7 @@ static bool audio_driver_deinit_internal(void)
|
|||||||
|
|
||||||
command_event(CMD_EVENT_DSP_FILTER_DEINIT, NULL);
|
command_event(CMD_EVENT_DSP_FILTER_DEINIT, NULL);
|
||||||
|
|
||||||
#ifdef DEBUG
|
report_audio_buffer_statistics();
|
||||||
compute_audio_buffer_statistics();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,14 @@ enum audio_action
|
|||||||
AUDIO_ACTION_MIXER
|
AUDIO_ACTION_MIXER
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct audio_statistics
|
||||||
|
{
|
||||||
|
float average_buffer_saturation;
|
||||||
|
float std_deviation_percentage;
|
||||||
|
float close_to_underrun;
|
||||||
|
float close_to_blocking;
|
||||||
|
} audio_statistics_t;
|
||||||
|
|
||||||
typedef struct audio_driver
|
typedef struct audio_driver
|
||||||
{
|
{
|
||||||
/* Creates and initializes handle to audio driver.
|
/* Creates and initializes handle to audio driver.
|
||||||
@ -266,6 +274,8 @@ bool audio_driver_mixer_add_stream(audio_mixer_stream_params_t *params);
|
|||||||
|
|
||||||
enum resampler_quality audio_driver_get_resampler_quality(void);
|
enum resampler_quality audio_driver_get_resampler_quality(void);
|
||||||
|
|
||||||
|
bool compute_audio_buffer_statistics(audio_statistics_t *stats);
|
||||||
|
|
||||||
extern audio_driver_t audio_rsound;
|
extern audio_driver_t audio_rsound;
|
||||||
extern audio_driver_t audio_oss;
|
extern audio_driver_t audio_oss;
|
||||||
extern audio_driver_t audio_alsa;
|
extern audio_driver_t audio_alsa;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user