FFmpeg
af_acrossover.c
Go to the documentation of this file.
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * FFmpeg is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 /**
20  * @file
21  * Crossover filter
22  *
23  * Split an audio stream into several bands.
24  */
25 
26 #include "libavutil/attributes.h"
27 #include "libavutil/avstring.h"
29 #include "libavutil/eval.h"
30 #include "libavutil/float_dsp.h"
31 #include "libavutil/internal.h"
32 #include "libavutil/opt.h"
33 
34 #include "audio.h"
35 #include "avfilter.h"
36 #include "filters.h"
37 #include "formats.h"
38 #include "internal.h"
39 
40 #define MAX_SPLITS 16
41 #define MAX_BANDS MAX_SPLITS + 1
42 
43 #define B0 0
44 #define B1 1
45 #define B2 2
46 #define A1 3
47 #define A2 4
48 
49 typedef struct BiquadCoeffs {
50  double cd[5];
51  float cf[5];
52 } BiquadCoeffs;
53 
54 typedef struct AudioCrossoverContext {
55  const AVClass *class;
56 
57  char *splits_str;
58  char *gains_str;
59  int order_opt;
60  float level_in;
61  int precision;
62 
63  int order;
67  int nb_splits;
69 
70  float gains[MAX_BANDS];
71 
75 
77 
79 
80  int (*filter_channels)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs);
81 
84 
85 #define OFFSET(x) offsetof(AudioCrossoverContext, x)
86 #define AF AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_FILTERING_PARAM
87 
88 static const AVOption acrossover_options[] = {
89  { "split", "set split frequencies", OFFSET(splits_str), AV_OPT_TYPE_STRING, {.str="500"}, 0, 0, AF },
90  { "order", "set filter order", OFFSET(order_opt), AV_OPT_TYPE_INT, {.i64=1}, 0, 9, AF, "m" },
91  { "2nd", "2nd order (12 dB/8ve)", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "m" },
92  { "4th", "4th order (24 dB/8ve)", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "m" },
93  { "6th", "6th order (36 dB/8ve)", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, AF, "m" },
94  { "8th", "8th order (48 dB/8ve)", 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, AF, "m" },
95  { "10th", "10th order (60 dB/8ve)",0, AV_OPT_TYPE_CONST, {.i64=4}, 0, 0, AF, "m" },
96  { "12th", "12th order (72 dB/8ve)",0, AV_OPT_TYPE_CONST, {.i64=5}, 0, 0, AF, "m" },
97  { "14th", "14th order (84 dB/8ve)",0, AV_OPT_TYPE_CONST, {.i64=6}, 0, 0, AF, "m" },
98  { "16th", "16th order (96 dB/8ve)",0, AV_OPT_TYPE_CONST, {.i64=7}, 0, 0, AF, "m" },
99  { "18th", "18th order (108 dB/8ve)",0, AV_OPT_TYPE_CONST, {.i64=8}, 0, 0, AF, "m" },
100  { "20th", "20th order (120 dB/8ve)",0, AV_OPT_TYPE_CONST, {.i64=9}, 0, 0, AF, "m" },
101  { "level", "set input gain", OFFSET(level_in), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 1, AF },
102  { "gain", "set output bands gain", OFFSET(gains_str), AV_OPT_TYPE_STRING, {.str="1.f"}, 0, 0, AF },
103  { "precision", "set processing precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=0}, 0, 2, AF, "precision" },
104  { "auto", "set auto processing precision", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "precision" },
105  { "float", "set single-floating point processing precision", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "precision" },
106  { "double","set double-floating point processing precision", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, AF, "precision" },
107  { NULL }
108 };
109 
110 AVFILTER_DEFINE_CLASS(acrossover);
111 
113 {
114  AudioCrossoverContext *s = ctx->priv;
115  static const enum AVSampleFormat auto_sample_fmts[] = {
119  };
120  enum AVSampleFormat sample_fmts[] = {
123  };
124  const enum AVSampleFormat *sample_fmts_list = sample_fmts;
126  if (ret < 0)
127  return ret;
128 
129  switch (s->precision) {
130  case 0:
131  sample_fmts_list = auto_sample_fmts;
132  break;
133  case 1:
135  break;
136  case 2:
138  break;
139  default:
140  break;
141  }
142  ret = ff_set_common_formats_from_list(ctx, sample_fmts_list);
143  if (ret < 0)
144  return ret;
145 
147 }
148 
150 {
151  AudioCrossoverContext *s = ctx->priv;
152  char *p, *arg, *saveptr = NULL;
153  int i, ret = 0;
154 
155  saveptr = NULL;
156  p = s->gains_str;
157  for (i = 0; i < MAX_BANDS; i++) {
158  float gain;
159  char c[3] = { 0 };
160 
161  if (!(arg = av_strtok(p, " |", &saveptr)))
162  break;
163 
164  p = NULL;
165 
166  if (av_sscanf(arg, "%f%2s", &gain, c) < 1) {
167  av_log(ctx, AV_LOG_ERROR, "Invalid syntax for gain[%d].\n", i);
168  ret = AVERROR(EINVAL);
169  break;
170  }
171 
172  if (c[0] == 'd' && c[1] == 'B')
173  s->gains[i] = expf(gain * M_LN10 / 20.f);
174  else
175  s->gains[i] = gain;
176  }
177 
178  for (; i < MAX_BANDS; i++)
179  s->gains[i] = 1.f;
180 
181  return ret;
182 }
183 
185 {
186  AudioCrossoverContext *s = ctx->priv;
187  char *p, *arg, *saveptr = NULL;
188  int i, ret = 0;
189 
190  s->fdsp = avpriv_float_dsp_alloc(0);
191  if (!s->fdsp)
192  return AVERROR(ENOMEM);
193 
194  p = s->splits_str;
195  for (i = 0; i < MAX_SPLITS; i++) {
196  float freq;
197 
198  if (!(arg = av_strtok(p, " |", &saveptr)))
199  break;
200 
201  p = NULL;
202 
203  if (av_sscanf(arg, "%f", &freq) != 1) {
204  av_log(ctx, AV_LOG_ERROR, "Invalid syntax for frequency[%d].\n", i);
205  return AVERROR(EINVAL);
206  }
207  if (freq <= 0) {
208  av_log(ctx, AV_LOG_ERROR, "Frequency %f must be positive number.\n", freq);
209  return AVERROR(EINVAL);
210  }
211 
212  if (i > 0 && freq <= s->splits[i-1]) {
213  av_log(ctx, AV_LOG_ERROR, "Frequency %f must be in increasing order.\n", freq);
214  return AVERROR(EINVAL);
215  }
216 
217  s->splits[i] = freq;
218  }
219 
220  s->nb_splits = i;
221 
222  ret = parse_gains(ctx);
223  if (ret < 0)
224  return ret;
225 
226  for (i = 0; i <= s->nb_splits; i++) {
227  AVFilterPad pad = { 0 };
228  char *name;
229 
230  pad.type = AVMEDIA_TYPE_AUDIO;
231  name = av_asprintf("out%d", ctx->nb_outputs);
232  if (!name)
233  return AVERROR(ENOMEM);
234  pad.name = name;
235 
236  if ((ret = ff_append_outpad_free_name(ctx, &pad)) < 0)
237  return ret;
238  }
239 
240  return ret;
241 }
242 
243 static void set_lp(BiquadCoeffs *b, double fc, double q, double sr)
244 {
245  double omega = 2. * M_PI * fc / sr;
246  double cosine = cos(omega);
247  double alpha = sin(omega) / (2. * q);
248 
249  double b0 = (1. - cosine) / 2.;
250  double b1 = 1. - cosine;
251  double b2 = (1. - cosine) / 2.;
252  double a0 = 1. + alpha;
253  double a1 = -2. * cosine;
254  double a2 = 1. - alpha;
255 
256  b->cd[B0] = b0 / a0;
257  b->cd[B1] = b1 / a0;
258  b->cd[B2] = b2 / a0;
259  b->cd[A1] = -a1 / a0;
260  b->cd[A2] = -a2 / a0;
261 
262  b->cf[B0] = b->cd[B0];
263  b->cf[B1] = b->cd[B1];
264  b->cf[B2] = b->cd[B2];
265  b->cf[A1] = b->cd[A1];
266  b->cf[A2] = b->cd[A2];
267 }
268 
269 static void set_hp(BiquadCoeffs *b, double fc, double q, double sr)
270 {
271  double omega = 2. * M_PI * fc / sr;
272  double cosine = cos(omega);
273  double alpha = sin(omega) / (2. * q);
274 
275  double b0 = (1. + cosine) / 2.;
276  double b1 = -1. - cosine;
277  double b2 = (1. + cosine) / 2.;
278  double a0 = 1. + alpha;
279  double a1 = -2. * cosine;
280  double a2 = 1. - alpha;
281 
282  b->cd[B0] = b0 / a0;
283  b->cd[B1] = b1 / a0;
284  b->cd[B2] = b2 / a0;
285  b->cd[A1] = -a1 / a0;
286  b->cd[A2] = -a2 / a0;
287 
288  b->cf[B0] = b->cd[B0];
289  b->cf[B1] = b->cd[B1];
290  b->cf[B2] = b->cd[B2];
291  b->cf[A1] = b->cd[A1];
292  b->cf[A2] = b->cd[A2];
293 }
294 
295 static void set_ap(BiquadCoeffs *b, double fc, double q, double sr)
296 {
297  double omega = 2. * M_PI * fc / sr;
298  double cosine = cos(omega);
299  double alpha = sin(omega) / (2. * q);
300 
301  double a0 = 1. + alpha;
302  double a1 = -2. * cosine;
303  double a2 = 1. - alpha;
304  double b0 = a2;
305  double b1 = a1;
306  double b2 = a0;
307 
308  b->cd[B0] = b0 / a0;
309  b->cd[B1] = b1 / a0;
310  b->cd[B2] = b2 / a0;
311  b->cd[A1] = -a1 / a0;
312  b->cd[A2] = -a2 / a0;
313 
314  b->cf[B0] = b->cd[B0];
315  b->cf[B1] = b->cd[B1];
316  b->cf[B2] = b->cd[B2];
317  b->cf[A1] = b->cd[A1];
318  b->cf[A2] = b->cd[A2];
319 }
320 
321 static void set_ap1(BiquadCoeffs *b, double fc, double sr)
322 {
323  double omega = 2. * M_PI * fc / sr;
324 
325  b->cd[A1] = exp(-omega);
326  b->cd[A2] = 0.;
327  b->cd[B0] = -b->cd[A1];
328  b->cd[B1] = 1.;
329  b->cd[B2] = 0.;
330 
331  b->cf[B0] = b->cd[B0];
332  b->cf[B1] = b->cd[B1];
333  b->cf[B2] = b->cd[B2];
334  b->cf[A1] = b->cd[A1];
335  b->cf[A2] = b->cd[A2];
336 }
337 
338 static void calc_q_factors(int order, double *q)
339 {
340  double n = order / 2.;
341 
342  for (int i = 0; i < n / 2; i++)
343  q[i] = 1. / (-2. * cos(M_PI * (2. * (i + 1) + n - 1.) / (2. * n)));
344 }
345 
346 #define BIQUAD_PROCESS(name, type) \
347 static void biquad_process_## name(const type *const c, \
348  type *b, \
349  type *dst, const type *src, \
350  int nb_samples) \
351 { \
352  const type b0 = c[B0]; \
353  const type b1 = c[B1]; \
354  const type b2 = c[B2]; \
355  const type a1 = c[A1]; \
356  const type a2 = c[A2]; \
357  type z1 = b[0]; \
358  type z2 = b[1]; \
359  \
360  for (int n = 0; n + 1 < nb_samples; n++) { \
361  type in = src[n]; \
362  type out; \
363  \
364  out = in * b0 + z1; \
365  z1 = b1 * in + z2 + a1 * out; \
366  z2 = b2 * in + a2 * out; \
367  dst[n] = out; \
368  \
369  n++; \
370  in = src[n]; \
371  out = in * b0 + z1; \
372  z1 = b1 * in + z2 + a1 * out; \
373  z2 = b2 * in + a2 * out; \
374  dst[n] = out; \
375  } \
376  \
377  if (nb_samples & 1) { \
378  const int n = nb_samples - 1; \
379  const type in = src[n]; \
380  type out; \
381  \
382  out = in * b0 + z1; \
383  z1 = b1 * in + z2 + a1 * out; \
384  z2 = b2 * in + a2 * out; \
385  dst[n] = out; \
386  } \
387  \
388  b[0] = z1; \
389  b[1] = z2; \
390 }
391 
392 BIQUAD_PROCESS(fltp, float)
393 BIQUAD_PROCESS(dblp, double)
394 
395 #define XOVER_PROCESS(name, type, one, ff) \
396 static int filter_channels_## name(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) \
397 { \
398  AudioCrossoverContext *s = ctx->priv; \
399  AVFrame *in = arg; \
400  AVFrame **frames = s->frames; \
401  const int start = (in->ch_layout.nb_channels * jobnr) / nb_jobs; \
402  const int end = (in->ch_layout.nb_channels * (jobnr+1)) / nb_jobs; \
403  const int nb_samples = in->nb_samples; \
404  const int nb_outs = ctx->nb_outputs; \
405  const int first_order = s->first_order; \
406  \
407  for (int ch = start; ch < end; ch++) { \
408  const type *src = (const type *)in->extended_data[ch]; \
409  type *xover = (type *)s->xover->extended_data[ch]; \
410  \
411  s->fdsp->vector_## ff ##mul_scalar((type *)frames[0]->extended_data[ch], src, \
412  s->level_in, FFALIGN(nb_samples, sizeof(type))); \
413  \
414  for (int band = 0; band < nb_outs; band++) { \
415  for (int f = 0; band + 1 < nb_outs && f < s->filter_count; f++) { \
416  const type *prv = (const type *)frames[band]->extended_data[ch]; \
417  type *dst = (type *)frames[band + 1]->extended_data[ch]; \
418  const type *hsrc = f == 0 ? prv : dst; \
419  type *hp = xover + nb_outs * 20 + band * 20 + f * 2; \
420  const type *const hpc = (type *)&s->hp[band][f].c ## ff; \
421  \
422  biquad_process_## name(hpc, hp, dst, hsrc, nb_samples); \
423  } \
424  \
425  for (int f = 0; band + 1 < nb_outs && f < s->filter_count; f++) { \
426  type *dst = (type *)frames[band]->extended_data[ch]; \
427  const type *lsrc = dst; \
428  type *lp = xover + band * 20 + f * 2; \
429  const type *const lpc = (type *)&s->lp[band][f].c ## ff; \
430  \
431  biquad_process_## name(lpc, lp, dst, lsrc, nb_samples); \
432  } \
433  \
434  for (int aband = band + 1; aband + 1 < nb_outs; aband++) { \
435  if (first_order) { \
436  const type *asrc = (const type *)frames[band]->extended_data[ch]; \
437  type *dst = (type *)frames[band]->extended_data[ch]; \
438  type *ap = xover + nb_outs * 40 + (aband * nb_outs + band) * 20; \
439  const type *const apc = (type *)&s->ap[aband][0].c ## ff; \
440  \
441  biquad_process_## name(apc, ap, dst, asrc, nb_samples); \
442  } \
443  \
444  for (int f = first_order; f < s->ap_filter_count; f++) { \
445  const type *asrc = (const type *)frames[band]->extended_data[ch]; \
446  type *dst = (type *)frames[band]->extended_data[ch]; \
447  type *ap = xover + nb_outs * 40 + (aband * nb_outs + band) * 20 + f * 2;\
448  const type *const apc = (type *)&s->ap[aband][f].c ## ff; \
449  \
450  biquad_process_## name(apc, ap, dst, asrc, nb_samples); \
451  } \
452  } \
453  } \
454  \
455  for (int band = 0; band < nb_outs; band++) { \
456  const type gain = s->gains[band] * ((band & 1 && first_order) ? -one : one); \
457  type *dst = (type *)frames[band]->extended_data[ch]; \
458  \
459  s->fdsp->vector_## ff ##mul_scalar(dst, dst, gain, \
460  FFALIGN(nb_samples, sizeof(type))); \
461  } \
462  } \
463  \
464  return 0; \
465 }
466 
467 XOVER_PROCESS(fltp, float, 1.f, f)
468 XOVER_PROCESS(dblp, double, 1.0, d)
469 
471 {
472  AVFilterContext *ctx = inlink->dst;
473  AudioCrossoverContext *s = ctx->priv;
474  int sample_rate = inlink->sample_rate;
475  double q[16];
476 
477  s->order = (s->order_opt + 1) * 2;
478  s->filter_count = s->order / 2;
479  s->first_order = s->filter_count & 1;
480  s->ap_filter_count = s->filter_count / 2 + s->first_order;
481  calc_q_factors(s->order, q);
482 
483  for (int band = 0; band <= s->nb_splits; band++) {
484  if (s->first_order) {
485  set_lp(&s->lp[band][0], s->splits[band], 0.5, sample_rate);
486  set_hp(&s->hp[band][0], s->splits[band], 0.5, sample_rate);
487  }
488 
489  for (int n = s->first_order; n < s->filter_count; n++) {
490  const int idx = s->filter_count / 2 - ((n + s->first_order) / 2 - s->first_order) - 1;
491 
492  set_lp(&s->lp[band][n], s->splits[band], q[idx], sample_rate);
493  set_hp(&s->hp[band][n], s->splits[band], q[idx], sample_rate);
494  }
495 
496  if (s->first_order)
497  set_ap1(&s->ap[band][0], s->splits[band], sample_rate);
498 
499  for (int n = s->first_order; n < s->ap_filter_count; n++) {
500  const int idx = (s->filter_count / 2 - ((n * 2 + s->first_order) / 2 - s->first_order) - 1);
501 
502  set_ap(&s->ap[band][n], s->splits[band], q[idx], sample_rate);
503  }
504  }
505 
506  switch (inlink->format) {
507  case AV_SAMPLE_FMT_FLTP: s->filter_channels = filter_channels_fltp; break;
508  case AV_SAMPLE_FMT_DBLP: s->filter_channels = filter_channels_dblp; break;
509  default: return AVERROR_BUG;
510  }
511 
512  s->xover = ff_get_audio_buffer(inlink, 2 * (ctx->nb_outputs * 10 + ctx->nb_outputs * 10 +
513  ctx->nb_outputs * ctx->nb_outputs * 10));
514  if (!s->xover)
515  return AVERROR(ENOMEM);
516 
517  return 0;
518 }
519 
521 {
522  AVFilterContext *ctx = inlink->dst;
523  AudioCrossoverContext *s = ctx->priv;
524  AVFrame **frames = s->frames;
525  int ret = 0;
526 
527  for (int i = 0; i < ctx->nb_outputs; i++) {
528  frames[i] = ff_get_audio_buffer(ctx->outputs[i], in->nb_samples);
529  if (!frames[i]) {
530  ret = AVERROR(ENOMEM);
531  break;
532  }
533 
534  frames[i]->pts = in->pts;
535  }
536 
537  if (ret < 0)
538  goto fail;
539 
540  ff_filter_execute(ctx, s->filter_channels, in, NULL,
541  FFMIN(inlink->ch_layout.nb_channels, ff_filter_get_nb_threads(ctx)));
542 
543  for (int i = 0; i < ctx->nb_outputs; i++) {
544  if (ff_outlink_get_status(ctx->outputs[i])) {
546  continue;
547  }
548 
549  ret = ff_filter_frame(ctx->outputs[i], frames[i]);
550  frames[i] = NULL;
551  if (ret < 0)
552  break;
553  }
554 
555 fail:
556  for (int i = 0; i < ctx->nb_outputs; i++)
558 
559  return ret;
560 }
561 
563 {
564  AVFilterLink *inlink = ctx->inputs[0];
565  int status, ret;
566  AVFrame *in;
567  int64_t pts;
568 
569  for (int i = 0; i < ctx->nb_outputs; i++) {
571  }
572 
574  if (ret < 0)
575  return ret;
576  if (ret > 0) {
577  ret = filter_frame(inlink, in);
578  av_frame_free(&in);
579  if (ret < 0)
580  return ret;
581  }
582 
584  for (int i = 0; i < ctx->nb_outputs; i++) {
585  if (ff_outlink_get_status(ctx->outputs[i]))
586  continue;
587  ff_outlink_set_status(ctx->outputs[i], status, pts);
588  }
589  return 0;
590  }
591 
592  for (int i = 0; i < ctx->nb_outputs; i++) {
593  if (ff_outlink_get_status(ctx->outputs[i]))
594  continue;
595 
596  if (ff_outlink_frame_wanted(ctx->outputs[i])) {
598  return 0;
599  }
600  }
601 
602  return FFERROR_NOT_READY;
603 }
604 
606 {
607  AudioCrossoverContext *s = ctx->priv;
608 
609  av_freep(&s->fdsp);
610  av_frame_free(&s->xover);
611 }
612 
613 static const AVFilterPad inputs[] = {
614  {
615  .name = "default",
616  .type = AVMEDIA_TYPE_AUDIO,
617  .config_props = config_input,
618  },
619 };
620 
622  .name = "acrossover",
623  .description = NULL_IF_CONFIG_SMALL("Split audio into per-bands streams."),
624  .priv_size = sizeof(AudioCrossoverContext),
625  .priv_class = &acrossover_class,
626  .init = init,
627  .activate = activate,
628  .uninit = uninit,
630  .outputs = NULL,
634 };
ff_get_audio_buffer
AVFrame * ff_get_audio_buffer(AVFilterLink *link, int nb_samples)
Request an audio samples buffer with a specific set of permissions.
Definition: audio.c:107
AV_SAMPLE_FMT_FLTP
@ AV_SAMPLE_FMT_FLTP
float, planar
Definition: samplefmt.h:66
name
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default minimum maximum flags name is the option name
Definition: writing_filters.txt:88
OFFSET
#define OFFSET(x)
Definition: af_acrossover.c:85
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
BiquadCoeffs::cf
float cf[5]
Definition: af_acrossover.c:51
AudioCrossoverContext::lp
BiquadCoeffs lp[MAX_BANDS][20]
Definition: af_acrossover.c:72
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:978
sample_fmts
static enum AVSampleFormat sample_fmts[]
Definition: adpcmenc.c:947
FFERROR_NOT_READY
return FFERROR_NOT_READY
Definition: filter_design.txt:204
inlink
The exact code depends on how similar the blocks are and how related they are to the and needs to apply these operations to the correct inlink or outlink if there are several Macros are available to factor that when no extra processing is inlink
Definition: filter_design.txt:212
av_asprintf
char * av_asprintf(const char *fmt,...)
Definition: avstring.c:115
AudioCrossoverContext::hp
BiquadCoeffs hp[MAX_BANDS][20]
Definition: af_acrossover.c:73
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:100
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:340
AVFrame::pts
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:452
AVOption
AVOption.
Definition: opt.h:251
b
#define b
Definition: input.c:41
FILTER_QUERY_FUNC
#define FILTER_QUERY_FUNC(func)
Definition: internal.h:169
MAX_SPLITS
#define MAX_SPLITS
Definition: af_acrossover.c:40
expf
#define expf(x)
Definition: libm.h:283
ff_set_common_all_samplerates
int ff_set_common_all_samplerates(AVFilterContext *ctx)
Equivalent to ff_set_common_samplerates(ctx, ff_all_samplerates())
Definition: formats.c:760
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(acrossover)
fc
#define fc(width, name, range_min, range_max)
Definition: cbs_av1.c:464
B2
#define B2
Definition: af_acrossover.c:45
BIQUAD_PROCESS
#define BIQUAD_PROCESS(name, type)
Definition: af_acrossover.c:346
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:170
AudioCrossoverContext::frames
AVFrame * frames[MAX_BANDS]
Definition: af_acrossover.c:78
sample_rate
sample_rate
Definition: ffmpeg_filter.c:368
AudioCrossoverContext::filter_channels
int(* filter_channels)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: af_acrossover.c:80
formats.h
AF
#define AF
Definition: af_acrossover.c:86
BiquadCoeffs
Definition: af_acrossover.c:49
ff_inlink_consume_frame
int ff_inlink_consume_frame(AVFilterLink *link, AVFrame **rframe)
Take a frame from the link's FIFO and update the link's stats.
Definition: avfilter.c:1383
FF_FILTER_FORWARD_STATUS_BACK_ALL
#define FF_FILTER_FORWARD_STATUS_BACK_ALL(outlink, filter)
Forward the status on an output link to all input links.
Definition: filters.h:212
b1
static double b1(void *priv, double x, double y)
Definition: vf_xfade.c:2035
acrossover_options
static const AVOption acrossover_options[]
Definition: af_acrossover.c:88
fail
#define fail()
Definition: checkasm.h:138
frames
if it could not because there are no more frames
Definition: filter_design.txt:266
AudioCrossoverContext::xover
AVFrame * xover
Definition: af_acrossover.c:76
parse_gains
static int parse_gains(AVFilterContext *ctx)
Definition: af_acrossover.c:149
pts
static int64_t pts
Definition: transcode_aac.c:643
set_hp
static void set_hp(BiquadCoeffs *b, double fc, double q, double sr)
Definition: af_acrossover.c:269
AudioCrossoverContext
Definition: af_acrossover.c:54
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:47
B1
#define B1
Definition: af_acrossover.c:44
a1
#define a1
Definition: regdef.h:47
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
av_cold
#define av_cold
Definition: attributes.h:90
ff_outlink_set_status
static void ff_outlink_set_status(AVFilterLink *link, int status, int64_t pts)
Set the status field of a link from the source filter.
Definition: filters.h:189
ff_inlink_request_frame
void ff_inlink_request_frame(AVFilterLink *link)
Mark that a frame is wanted on the link.
Definition: avfilter.c:1506
s
#define s(width, name)
Definition: cbs_vp9.c:198
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
av_strtok
char * av_strtok(char *s, const char *delim, char **saveptr)
Split the string into several tokens which can be accessed by successive calls to av_strtok().
Definition: avstring.c:178
ff_set_common_formats_from_list
int ff_set_common_formats_from_list(AVFilterContext *ctx, const int *fmts)
Equivalent to ff_set_common_formats(ctx, ff_make_format_list(fmts))
Definition: formats.c:776
filters.h
ff_af_acrossover
const AVFilter ff_af_acrossover
Definition: af_acrossover.c:621
AudioCrossoverContext::first_order
int first_order
Definition: af_acrossover.c:65
ctx
AVFormatContext * ctx
Definition: movenc.c:48
A2
#define A2
Definition: af_acrossover.c:47
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: internal.h:192
arg
const char * arg
Definition: jacosubdec.c:67
av_sscanf
int av_sscanf(const char *string, const char *format,...)
See libc sscanf manual for more information.
Definition: avsscanf.c:962
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
NULL
#define NULL
Definition: coverity.c:32
B0
#define B0
Definition: af_acrossover.c:43
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: af_acrossover.c:520
AudioCrossoverContext::nb_splits
int nb_splits
Definition: af_acrossover.c:67
ff_set_common_all_channel_counts
int ff_set_common_all_channel_counts(AVFilterContext *ctx)
Equivalent to ff_set_common_channel_layouts(ctx, ff_all_channel_counts())
Definition: formats.c:742
exp
int8_t exp
Definition: eval.c:72
ff_inlink_acknowledge_status
int ff_inlink_acknowledge_status(AVFilterLink *link, int *rstatus, int64_t *rpts)
Test and acknowledge the change of status on the link.
Definition: avfilter.c:1337
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
AudioCrossoverContext::ap
BiquadCoeffs ap[MAX_BANDS][20]
Definition: af_acrossover.c:74
float_dsp.h
AVFILTER_FLAG_DYNAMIC_OUTPUTS
#define AVFILTER_FLAG_DYNAMIC_OUTPUTS
The number of the filter outputs is not determined just by AVFilter.outputs.
Definition: avfilter.h:112
eval.h
query_formats
static int query_formats(AVFilterContext *ctx)
Definition: af_acrossover.c:112
f
f
Definition: af_crystalizer.c:121
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:106
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: af_acrossover.c:605
AV_SAMPLE_FMT_NONE
@ AV_SAMPLE_FMT_NONE
Definition: samplefmt.h:56
AudioCrossoverContext::splits
float splits[MAX_SPLITS]
Definition: af_acrossover.c:68
AVFloatDSPContext
Definition: float_dsp.h:24
b2
static double b2(void *priv, double x, double y)
Definition: vf_xfade.c:2036
calc_q_factors
static void calc_q_factors(int order, double *q)
Definition: af_acrossover.c:338
attributes.h
AudioCrossoverContext::order
int order
Definition: af_acrossover.c:63
a0
#define a0
Definition: regdef.h:46
M_PI
#define M_PI
Definition: mathematics.h:67
internal.h
AV_OPT_TYPE_FLOAT
@ AV_OPT_TYPE_FLOAT
Definition: opt.h:228
AVFrame::nb_samples
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:420
AudioCrossoverContext::filter_count
int filter_count
Definition: af_acrossover.c:64
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
internal.h
a2
#define a2
Definition: regdef.h:48
ff_filter_get_nb_threads
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Definition: avfilter.c:786
AVSampleFormat
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:55
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:53
set_lp
static void set_lp(BiquadCoeffs *b, double fc, double q, double sr)
Definition: af_acrossover.c:243
inputs
static const AVFilterPad inputs[]
Definition: af_acrossover.c:613
AudioCrossoverContext::ap_filter_count
int ap_filter_count
Definition: af_acrossover.c:66
AVFilter
Filter definition.
Definition: avfilter.h:166
set_ap
static void set_ap(BiquadCoeffs *b, double fc, double q, double sr)
Definition: af_acrossover.c:295
ret
ret
Definition: filter_design.txt:187
AVFilterPad::type
enum AVMediaType type
AVFilterPad type.
Definition: internal.h:58
set_ap1
static void set_ap1(BiquadCoeffs *b, double fc, double sr)
Definition: af_acrossover.c:321
AudioCrossoverContext::gains_str
char * gains_str
Definition: af_acrossover.c:58
status
ov_status_e status
Definition: dnn_backend_openvino.c:119
init
static av_cold int init(AVFilterContext *ctx)
Definition: af_acrossover.c:184
channel_layout.h
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:225
avfilter.h
MAX_BANDS
#define MAX_BANDS
Definition: af_acrossover.c:41
AudioCrossoverContext::fdsp
AVFloatDSPContext * fdsp
Definition: af_acrossover.c:82
AV_SAMPLE_FMT_DBLP
@ AV_SAMPLE_FMT_DBLP
double, planar
Definition: samplefmt.h:67
activate
static int activate(AVFilterContext *ctx)
Definition: af_acrossover.c:562
ff_outlink_get_status
int ff_outlink_get_status(AVFilterLink *link)
Get the status on an output link.
Definition: avfilter.c:1529
AVFilterContext
An instance of a filter.
Definition: avfilter.h:397
AVFILTER_FLAG_SLICE_THREADS
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
Definition: avfilter.h:117
A1
#define A1
Definition: af_acrossover.c:46
AudioCrossoverContext::gains
float gains[MAX_BANDS]
Definition: af_acrossover.c:70
audio.h
M_LN10
#define M_LN10
Definition: mathematics.h:49
config_input
static int config_input(AVFilterLink *inlink)
Definition: af_acrossover.c:470
alpha
static const int16_t alpha[]
Definition: ilbcdata.h:55
ff_append_outpad_free_name
int ff_append_outpad_free_name(AVFilterContext *f, AVFilterPad *p)
Definition: avfilter.c:143
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
avpriv_float_dsp_alloc
av_cold AVFloatDSPContext * avpriv_float_dsp_alloc(int bit_exact)
Allocate a float DSP context.
Definition: float_dsp.c:135
d
d
Definition: ffmpeg_filter.c:368
XOVER_PROCESS
#define XOVER_PROCESS(name, type, one, ff)
Definition: af_acrossover.c:395
AVERROR_BUG
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:52
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AudioCrossoverContext::precision
int precision
Definition: af_acrossover.c:61
AudioCrossoverContext::level_in
float level_in
Definition: af_acrossover.c:60
b0
static double b0(void *priv, double x, double y)
Definition: vf_xfade.c:2034
ff_outlink_frame_wanted
the definition of that something depends on the semantic of the filter The callback must examine the status of the filter s links and proceed accordingly The status of output links is stored in the status_in and status_out fields and tested by the ff_outlink_frame_wanted() function. If this function returns true
AudioCrossoverContext::order_opt
int order_opt
Definition: af_acrossover.c:59
BiquadCoeffs::cd
double cd[5]
Definition: af_acrossover.c:50
avstring.h
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:229
ff_filter_execute
static av_always_inline int ff_filter_execute(AVFilterContext *ctx, avfilter_action_func *func, void *arg, int *ret, int nb_jobs)
Definition: internal.h:144
int
int
Definition: ffmpeg_filter.c:368
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:234
AudioCrossoverContext::splits_str
char * splits_str
Definition: af_acrossover.c:57