1
0
Fork 0

avfilter: add tiltshelf audio filter

This commit is contained in:
Paul B Mahol 2022-05-25 11:13:32 +02:00
parent fab9130c7a
commit 525f83becd
5 changed files with 127 additions and 7 deletions

View File

@ -17,6 +17,7 @@ version 5.1:
- multiply video filter
- PGS subtitle frame merge bitstream filter
- blurdetect filter
- tiltshelf audio filter
version 5.0:

View File

@ -6690,6 +6690,97 @@ Set window overlap. If set to 1, the recommended overlap for selected
window function will be picked. Default is @code{0.5}.
@end table
@section tiltshelf
Boost or cut the lower frequencies and cut or boost higher frequencies
of the audio using a two-pole shelving filter with a response similar to
that of a standard hi-fi's tone-controls.
This is also known as shelving equalisation (EQ).
The filter accepts the following options:
@table @option
@item gain, g
Give the gain at 0 Hz. Its useful range is about -20
(for a large cut) to +20 (for a large boost).
Beware of clipping when using a positive gain.
@item frequency, f
Set the filter's central frequency and so can be used
to extend or reduce the frequency range to be boosted or cut.
The default value is @code{3000} Hz.
@item width_type, t
Set method to specify band-width of filter.
@table @option
@item h
Hz
@item q
Q-Factor
@item o
octave
@item s
slope
@item k
kHz
@end table
@item width, w
Determine how steep is the filter's shelf transition.
@item poles, p
Set number of poles. Default is 2.
@item mix, m
How much to use filtered signal in output. Default is 1.
Range is between 0 and 1.
@item channels, c
Specify which channels to filter, by default all available are filtered.
@item normalize, n
Normalize biquad coefficients, by default is disabled.
Enabling it will normalize magnitude response at DC to 0dB.
@item transform, a
Set transform type of IIR filter.
@table @option
@item di
@item dii
@item tdi
@item tdii
@item latt
@item svf
@item zdf
@end table
@item precision, r
Set precison of filtering.
@table @option
@item auto
Pick automatic sample format depending on surround filters.
@item s16
Always use signed 16-bit.
@item s32
Always use signed 32-bit.
@item f32
Always use float 32-bit.
@item f64
Always use float 64-bit.
@end table
@item block_size, b
Set block size used for reverse IIR processing. If this value is set to high enough
value (higher than impulse response length truncated when reaches near zero values) filtering
will become linear phase otherwise if not big enough it will just produce nasty artifacts.
Note that filter delay will be exactly this many samples when set to non-zero value.
@end table
@subsection Commands
This filter supports some options as @ref{commands}.
@section treble, highshelf
Boost or cut treble (upper) frequencies of the audio using a two-pole

View File

