mirror of https://git.ffmpeg.org/ffmpeg.git
avfilter/af_aspectralstats: allow to select subset of measurements
This commit is contained in:
parent
37ee36f689
commit
504fbc2149
|
@ -2961,6 +2961,10 @@ Default is @code{hann}.
|
|||
Set window overlap. Allowed range is from @code{0}
|
||||
to @code{1}. Default value is @code{0.5}.
|
||||
|
||||
@item measure
|
||||
Select the parameters which are measured. The metadata keys can
|
||||
be used as flags, default is @option{all} which measures everything.
|
||||
@option{none} disables all measurement.
|
||||
@end table
|
||||
|
||||
A list of each metadata key follows:
|
||||
|
|
|
@ -29,6 +29,22 @@
|
|||
#include "internal.h"
|
||||
#include "window_func.h"
|
||||
|
||||
#define MEASURE_ALL UINT_MAX
|
||||
#define MEASURE_NONE 0
|
||||
#define MEASURE_MEAN (1 << 0)
|
||||
#define MEASURE_VARIANCE (1 << 1)
|
||||
#define MEASURE_CENTROID (1 << 2)
|
||||
#define MEASURE_SPREAD (1 << 3)
|
||||
#define MEASURE_SKEWNESS (1 << 4)
|
||||
#define MEASURE_KURTOSIS (1 << 5)
|
||||
#define MEASURE_ENTROPY (1 << 6)
|
||||
#define MEASURE_FLATNESS (1 << 7)
|
||||
#define MEASURE_CREST (1 << 8)
|
||||
#define MEASURE_FLUX (1 << 9)
|
||||
#define MEASURE_SLOPE (1 << 10)
|
||||
#define MEASURE_DECREASE (1 << 11)
|
||||
#define MEASURE_ROLLOFF (1 << 12)
|
||||
|
||||
typedef struct ChannelSpectralStats {
|
||||
float mean;
|
||||
float variance;
|
||||
|
@ -47,6 +63,7 @@ typedef struct ChannelSpectralStats {
|
|||
|
||||
typedef struct AudioSpectralStatsContext {
|
||||
const AVClass *class;
|
||||
unsigned measure;
|
||||
int win_size;
|
||||
int win_func;
|
||||
float overlap;
|
||||
|
@ -70,6 +87,22 @@ static const AVOption aspectralstats_options[] = {
|
|||
{ "win_size", "set the window size", OFFSET(win_size), AV_OPT_TYPE_INT, {.i64=2048}, 32, 65536, A },
|
||||
WIN_FUNC_OPTION("win_func", OFFSET(win_func), A, WFUNC_HANNING),
|
||||
{ "overlap", "set window overlap", OFFSET(overlap), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, A },
|
||||
{ "measure", "select the parameters which are measured", OFFSET(measure), AV_OPT_TYPE_FLAGS, {.i64=MEASURE_ALL}, 0, UINT_MAX, A, "measure" },
|
||||
{ "none", "", 0, AV_OPT_TYPE_CONST, {.i64=MEASURE_NONE }, 0, 0, A, "measure" },
|
||||
{ "all", "", 0, AV_OPT_TYPE_CONST, {.i64=MEASURE_ALL }, 0, 0, A, "measure" },
|
||||
{ "mean", "", 0, AV_OPT_TYPE_CONST, {.i64=MEASURE_MEAN }, 0, 0, A, "measure" },
|
||||
{ "variance", "", 0, AV_OPT_TYPE_CONST, {.i64=MEASURE_VARIANCE}, 0, 0, A, "measure" },
|
||||
{ "centroid", "", 0, AV_OPT_TYPE_CONST, {.i64=MEASURE_CENTROID}, 0, 0, A, "measure" },
|
||||
{ "spread", "", 0, AV_OPT_TYPE_CONST, {.i64=MEASURE_SPREAD }, 0, 0, A, "measure" },
|
||||
{ "skewness", "", 0, AV_OPT_TYPE_CONST, {.i64=MEASURE_SKEWNESS}, 0, 0, A, "measure" },
|
||||
{ "kurtosis", "", 0, AV_OPT_TYPE_CONST, {.i64=MEASURE_KURTOSIS}, 0, 0, A, "measure" },
|
||||
{ "entropy", "", 0, AV_OPT_TYPE_CONST, {.i64=MEASURE_ENTROPY }, 0, 0, A, "measure" },
|
||||
{ "flatness", "", 0, AV_OPT_TYPE_CONST, {.i64=MEASURE_FLATNESS}, 0, 0, A, "measure" },
|
||||
{ "crest", "", 0, AV_OPT_TYPE_CONST, {.i64=MEASURE_CREST }, 0, 0, A, "measure" },
|
||||
{ "flux", "", 0, AV_OPT_TYPE_CONST, {.i64=MEASURE_FLUX }, 0, 0, A, "measure" },
|
||||
{ "slope", "", 0, AV_OPT_TYPE_CONST, {.i64=MEASURE_SLOPE }, 0, 0, A, "measure" },
|
||||
{ "decrease", "", 0, AV_OPT_TYPE_CONST, {.i64=MEASURE_DECREASE}, 0, 0, A, "measure" },
|
||||
{ "rolloff", "", 0, AV_OPT_TYPE_CONST, {.i64=MEASURE_ROLLOFF }, 0, 0, A, "measure" },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
@ -166,19 +199,32 @@ static void set_metadata(AudioSpectralStatsContext *s, AVDictionary **metadata)
|
|||
for (int ch = 0; ch < s->nb_channels; ch++) {
|
||||
ChannelSpectralStats *stats = &s->stats[ch];
|
||||
|
||||
set_meta(metadata, ch + 1, "mean", "%g", stats->mean);
|
||||
set_meta(metadata, ch + 1, "variance", "%g", stats->variance);
|
||||
set_meta(metadata, ch + 1, "centroid", "%g", stats->centroid);
|
||||
set_meta(metadata, ch + 1, "spread", "%g", stats->spread);
|
||||
set_meta(metadata, ch + 1, "skewness", "%g", stats->skewness);
|
||||
set_meta(metadata, ch + 1, "kurtosis", "%g", stats->kurtosis);
|
||||
set_meta(metadata, ch + 1, "entropy", "%g", stats->entropy);
|
||||
set_meta(metadata, ch + 1, "flatness", "%g", stats->flatness);
|
||||
set_meta(metadata, ch + 1, "crest", "%g", stats->crest);
|
||||
set_meta(metadata, ch + 1, "flux", "%g", stats->flux);
|
||||
set_meta(metadata, ch + 1, "slope", "%g", stats->slope);
|
||||
set_meta(metadata, ch + 1, "decrease", "%g", stats->decrease);
|
||||
set_meta(metadata, ch + 1, "rolloff", "%g", stats->rolloff);
|
||||
if (s->measure & MEASURE_MEAN)
|
||||
set_meta(metadata, ch + 1, "mean", "%g", stats->mean);
|
||||
if (s->measure & MEASURE_VARIANCE)
|
||||
set_meta(metadata, ch + 1, "variance", "%g", stats->variance);
|
||||
if (s->measure & MEASURE_CENTROID)
|
||||
set_meta(metadata, ch + 1, "centroid", "%g", stats->centroid);
|
||||
if (s->measure & MEASURE_SPREAD)
|
||||
set_meta(metadata, ch + 1, "spread", "%g", stats->spread);
|
||||
if (s->measure & MEASURE_SKEWNESS)
|
||||
set_meta(metadata, ch + 1, "skewness", "%g", stats->skewness);
|
||||
if (s->measure & MEASURE_KURTOSIS)
|
||||
set_meta(metadata, ch + 1, "kurtosis", "%g", stats->kurtosis);
|
||||
if (s->measure & MEASURE_ENTROPY)
|
||||
set_meta(metadata, ch + 1, "entropy", "%g", stats->entropy);
|
||||
if (s->measure & MEASURE_FLATNESS)
|
||||
set_meta(metadata, ch + 1, "flatness", "%g", stats->flatness);
|
||||
if (s->measure & MEASURE_CREST)
|
||||
set_meta(metadata, ch + 1, "crest", "%g", stats->crest);
|
||||
if (s->measure & MEASURE_FLUX)
|
||||
set_meta(metadata, ch + 1, "flux", "%g", stats->flux);
|
||||
if (s->measure & MEASURE_SLOPE)
|
||||
set_meta(metadata, ch + 1, "slope", "%g", stats->slope);
|
||||
if (s->measure & MEASURE_DECREASE)
|
||||
set_meta(metadata, ch + 1, "decrease", "%g", stats->decrease);
|
||||
if (s->measure & MEASURE_ROLLOFF)
|
||||
set_meta(metadata, ch + 1, "rolloff", "%g", stats->rolloff);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -424,19 +470,32 @@ static int filter_channel(AVFilterContext *ctx, void *arg, int jobnr, int nb_job
|
|||
for (int n = 0; n < s->win_size / 2; n++)
|
||||
magnitude[n] = hypotf(fft_out[n].re, fft_out[n].im);
|
||||
|
||||
stats->mean = spectral_mean(magnitude, s->win_size / 2, in->sample_rate / 2);
|
||||
stats->variance = spectral_variance(magnitude, s->win_size / 2, in->sample_rate / 2, stats->mean);
|
||||
stats->centroid = spectral_centroid(magnitude, s->win_size / 2, in->sample_rate / 2);
|
||||
stats->spread = spectral_spread(magnitude, s->win_size / 2, in->sample_rate / 2, stats->centroid);
|
||||
stats->skewness = spectral_skewness(magnitude, s->win_size / 2, in->sample_rate / 2, stats->centroid, stats->spread);
|
||||
stats->kurtosis = spectral_kurtosis(magnitude, s->win_size / 2, in->sample_rate / 2, stats->centroid, stats->spread);
|
||||
stats->entropy = spectral_entropy(magnitude, s->win_size / 2, in->sample_rate / 2);
|
||||
stats->flatness = spectral_flatness(magnitude, s->win_size / 2, in->sample_rate / 2);
|
||||
stats->crest = spectral_crest(magnitude, s->win_size / 2, in->sample_rate / 2);
|
||||
stats->flux = spectral_flux(magnitude, prev_magnitude, s->win_size / 2, in->sample_rate / 2);
|
||||
stats->slope = spectral_slope(magnitude, s->win_size / 2, in->sample_rate / 2);
|
||||
stats->decrease = spectral_decrease(magnitude, s->win_size / 2, in->sample_rate / 2);
|
||||
stats->rolloff = spectral_rolloff(magnitude, s->win_size / 2, in->sample_rate / 2);
|
||||
if (s->measure & (MEASURE_MEAN | MEASURE_VARIANCE))
|
||||
stats->mean = spectral_mean(magnitude, s->win_size / 2, in->sample_rate / 2);
|
||||
if (s->measure & MEASURE_VARIANCE)
|
||||
stats->variance = spectral_variance(magnitude, s->win_size / 2, in->sample_rate / 2, stats->mean);
|
||||
if (s->measure & (MEASURE_SPREAD | MEASURE_KURTOSIS | MEASURE_SKEWNESS | MEASURE_CENTROID))
|
||||
stats->centroid = spectral_centroid(magnitude, s->win_size / 2, in->sample_rate / 2);
|
||||
if (s->measure & (MEASURE_SPREAD | MEASURE_KURTOSIS | MEASURE_SKEWNESS))
|
||||
stats->spread = spectral_spread(magnitude, s->win_size / 2, in->sample_rate / 2, stats->centroid);
|
||||
if (s->measure & MEASURE_SKEWNESS)
|
||||
stats->skewness = spectral_skewness(magnitude, s->win_size / 2, in->sample_rate / 2, stats->centroid, stats->spread);
|
||||
if (s->measure & MEASURE_KURTOSIS)
|
||||
stats->kurtosis = spectral_kurtosis(magnitude, s->win_size / 2, in->sample_rate / 2, stats->centroid, stats->spread);
|
||||
if (s->measure & MEASURE_ENTROPY)
|
||||
stats->entropy = spectral_entropy(magnitude, s->win_size / 2, in->sample_rate / 2);
|
||||
if (s->measure & MEASURE_FLATNESS)
|
||||
stats->flatness = spectral_flatness(magnitude, s->win_size / 2, in->sample_rate / 2);
|
||||
if (s->measure & MEASURE_CREST)
|
||||
stats->crest = spectral_crest(magnitude, s->win_size / 2, in->sample_rate / 2);
|
||||
if (s->measure & MEASURE_FLUX)
|
||||
stats->flux = spectral_flux(magnitude, prev_magnitude, s->win_size / 2, in->sample_rate / 2);
|
||||
if (s->measure & MEASURE_SLOPE)
|
||||
stats->slope = spectral_slope(magnitude, s->win_size / 2, in->sample_rate / 2);
|
||||
if (s->measure & MEASURE_DECREASE)
|
||||
stats->decrease = spectral_decrease(magnitude, s->win_size / 2, in->sample_rate / 2);
|
||||
if (s->measure & MEASURE_ROLLOFF)
|
||||
stats->rolloff = spectral_rolloff(magnitude, s->win_size / 2, in->sample_rate / 2);
|
||||
|
||||
memcpy(prev_magnitude, magnitude, s->win_size * sizeof(float));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue