FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavfilter/af_biquads.c
Date: 2024-11-20 23:03:26
Exec Total Coverage
Lines: 0 729 0.0%
Functions: 0 53 0.0%
Branches: 0 450 0.0%

Line Branch Exec Source
1 /*
2 * Copyright (c) 2013 Paul B Mahol
3 * Copyright (c) 2006-2008 Rob Sykes <robs@users.sourceforge.net>
4 *
5 * This file is part of FFmpeg.
6 *
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.
11 *
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.
16 *
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
20 */
21
22 /*
23 * 2-pole filters designed by Robert Bristow-Johnson <rbj@audioimagination.com>
24 * see http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt
25 *
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
29 *
30 * low-pass: output[N] = input[N] * A + output[N-1] * B
31 * X = exp(-2.0 * pi * Fc)
32 * A = 1 - X
33 * B = X
34 * Fc = cutoff freq / sample rate
35 *
36 * Mimics an RC low-pass filter:
37 *
38 * ---/\/\/\/\----------->
39 * |
40 * --- C
41 * ---
42 * |
43 * |
44 * V
45 *
46 * high-pass: output[N] = A0 * input[N] + A1 * input[N-1] + B1 * output[N-1]
47 * X = exp(-2.0 * pi * Fc)
48 * A0 = (1 + X) / 2
49 * A1 = -(1 + X) / 2
50 * B1 = X
51 * Fc = cutoff freq / sample rate
52 *
53 * Mimics an RC high-pass filter:
54 *
55 * || C
56 * ----||--------->
57 * || |
58 * <
59 * > R
60 * <
61 * |
62 * V
63 */
64
65 #include "config_components.h"
66
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"
72 #include "audio.h"
73 #include "avfilter.h"
74 #include "filters.h"
75 #include "formats.h"
76
77 enum FilterType {
78 biquad,
79 equalizer,
80 bass,
81 treble,
82 bandpass,
83 bandreject,
84 allpass,
85 highpass,
86 lowpass,
87 lowshelf,
88 highshelf,
89 tiltshelf,
90 };
91
92 enum WidthType {
93 NONE,
94 HERTZ,
95 OCTAVE,
96 QFACTOR,
97 SLOPE,
98 KHERTZ,
99 NB_WTYPE,
100 };
101
102 enum TransformType {
103 DI,
104 DII,
105 TDI,
106 TDII,
107 LATT,
108 SVF,
109 ZDF,
110 NB_TTYPE,
111 };
112
113 typedef struct BiquadsContext {
114 const AVClass *class;
115
116 enum FilterType filter_type;
117 int width_type;
118 int poles;
119 int csg;
120 int transform_type;
121 int precision;
122 int block_samples;
123
124 int bypass;
125
126 double gain;
127 double frequency;
128 double width;
129 double mix;
130 char *ch_layout_str;
131 AVChannelLayout ch_layout;
132 int normalize;
133 int order;
134
135 double a_double[3];
136 double b_double[3];
137
138 float a_float[3];
139 float b_float[3];
140
141 double oa[3];
142 double ob[3];
143
144 AVFrame *block[3];
145
146 int *clip;
147 AVFrame *cache[2];
148 int block_align;
149
150 int64_t pts;
151 int nb_samples;
152
153 void (*filter)(struct BiquadsContext *s, const void *ibuf, void *obuf, int len,
154 void *cache, int *clip, int disabled);
155 } BiquadsContext;
156
157 static int query_formats(const AVFilterContext *ctx,
158 AVFilterFormatsConfig **cfg_in,
159 AVFilterFormatsConfig **cfg_out)
160 {
161 const BiquadsContext *s = ctx->priv;
162 static const enum AVSampleFormat auto_sample_fmts[] = {
163 AV_SAMPLE_FMT_S16P,
164 AV_SAMPLE_FMT_S32P,
165 AV_SAMPLE_FMT_FLTP,
166 AV_SAMPLE_FMT_DBLP,
167 AV_SAMPLE_FMT_NONE
168 };
169 enum AVSampleFormat sample_fmts[] = {
170 AV_SAMPLE_FMT_S16P,
171 AV_SAMPLE_FMT_NONE
172 };
173 const enum AVSampleFormat *sample_fmts_list = sample_fmts;
174 int ret;
175
176 switch (s->precision) {
177 case 0:
178 sample_fmts[0] = AV_SAMPLE_FMT_S16P;
179 break;
180 case 1:
181 sample_fmts[0] = AV_SAMPLE_FMT_S32P;
182 break;
183 case 2:
184 sample_fmts[0] = AV_SAMPLE_FMT_FLTP;
185 break;
186 case 3:
187 sample_fmts[0] = AV_SAMPLE_FMT_DBLP;
188 break;
189 default:
190 sample_fmts_list = auto_sample_fmts;
191 break;
192 }
193 ret = ff_set_common_formats_from_list2(ctx, cfg_in, cfg_out, sample_fmts_list);
194 if (ret < 0)
195 return ret;
196
197 return 0;
198 }
199
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) \
204 { \
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; \
211 ftype a1 = -a[1]; \
212 ftype a2 = -a[2]; \
213 ftype b0 = b[0]; \
214 ftype b1 = b[1]; \
215 ftype b2 = b[2]; \
216 ftype wet = s->mix; \
217 ftype dry = 1. - wet; \
218 ftype out; \
219 int i; \
220 \
221 for (i = 0; i+1 < len; i++) { \
222 o2 = i2 * b2 + i1 * b1 + ibuf[i] * b0 + o2 * a2 + o1 * a1; \
223 i2 = ibuf[i]; \
224 out = o2 * wet + i2 * dry; \
225 if (disabled) { \
226 obuf[i] = i2; \
227 } else if (need_clipping && out < min) { \
228 (*clippings)++; \
229 obuf[i] = min; \
230 } else if (need_clipping && out > max) { \
231 (*clippings)++; \
232 obuf[i] = max; \
233 } else { \
234 obuf[i] = out; \
235 } \
236 i++; \
237 o1 = i1 * b2 + i2 * b1 + ibuf[i] * b0 + o1 * a2 + o2 * a1; \
238 i1 = ibuf[i]; \
239 out = o1 * wet + i1 * dry; \
240 if (disabled) { \
241 obuf[i] = i1; \
242 } else if (need_clipping && out < min) { \
243 (*clippings)++; \
244 obuf[i] = min; \
245 } else if (need_clipping && out > max) { \
246 (*clippings)++; \
247 obuf[i] = max; \
248 } else { \
249 obuf[i] = out; \
250 } \
251 } \
252 if (i < len) { \
253 ftype o0 = ibuf[i] * b0 + i1 * b1 + i2 * b2 + o1 * a1 + o2 * a2; \
254 i2 = i1; \
255 i1 = ibuf[i]; \
256 o2 = o1; \
257 o1 = o0; \
258 out = o0 * wet + i1 * dry; \
259 if (disabled) { \
260 obuf[i] = i1; \
261 } else if (need_clipping && out < min) { \
262 (*clippings)++; \
263 obuf[i] = min; \
264 } else if (need_clipping && out > max) { \
265 (*clippings)++; \
266 obuf[i] = max; \
267 } else { \
268 obuf[i] = out; \
269 } \
270 } \
271 fcache[0] = i1; \
272 fcache[1] = i2; \
273 fcache[2] = o1; \
274 fcache[3] = o2; \
275 }
276
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)
281
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) \
286 { \
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; \
292 ftype a1 = -a[1]; \
293 ftype a2 = -a[2]; \
294 ftype b0 = b[0]; \
295 ftype b1 = b[1]; \
296 ftype b2 = b[2]; \
297 ftype w1 = fcache[0]; \
298 ftype w2 = fcache[1]; \
299 ftype wet = s->mix; \
300 ftype dry = 1. - wet; \
301 ftype in, out, w0; \
302 \
303 for (int i = 0; i < len; i++) { \
304 in = ibuf[i]; \
305 w0 = in + a1 * w1 + a2 * w2; \
306 out = b0 * w0 + b1 * w1 + b2 * w2; \
307 w2 = w1; \
308 w1 = w0; \
309 out = out * wet + in * dry; \
310 if (disabled) { \
311 obuf[i] = in; \
312 } else if (need_clipping && out < min) { \
313 (*clippings)++; \
314 obuf[i] = min; \
315 } else if (need_clipping && out > max) { \
316 (*clippings)++; \
317 obuf[i] = max; \
318 } else { \
319 obuf[i] = out; \
320 } \
321 } \
322 fcache[0] = w1; \
323 fcache[1] = w2; \
324 }
325
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)
330
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) \
335 { \
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; \
341 ftype a1 = -a[1]; \
342 ftype a2 = -a[2]; \
343 ftype b0 = b[0]; \
344 ftype b1 = b[1]; \
345 ftype b2 = b[2]; \
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; \
352 ftype in, out; \
353 \
354 for (int i = 0; i < len; i++) { \
355 ftype t1, t2, t3, t4; \
356 in = ibuf[i] + s1; \
357 t1 = in * a1 + s2; \
358 t2 = in * a2; \
359 t3 = in * b1 + s4; \
360 t4 = in * b2; \
361 out = b0 * in + s3; \
362 out = out * wet + in * dry; \
363 s1 = t1; s2 = t2; s3 = t3; s4 = t4; \
364 if (disabled) { \
365 obuf[i] = in; \
366 } else if (need_clipping && out < min) { \
367 (*clippings)++; \
368 obuf[i] = min; \
369 } else if (need_clipping && out > max) { \
370 (*clippings)++; \
371 obuf[i] = max; \
372 } else { \
373 obuf[i] = out; \
374 } \
375 } \
376 \
377 fcache[0] = s1; \
378 fcache[1] = s2; \
379 fcache[2] = s3; \
380 fcache[3] = s4; \
381 }
382
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)
387
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) \
392 { \
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; \
398 ftype a1 = -a[1]; \
399 ftype a2 = -a[2]; \
400 ftype b0 = b[0]; \
401 ftype b1 = b[1]; \
402 ftype b2 = b[2]; \
403 ftype w1 = fcache[0]; \
404 ftype w2 = fcache[1]; \
405 ftype wet = s->mix; \
406 ftype dry = 1. - wet; \
407 ftype in, out; \
408 \
409 for (int i = 0; i < len; i++) { \
410 in = ibuf[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; \
415 if (disabled) { \
416 obuf[i] = in; \
417 } else if (need_clipping && out < min) { \
418 (*clippings)++; \
419 obuf[i] = min; \
420 } else if (need_clipping && out > max) { \
421 (*clippings)++; \
422 obuf[i] = max; \
423 } else { \
424 obuf[i] = out; \
425 } \
426 } \
427 fcache[0] = w1; \
428 fcache[1] = w2; \
429 }
430
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)
435
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) \
440 { \
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; \
446 ftype k0 = a[1]; \
447 ftype k1 = a[2]; \
448 ftype v0 = b[0]; \
449 ftype v1 = b[1]; \
450 ftype v2 = b[2]; \
451 ftype s0 = fcache[0]; \
452 ftype s1 = fcache[1]; \
453 ftype wet = s->mix; \
454 ftype dry = 1. - wet; \
455 ftype in, out; \
456 ftype t0, t1; \
457 \
458 for (int i = 0; i < len; i++) { \
459 out = 0.; \
460 in = ibuf[i]; \
461 t0 = in - k1 * s0; \
462 t1 = t0 * k1 + s0; \
463 out += t1 * v2; \
464 \
465 t0 = t0 - k0 * s1; \
466 t1 = t0 * k0 + s1; \
467 out += t1 * v1; \
468 \
469 out += t0 * v0; \
470 s0 = t1; \
471 s1 = t0; \
472 \
473 out = out * wet + in * dry; \
474 if (disabled) { \
475 obuf[i] = in; \
476 } else if (need_clipping && out < min) { \
477 (*clippings)++; \
478 obuf[i] = min; \
479 } else if (need_clipping && out > max) { \
480 (*clippings)++; \
481 obuf[i] = max; \
482 } else { \
483 obuf[i] = out; \
484 } \
485 } \
486 fcache[0] = s0; \
487 fcache[1] = s1; \
488 }
489
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)
494
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) \
499 { \
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; \
505 ftype a1 = a[1]; \
506 ftype a2 = a[2]; \
507 ftype b0 = b[0]; \
508 ftype b1 = b[1]; \
509 ftype b2 = b[2]; \
510 ftype s0 = fcache[0]; \
511 ftype s1 = fcache[1]; \
512 ftype wet = s->mix; \
513 ftype dry = 1. - wet; \
514 ftype in, out; \
515 ftype t0, t1; \
516 \
517 for (int i = 0; i < len; i++) { \
518 in = ibuf[i]; \
519 out = b2 * in + s0; \
520 t0 = b0 * in + a1 * s0 + s1; \
521 t1 = b1 * in + a2 * s0; \
522 s0 = t0; \
523 s1 = t1; \
524 \
525 out = out * wet + in * dry; \
526 if (disabled) { \
527 obuf[i] = in; \
528 } else if (need_clipping && out < min) { \
529 (*clippings)++; \
530 obuf[i] = min; \
531 } else if (need_clipping && out > max) { \
532 (*clippings)++; \
533 obuf[i] = max; \
534 } else { \
535 obuf[i] = out; \
536 } \
537 } \
538 fcache[0] = s0; \
539 fcache[1] = s1; \
540 }
541
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)
546
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) \
551 { \
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; \
557 ftype m0 = b[0]; \
558 ftype m1 = b[1]; \
559 ftype m2 = b[2]; \
560 ftype a0 = a[0]; \
561 ftype a1 = a[1]; \
562 ftype a2 = a[2]; \
563 ftype b0 = fcache[0]; \
564 ftype b1 = fcache[1]; \
565 ftype wet = s->mix; \
566 ftype dry = 1. - wet; \
567 ftype out; \
568 \
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; \
575 \
576 b0 = two * v1 - b0; \
577 b1 = two * v2 - b1; \
578 \
579 out = m0 * v0 + m1 * v1 + m2 * v2; \
580 out = out * wet + in * dry; \
581 if (disabled) { \
582 obuf[i] = in; \
583 } else if (need_clipping && out < min) { \
584 (*clippings)++; \
585 obuf[i] = min; \
586 } else if (need_clipping && out > max) { \
587 (*clippings)++; \
588 obuf[i] = max; \
589 } else { \
590 obuf[i] = out; \
591 } \
592 } \
593 fcache[0] = b0; \
594 fcache[1] = b1; \
595 }
596
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)
601
602 static void convert_dir2latt(BiquadsContext *s)
603 {
604 double k0, k1, v0, v1, v2;
605
606 k1 = s->a_double[2];
607 k0 = s->a_double[1] / (1. + k1);
608 v2 = s->b_double[2];
609 v1 = s->b_double[1] - v2 * s->a_double[1];
610 v0 = s->b_double[0] - v1 * k0 - v2 * k1;
611
612 s->a_double[1] = k0;
613 s->a_double[2] = k1;
614 s->b_double[0] = v0;
615 s->b_double[1] = v1;
616 s->b_double[2] = v2;
617 }
618
619 static void convert_dir2svf(BiquadsContext *s)
620 {
621 double a[2];
622 double b[3];
623
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];
629
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];
635 }
636
637 static double convert_width2qfactor(double width,
638 double frequency,
639 double gain,
640 double sample_rate,
641 int width_type)
642 {
643 double w0 = 2. * M_PI * frequency / sample_rate;
644 double A = ff_exp10(gain / 40.);
645 double ret;
646
647 switch (width_type) {
648 case NONE:
649 case QFACTOR:
650 ret = width;
651 break;
652 case HERTZ:
653 ret = frequency / width;
654 break;
655 case KHERTZ:
656 ret = frequency / (width * 1000.);
657 break;
658 case OCTAVE:
659 ret = 1. / (2. * sinh(log(2.) / 2. * width * w0 / sin(w0)));
660 break;
661 case SLOPE:
662 ret = 1. / sqrt((A + 1. / A) * (1. / width - 1.) + 2.);
663 break;
664 default:
665 av_assert0(0);
666 break;
667 }
668
669 return ret;
670 }
671
672 static void convert_dir2zdf(BiquadsContext *s, int sample_rate)
673 {
674 double Q = convert_width2qfactor(s->width, s->frequency, s->gain, sample_rate, s->width_type);
675 double g, k, A;
676 double a[3];
677 double m[3];
678
679 switch (s->filter_type) {
680 case biquad:
681 a[0] = s->oa[0];
682 a[1] = s->oa[1];
683 a[2] = s->oa[2];
684 m[0] = s->ob[0];
685 m[1] = s->ob[1];
686 m[2] = s->ob[2];
687 break;
688 case equalizer:
689 A = ff_exp10(s->gain / 40.);
690 g = tan(M_PI * s->frequency / sample_rate);
691 k = 1. / (Q * A);
692 a[0] = 1. / (1. + g * (g + k));
693 a[1] = g * a[0];
694 a[2] = g * a[1];
695 m[0] = 1.;
696 m[1] = k * (A * A - 1.);
697 m[2] = 0.;
698 break;
699 case bass:
700 case lowshelf:
701 A = ff_exp10(s->gain / 40.);
702 g = tan(M_PI * s->frequency / sample_rate) / sqrt(A);
703 k = 1. / Q;
704 a[0] = 1. / (1. + g * (g + k));
705 a[1] = g * a[0];
706 a[2] = g * a[1];
707 m[0] = 1.;
708 m[1] = k * (A - 1.);
709 m[2] = A * A - 1.;
710 break;
711 case tiltshelf:
712 A = ff_exp10(s->gain / 20.);
713 g = tan(M_PI * s->frequency / sample_rate) / sqrt(A);
714 k = 1. / Q;
715 a[0] = 1. / (1. + g * (g + k));
716 a[1] = g * a[0];
717 a[2] = g * a[1];
718 m[0] = 1./ A;
719 m[1] = k * (A - 1.) / A;
720 m[2] = (A * A - 1.) / A;
721 break;
722 case treble:
723 case highshelf:
724 A = ff_exp10(s->gain / 40.);
725 g = tan(M_PI * s->frequency / sample_rate) * sqrt(A);
726 k = 1. / Q;
727 a[0] = 1. / (1. + g * (g + k));
728 a[1] = g * a[0];
729 a[2] = g * a[1];
730 m[0] = A * A;
731 m[1] = k * (1. - A) * A;
732 m[2] = 1. - A * A;
733 break;
734 case bandpass:
735 g = tan(M_PI * s->frequency / sample_rate);
736 k = 1. / Q;
737 a[0] = 1. / (1. + g * (g + k));
738 a[1] = g * a[0];
739 a[2] = g * a[1];
740 m[0] = 0.;
741 m[1] = s->csg ? 1. : k;
742 m[2] = 0.;
743 break;
744 case bandreject:
745 g = tan(M_PI * s->frequency / sample_rate);
746 k = 1. / Q;
747 a[0] = 1. / (1. + g * (g + k));
748 a[1] = g * a[0];
749 a[2] = g * a[1];
750 m[0] = 1.;
751 m[1] = -k;
752 m[2] = 0.;
753 break;
754 case lowpass:
755 g = tan(M_PI * s->frequency / sample_rate);
756 k = 1. / Q;
757 a[0] = 1. / (1. + g * (g + k));
758 a[1] = g * a[0];
759 a[2] = g * a[1];
760 m[0] = 0.;
761 m[1] = 0.;
762 m[2] = 1.;
763 break;
764 case highpass:
765 g = tan(M_PI * s->frequency / sample_rate);
766 k = 1. / Q;
767 a[0] = 1. / (1. + g * (g + k));
768 a[1] = g * a[0];
769 a[2] = g * a[1];
770 m[0] = 1.;
771 m[1] = -k;
772 m[2] = -1.;
773 break;
774 case allpass:
775 g = tan(M_PI * s->frequency / sample_rate);
776 k = 1. / Q;
777 a[0] = 1. / (1. + g * (g + k));
778 a[1] = g * a[0];
779 a[2] = g * a[1];
780 m[0] = 1.;
781 m[1] = -2. * k;
782 m[2] = 0.;
783 break;
784 default:
785 av_assert0(0);
786 }
787
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];
794 }
795
796 static int config_filter(AVFilterLink *outlink, int reset)
797 {
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.);
805 double alpha, beta;
806
807 s->bypass = (((w0 > M_PI || w0 <= 0.) && reset) || (s->width <= 0.)) && (s->filter_type != biquad);
808 if (s->bypass) {
809 av_log(ctx, AV_LOG_WARNING, "Invalid frequency and/or width!\n");
810 return 0;
811 }
812
813 if ((w0 > M_PI || w0 <= 0.) && (s->filter_type != biquad))
814 return AVERROR(EINVAL);
815
816 switch (s->width_type) {
817 case NONE:
818 alpha = 0.0;
819 break;
820 case HERTZ:
821 alpha = sin(w0) / (2 * s->frequency / s->width);
822 break;
823 case KHERTZ:
824 alpha = sin(w0) / (2 * s->frequency / (s->width * 1000));
825 break;
826 case OCTAVE:
827 alpha = sin(w0) * sinh(log(2.) / 2 * s->width * w0 / sin(w0));
828 break;
829 case QFACTOR:
830 alpha = sin(w0) / (2 * s->width);
831 break;
832 case SLOPE:
833 alpha = sin(w0) / 2 * sqrt((A + 1 / A) * (1 / s->width - 1) + 2);
834 break;
835 default:
836 av_assert0(0);
837 }
838
839 beta = 2 * sqrt(A);
840
841 switch (s->filter_type) {
842 case biquad:
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];
849 break;
850 case equalizer:
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;
857 break;
858 case bass:
859 beta = sqrt((A * A + 1) - (A - 1) * (A - 1));
860 case tiltshelf:
861 case lowshelf:
862 if (s->poles == 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;
869
870 s->a_double[0] = 1 + ro * alpha1;
871 s->a_double[1] = -ro - alpha1;
872 s->a_double[2] = 0;
873 s->b_double[0] = beta0 + ro * beta1;
874 s->b_double[1] = -beta1 - ro * beta0;
875 s->b_double[2] = 0;
876 } else {
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);
883 }
884 break;
885 case treble:
886 beta = sqrt((A * A + 1) - (A - 1) * (A - 1));
887 case highshelf:
888 if (s->poles == 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;
895
896 s->a_double[0] = 1 + ro * alpha1;
897 s->a_double[1] = ro + alpha1;
898 s->a_double[2] = 0;
899 s->b_double[0] = beta0 + ro * beta1;
900 s->b_double[1] = beta1 + ro * beta0;
901 s->b_double[2] = 0;
902 } else {
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);
909 }
910 break;
911 case bandpass:
912 if (s->csg) {
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;
917 s->b_double[1] = 0;
918 s->b_double[2] = -sin(w0) / 2;
919 } else {
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;
924 s->b_double[1] = 0;
925 s->b_double[2] = -alpha;
926 }
927 break;
928 case bandreject:
929 s->a_double[0] = 1 + alpha;
930 s->a_double[1] = -2 * cos(w0);
931 s->a_double[2] = 1 - alpha;
932 s->b_double[0] = 1;
933 s->b_double[1] = -2 * cos(w0);
934 s->b_double[2] = 1;
935 break;
936 case lowpass:
937 if (s->poles == 1) {
938 s->a_double[0] = 1;
939 s->a_double[1] = -exp(-w0);
940 s->a_double[2] = 0;
941 s->b_double[0] = 1 + s->a_double[1];
942 s->b_double[1] = 0;
943 s->b_double[2] = 0;
944 } else {
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;
951 }
952 break;
953 case highpass:
954 if (s->poles == 1) {
955 s->a_double[0] = 1;
956 s->a_double[1] = -exp(-w0);
957 s->a_double[2] = 0;
958 s->b_double[0] = (1 - s->a_double[1]) / 2;
959 s->b_double[1] = -s->b_double[0];
960 s->b_double[2] = 0;
961 } else {
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;
968 }
969 break;
970 case allpass:
971 switch (s->order) {
972 case 1:
973 s->a_double[0] = 1.;
974 s->a_double[1] = -(1. - K) / (1. + K);
975 s->a_double[2] = 0.;
976 s->b_double[0] = s->a_double[1];
977 s->b_double[1] = s->a_double[0];
978 s->b_double[2] = 0.;
979 break;
980 case 2:
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;
987 break;
988 }
989 break;
990 default:
991 av_assert0(0);
992 }
993
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]);
997
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];
1004
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]);
1008
1009 s->b_double[0] *= factor;
1010 s->b_double[1] *= factor;
1011 s->b_double[2] *= factor;
1012 }
1013
1014 switch (s->filter_type) {
1015 case tiltshelf:
1016 s->b_double[0] /= A;
1017 s->b_double[1] /= A;
1018 s->b_double[2] /= A;
1019 break;
1020 }
1021
1022 if (!s->cache[0])
1023 s->cache[0] = ff_get_audio_buffer(outlink, 4 * sizeof(double));
1024 if (!s->clip)
1025 s->clip = av_calloc(outlink->ch_layout.nb_channels, sizeof(*s->clip));
1026 if (!s->cache[0] || !s->clip)
1027 return AVERROR(ENOMEM);
1028 if (reset) {
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);
1031 }
1032
1033 if (reset && s->block_samples > 0) {
1034 if (!s->cache[1])
1035 s->cache[1] = ff_get_audio_buffer(outlink, 4 * sizeof(double));
1036 if (!s->cache[1])
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++) {
1041 if (!s->block[i])
1042 s->block[i] = ff_get_audio_buffer(outlink, s->block_samples * 2);
1043 if (!s->block[i])
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);
1047 }
1048 }
1049
1050 switch (s->transform_type) {
1051 case DI:
1052 switch (inlink->format) {
1053 case AV_SAMPLE_FMT_S16P:
1054 s->filter = biquad_s16;
1055 break;
1056 case AV_SAMPLE_FMT_S32P:
1057 s->filter = biquad_s32;
1058 break;
1059 case AV_SAMPLE_FMT_FLTP:
1060 s->filter = biquad_flt;
1061 break;
1062 case AV_SAMPLE_FMT_DBLP:
1063 s->filter = biquad_dbl;
1064 break;
1065 default: av_assert0(0);
1066 }
1067 break;
1068 case DII:
1069 switch (inlink->format) {
1070 case AV_SAMPLE_FMT_S16P:
1071 s->filter = biquad_dii_s16;
1072 break;
1073 case AV_SAMPLE_FMT_S32P:
1074 s->filter = biquad_dii_s32;
1075 break;
1076 case AV_SAMPLE_FMT_FLTP:
1077 s->filter = biquad_dii_flt;
1078 break;
1079 case AV_SAMPLE_FMT_DBLP:
1080 s->filter = biquad_dii_dbl;
1081 break;
1082 default: av_assert0(0);
1083 }
1084 break;
1085 case TDI:
1086 switch (inlink->format) {
1087 case AV_SAMPLE_FMT_S16P:
1088 s->filter = biquad_tdi_s16;
1089 break;
1090 case AV_SAMPLE_FMT_S32P:
1091 s->filter = biquad_tdi_s32;
1092 break;
1093 case AV_SAMPLE_FMT_FLTP:
1094 s->filter = biquad_tdi_flt;
1095 break;
1096 case AV_SAMPLE_FMT_DBLP:
1097 s->filter = biquad_tdi_dbl;
1098 break;
1099 default: av_assert0(0);
1100 }
1101 break;
1102 case TDII:
1103 switch (inlink->format) {
1104 case AV_SAMPLE_FMT_S16P:
1105 s->filter = biquad_tdii_s16;
1106 break;
1107 case AV_SAMPLE_FMT_S32P:
1108 s->filter = biquad_tdii_s32;
1109 break;
1110 case AV_SAMPLE_FMT_FLTP:
1111 s->filter = biquad_tdii_flt;
1112 break;
1113 case AV_SAMPLE_FMT_DBLP:
1114 s->filter = biquad_tdii_dbl;
1115 break;
1116 default: av_assert0(0);
1117 }
1118 break;
1119 case LATT:
1120 switch (inlink->format) {
1121 case AV_SAMPLE_FMT_S16P:
1122 s->filter = biquad_latt_s16;
1123 break;
1124 case AV_SAMPLE_FMT_S32P:
1125 s->filter = biquad_latt_s32;
1126 break;
1127 case AV_SAMPLE_FMT_FLTP:
1128 s->filter = biquad_latt_flt;
1129 break;
1130 case AV_SAMPLE_FMT_DBLP:
1131 s->filter = biquad_latt_dbl;
1132 break;
1133 default: av_assert0(0);
1134 }
1135 break;
1136 case SVF:
1137 switch (inlink->format) {
1138 case AV_SAMPLE_FMT_S16P:
1139 s->filter = biquad_svf_s16;
1140 break;
1141 case AV_SAMPLE_FMT_S32P:
1142 s->filter = biquad_svf_s32;
1143 break;
1144 case AV_SAMPLE_FMT_FLTP:
1145 s->filter = biquad_svf_flt;
1146 break;
1147 case AV_SAMPLE_FMT_DBLP:
1148 s->filter = biquad_svf_dbl;
1149 break;
1150 default: av_assert0(0);
1151 }
1152 break;
1153 case ZDF:
1154 switch (inlink->format) {
1155 case AV_SAMPLE_FMT_S16P:
1156 s->filter = biquad_zdf_s16;
1157 break;
1158 case AV_SAMPLE_FMT_S32P:
1159 s->filter = biquad_zdf_s32;
1160 break;
1161 case AV_SAMPLE_FMT_FLTP:
1162 s->filter = biquad_zdf_flt;
1163 break;
1164 case AV_SAMPLE_FMT_DBLP:
1165 s->filter = biquad_zdf_dbl;
1166 break;
1167 default: av_assert0(0);
1168 }
1169 break;
1170 default:
1171 av_assert0(0);
1172 }
1173
1174 s->block_align = av_get_bytes_per_sample(inlink->format);
1175
1176 if (s->transform_type == LATT)
1177 convert_dir2latt(s);
1178 else if (s->transform_type == SVF)
1179 convert_dir2svf(s);
1180 else if (s->transform_type == ZDF)
1181 convert_dir2zdf(s, inlink->sample_rate);
1182
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];
1189
1190 return 0;
1191 }
1192
1193 static int config_output(AVFilterLink *outlink)
1194 {
1195 return config_filter(outlink, 1);
1196 }
1197
1198 typedef struct ThreadData {
1199 AVFrame *in, *out;
1200 int eof;
1201 } ThreadData;
1202
1203 static void reverse_samples(AVFrame *out, AVFrame *in, int p,
1204 int oo, int io, int nb_samples)
1205 {
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--)
1211 dst[i] = src[j];
1212 }
1213 break;
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--)
1218 dst[i] = src[j];
1219 }
1220 break;
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--)
1225 dst[i] = src[j];
1226 }
1227 break;
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--)
1232 dst[i] = src[j];
1233 }
1234 break;
1235 }
1236 }
1237
1238 static int filter_channel(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
1239 {
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;
1247 int ch;
1248
1249 for (ch = start; ch < end; ch++) {
1250 enum AVChannel channel = av_channel_layout_channel_from_index(&inlink->ch_layout, ch);
1251
1252 if (av_channel_layout_index_from_channel(&s->ch_layout, channel) < 0) {
1253 if (buf != out_buf)
1254 memcpy(out_buf->extended_data[ch], buf->extended_data[ch],
1255 buf->nb_samples * s->block_align);
1256 continue;
1257 }
1258
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);
1265 } else {
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,
1278 ctx->is_disabled);
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);
1289 }
1290 }
1291
1292 return 0;
1293 }
1294
1295 static int filter_frame(AVFilterLink *inlink, AVFrame *buf, int eof)
1296 {
1297 AVFilterContext *ctx = inlink->dst;
1298 BiquadsContext *s = ctx->priv;
1299 AVFilterLink *outlink = ctx->outputs[0];
1300 AVFrame *out_buf;
1301 ThreadData td;
1302 int ch, ret, drop = 0;
1303
1304 if (s->bypass)
1305 return ff_filter_frame(outlink, buf);
1306
1307 ret = av_channel_layout_copy(&s->ch_layout, &inlink->ch_layout);
1308 if (ret < 0) {
1309 av_frame_free(&buf);
1310 return ret;
1311 }
1312 if (strcmp(s->ch_layout_str, "all"))
1313 av_channel_layout_from_string(&s->ch_layout,
1314 s->ch_layout_str);
1315
1316 if (av_frame_is_writable(buf) && s->block_samples == 0) {
1317 out_buf = buf;
1318 } else {
1319 out_buf = ff_get_audio_buffer(outlink, s->block_samples > 0 ? s->block_samples : buf->nb_samples);
1320 if (!out_buf) {
1321 av_frame_free(&buf);
1322 return AVERROR(ENOMEM);
1323 }
1324 av_frame_copy_props(out_buf, buf);
1325 }
1326
1327 if (s->block_samples > 0 && s->pts == AV_NOPTS_VALUE)
1328 drop = 1;
1329 td.in = buf;
1330 td.out = out_buf;
1331 td.eof = eof;
1332 ff_filter_execute(ctx, filter_channel, &td, NULL,
1333 FFMIN(outlink->ch_layout.nb_channels, ff_filter_get_nb_threads(ctx)));
1334
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",
1338 ch, s->clip[ch]);
1339 s->clip[ch] = 0;
1340 }
1341
1342 if (s->block_samples > 0) {
1343 int nb_samples = buf->nb_samples;
1344 int64_t pts = buf->pts;
1345
1346 out_buf->pts = s->pts;
1347 out_buf->nb_samples = s->nb_samples;
1348 s->pts = pts;
1349 s->nb_samples = nb_samples;
1350 }
1351
1352 if (buf != out_buf)
1353 av_frame_free(&buf);
1354
1355 if (!drop)
1356 return ff_filter_frame(outlink, out_buf);
1357 else {
1358 av_frame_free(&out_buf);
1359 ff_filter_set_ready(ctx, 10);
1360 return 0;
1361 }
1362 }
1363
1364 static int activate(AVFilterContext *ctx)
1365 {
1366 AVFilterLink *inlink = ctx->inputs[0];
1367 AVFilterLink *outlink = ctx->outputs[0];
1368 BiquadsContext *s = ctx->priv;
1369 AVFrame *in = NULL;
1370 int64_t pts;
1371 int status;
1372 int ret;
1373
1374 FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink);
1375
1376 if (s->block_samples > 0) {
1377 ret = ff_inlink_consume_samples(inlink, s->block_samples, s->block_samples, &in);
1378 } else {
1379 ret = ff_inlink_consume_frame(inlink, &in);
1380 }
1381 if (ret < 0)
1382 return ret;
1383 if (ret > 0)
1384 return filter_frame(inlink, in, 0);
1385
1386 if (s->block_samples > 0 && ff_inlink_queued_samples(inlink) >= s->block_samples) {
1387 ff_filter_set_ready(ctx, 10);
1388 return 0;
1389 }
1390
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);
1394 if (!in)
1395 return AVERROR(ENOMEM);
1396
1397 ret = filter_frame(inlink, in, 1);
1398 }
1399
1400 ff_outlink_set_status(outlink, status, pts);
1401
1402 return ret;
1403 }
1404
1405 FF_FILTER_FORWARD_WANTED(outlink, inlink);
1406
1407 return FFERROR_NOT_READY;
1408 }
1409
1410 static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
1411 char *res, int res_len, int flags)
1412 {
1413 AVFilterLink *outlink = ctx->outputs[0];
1414 int ret;
1415
1416 ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags);
1417 if (ret < 0)
1418 return ret;
1419
1420 return config_filter(outlink, 0);
1421 }
1422
1423 static av_cold void uninit(AVFilterContext *ctx)
1424 {
1425 BiquadsContext *s = ctx->priv;
1426
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]);
1431 av_freep(&s->clip);
1432 av_channel_layout_uninit(&s->ch_layout);
1433 }
1434
1435 static const AVFilterPad outputs[] = {
1436 {
1437 .name = "default",
1438 .type = AVMEDIA_TYPE_AUDIO,
1439 .config_props = config_output,
1440 },
1441 };
1442
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
1446
1447 #define DEFINE_BIQUAD_FILTER_2(name_, description_, priv_class_) \
1448 static av_cold int name_##_init(AVFilterContext *ctx) \
1449 { \
1450 BiquadsContext *s = ctx->priv; \
1451 s->filter_type = name_; \
1452 s->pts = AV_NOPTS_VALUE; \
1453 return 0; \
1454 } \
1455 \
1456 const AVFilter ff_af_##name_ = { \
1457 .name = #name_, \
1458 .description = NULL_IF_CONFIG_SMALL(description_), \
1459 .priv_class = &priv_class_##_class, \
1460 .priv_size = sizeof(BiquadsContext), \
1461 .init = name_##_init, \
1462 .activate = activate, \
1463 .uninit = uninit, \
1464 FILTER_INPUTS(ff_audio_default_filterpad), \
1465 FILTER_OUTPUTS(outputs), \
1466 FILTER_QUERY_FUNC2(query_formats), \
1467 .process_command = process_command, \
1468 .flags = AVFILTER_FLAG_SLICE_THREADS | AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL, \
1469 }
1470
1471 #define DEFINE_BIQUAD_FILTER(name, description) \
1472 AVFILTER_DEFINE_CLASS(name); \
1473 DEFINE_BIQUAD_FILTER_2(name, description, name)
1474
1475 #define WIDTH_OPTION(x) \
1476 {"width", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=x}, 0, 99999, FLAGS}, \
1477 {"w", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=x}, 0, 99999, FLAGS}
1478
1479 #define WIDTH_TYPE_OPTION(x) \
1480 {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=x}, HERTZ, NB_WTYPE-1, FLAGS, .unit = "width_type"}, \
1481 {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=x}, HERTZ, NB_WTYPE-1, FLAGS, .unit = "width_type"}, \
1482 {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, .unit = "width_type"}, \
1483 {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, .unit = "width_type"}, \
1484 {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, .unit = "width_type"}, \
1485 {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, .unit = "width_type"}, \
1486 {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, .unit = "width_type"}
1487
1488 #define MIX_CHANNELS_NORMALIZE_OPTION(x, y, z) \
1489 {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=x}, 0, 1, FLAGS}, \
1490 {"m", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=x}, 0, 1, FLAGS}, \
1491 {"channels", "set channels to filter", OFFSET(ch_layout_str), AV_OPT_TYPE_STRING, {.str=y}, 0, 0, FLAGS}, \
1492 {"c", "set channels to filter", OFFSET(ch_layout_str), AV_OPT_TYPE_STRING, {.str=y}, 0, 0, FLAGS}, \
1493 {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=z}, 0, 1, FLAGS}, \
1494 {"n", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=z}, 0, 1, FLAGS}
1495
1496 #define TRANSFORM_OPTION(x) \
1497 {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=x}, 0, NB_TTYPE-1, AF, .unit = "transform_type"}, \
1498 {"a", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=x}, 0, NB_TTYPE-1, AF, .unit = "transform_type"}, \
1499 {"di", "direct form I", 0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, .unit = "transform_type"}, \
1500 {"dii", "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, .unit = "transform_type"}, \
1501 {"tdi", "transposed direct form I", 0, AV_OPT_TYPE_CONST, {.i64=TDI}, 0, 0, AF, .unit = "transform_type"}, \
1502 {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, .unit = "transform_type"}, \
1503 {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, .unit = "transform_type"}, \
1504 {"svf", "state variable filter form", 0, AV_OPT_TYPE_CONST, {.i64=SVF}, 0, 0, AF, .unit = "transform_type"}, \
1505 {"zdf", "zero-delay filter form", 0, AV_OPT_TYPE_CONST, {.i64=ZDF}, 0, 0, AF, .unit = "transform_type"}
1506
1507 #define PRECISION_OPTION(x) \
1508 {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=x}, -1, 3, AF, .unit = "precision"}, \
1509 {"r", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=x}, -1, 3, AF, .unit = "precision"}, \
1510 {"auto", "automatic", 0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, .unit = "precision"}, \
1511 {"s16", "signed 16-bit", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, .unit = "precision"}, \
1512 {"s32", "signed 32-bit", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, .unit = "precision"}, \
1513 {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, AF, .unit = "precision"}, \
1514 {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, AF, .unit = "precision"}
1515
1516 #define BLOCKSIZE_OPTION(x) \
1517 {"blocksize", "set the block size", OFFSET(block_samples), AV_OPT_TYPE_INT, {.i64=x}, 0, 32768, AF}, \
1518 {"b", "set the block size", OFFSET(block_samples), AV_OPT_TYPE_INT, {.i64=x}, 0, 32768, AF}
1519
1520 #if CONFIG_EQUALIZER_FILTER
1521 static const AVOption equalizer_options[] = {
1522 {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, 999999, FLAGS},
1523 {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, 999999, FLAGS},
1524 WIDTH_TYPE_OPTION(QFACTOR),
1525 WIDTH_OPTION(1.0),
1526 {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
1527 {"g", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
1528 MIX_CHANNELS_NORMALIZE_OPTION(1, "all", 0),
1529 TRANSFORM_OPTION(DI),
1530 PRECISION_OPTION(-1),
1531 BLOCKSIZE_OPTION(0),
1532 {NULL}
1533 };
1534
1535 DEFINE_BIQUAD_FILTER(equalizer, "Apply two-pole peaking equalization (EQ) filter.");
1536 #endif /* CONFIG_EQUALIZER_FILTER */
1537 #if CONFIG_BASS_FILTER || CONFIG_LOWSHELF_FILTER
1538 static const AVOption bass_lowshelf_options[] = {
1539 {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
1540 {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
1541 WIDTH_TYPE_OPTION(QFACTOR),
1542 WIDTH_OPTION(0.5),
1543 {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
1544 {"g", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
1545 {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
1546 {"p", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
1547 MIX_CHANNELS_NORMALIZE_OPTION(1, "all", 0),
1548 TRANSFORM_OPTION(DI),
1549 PRECISION_OPTION(-1),
1550 BLOCKSIZE_OPTION(0),
1551 {NULL}
1552 };
1553
1554 AVFILTER_DEFINE_CLASS_EXT(bass_lowshelf, "bass/lowshelf", bass_lowshelf_options);
1555 #if CONFIG_BASS_FILTER
1556 DEFINE_BIQUAD_FILTER_2(bass, "Boost or cut lower frequencies.", bass_lowshelf);
1557 #endif /* CONFIG_BASS_FILTER */
1558
1559 #if CONFIG_LOWSHELF_FILTER
1560 DEFINE_BIQUAD_FILTER_2(lowshelf, "Apply a low shelf filter.", bass_lowshelf);
1561 #endif /* CONFIG_LOWSHELF_FILTER */
1562 #endif /* CONFIG_BASS_FILTER || CONFIG LOWSHELF_FILTER */
1563 #if CONFIG_TREBLE_FILTER || CONFIG_HIGHSHELF_FILTER || CONFIG_TILTSHELF_FILTER
1564 static const AVOption treble_highshelf_options[] = {
1565 {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1566 {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1567 WIDTH_TYPE_OPTION(QFACTOR),
1568 WIDTH_OPTION(0.5),
1569 {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
1570 {"g", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
1571 {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
1572 {"p", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
1573 MIX_CHANNELS_NORMALIZE_OPTION(1, "all", 0),
1574 TRANSFORM_OPTION(DI),
1575 PRECISION_OPTION(-1),
1576 BLOCKSIZE_OPTION(0),
1577 {NULL}
1578 };
1579
1580 AVFILTER_DEFINE_CLASS_EXT(treble_highshelf, "treble/high/tiltshelf",
1581 treble_highshelf_options);
1582
1583 #if CONFIG_TREBLE_FILTER
1584 DEFINE_BIQUAD_FILTER_2(treble, "Boost or cut upper frequencies.", treble_highshelf);
1585 #endif /* CONFIG_TREBLE_FILTER */
1586
1587 #if CONFIG_HIGHSHELF_FILTER
1588 DEFINE_BIQUAD_FILTER_2(highshelf, "Apply a high shelf filter.", treble_highshelf);
1589 #endif /* CONFIG_HIGHSHELF_FILTER */
1590
1591 #if CONFIG_TILTSHELF_FILTER
1592 DEFINE_BIQUAD_FILTER_2(tiltshelf, "Apply a tilt shelf filter.", treble_highshelf);
1593 #endif
1594 #endif /* CONFIG_TREBLE_FILTER || CONFIG_HIGHSHELF_FILTER || CONFIG_TILTSHELF_FILTER */
1595
1596 #if CONFIG_BANDPASS_FILTER
1597 static const AVOption bandpass_options[] = {
1598 {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1599 {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1600 WIDTH_TYPE_OPTION(QFACTOR),
1601 WIDTH_OPTION(0.5),
1602 {"csg", "use constant skirt gain", OFFSET(csg), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1603 MIX_CHANNELS_NORMALIZE_OPTION(1, "all", 0),
1604 TRANSFORM_OPTION(DI),
1605 PRECISION_OPTION(-1),
1606 BLOCKSIZE_OPTION(0),
1607 {NULL}
1608 };
1609
1610 DEFINE_BIQUAD_FILTER(bandpass, "Apply a two-pole Butterworth band-pass filter.");
1611 #endif /* CONFIG_BANDPASS_FILTER */
1612 #if CONFIG_BANDREJECT_FILTER
1613 static const AVOption bandreject_options[] = {
1614 {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1615 {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1616 WIDTH_TYPE_OPTION(QFACTOR),
1617 WIDTH_OPTION(0.5),
1618 MIX_CHANNELS_NORMALIZE_OPTION(1, "all", 0),
1619 TRANSFORM_OPTION(DI),
1620 PRECISION_OPTION(-1),
1621 BLOCKSIZE_OPTION(0),
1622 {NULL}
1623 };
1624
1625 DEFINE_BIQUAD_FILTER(bandreject, "Apply a two-pole Butterworth band-reject filter.");
1626 #endif /* CONFIG_BANDREJECT_FILTER */
1627 #if CONFIG_LOWPASS_FILTER
1628 static const AVOption lowpass_options[] = {
1629 {"frequency", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=500}, 0, 999999, FLAGS},
1630 {"f", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=500}, 0, 999999, FLAGS},
1631 WIDTH_TYPE_OPTION(QFACTOR),
1632 WIDTH_OPTION(0.707),
1633 {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
1634 {"p", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
1635 MIX_CHANNELS_NORMALIZE_OPTION(1, "all", 0),
1636 TRANSFORM_OPTION(DI),
1637 PRECISION_OPTION(-1),
1638 BLOCKSIZE_OPTION(0),
1639 {NULL}
1640 };
1641
1642 DEFINE_BIQUAD_FILTER(lowpass, "Apply a low-pass filter with 3dB point frequency.");
1643 #endif /* CONFIG_LOWPASS_FILTER */
1644 #if CONFIG_HIGHPASS_FILTER
1645 static const AVOption highpass_options[] = {
1646 {"frequency", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1647 {"f", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1648 WIDTH_TYPE_OPTION(QFACTOR),
1649 WIDTH_OPTION(0.707),
1650 {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
1651 {"p", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
1652 MIX_CHANNELS_NORMALIZE_OPTION(1, "all", 0),
1653 TRANSFORM_OPTION(DI),
1654 PRECISION_OPTION(-1),
1655 BLOCKSIZE_OPTION(0),
1656 {NULL}
1657 };
1658
1659 DEFINE_BIQUAD_FILTER(highpass, "Apply a high-pass filter with 3dB point frequency.");
1660 #endif /* CONFIG_HIGHPASS_FILTER */
1661 #if CONFIG_ALLPASS_FILTER
1662 static const AVOption allpass_options[] = {
1663 {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1664 {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1665 WIDTH_TYPE_OPTION(QFACTOR),
1666 WIDTH_OPTION(0.707),
1667 MIX_CHANNELS_NORMALIZE_OPTION(1, "all", 0),
1668 {"order", "set filter order", OFFSET(order), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
1669 {"o", "set filter order", OFFSET(order), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
1670 TRANSFORM_OPTION(DI),
1671 PRECISION_OPTION(-1),
1672 {NULL}
1673 };
1674
1675 DEFINE_BIQUAD_FILTER(allpass, "Apply a two-pole all-pass filter.");
1676 #endif /* CONFIG_ALLPASS_FILTER */
1677 #if CONFIG_BIQUAD_FILTER
1678 static const AVOption biquad_options[] = {
1679 {"a0", NULL, OFFSET(oa[0]), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT32_MIN, INT32_MAX, FLAGS},
1680 {"a1", NULL, OFFSET(oa[1]), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
1681 {"a2", NULL, OFFSET(oa[2]), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
1682 {"b0", NULL, OFFSET(ob[0]), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
1683 {"b1", NULL, OFFSET(ob[1]), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
1684 {"b2", NULL, OFFSET(ob[2]), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
1685 MIX_CHANNELS_NORMALIZE_OPTION(1, "all", 0),
1686 TRANSFORM_OPTION(DI),
1687 PRECISION_OPTION(-1),
1688 BLOCKSIZE_OPTION(0),
1689 {NULL}
1690 };
1691
1692 DEFINE_BIQUAD_FILTER(biquad, "Apply a biquad IIR filter with the given coefficients.");
1693 #endif /* CONFIG_BIQUAD_FILTER */
1694