@ -85,6 +85,7 @@ enum FilterType {
lowpass,
lowshelf,
highshelf,
tiltshelf,
};
enum WidthType {
@ -698,6 +699,17 @@ static void convert_dir2zdf(BiquadsContext *s, int sample_rate)
m[1] = k * (A - 1.);
m[2] = A * A - 1.;
break;
case tiltshelf:
A = ff_exp10(s->gain / 20.);
g = tan(M_PI * s->frequency / sample_rate) / sqrt(A);
k = 1. / Q;
a[0] = 1. / (1. + g * (g + k));
a[1] = g * a[0];
a[2] = g * a[1];
m[0] = 1./ A;
m[1] = k * (A - 1.) / A;
m[2] = (A * A - 1.) / A;
break;
case treble:
case highshelf:
A = ff_exp10(s->gain / 40.);
@ -777,7 +789,8 @@ static int config_filter(AVFilterLink *outlink, int reset)
AVFilterContext *ctx = outlink->src;
BiquadsContext *s = ctx->priv;
AVFilterLink *inlink = ctx->inputs[0];
double A = ff_exp10(s->gain / 40);
double gain = s->gain * ((s->filter_type == tiltshelf) + 1.);
double A = ff_exp10(gain / 40);
double w0 = 2 * M_PI * s->frequency / inlink->sample_rate;
double K = tan(w0 / 2.);
double alpha, beta;
@ -835,9 +848,10 @@ static int config_filter(AVFilterLink *outlink, int reset)
break;
case bass:
beta = sqrt((A * A + 1) - (A - 1) * (A - 1));
case tiltshelf:
case lowshelf:
if (s->poles == 1) {
double A = ff_exp10(s->gain / 20);
double A = ff_exp10(gain / 20);
double ro = -sin(w0 / 2. - M_PI_4) / sin(w0 / 2. + M_PI_4);
double n = (A + 1) / (A - 1);
double alpha1 = A == 1. ? 0. : n - FFSIGN(n) * sqrt(n * n - 1);
@ -863,7 +877,7 @@ static int config_filter(AVFilterLink *outlink, int reset)
beta = sqrt((A * A + 1) - (A - 1) * (A - 1));
case highshelf:
if (s->poles == 1) {
double A = ff_exp10(s->gain / 20);
double A = ff_exp10(gain / 20);
double ro = sin(w0 / 2. - M_PI_4) / sin(w0 / 2. + M_PI_4);
double n = (A + 1) / (A - 1);
double alpha1 = A == 1. ? 0. : n - FFSIGN(n) * sqrt(n * n - 1);
@ -985,6 +999,14 @@ static int config_filter(AVFilterLink *outlink, int reset)
s->b2 *= factor;
}
switch (s->filter_type) {
case tiltshelf:
s->b0 /= A;
s->b1 /= A;
s->b2 /= A;
break;
}
s->cache = av_realloc_f(s->cache, sizeof(ChanCache), inlink->ch_layout.nb_channels);
if (!s->cache)
return AVERROR(ENOMEM);
@ -1528,7 +1550,7 @@ DEFINE_BIQUAD_FILTER_2(bass, "Boost or cut lower frequencies.", bass_lowshelf);
DEFINE_BIQUAD_FILTER_2(lowshelf, "Apply a low shelf filter.", bass_lowshelf);
#endif /* CONFIG_LOWSHELF_FILTER */
#endif /* CONFIG_BASS_FILTER || CONFIG LOWSHELF_FILTER */
#if CONFIG_TREBLE_FILTER || CONFIG_HIGHSHELF_FILTER
#if CONFIG_TREBLE_FILTER || CONFIG_HIGHSHELF_FILTER || CONFIG_TILTSHELF_FILTER
static const AVOption treble_highshelf_options[] = {
{"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
{"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
@ -1572,7 +1594,7 @@ static const AVOption treble_highshelf_options[] = {
{NULL}
};
AVFILTER_DEFINE_CLASS_EXT(treble_highshelf, "treble/highshelf",
AVFILTER_DEFINE_CLASS_EXT(treble_highshelf, "treble/high/tiltshelf",
treble_highshelf_options);
#if CONFIG_TREBLE_FILTER
@ -1582,7 +1604,12 @@ DEFINE_BIQUAD_FILTER_2(treble, "Boost or cut upper frequencies.", treble_highshe
#if CONFIG_HIGHSHELF_FILTER
DEFINE_BIQUAD_FILTER_2(highshelf, "Apply a high shelf filter.", treble_highshelf);
#endif /* CONFIG_HIGHSHELF_FILTER */
#endif /* CONFIG_TREBLE_FILTER || CONFIG_HIGHSHELF_FILTER */
#if CONFIG_TILTSHELF_FILTER
DEFINE_BIQUAD_FILTER_2(tiltshelf, "Apply a tilt shelf filter.", treble_highshelf);
#endif
#endif /* CONFIG_TREBLE_FILTER || CONFIG_HIGHSHELF_FILTER || CONFIG_TILTSHELF_FILTER */
#if CONFIG_BANDPASS_FILTER
static const AVOption bandpass_options[] = {
{"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},

View File

@ -149,6 +149,7 @@ extern const AVFilter ff_af_stereotools;
extern const AVFilter ff_af_stereowiden;
extern const AVFilter ff_af_superequalizer;
extern const AVFilter ff_af_surround;
extern const AVFilter ff_af_tiltshelf;
extern const AVFilter ff_af_treble;
extern const AVFilter ff_af_tremolo;
extern const AVFilter ff_af_vibrato;

View File

@ -31,7 +31,7 @@
#include "version_major.h"
#define LIBAVFILTER_VERSION_MINOR 39
#define LIBAVFILTER_VERSION_MINOR 40
#define LIBAVFILTER_VERSION_MICRO 100