Commit 12791ec5 authored by Paul B Mahol's avatar Paul B Mahol

avfilter/af_astats: measure dynamic range

Signed-off-by: 's avatarPaul B Mahol <onemda@gmail.com>
parent cb13f448
...@@ -1623,6 +1623,7 @@ Crest_factor ...@@ -1623,6 +1623,7 @@ Crest_factor
Flat_factor Flat_factor
Peak_count Peak_count
Bit_depth Bit_depth
Dynamic_range
and for Overall: and for Overall:
DC_offset DC_offset
...@@ -1697,6 +1698,9 @@ Number of occasions (not the number of samples) that the signal attained either ...@@ -1697,6 +1698,9 @@ Number of occasions (not the number of samples) that the signal attained either
@item Bit depth @item Bit depth
Overall bit depth of audio. Number of bits used for each sample. Overall bit depth of audio. Number of bits used for each sample.
@item Dynamic range
Measured dynamic range of audio in dB.
@end table @end table
@section atempo @section atempo
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
typedef struct ChannelStats { typedef struct ChannelStats {
double last; double last;
double min_non_zero;
double sigma_x, sigma_x2; double sigma_x, sigma_x2;
double avg_sigma_x2, min_sigma_x2, max_sigma_x2; double avg_sigma_x2, min_sigma_x2, max_sigma_x2;
double min, max; double min, max;
...@@ -110,6 +111,7 @@ static void reset_stats(AudioStatsContext *s) ...@@ -110,6 +111,7 @@ static void reset_stats(AudioStatsContext *s)
p->min = p->nmin = p->min_sigma_x2 = DBL_MAX; p->min = p->nmin = p->min_sigma_x2 = DBL_MAX;
p->max = p->nmax = p->max_sigma_x2 = DBL_MIN; p->max = p->nmax = p->max_sigma_x2 = DBL_MIN;
p->min_non_zero = DBL_MAX;
p->min_diff = DBL_MAX; p->min_diff = DBL_MAX;
p->max_diff = DBL_MIN; p->max_diff = DBL_MIN;
p->sigma_x = 0; p->sigma_x = 0;
...@@ -178,6 +180,9 @@ static inline void update_stat(AudioStatsContext *s, ChannelStats *p, double d, ...@@ -178,6 +180,9 @@ static inline void update_stat(AudioStatsContext *s, ChannelStats *p, double d,
p->min_runs += p->min_run * p->min_run; 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) { if (d > p->max) {
p->max = d; p->max = d;
p->nmax = nd; p->nmax = nd;
...@@ -286,6 +291,7 @@ static void set_metadata(AudioStatsContext *s, AVDictionary **metadata) ...@@ -286,6 +291,7 @@ static void set_metadata(AudioStatsContext *s, AVDictionary **metadata)
bit_depth(s, p->mask, p->imask, &depth); bit_depth(s, p->mask, p->imask, &depth);
set_meta(metadata, c + 1, "Bit_depth", "%f", depth.num); 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, "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)); 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) ...@@ -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); av_log(ctx, AV_LOG_INFO, "Peak count: %"PRId64"\n", p->min_count + p->max_count);
bit_depth(s, p->mask, p->imask, &depth); 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, "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"); av_log(ctx, AV_LOG_INFO, "Overall\n");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment