From 12791ec5b0d3653ad2a453d20368229f53df65c4 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Wed, 19 Jul 2017 20:44:14 +0200 Subject: [PATCH] avfilter/af_astats: measure dynamic range Signed-off-by: Paul B Mahol --- doc/filters.texi | 4 ++++ libavfilter/af_astats.c | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/doc/filters.texi b/doc/filters.texi index dd88636bb9..119d1be69d 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -1623,6 +1623,7 @@ Crest_factor Flat_factor Peak_count Bit_depth +Dynamic_range and for Overall: DC_offset @@ -1697,6 +1698,9 @@ Number of occasions (not the number of samples) that the signal attained either @item Bit depth Overall bit depth of audio. Number of bits used for each sample. + +@item Dynamic range +Measured dynamic range of audio in dB. @end table @section atempo diff --git a/libavfilter/af_astats.c b/libavfilter/af_astats.c index 41fec156a3..2922da9f44 100644 --- a/libavfilter/af_astats.c +++ b/libavfilter/af_astats.c @@ -28,6 +28,7 @@ typedef struct ChannelStats { double last; + double min_non_zero; double sigma_x, sigma_x2; double avg_sigma_x2, min_sigma_x2, max_sigma_x2; double min, max; @@ -110,6 +111,7 @@ static void reset_stats(AudioStatsContext *s) p->min = p->nmin = p->min_sigma_x2 = DBL_MAX; p->max = p->nmax = p->max_sigma_x2 = DBL_MIN; + p->min_non_zero = DBL_MAX; p->min_diff = DBL_MAX; p->max_diff = DBL_MIN; p->sigma_x = 0; @@ -178,6 +180,9 @@ static inline void update_stat(AudioStatsContext *s, ChannelStats *p, double d, p->min_runs += p->min_run * p->min_run; } + if (d != 0 && FFABS(d) < p->min_non_zero) + p->min_non_zero = FFABS(d); + if (d > p->max) { p->max = d; p->nmax = nd; @@ -286,6 +291,7 @@ static void set_metadata(AudioStatsContext *s, AVDictionary **metadata) bit_depth(s, p->mask, p->imask, &depth); set_meta(metadata, c + 1, "Bit_depth", "%f", depth.num); set_meta(metadata, c + 1, "Bit_depth2", "%f", depth.den); + set_meta(metadata, c + 1, "Dynamic_range", "%f", LINEAR_TO_DB(2 * FFMAX(FFABS(p->min), FFABS(p->max))/ p->min_non_zero)); } set_meta(metadata, 0, "Overall.DC_offset", "%f", max_sigma_x / (nb_samples / s->nb_channels)); @@ -479,6 +485,7 @@ static void print_stats(AVFilterContext *ctx) av_log(ctx, AV_LOG_INFO, "Peak count: %"PRId64"\n", p->min_count + p->max_count); bit_depth(s, p->mask, p->imask, &depth); av_log(ctx, AV_LOG_INFO, "Bit depth: %u/%u\n", depth.num, depth.den); + av_log(ctx, AV_LOG_INFO, "Dynamic range: %f\n", LINEAR_TO_DB(2 * FFMAX(FFABS(p->min), FFABS(p->max))/ p->min_non_zero)); } av_log(ctx, AV_LOG_INFO, "Overall\n");