2 * Copyright (c) 2013 Paul B Mahol
3 * Copyright (c) 2006-2008 Rob Sykes <robs@users.sourceforge.net>
5 * This file is part of FFmpeg.
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 * 2-pole filters designed by Robert Bristow-Johnson <rbj@audioimagination.com>
24 * see http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt
26 * 1-pole filters based on code (c) 2000 Chris Bagwell <cbagwell@sprynet.com>
27 * Algorithms: Recursive single pole low/high pass filter
28 * Reference: The Scientist and Engineer's Guide to Digital Signal Processing
30 * low-pass: output[N] = input[N] * A + output[N-1] * B
31 * X = exp(-2.0 * pi * Fc)
34 * Fc = cutoff freq / sample rate
36 * Mimics an RC low-pass filter:
38 * ---/\/\/\/\----------->
46 * high-pass: output[N] = A0 * input[N] + A1 * input[N-1] + B1 * output[N-1]
47 * X = exp(-2.0 * pi * Fc)
51 * Fc = cutoff freq / sample rate
53 * Mimics an RC high-pass filter:
65 #include "config_components.h"
67 #include "libavutil/avassert.h"
68 #include "libavutil/channel_layout.h"
69 #include "libavutil/ffmath.h"
70 #include "libavutil/mem.h"
71 #include "libavutil/opt.h"
113 typedef struct BiquadsContext
{
114 const AVClass
*class;
116 enum FilterType filter_type
;
131 AVChannelLayout ch_layout
;
153 void (*filter
)(struct BiquadsContext
*s
, const void *ibuf
, void *obuf
, int len
,
154 void *cache
, int *clip
, int disabled
);
157 static int query_formats(const AVFilterContext
*ctx
,
158 AVFilterFormatsConfig
**cfg_in
,
159 AVFilterFormatsConfig
**cfg_out
)
161 const BiquadsContext
*s
= ctx
->priv
;
162 static const enum AVSampleFormat auto_sample_fmts
[] = {
169 enum AVSampleFormat sample_fmts
[] = {
173 const enum AVSampleFormat
*sample_fmts_list
= sample_fmts
;
176 switch (s
->precision
) {
178 sample_fmts
[0] = AV_SAMPLE_FMT_S16P
;
181 sample_fmts
[0] = AV_SAMPLE_FMT_S32P
;
184 sample_fmts
[0] = AV_SAMPLE_FMT_FLTP
;
187 sample_fmts
[0] = AV_SAMPLE_FMT_DBLP
;
190 sample_fmts_list
= auto_sample_fmts
;
193 ret
= ff_set_common_formats_from_list2(ctx
, cfg_in
, cfg_out
, sample_fmts_list
);
200 #define BIQUAD_FILTER(name, type, ftype, min, max, need_clipping) \
201 static void biquad_## name (BiquadsContext *s, \
202 const void *input, void *output, int len, \
203 void *cache, int *clippings, int disabled) \
205 const type *ibuf = input; \
206 type *obuf = output; \
207 ftype *fcache = cache; \
208 ftype i1 = fcache[0], i2 = fcache[1], o1 = fcache[2], o2 = fcache[3]; \
209 ftype *a = s->a_##ftype; \
210 ftype *b = s->b_##ftype; \
216 ftype wet = s->mix; \
217 ftype dry = 1. - wet; \
221 for (i = 0; i+1 < len; i++) { \
222 o2 = i2 * b2 + i1 * b1 + ibuf[i] * b0 + o2 * a2 + o1 * a1; \
224 out = o2 * wet + i2 * dry; \
227 } else if (need_clipping && out < min) { \
230 } else if (need_clipping && out > max) { \
237 o1 = i1 * b2 + i2 * b1 + ibuf[i] * b0 + o1 * a2 + o2 * a1; \
239 out = o1 * wet + i1 * dry; \
242 } else if (need_clipping && out < min) { \
245 } else if (need_clipping && out > max) { \
253 ftype o0 = ibuf[i] * b0 + i1 * b1 + i2 * b2 + o1 * a1 + o2 * a2; \
258 out = o0 * wet + i1 * dry; \
261 } else if (need_clipping && out < min) { \
264 } else if (need_clipping && out > max) { \
277 BIQUAD_FILTER(s16
, int16_t, float, INT16_MIN
, INT16_MAX
, 1)
278 BIQUAD_FILTER(s32
, int32_t, double, INT32_MIN
, INT32_MAX
, 1)
279 BIQUAD_FILTER(flt
, float, float, -1.f
, 1.f
, 0)
280 BIQUAD_FILTER(dbl
, double, double, -1., 1., 0)
282 #define BIQUAD_DII_FILTER(name, type, ftype, min, max, need_clipping) \
283 static void biquad_dii_## name (BiquadsContext *s, \
284 const void *input, void *output, int len, \
285 void *cache, int *clippings, int disabled) \
287 const type *ibuf = input; \
288 type *obuf = output; \
289 ftype *fcache = cache; \
290 ftype *a = s->a_##ftype; \
291 ftype *b = s->b_##ftype; \
297 ftype w1 = fcache[0]; \
298 ftype w2 = fcache[1]; \
299 ftype wet = s->mix; \
300 ftype dry = 1. - wet; \
303 for (int i = 0; i < len; i++) { \
305 w0 = in + a1 * w1 + a2 * w2; \
306 out = b0 * w0 + b1 * w1 + b2 * w2; \
309 out = out * wet + in * dry; \
312 } else if (need_clipping && out < min) { \
315 } else if (need_clipping && out > max) { \
326 BIQUAD_DII_FILTER(s16
, int16_t, float, INT16_MIN
, INT16_MAX
, 1)
327 BIQUAD_DII_FILTER(s32
, int32_t, double, INT32_MIN
, INT32_MAX
, 1)
328 BIQUAD_DII_FILTER(flt
, float, float, -1.f
, 1.f
, 0)
329 BIQUAD_DII_FILTER(dbl
, double, double, -1., 1., 0)
331 #define BIQUAD_TDI_FILTER(name, type, ftype, min, max, need_clipping) \
332 static void biquad_tdi_## name (BiquadsContext *s, \
333 const void *input, void *output, int len, \
334 void *cache, int *clippings, int disabled) \
336 const type *ibuf = input; \
337 type *obuf = output; \
338 ftype *fcache = cache; \
339 ftype *a = s->a_##ftype; \
340 ftype *b = s->b_##ftype; \
346 ftype s1 = fcache[0]; \
347 ftype s2 = fcache[1]; \
348 ftype s3 = fcache[2]; \
349 ftype s4 = fcache[3]; \
350 ftype wet = s->mix; \
351 ftype dry = 1. - wet; \
354 for (int i = 0; i < len; i++) { \
355 ftype t1, t2, t3, t4; \
361 out = b0 * in + s3; \
362 out = out * wet + in * dry; \
363 s1 = t1; s2 = t2; s3 = t3; s4 = t4; \
366 } else if (need_clipping && out < min) { \
369 } else if (need_clipping && out > max) { \
383 BIQUAD_TDI_FILTER(s16
, int16_t, float, INT16_MIN
, INT16_MAX
, 1)
384 BIQUAD_TDI_FILTER(s32
, int32_t, double, INT32_MIN
, INT32_MAX
, 1)
385 BIQUAD_TDI_FILTER(flt
, float, float, -1.f
, 1.f
, 0)
386 BIQUAD_TDI_FILTER(dbl
, double, double, -1., 1., 0)
388 #define BIQUAD_TDII_FILTER(name, type, ftype, min, max, need_clipping) \
389 static void biquad_tdii_## name (BiquadsContext *s, \
390 const void *input, void *output, int len, \
391 void *cache, int *clippings, int disabled) \
393 const type *ibuf = input; \
394 type *obuf = output; \
395 ftype *fcache = cache; \
396 ftype *a = s->a_##ftype; \
397 ftype *b = s->b_##ftype; \
403 ftype w1 = fcache[0]; \
404 ftype w2 = fcache[1]; \
405 ftype wet = s->mix; \
406 ftype dry = 1. - wet; \
409 for (int i = 0; i < len; i++) { \
411 out = b0 * in + w1; \
412 w1 = b1 * in + w2 + a1 * out; \
413 w2 = b2 * in + a2 * out; \
414 out = out * wet + in * dry; \
417 } else if (need_clipping && out < min) { \
420 } else if (need_clipping && out > max) { \
431 BIQUAD_TDII_FILTER(s16
, int16_t, float, INT16_MIN
, INT16_MAX
, 1)
432 BIQUAD_TDII_FILTER(s32
, int32_t, double, INT32_MIN
, INT32_MAX
, 1)
433 BIQUAD_TDII_FILTER(flt
, float, float, -1.f
, 1.f
, 0)
434 BIQUAD_TDII_FILTER(dbl
, double, double, -1., 1., 0)
436 #define BIQUAD_LATT_FILTER(name, type, ftype, min, max, need_clipping) \
437 static void biquad_latt_## name (BiquadsContext *s, \
438 const void *input, void *output, int len, \
439 void *cache, int *clippings, int disabled) \
441 const type *ibuf = input; \
442 type *obuf = output; \
443 ftype *fcache = cache; \
444 ftype *a = s->a_##ftype; \
445 ftype *b = s->b_##ftype; \
451 ftype s0 = fcache[0]; \
452 ftype s1 = fcache[1]; \
453 ftype wet = s->mix; \
454 ftype dry = 1. - wet; \
458 for (int i = 0; i < len; i++) { \
473 out = out * wet + in * dry; \
476 } else if (need_clipping && out < min) { \
479 } else if (need_clipping && out > max) { \
490 BIQUAD_LATT_FILTER(s16
, int16_t, float, INT16_MIN
, INT16_MAX
, 1)
491 BIQUAD_LATT_FILTER(s32
, int32_t, double, INT32_MIN
, INT32_MAX
, 1)
492 BIQUAD_LATT_FILTER(flt
, float, float, -1.f
, 1.f
, 0)
493 BIQUAD_LATT_FILTER(dbl
, double, double, -1., 1., 0)
495 #define BIQUAD_SVF_FILTER(name, type, ftype, min, max, need_clipping) \
496 static void biquad_svf_## name (BiquadsContext *s, \
497 const void *input, void *output, int len, \
498 void *cache, int *clippings, int disabled) \
500 const type *ibuf = input; \
501 type *obuf = output; \
502 ftype *fcache = cache; \
503 ftype *a = s->a_##ftype; \
504 ftype *b = s->b_##ftype; \
510 ftype s0 = fcache[0]; \
511 ftype s1 = fcache[1]; \
512 ftype wet = s->mix; \
513 ftype dry = 1. - wet; \
517 for (int i = 0; i < len; i++) { \
519 out = b2 * in + s0; \
520 t0 = b0 * in + a1 * s0 + s1; \
521 t1 = b1 * in + a2 * s0; \
525 out = out * wet + in * dry; \
528 } else if (need_clipping && out < min) { \
531 } else if (need_clipping && out > max) { \
542 BIQUAD_SVF_FILTER(s16
, int16_t, float, INT16_MIN
, INT16_MAX
, 1)
543 BIQUAD_SVF_FILTER(s32
, int32_t, double, INT32_MIN
, INT32_MAX
, 1)
544 BIQUAD_SVF_FILTER(flt
, float, float, -1.f
, 1.f
, 0)
545 BIQUAD_SVF_FILTER(dbl
, double, double, -1., 1., 0)
547 #define BIQUAD_ZDF_FILTER(name, type, ftype, min, max, need_clipping, two) \
548 static void biquad_zdf_## name (BiquadsContext *s, \
549 const void *input, void *output, int len, \
550 void *cache, int *clippings, int disabled) \
552 const type *ibuf = input; \
553 type *obuf = output; \
554 ftype *fcache = cache; \
555 ftype *a = s->a_##ftype; \
556 ftype *b = s->b_##ftype; \
563 ftype b0 = fcache[0]; \
564 ftype b1 = fcache[1]; \
565 ftype wet = s->mix; \
566 ftype dry = 1. - wet; \
569 for (int i = 0; i < len; i++) { \
570 const ftype in = ibuf[i]; \
571 const ftype v0 = in; \
572 const ftype v3 = v0 - b1; \
573 const ftype v1 = a0 * b0 + a1 * v3; \
574 const ftype v2 = b1 + a1 * b0 + a2 * v3; \
576 b0 = two * v1 - b0; \
577 b1 = two * v2 - b1; \
579 out = m0 * v0 + m1 * v1 + m2 * v2; \
580 out = out * wet + in * dry; \
583 } else if (need_clipping && out < min) { \
586 } else if (need_clipping && out > max) { \
597 BIQUAD_ZDF_FILTER(s16
, int16_t, float, INT16_MIN
, INT16_MAX
, 1, 2.f
)
598 BIQUAD_ZDF_FILTER(s32
, int32_t, double, INT32_MIN
, INT32_MAX
, 1, 2.0)
599 BIQUAD_ZDF_FILTER(flt
, float, float, -1.f
, 1.f
, 0, 2.f
)
600 BIQUAD_ZDF_FILTER(dbl
, double, double, -1., 1., 0, 2.0)
602 static void convert_dir2latt(BiquadsContext
*s
)
604 double k0
, k1
, v0
, v1
, v2
;
607 k0
= s
->a_double
[1] / (1. + k1
);
609 v1
= s
->b_double
[1] - v2
* s
->a_double
[1];
610 v0
= s
->b_double
[0] - v1
* k0
- v2
* k1
;
619 static void convert_dir2svf(BiquadsContext
*s
)
624 a
[0] = -s
->a_double
[1];
625 a
[1] = -s
->a_double
[2];
626 b
[0] = s
->b_double
[1] - s
->a_double
[1] * s
->b_double
[0];
627 b
[1] = s
->b_double
[2] - s
->a_double
[2] * s
->b_double
[0];
628 b
[2] = s
->b_double
[0];
630 s
->a_double
[1] = a
[0];
631 s
->a_double
[2] = a
[1];
632 s
->b_double
[0] = b
[0];
633 s
->b_double
[1] = b
[1];
634 s
->b_double
[2] = b
[2];
637 static double convert_width2qfactor(double width
,
643 double w0
= 2. * M_PI
* frequency
/ sample_rate
;
644 double A
= ff_exp10(gain
/ 40.);
647 switch (width_type
) {
653 ret
= frequency
/ width
;
656 ret
= frequency
/ (width
* 1000.);
659 ret
= 1. / (2. * sinh(log(2.) / 2. * width
* w0
/ sin(w0
)));
662 ret
= 1. / sqrt((A
+ 1. / A
) * (1. / width
- 1.) + 2.);
672 static void convert_dir2zdf(BiquadsContext
*s
, int sample_rate
)
674 double Q
= convert_width2qfactor(s
->width
, s
->frequency
, s
->gain
, sample_rate
, s
->width_type
);
679 switch (s
->filter_type
) {
689 A
= ff_exp10(s
->gain
/ 40.);
690 g
= tan(M_PI
* s
->frequency
/ sample_rate
);
692 a
[0] = 1. / (1. + g
* (g
+ k
));
696 m
[1] = k
* (A
* A
- 1.);
701 A
= ff_exp10(s
->gain
/ 40.);
702 g
= tan(M_PI
* s
->frequency
/ sample_rate
) / sqrt(A
);
704 a
[0] = 1. / (1. + g
* (g
+ k
));
712 A
= ff_exp10(s
->gain
/ 20.);
713 g
= tan(M_PI
* s
->frequency
/ sample_rate
) / sqrt(A
);
715 a
[0] = 1. / (1. + g
* (g
+ k
));
719 m
[1] = k
* (A
- 1.) / A
;
720 m
[2] = (A
* A
- 1.) / A
;
724 A
= ff_exp10(s
->gain
/ 40.);
725 g
= tan(M_PI
* s
->frequency
/ sample_rate
) * sqrt(A
);
727 a
[0] = 1. / (1. + g
* (g
+ k
));
731 m
[1] = k
* (1. - A
) * A
;
735 g
= tan(M_PI
* s
->frequency
/ sample_rate
);
737 a
[0] = 1. / (1. + g
* (g
+ k
));
741 m
[1] = s
->csg
? 1. : k
;
745 g
= tan(M_PI
* s
->frequency
/ sample_rate
);
747 a
[0] = 1. / (1. + g
* (g
+ k
));
755 g
= tan(M_PI
* s
->frequency
/ sample_rate
);
757 a
[0] = 1. / (1. + g
* (g
+ k
));
765 g
= tan(M_PI
* s
->frequency
/ sample_rate
);
767 a
[0] = 1. / (1. + g
* (g
+ k
));
775 g
= tan(M_PI
* s
->frequency
/ sample_rate
);
777 a
[0] = 1. / (1. + g
* (g
+ k
));
788 s
->a_double
[0] = a
[0];
789 s
->a_double
[1] = a
[1];
790 s
->a_double
[2] = a
[2];
791 s
->b_double
[0] = m
[0];
792 s
->b_double
[1] = m
[1];
793 s
->b_double
[2] = m
[2];
796 static int config_filter(AVFilterLink
*outlink
, int reset
)
798 AVFilterContext
*ctx
= outlink
->src
;
799 BiquadsContext
*s
= ctx
->priv
;
800 AVFilterLink
*inlink
= ctx
->inputs
[0];
801 double gain
= s
->gain
* ((s
->filter_type
== tiltshelf
) + 1.);
802 double A
= ff_exp10(gain
/ 40);
803 double w0
= 2 * M_PI
* s
->frequency
/ inlink
->sample_rate
;
804 double K
= tan(w0
/ 2.);
807 s
->bypass
= (((w0
> M_PI
|| w0
<= 0.) && reset
) || (s
->width
<= 0.)) && (s
->filter_type
!= biquad
);
809 av_log(ctx
, AV_LOG_WARNING
, "Invalid frequency and/or width!\n");
813 if ((w0
> M_PI
|| w0
<= 0.) && (s
->filter_type
!= biquad
))
814 return AVERROR(EINVAL
);
816 switch (s
->width_type
) {
821 alpha
= sin(w0
) / (2 * s
->frequency
/ s
->width
);
824 alpha
= sin(w0
) / (2 * s
->frequency
/ (s
->width
* 1000));
827 alpha
= sin(w0
) * sinh(log(2.) / 2 * s
->width
* w0
/ sin(w0
));
830 alpha
= sin(w0
) / (2 * s
->width
);
833 alpha
= sin(w0
) / 2 * sqrt((A
+ 1 / A
) * (1 / s
->width
- 1) + 2);
841 switch (s
->filter_type
) {
843 s
->a_double
[0] = s
->oa
[0];
844 s
->a_double
[1] = s
->oa
[1];
845 s
->a_double
[2] = s
->oa
[2];
846 s
->b_double
[0] = s
->ob
[0];
847 s
->b_double
[1] = s
->ob
[1];
848 s
->b_double
[2] = s
->ob
[2];
851 s
->a_double
[0] = 1 + alpha
/ A
;
852 s
->a_double
[1] = -2 * cos(w0
);
853 s
->a_double
[2] = 1 - alpha
/ A
;
854 s
->b_double
[0] = 1 + alpha
* A
;
855 s
->b_double
[1] = -2 * cos(w0
);
856 s
->b_double
[2] = 1 - alpha
* A
;
859 beta
= sqrt((A
* A
+ 1) - (A
- 1) * (A
- 1));
863 double A
= ff_exp10(gain
/ 20);
864 double ro
= -sin(w0
/ 2. - M_PI_4
) / sin(w0
/ 2. + M_PI_4
);
865 double n
= (A
+ 1) / (A
- 1);
866 double alpha1
= A
== 1. ? 0. : n
- FFSIGN(n
) * sqrt(n
* n
- 1);
867 double beta0
= ((1 + A
) + (1 - A
) * alpha1
) * 0.5;
868 double beta1
= ((1 - A
) + (1 + A
) * alpha1
) * 0.5;
870 s
->a_double
[0] = 1 + ro
* alpha1
;
871 s
->a_double
[1] = -ro
- alpha1
;
873 s
->b_double
[0] = beta0
+ ro
* beta1
;
874 s
->b_double
[1] = -beta1
- ro
* beta0
;
877 s
->a_double
[0] = (A
+ 1) + (A
- 1) * cos(w0
) + beta
* alpha
;
878 s
->a_double
[1] = -2 * ((A
- 1) + (A
+ 1) * cos(w0
));
879 s
->a_double
[2] = (A
+ 1) + (A
- 1) * cos(w0
) - beta
* alpha
;
880 s
->b_double
[0] = A
* ((A
+ 1) - (A
- 1) * cos(w0
) + beta
* alpha
);
881 s
->b_double
[1] = 2 * A
* ((A
- 1) - (A
+ 1) * cos(w0
));
882 s
->b_double
[2] = A
* ((A
+ 1) - (A
- 1) * cos(w0
) - beta
* alpha
);
886 beta
= sqrt((A
* A
+ 1) - (A
- 1) * (A
- 1));
889 double A
= ff_exp10(gain
/ 20);
890 double ro
= sin(w0
/ 2. - M_PI_4
) / sin(w0
/ 2. + M_PI_4
);
891 double n
= (A
+ 1) / (A
- 1);
892 double alpha1
= A
== 1. ? 0. : n
- FFSIGN(n
) * sqrt(n
* n
- 1);
893 double beta0
= ((1 + A
) + (1 - A
) * alpha1
) * 0.5;
894 double beta1
= ((1 - A
) + (1 + A
) * alpha1
) * 0.5;
896 s
->a_double
[0] = 1 + ro
* alpha1
;
897 s
->a_double
[1] = ro
+ alpha1
;
899 s
->b_double
[0] = beta0
+ ro
* beta1
;
900 s
->b_double
[1] = beta1
+ ro
* beta0
;
903 s
->a_double
[0] = (A
+ 1) - (A
- 1) * cos(w0
) + beta
* alpha
;
904 s
->a_double
[1] = 2 * ((A
- 1) - (A
+ 1) * cos(w0
));
905 s
->a_double
[2] = (A
+ 1) - (A
- 1) * cos(w0
) - beta
* alpha
;
906 s
->b_double
[0] = A
* ((A
+ 1) + (A
- 1) * cos(w0
) + beta
* alpha
);
907 s
->b_double
[1] =-2 * A
* ((A
- 1) + (A
+ 1) * cos(w0
));
908 s
->b_double
[2] = A
* ((A
+ 1) + (A
- 1) * cos(w0
) - beta
* alpha
);
913 s
->a_double
[0] = 1 + alpha
;
914 s
->a_double
[1] = -2 * cos(w0
);
915 s
->a_double
[2] = 1 - alpha
;
916 s
->b_double
[0] = sin(w0
) / 2;
918 s
->b_double
[2] = -sin(w0
) / 2;
920 s
->a_double
[0] = 1 + alpha
;
921 s
->a_double
[1] = -2 * cos(w0
);
922 s
->a_double
[2] = 1 - alpha
;
923 s
->b_double
[0] = alpha
;
925 s
->b_double
[2] = -alpha
;
929 s
->a_double
[0] = 1 + alpha
;
930 s
->a_double
[1] = -2 * cos(w0
);
931 s
->a_double
[2] = 1 - alpha
;
933 s
->b_double
[1] = -2 * cos(w0
);
939 s
->a_double
[1] = -exp(-w0
);
941 s
->b_double
[0] = 1 + s
->a_double
[1];
945 s
->a_double
[0] = 1 + alpha
;
946 s
->a_double
[1] = -2 * cos(w0
);
947 s
->a_double
[2] = 1 - alpha
;
948 s
->b_double
[0] = (1 - cos(w0
)) / 2;
949 s
->b_double
[1] = 1 - cos(w0
);
950 s
->b_double
[2] = (1 - cos(w0
)) / 2;
956 s
->a_double
[1] = -exp(-w0
);
958 s
->b_double
[0] = (1 - s
->a_double
[1]) / 2;
959 s
->b_double
[1] = -s
->b_double
[0];
962 s
->a_double
[0] = 1 + alpha
;
963 s
->a_double
[1] = -2 * cos(w0
);
964 s
->a_double
[2] = 1 - alpha
;
965 s
->b_double
[0] = (1 + cos(w0
)) / 2;
966 s
->b_double
[1] = -(1 + cos(w0
));
967 s
->b_double
[2] = (1 + cos(w0
)) / 2;
974 s
->a_double
[1] = -(1. - K
) / (1. + K
);
976 s
->b_double
[0] = s
->a_double
[1];
977 s
->b_double
[1] = s
->a_double
[0];
981 s
->a_double
[0] = 1 + alpha
;
982 s
->a_double
[1] = -2 * cos(w0
);
983 s
->a_double
[2] = 1 - alpha
;
984 s
->b_double
[0] = 1 - alpha
;
985 s
->b_double
[1] = -2 * cos(w0
);
986 s
->b_double
[2] = 1 + alpha
;
994 av_log(ctx
, AV_LOG_VERBOSE
, "a=%f %f %f:b=%f %f %f\n",
995 s
->a_double
[0], s
->a_double
[1], s
->a_double
[2],
996 s
->b_double
[0], s
->b_double
[1], s
->b_double
[2]);
998 s
->a_double
[1] /= s
->a_double
[0];
999 s
->a_double
[2] /= s
->a_double
[0];
1000 s
->b_double
[0] /= s
->a_double
[0];
1001 s
->b_double
[1] /= s
->a_double
[0];
1002 s
->b_double
[2] /= s
->a_double
[0];
1003 s
->a_double
[0] /= s
->a_double
[0];
1005 if (s
->normalize
&& fabs(s
->b_double
[0] + s
->b_double
[1] + s
->b_double
[2]) > 1e-6) {
1006 double factor
= (s
->a_double
[0] + s
->a_double
[1] + s
->a_double
[2]) /
1007 (s
->b_double
[0] + s
->b_double
[1] + s
->b_double
[2]);
1009 s
->b_double
[0] *= factor
;
1010 s
->b_double
[1] *= factor
;
1011 s
->b_double
[2] *= factor
;
1014 switch (s
->filter_type
) {
1016 s
->b_double
[0] /= A
;
1017 s
->b_double
[1] /= A
;
1018 s
->b_double
[2] /= A
;
1023 s
->cache
[0] = ff_get_audio_buffer(outlink
, 4 * sizeof(double));
1025 s
->clip
= av_calloc(outlink
->ch_layout
.nb_channels
, sizeof(*s
->clip
));
1026 if (!s
->cache
[0] || !s
->clip
)
1027 return AVERROR(ENOMEM
);
1029 av_samples_set_silence(s
->cache
[0]->extended_data
, 0, s
->cache
[0]->nb_samples
,
1030 s
->cache
[0]->ch_layout
.nb_channels
, s
->cache
[0]->format
);
1033 if (reset
&& s
->block_samples
> 0) {
1035 s
->cache
[1] = ff_get_audio_buffer(outlink
, 4 * sizeof(double));
1037 return AVERROR(ENOMEM
);
1038 av_samples_set_silence(s
->cache
[1]->extended_data
, 0, s
->cache
[1]->nb_samples
,
1039 s
->cache
[1]->ch_layout
.nb_channels
, s
->cache
[1]->format
);
1040 for (int i
= 0; i
< 3; i
++) {
1042 s
->block
[i
] = ff_get_audio_buffer(outlink
, s
->block_samples
* 2);
1044 return AVERROR(ENOMEM
);
1045 av_samples_set_silence(s
->block
[i
]->extended_data
, 0, s
->block_samples
* 2,
1046 s
->block
[i
]->ch_layout
.nb_channels
, s
->block
[i
]->format
);
1050 switch (s
->transform_type
) {
1052 switch (inlink
->format
) {
1053 case AV_SAMPLE_FMT_S16P
:
1054 s
->filter
= biquad_s16
;
1056 case AV_SAMPLE_FMT_S32P
:
1057 s
->filter
= biquad_s32
;
1059 case AV_SAMPLE_FMT_FLTP
:
1060 s
->filter
= biquad_flt
;
1062 case AV_SAMPLE_FMT_DBLP
:
1063 s
->filter
= biquad_dbl
;
1065 default: av_assert0(0);
1069 switch (inlink
->format
) {
1070 case AV_SAMPLE_FMT_S16P
:
1071 s
->filter
= biquad_dii_s16
;
1073 case AV_SAMPLE_FMT_S32P
:
1074 s
->filter
= biquad_dii_s32
;
1076 case AV_SAMPLE_FMT_FLTP
:
1077 s
->filter
= biquad_dii_flt
;
1079 case AV_SAMPLE_FMT_DBLP
:
1080 s
->filter
= biquad_dii_dbl
;
1082 default: av_assert0(0);
1086 switch (inlink
->format
) {
1087 case AV_SAMPLE_FMT_S16P
:
1088 s
->filter
= biquad_tdi_s16
;
1090 case AV_SAMPLE_FMT_S32P
:
1091 s
->filter
= biquad_tdi_s32
;
1093 case AV_SAMPLE_FMT_FLTP
:
1094 s
->filter
= biquad_tdi_flt
;
1096 case AV_SAMPLE_FMT_DBLP
:
1097 s
->filter
= biquad_tdi_dbl
;
1099 default: av_assert0(0);
1103 switch (inlink
->format
) {
1104 case AV_SAMPLE_FMT_S16P
:
1105 s
->filter
= biquad_tdii_s16
;
1107 case AV_SAMPLE_FMT_S32P
:
1108 s
->filter
= biquad_tdii_s32
;
1110 case AV_SAMPLE_FMT_FLTP
:
1111 s
->filter
= biquad_tdii_flt
;
1113 case AV_SAMPLE_FMT_DBLP
:
1114 s
->filter
= biquad_tdii_dbl
;
1116 default: av_assert0(0);
1120 switch (inlink
->format
) {
1121 case AV_SAMPLE_FMT_S16P
:
1122 s
->filter
= biquad_latt_s16
;
1124 case AV_SAMPLE_FMT_S32P
:
1125 s
->filter
= biquad_latt_s32
;
1127 case AV_SAMPLE_FMT_FLTP
:
1128 s
->filter
= biquad_latt_flt
;
1130 case AV_SAMPLE_FMT_DBLP
:
1131 s
->filter
= biquad_latt_dbl
;
1133 default: av_assert0(0);
1137 switch (inlink
->format
) {
1138 case AV_SAMPLE_FMT_S16P
:
1139 s
->filter
= biquad_svf_s16
;
1141 case AV_SAMPLE_FMT_S32P
:
1142 s
->filter
= biquad_svf_s32
;
1144 case AV_SAMPLE_FMT_FLTP
:
1145 s
->filter
= biquad_svf_flt
;
1147 case AV_SAMPLE_FMT_DBLP
:
1148 s
->filter
= biquad_svf_dbl
;
1150 default: av_assert0(0);
1154 switch (inlink
->format
) {
1155 case AV_SAMPLE_FMT_S16P
:
1156 s
->filter
= biquad_zdf_s16
;
1158 case AV_SAMPLE_FMT_S32P
:
1159 s
->filter
= biquad_zdf_s32
;
1161 case AV_SAMPLE_FMT_FLTP
:
1162 s
->filter
= biquad_zdf_flt
;
1164 case AV_SAMPLE_FMT_DBLP
:
1165 s
->filter
= biquad_zdf_dbl
;
1167 default: av_assert0(0);
1174 s
->block_align
= av_get_bytes_per_sample(inlink
->format
);
1176 if (s
->transform_type
== LATT
)
1177 convert_dir2latt(s
);
1178 else if (s
->transform_type
== SVF
)
1180 else if (s
->transform_type
== ZDF
)
1181 convert_dir2zdf(s
, inlink
->sample_rate
);
1183 s
->a_float
[0] = s
->a_double
[0];
1184 s
->a_float
[1] = s
->a_double
[1];
1185 s
->a_float
[2] = s
->a_double
[2];
1186 s
->b_float
[0] = s
->b_double
[0];
1187 s
->b_float
[1] = s
->b_double
[1];
1188 s
->b_float
[2] = s
->b_double
[2];
1193 static int config_output(AVFilterLink
*outlink
)
1195 return config_filter(outlink
, 1);
1198 typedef struct ThreadData
{
1203 static void reverse_samples(AVFrame
*out
, AVFrame
*in
, int p
,
1204 int oo
, int io
, int nb_samples
)
1206 switch (out
->format
) {
1207 case AV_SAMPLE_FMT_S16P
: {
1208 const int16_t *src
= ((const int16_t *)in
->extended_data
[p
]) + io
;
1209 int16_t *dst
= ((int16_t *)out
->extended_data
[p
]) + oo
;
1210 for (int i
= 0, j
= nb_samples
- 1; i
< nb_samples
; i
++, j
--)
1214 case AV_SAMPLE_FMT_S32P
: {
1215 const int32_t *src
= ((const int32_t *)in
->extended_data
[p
]) + io
;
1216 int32_t *dst
= ((int32_t *)out
->extended_data
[p
]) + oo
;
1217 for (int i
= 0, j
= nb_samples
- 1; i
< nb_samples
; i
++, j
--)
1221 case AV_SAMPLE_FMT_FLTP
: {
1222 const float *src
= ((const float *)in
->extended_data
[p
]) + io
;
1223 float *dst
= ((float *)out
->extended_data
[p
]) + oo
;
1224 for (int i
= 0, j
= nb_samples
- 1; i
< nb_samples
; i
++, j
--)
1228 case AV_SAMPLE_FMT_DBLP
: {
1229 const double *src
= ((const double *)in
->extended_data
[p
]) + io
;
1230 double *dst
= ((double *)out
->extended_data
[p
]) + oo
;
1231 for (int i
= 0, j
= nb_samples
- 1; i
< nb_samples
; i
++, j
--)
1238 static int filter_channel(AVFilterContext
*ctx
, void *arg
, int jobnr
, int nb_jobs
)
1240 AVFilterLink
*inlink
= ctx
->inputs
[0];
1241 ThreadData
*td
= arg
;
1242 AVFrame
*buf
= td
->in
;
1243 AVFrame
*out_buf
= td
->out
;
1244 BiquadsContext
*s
= ctx
->priv
;
1245 const int start
= (buf
->ch_layout
.nb_channels
* jobnr
) / nb_jobs
;
1246 const int end
= (buf
->ch_layout
.nb_channels
* (jobnr
+1)) / nb_jobs
;
1249 for (ch
= start
; ch
< end
; ch
++) {
1250 enum AVChannel channel
= av_channel_layout_channel_from_index(&inlink
->ch_layout
, ch
);
1252 if (av_channel_layout_index_from_channel(&s
->ch_layout
, channel
) < 0) {
1254 memcpy(out_buf
->extended_data
[ch
], buf
->extended_data
[ch
],
1255 buf
->nb_samples
* s
->block_align
);
1259 if (!s
->block_samples
) {
1260 s
->filter(s
, buf
->extended_data
[ch
], out_buf
->extended_data
[ch
], buf
->nb_samples
,
1261 s
->cache
[0]->extended_data
[ch
], s
->clip
+ch
, ctx
->is_disabled
);
1262 } else if (td
->eof
) {
1263 memcpy(out_buf
->extended_data
[ch
], s
->block
[1]->extended_data
[ch
] + s
->block_align
* s
->block_samples
,
1264 s
->nb_samples
* s
->block_align
);
1266 memcpy(s
->block
[0]->extended_data
[ch
] + s
->block_align
* s
->block_samples
, buf
->extended_data
[ch
],
1267 buf
->nb_samples
* s
->block_align
);
1268 memset(s
->block
[0]->extended_data
[ch
] + s
->block_align
* (s
->block_samples
+ buf
->nb_samples
),
1269 0, (s
->block_samples
- buf
->nb_samples
) * s
->block_align
);
1270 s
->filter(s
, s
->block
[0]->extended_data
[ch
], s
->block
[1]->extended_data
[ch
], s
->block_samples
,
1271 s
->cache
[0]->extended_data
[ch
], s
->clip
+ch
, ctx
->is_disabled
);
1272 av_samples_copy(s
->cache
[1]->extended_data
, s
->cache
[0]->extended_data
, 0, 0,
1273 s
->cache
[0]->nb_samples
, s
->cache
[0]->ch_layout
.nb_channels
,
1274 s
->cache
[0]->format
);
1275 s
->filter(s
, s
->block
[0]->extended_data
[ch
] + s
->block_samples
* s
->block_align
,
1276 s
->block
[1]->extended_data
[ch
] + s
->block_samples
* s
->block_align
,
1277 s
->block_samples
, s
->cache
[1]->extended_data
[ch
], s
->clip
+ch
,
1279 reverse_samples(s
->block
[2], s
->block
[1], ch
, 0, 0, 2 * s
->block_samples
);
1280 av_samples_set_silence(s
->cache
[1]->extended_data
, 0, s
->cache
[1]->nb_samples
,
1281 s
->cache
[1]->ch_layout
.nb_channels
, s
->cache
[1]->format
);
1282 s
->filter(s
, s
->block
[2]->extended_data
[ch
], s
->block
[2]->extended_data
[ch
], 2 * s
->block_samples
,
1283 s
->cache
[1]->extended_data
[ch
], s
->clip
+ch
, ctx
->is_disabled
);
1284 reverse_samples(s
->block
[1], s
->block
[2], ch
, 0, 0, 2 * s
->block_samples
);
1285 memcpy(out_buf
->extended_data
[ch
], s
->block
[1]->extended_data
[ch
],
1286 s
->block_samples
* s
->block_align
);
1287 memmove(s
->block
[0]->extended_data
[ch
], s
->block
[0]->extended_data
[ch
] + s
->block_align
* s
->block_samples
,
1288 s
->block_samples
* s
->block_align
);
1295 static int filter_frame(AVFilterLink
*inlink
, AVFrame
*buf
, int eof
)
1297 AVFilterContext
*ctx
= inlink
->dst
;
1298 BiquadsContext
*s
= ctx
->priv
;
1299 AVFilterLink
*outlink
= ctx
->outputs
[0];
1302 int ch
, ret
, drop
= 0;
1305 return ff_filter_frame(outlink
, buf
);
1307 ret
= av_channel_layout_copy(&s
->ch_layout
, &inlink
->ch_layout
);
1309 av_frame_free(&buf
);
1312 if (strcmp(s
->ch_layout_str
, "all"))
1313 av_channel_layout_from_string(&s
->ch_layout
,
1316 if (av_frame_is_writable(buf
) && s
->block_samples
== 0) {
1319 out_buf
= ff_get_audio_buffer(outlink
, s
->block_samples
> 0 ? s
->block_samples
: buf
->nb_samples
);
1321 av_frame_free(&buf
);
1322 return AVERROR(ENOMEM
);
1324 av_frame_copy_props(out_buf
, buf
);
1327 if (s
->block_samples
> 0 && s
->pts
== AV_NOPTS_VALUE
)
1332 ff_filter_execute(ctx
, filter_channel
, &td
, NULL
,
1333 FFMIN(outlink
->ch_layout
.nb_channels
, ff_filter_get_nb_threads(ctx
)));
1335 for (ch
= 0; ch
< outlink
->ch_layout
.nb_channels
; ch
++) {
1336 if (s
->clip
[ch
] > 0)
1337 av_log(ctx
, AV_LOG_WARNING
, "Channel %d clipping %d times. Please reduce gain.\n",
1342 if (s
->block_samples
> 0) {
1343 int nb_samples
= buf
->nb_samples
;
1344 int64_t pts
= buf
->pts
;
1346 out_buf
->pts
= s
->pts
;
1347 out_buf
->nb_samples
= s
->nb_samples
;
1349 s
->nb_samples
= nb_samples
;
1353 av_frame_free(&buf
);
1356 return ff_filter_frame(outlink
, out_buf
);
1358 av_frame_free(&out_buf
);
1359 ff_filter_set_ready(ctx
, 10);
1364 static int activate(AVFilterContext
*ctx
)
1366 AVFilterLink
*inlink
= ctx
->inputs
[0];
1367 AVFilterLink
*outlink
= ctx
->outputs
[0];
1368 BiquadsContext
*s
= ctx
->priv
;
1374 FF_FILTER_FORWARD_STATUS_BACK(outlink
, inlink
);
1376 if (s
->block_samples
> 0) {
1377 ret
= ff_inlink_consume_samples(inlink
, s
->block_samples
, s
->block_samples
, &in
);
1379 ret
= ff_inlink_consume_frame(inlink
, &in
);
1384 return filter_frame(inlink
, in
, 0);
1386 if (s
->block_samples
> 0 && ff_inlink_queued_samples(inlink
) >= s
->block_samples
) {
1387 ff_filter_set_ready(ctx
, 10);
1391 if (ff_inlink_acknowledge_status(inlink
, &status
, &pts
)) {
1392 if (s
->block_samples
> 0) {
1393 AVFrame
*in
= ff_get_audio_buffer(outlink
, s
->block_samples
);
1395 return AVERROR(ENOMEM
);
1397 ret
= filter_frame(inlink
, in
, 1);
1400 ff_outlink_set_status(outlink
, status
, pts
);
1405 FF_FILTER_FORWARD_WANTED(outlink
, inlink
);
1407 return FFERROR_NOT_READY
;
1410 static int process_command(AVFilterContext
*ctx
, const char *cmd
, const char *args
,
1411 char *res
, int res_len
, int flags
)
1413 AVFilterLink
*outlink
= ctx
->outputs
[0];
1416 ret
= ff_filter_process_command(ctx
, cmd
, args
, res
, res_len
, flags
);
1420 return config_filter(outlink
, 0);
1423 static av_cold
void uninit(AVFilterContext
*ctx
)
1425 BiquadsContext
*s
= ctx
->priv
;
1427 for (int i
= 0; i
< 3; i
++)
1428 av_frame_free(&s
->block
[i
]);
1429 av_frame_free(&s
->cache
[0]);
1430 av_frame_free(&s
->cache
[1]);
1432 av_channel_layout_uninit(&s
->ch_layout
);
1435 static const AVFilterPad outputs
[] = {
1438 .type
= AVMEDIA_TYPE_AUDIO
,
1439 .config_props
= config_output
,
1443 #define OFFSET(x) offsetof(BiquadsContext, x)
1444 #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
1445 #define AF AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
1447 #define DEFINE_BIQUAD_FILTER_2(name_, description_, priv_class_) \
1448 static av_cold int name_##_init(AVFilterContext *ctx) \
1450 BiquadsContext *s = ctx->priv; \
1451 s->filter_type = name_; \
1452 s->pts = AV_NOPTS_VALUE; \
1456 const FFFilter ff_af_##name_ = { \
1458 .p.description = NULL_IF_CONFIG_SMALL(description_), \
1459 .p.priv_class = &priv_class_##_class, \
1460 .p.flags = AVFILTER_FLAG_SLICE_THREADS | \
1461 AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL, \
1462 .priv_size = sizeof(BiquadsContext), \
1463 .init = name_##_init, \
1464 .activate = activate, \
1466 FILTER_INPUTS(ff_audio_default_filterpad), \
1467 FILTER_OUTPUTS(outputs), \
1468 FILTER_QUERY_FUNC2(query_formats), \
1469 .process_command = process_command, \
1472 #define DEFINE_BIQUAD_FILTER(name, description) \
1473 AVFILTER_DEFINE_CLASS(name); \
1474 DEFINE_BIQUAD_FILTER_2(name, description, name)
1476 #define WIDTH_OPTION(x) \
1477 {"width", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=x}, 0, 99999, FLAGS}, \
1478 {"w", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=x}, 0, 99999, FLAGS}
1480 #define WIDTH_TYPE_OPTION(x) \
1481 {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=x}, HERTZ, NB_WTYPE-1, FLAGS, .unit = "width_type"}, \
1482 {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=x}, HERTZ, NB_WTYPE-1, FLAGS, .unit = "width_type"}, \
1483 {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, .unit = "width_type"}, \
1484 {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, .unit = "width_type"}, \
1485 {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, .unit = "width_type"}, \
1486 {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, .unit = "width_type"}, \
1487 {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, .unit = "width_type"}
1489 #define MIX_CHANNELS_NORMALIZE_OPTION(x, y, z) \
1490 {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=x}, 0, 1, FLAGS}, \
1491 {"m", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=x}, 0, 1, FLAGS}, \
1492 {"channels", "set channels to filter", OFFSET(ch_layout_str), AV_OPT_TYPE_STRING, {.str=y}, 0, 0, FLAGS}, \
1493 {"c", "set channels to filter", OFFSET(ch_layout_str), AV_OPT_TYPE_STRING, {.str=y}, 0, 0, FLAGS}, \
1494 {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=z}, 0, 1, FLAGS}, \
1495 {"n", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=z}, 0, 1, FLAGS}
1497 #define TRANSFORM_OPTION(x) \
1498 {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=x}, 0, NB_TTYPE-1, AF, .unit = "transform_type"}, \
1499 {"a", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=x}, 0, NB_TTYPE-1, AF, .unit = "transform_type"}, \
1500 {"di", "direct form I", 0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, .unit = "transform_type"}, \
1501 {"dii", "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, .unit = "transform_type"}, \
1502 {"tdi", "transposed direct form I", 0, AV_OPT_TYPE_CONST, {.i64=TDI}, 0, 0, AF, .unit = "transform_type"}, \
1503 {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, .unit = "transform_type"}, \
1504 {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, .unit = "transform_type"}, \
1505 {"svf", "state variable filter form", 0, AV_OPT_TYPE_CONST, {.i64=SVF}, 0, 0, AF, .unit = "transform_type"}, \
1506 {"zdf", "zero-delay filter form", 0, AV_OPT_TYPE_CONST, {.i64=ZDF}, 0, 0, AF, .unit = "transform_type"}
1508 #define PRECISION_OPTION(x) \
1509 {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=x}, -1, 3, AF, .unit = "precision"}, \
1510 {"r", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=x}, -1, 3, AF, .unit = "precision"}, \
1511 {"auto", "automatic", 0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, .unit = "precision"}, \
1512 {"s16", "signed 16-bit", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, .unit = "precision"}, \
1513 {"s32", "signed 32-bit", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, .unit = "precision"}, \
1514 {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, AF, .unit = "precision"}, \
1515 {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, AF, .unit = "precision"}
1517 #define BLOCKSIZE_OPTION(x) \
1518 {"blocksize", "set the block size", OFFSET(block_samples), AV_OPT_TYPE_INT, {.i64=x}, 0, 32768, AF}, \
1519 {"b", "set the block size", OFFSET(block_samples), AV_OPT_TYPE_INT, {.i64=x}, 0, 32768, AF}
1521 #if CONFIG_EQUALIZER_FILTER
1522 static const AVOption equalizer_options
[] = {
1523 {"frequency", "set central frequency", OFFSET(frequency
), AV_OPT_TYPE_DOUBLE
, {.dbl
=0}, 0, 999999, FLAGS
},
1524 {"f", "set central frequency", OFFSET(frequency
), AV_OPT_TYPE_DOUBLE
, {.dbl
=0}, 0, 999999, FLAGS
},
1525 WIDTH_TYPE_OPTION(QFACTOR
),
1527 {"gain", "set gain", OFFSET(gain
), AV_OPT_TYPE_DOUBLE
, {.dbl
=0}, -900, 900, FLAGS
},
1528 {"g", "set gain", OFFSET(gain
), AV_OPT_TYPE_DOUBLE
, {.dbl
=0}, -900, 900, FLAGS
},
1529 MIX_CHANNELS_NORMALIZE_OPTION(1, "all", 0),
1530 TRANSFORM_OPTION(DI
),
1531 PRECISION_OPTION(-1),
1532 BLOCKSIZE_OPTION(0),
1536 DEFINE_BIQUAD_FILTER(equalizer
, "Apply two-pole peaking equalization (EQ) filter.");
1537 #endif /* CONFIG_EQUALIZER_FILTER */
1538 #if CONFIG_BASS_FILTER || CONFIG_LOWSHELF_FILTER
1539 static const AVOption bass_lowshelf_options
[] = {
1540 {"frequency", "set central frequency", OFFSET(frequency
), AV_OPT_TYPE_DOUBLE
, {.dbl
=100}, 0, 999999, FLAGS
},
1541 {"f", "set central frequency", OFFSET(frequency
), AV_OPT_TYPE_DOUBLE
, {.dbl
=100}, 0, 999999, FLAGS
},
1542 WIDTH_TYPE_OPTION(QFACTOR
),
1544 {"gain", "set gain", OFFSET(gain
), AV_OPT_TYPE_DOUBLE
, {.dbl
=0}, -900, 900, FLAGS
},
1545 {"g", "set gain", OFFSET(gain
), AV_OPT_TYPE_DOUBLE
, {.dbl
=0}, -900, 900, FLAGS
},
1546 {"poles", "set number of poles", OFFSET(poles
), AV_OPT_TYPE_INT
, {.i64
=2}, 1, 2, AF
},
1547 {"p", "set number of poles", OFFSET(poles
), AV_OPT_TYPE_INT
, {.i64
=2}, 1, 2, AF
},
1548 MIX_CHANNELS_NORMALIZE_OPTION(1, "all", 0),
1549 TRANSFORM_OPTION(DI
),
1550 PRECISION_OPTION(-1),
1551 BLOCKSIZE_OPTION(0),
1555 AVFILTER_DEFINE_CLASS_EXT(bass_lowshelf
, "bass/lowshelf", bass_lowshelf_options
);
1556 #if CONFIG_BASS_FILTER
1557 DEFINE_BIQUAD_FILTER_2(bass
, "Boost or cut lower frequencies.", bass_lowshelf
);
1558 #endif /* CONFIG_BASS_FILTER */
1560 #if CONFIG_LOWSHELF_FILTER
1561 DEFINE_BIQUAD_FILTER_2(lowshelf
, "Apply a low shelf filter.", bass_lowshelf
);
1562 #endif /* CONFIG_LOWSHELF_FILTER */
1563 #endif /* CONFIG_BASS_FILTER || CONFIG LOWSHELF_FILTER */
1564 #if CONFIG_TREBLE_FILTER || CONFIG_HIGHSHELF_FILTER || CONFIG_TILTSHELF_FILTER
1565 static const AVOption treble_highshelf_options
[] = {
1566 {"frequency", "set central frequency", OFFSET(frequency
), AV_OPT_TYPE_DOUBLE
, {.dbl
=3000}, 0, 999999, FLAGS
},
1567 {"f", "set central frequency", OFFSET(frequency
), AV_OPT_TYPE_DOUBLE
, {.dbl
=3000}, 0, 999999, FLAGS
},
1568 WIDTH_TYPE_OPTION(QFACTOR
),
1570 {"gain", "set gain", OFFSET(gain
), AV_OPT_TYPE_DOUBLE
, {.dbl
=0}, -900, 900, FLAGS
},
1571 {"g", "set gain", OFFSET(gain
), AV_OPT_TYPE_DOUBLE
, {.dbl
=0}, -900, 900, FLAGS
},
1572 {"poles", "set number of poles", OFFSET(poles
), AV_OPT_TYPE_INT
, {.i64
=2}, 1, 2, AF
},
1573 {"p", "set number of poles", OFFSET(poles
), AV_OPT_TYPE_INT
, {.i64
=2}, 1, 2, AF
},
1574 MIX_CHANNELS_NORMALIZE_OPTION(1, "all", 0),
1575 TRANSFORM_OPTION(DI
),
1576 PRECISION_OPTION(-1),
1577 BLOCKSIZE_OPTION(0),
1581 AVFILTER_DEFINE_CLASS_EXT(treble_highshelf
, "treble/high/tiltshelf",
1582 treble_highshelf_options
);
1584 #if CONFIG_TREBLE_FILTER
1585 DEFINE_BIQUAD_FILTER_2(treble
, "Boost or cut upper frequencies.", treble_highshelf
);
1586 #endif /* CONFIG_TREBLE_FILTER */
1588 #if CONFIG_HIGHSHELF_FILTER
1589 DEFINE_BIQUAD_FILTER_2(highshelf
, "Apply a high shelf filter.", treble_highshelf
);
1590 #endif /* CONFIG_HIGHSHELF_FILTER */
1592 #if CONFIG_TILTSHELF_FILTER
1593 DEFINE_BIQUAD_FILTER_2(tiltshelf
, "Apply a tilt shelf filter.", treble_highshelf
);
1595 #endif /* CONFIG_TREBLE_FILTER || CONFIG_HIGHSHELF_FILTER || CONFIG_TILTSHELF_FILTER */
1597 #if CONFIG_BANDPASS_FILTER
1598 static const AVOption bandpass_options
[] = {
1599 {"frequency", "set central frequency", OFFSET(frequency
), AV_OPT_TYPE_DOUBLE
, {.dbl
=3000}, 0, 999999, FLAGS
},
1600 {"f", "set central frequency", OFFSET(frequency
), AV_OPT_TYPE_DOUBLE
, {.dbl
=3000}, 0, 999999, FLAGS
},
1601 WIDTH_TYPE_OPTION(QFACTOR
),
1603 {"csg", "use constant skirt gain", OFFSET(csg
), AV_OPT_TYPE_BOOL
, {.i64
=0}, 0, 1, FLAGS
},
1604 MIX_CHANNELS_NORMALIZE_OPTION(1, "all", 0),
1605 TRANSFORM_OPTION(DI
),
1606 PRECISION_OPTION(-1),
1607 BLOCKSIZE_OPTION(0),
1611 DEFINE_BIQUAD_FILTER(bandpass
, "Apply a two-pole Butterworth band-pass filter.");
1612 #endif /* CONFIG_BANDPASS_FILTER */
1613 #if CONFIG_BANDREJECT_FILTER
1614 static const AVOption bandreject_options
[] = {
1615 {"frequency", "set central frequency", OFFSET(frequency
), AV_OPT_TYPE_DOUBLE
, {.dbl
=3000}, 0, 999999, FLAGS
},
1616 {"f", "set central frequency", OFFSET(frequency
), AV_OPT_TYPE_DOUBLE
, {.dbl
=3000}, 0, 999999, FLAGS
},
1617 WIDTH_TYPE_OPTION(QFACTOR
),
1619 MIX_CHANNELS_NORMALIZE_OPTION(1, "all", 0),
1620 TRANSFORM_OPTION(DI
),
1621 PRECISION_OPTION(-1),
1622 BLOCKSIZE_OPTION(0),
1626 DEFINE_BIQUAD_FILTER(bandreject
, "Apply a two-pole Butterworth band-reject filter.");
1627 #endif /* CONFIG_BANDREJECT_FILTER */
1628 #if CONFIG_LOWPASS_FILTER
1629 static const AVOption lowpass_options
[] = {
1630 {"frequency", "set frequency", OFFSET(frequency
), AV_OPT_TYPE_DOUBLE
, {.dbl
=500}, 0, 999999, FLAGS
},
1631 {"f", "set frequency", OFFSET(frequency
), AV_OPT_TYPE_DOUBLE
, {.dbl
=500}, 0, 999999, FLAGS
},
1632 WIDTH_TYPE_OPTION(QFACTOR
),
1633 WIDTH_OPTION(0.707),
1634 {"poles", "set number of poles", OFFSET(poles
), AV_OPT_TYPE_INT
, {.i64
=2}, 1, 2, AF
},
1635 {"p", "set number of poles", OFFSET(poles
), AV_OPT_TYPE_INT
, {.i64
=2}, 1, 2, AF
},
1636 MIX_CHANNELS_NORMALIZE_OPTION(1, "all", 0),
1637 TRANSFORM_OPTION(DI
),
1638 PRECISION_OPTION(-1),
1639 BLOCKSIZE_OPTION(0),
1643 DEFINE_BIQUAD_FILTER(lowpass
, "Apply a low-pass filter with 3dB point frequency.");
1644 #endif /* CONFIG_LOWPASS_FILTER */
1645 #if CONFIG_HIGHPASS_FILTER
1646 static const AVOption highpass_options
[] = {
1647 {"frequency", "set frequency", OFFSET(frequency
), AV_OPT_TYPE_DOUBLE
, {.dbl
=3000}, 0, 999999, FLAGS
},
1648 {"f", "set frequency", OFFSET(frequency
), AV_OPT_TYPE_DOUBLE
, {.dbl
=3000}, 0, 999999, FLAGS
},
1649 WIDTH_TYPE_OPTION(QFACTOR
),
1650 WIDTH_OPTION(0.707),
1651 {"poles", "set number of poles", OFFSET(poles
), AV_OPT_TYPE_INT
, {.i64
=2}, 1, 2, AF
},
1652 {"p", "set number of poles", OFFSET(poles
), AV_OPT_TYPE_INT
, {.i64
=2}, 1, 2, AF
},
1653 MIX_CHANNELS_NORMALIZE_OPTION(1, "all", 0),
1654 TRANSFORM_OPTION(DI
),
1655 PRECISION_OPTION(-1),
1656 BLOCKSIZE_OPTION(0),
1660 DEFINE_BIQUAD_FILTER(highpass
, "Apply a high-pass filter with 3dB point frequency.");
1661 #endif /* CONFIG_HIGHPASS_FILTER */
1662 #if CONFIG_ALLPASS_FILTER
1663 static const AVOption allpass_options
[] = {
1664 {"frequency", "set central frequency", OFFSET(frequency
), AV_OPT_TYPE_DOUBLE
, {.dbl
=3000}, 0, 999999, FLAGS
},
1665 {"f", "set central frequency", OFFSET(frequency
), AV_OPT_TYPE_DOUBLE
, {.dbl
=3000}, 0, 999999, FLAGS
},
1666 WIDTH_TYPE_OPTION(QFACTOR
),
1667 WIDTH_OPTION(0.707),
1668 MIX_CHANNELS_NORMALIZE_OPTION(1, "all", 0),
1669 {"order", "set filter order", OFFSET(order
), AV_OPT_TYPE_INT
, {.i64
=2}, 1, 2, FLAGS
},
1670 {"o", "set filter order", OFFSET(order
), AV_OPT_TYPE_INT
, {.i64
=2}, 1, 2, FLAGS
},
1671 TRANSFORM_OPTION(DI
),
1672 PRECISION_OPTION(-1),
1676 DEFINE_BIQUAD_FILTER(allpass
, "Apply a two-pole all-pass filter.");
1677 #endif /* CONFIG_ALLPASS_FILTER */
1678 #if CONFIG_BIQUAD_FILTER
1679 static const AVOption biquad_options
[] = {
1680 {"a0", NULL
, OFFSET(oa
[0]), AV_OPT_TYPE_DOUBLE
, {.dbl
=1}, INT32_MIN
, INT32_MAX
, FLAGS
},
1681 {"a1", NULL
, OFFSET(oa
[1]), AV_OPT_TYPE_DOUBLE
, {.dbl
=0}, INT32_MIN
, INT32_MAX
, FLAGS
},
1682 {"a2", NULL
, OFFSET(oa
[2]), AV_OPT_TYPE_DOUBLE
, {.dbl
=0}, INT32_MIN
, INT32_MAX
, FLAGS
},
1683 {"b0", NULL
, OFFSET(ob
[0]), AV_OPT_TYPE_DOUBLE
, {.dbl
=0}, INT32_MIN
, INT32_MAX
, FLAGS
},
1684 {"b1", NULL
, OFFSET(ob
[1]), AV_OPT_TYPE_DOUBLE
, {.dbl
=0}, INT32_MIN
, INT32_MAX
, FLAGS
},
1685 {"b2", NULL
, OFFSET(ob
[2]), AV_OPT_TYPE_DOUBLE
, {.dbl
=0}, INT32_MIN
, INT32_MAX
, FLAGS
},
1686 MIX_CHANNELS_NORMALIZE_OPTION(1, "all", 0),
1687 TRANSFORM_OPTION(DI
),
1688 PRECISION_OPTION(-1),
1689 BLOCKSIZE_OPTION(0),
1693 DEFINE_BIQUAD_FILTER(biquad
, "Apply a biquad IIR filter with the given coefficients.");
1694 #endif /* CONFIG_BIQUAD_FILTER */