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 "formats.h"
37 #include "internal.h"
38 
39 #define MAX_SPLITS 16
40 #define MAX_BANDS MAX_SPLITS + 1
41 
42 #define B0 0
43 #define B1 1
44 #define B2 2
45 #define A1 3
46 #define A2 4
47 
48 typedef struct BiquadCoeffs {
49  double cd[5];
50  float cf[5];
51 } BiquadCoeffs;
52 
53 typedef struct AudioCrossoverContext {
54  const AVClass *class;
55 
56  char *splits_str;
57  char *gains_str;
58  int order_opt;
59  float level_in;
60 
61  int order;
65  int nb_splits;
67 
68  float gains[MAX_BANDS];
69 
73 
75 
78 
79  int (*filter_channels)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs);
80 
83 
84 #define OFFSET(x) offsetof(AudioCrossoverContext, x)
85 #define AF AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_FILTERING_PARAM
86 
87 static const AVOption acrossover_options[] = {
88  { "split", "set split frequencies", OFFSET(splits_str), AV_OPT_TYPE_STRING, {.str="500"}, 0, 0, AF },
89  { "order", "set filter order", OFFSET(order_opt), AV_OPT_TYPE_INT, {.i64=1}, 0, 9, AF, "m" },
90  { "2nd", "2nd order (12 dB/8ve)", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "m" },
91  { "4th", "4th order (24 dB/8ve)", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "m" },
92  { "6th", "6th order (36 dB/8ve)", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, AF, "m" },
93  { "8th", "8th order (48 dB/8ve)", 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, AF, "m" },
94  { "10th", "10th order (60 dB/8ve)",0, AV_OPT_TYPE_CONST, {.i64=4}, 0, 0, AF, "m" },
95  { "12th", "12th order (72 dB/8ve)",0, AV_OPT_TYPE_CONST, {.i64=5}, 0, 0, AF, "m" },
96  { "14th", "14th order (84 dB/8ve)",0, AV_OPT_TYPE_CONST, {.i64=6}, 0, 0, AF, "m" },
97  { "16th", "16th order (96 dB/8ve)",0, AV_OPT_TYPE_CONST, {.i64=7}, 0, 0, AF, "m" },
98  { "18th", "18th order (108 dB/8ve)",0, AV_OPT_TYPE_CONST, {.i64=8}, 0, 0, AF, "m" },
99  { "20th", "20th order (120 dB/8ve)",0, AV_OPT_TYPE_CONST, {.i64=9}, 0, 0, AF, "m" },
100  { "level", "set input gain", OFFSET(level_in), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 1, AF },
101  { "gain", "set output bands gain", OFFSET(gains_str), AV_OPT_TYPE_STRING, {.str="1.f"}, 0, 0, AF },
102  { NULL }
103 };
104 
105 AVFILTER_DEFINE_CLASS(acrossover);
106 
108 {
109  AudioCrossoverContext *s = ctx->priv;
110  char *p, *arg, *saveptr = NULL;
111  int i, ret = 0;
112 
113  saveptr = NULL;
114  p = s->gains_str;
115  for (i = 0; i < MAX_BANDS; i++) {
116  float gain;
117  char c[3] = { 0 };
118 
119  if (!(arg = av_strtok(p, " |", &saveptr)))
120  break;
121 
122  p = NULL;
123 
124  if (av_sscanf(arg, "%f%2s", &gain, c) < 1) {
125  av_log(ctx, AV_LOG_ERROR, "Invalid syntax for gain[%d].\n", i);
126  ret = AVERROR(EINVAL);
127  break;
128  }
129 
130  if (c[0] == 'd' && c[1] == 'B')
131  s->gains[i] = expf(gain * M_LN10 / 20.f);
132  else
133  s->gains[i] = gain;
134  }
135 
136  for (; i < MAX_BANDS; i++)
137  s->gains[i] = 1.f;
138 
139  return ret;
140 }
141 
143 {
144  AudioCrossoverContext *s = ctx->priv;
145  char *p, *arg, *saveptr = NULL;
146  int i, ret = 0;
147 
148  s->fdsp = avpriv_float_dsp_alloc(0);
149  if (!s->fdsp)
150  return AVERROR(ENOMEM);
151 
152  p = s->splits_str;
153  for (i = 0; i < MAX_SPLITS; i++) {
154  float freq;
155 
156  if (!(arg = av_strtok(p, " |", &saveptr)))
157  break;
158 
159  p = NULL;
160 
161  if (av_sscanf(arg, "%f", &freq) != 1) {
162  av_log(ctx, AV_LOG_ERROR, "Invalid syntax for frequency[%d].\n", i);
163  return AVERROR(EINVAL);
164  }
165  if (freq <= 0) {
166  av_log(ctx, AV_LOG_ERROR, "Frequency %f must be positive number.\n", freq);
167  return AVERROR(EINVAL);
168  }
169 
170  if (i > 0 && freq <= s->splits[i-1]) {
171  av_log(ctx, AV_LOG_ERROR, "Frequency %f must be in increasing order.\n", freq);
172  return AVERROR(EINVAL);
173  }
174 
175  s->splits[i] = freq;
176  }
177 
178  s->nb_splits = i;
179 
180  ret = parse_gains(ctx);
181  if (ret < 0)
182  return ret;
183 
184  for (i = 0; i <= s->nb_splits; i++) {
185  AVFilterPad pad = { 0 };
186  char *name;
187 
188  pad.type = AVMEDIA_TYPE_AUDIO;
189  name = av_asprintf("out%d", ctx->nb_outputs);
190  if (!name)
191  return AVERROR(ENOMEM);
192  pad.name = name;
193 
194  if ((ret = ff_append_outpad_free_name(ctx, &pad)) < 0)
195  return ret;
196  }
197 
198  return ret;
199 }
200 
201 static void set_lp(BiquadCoeffs *b, double fc, double q, double sr)
202 {
203  double omega = 2. * M_PI * fc / sr;
204  double cosine = cos(omega);
205  double alpha = sin(omega) / (2. * q);
206 
207  double b0 = (1. - cosine) / 2.;
208  double b1 = 1. - cosine;
209  double b2 = (1. - cosine) / 2.;
210  double a0 = 1. + alpha;
211  double a1 = -2. * cosine;
212  double a2 = 1. - alpha;
213 
214  b->cd[B0] = b0 / a0;
215  b->cd[B1] = b1 / a0;
216  b->cd[B2] = b2 / a0;
217  b->cd[A1] = -a1 / a0;
218  b->cd[A2] = -a2 / a0;
219 
220  b->cf[B0] = b->cd[B0];
221  b->cf[B1] = b->cd[B1];
222  b->cf[B2] = b->cd[B2];
223  b->cf[A1] = b->cd[A1];
224  b->cf[A2] = b->cd[A2];
225 }
226 
227 static void set_hp(BiquadCoeffs *b, double fc, double q, double sr)
228 {
229  double omega = 2. * M_PI * fc / sr;
230  double cosine = cos(omega);
231  double alpha = sin(omega) / (2. * q);
232 
233  double b0 = (1. + cosine) / 2.;
234  double b1 = -1. - cosine;
235  double b2 = (1. + cosine) / 2.;
236  double a0 = 1. + alpha;
237  double a1 = -2. * cosine;
238  double a2 = 1. - alpha;
239 
240  b->cd[B0] = b0 / a0;
241  b->cd[B1] = b1 / a0;
242  b->cd[B2] = b2 / a0;
243  b->cd[A1] = -a1 / a0;
244  b->cd[A2] = -a2 / a0;
245 
246  b->cf[B0] = b->cd[B0];
247  b->cf[B1] = b->cd[B1];
248  b->cf[B2] = b->cd[B2];
249  b->cf[A1] = b->cd[A1];
250  b->cf[A2] = b->cd[A2];
251 }
252 
253 static void set_ap(BiquadCoeffs *b, double fc, double q, double sr)
254 {
255  double omega = 2. * M_PI * fc / sr;
256  double cosine = cos(omega);
257  double alpha = sin(omega) / (2. * q);
258 
259  double a0 = 1. + alpha;
260  double a1 = -2. * cosine;
261  double a2 = 1. - alpha;
262  double b0 = a2;
263  double b1 = a1;
264  double b2 = a0;
265 
266  b->cd[B0] = b0 / a0;
267  b->cd[B1] = b1 / a0;
268  b->cd[B2] = b2 / a0;
269  b->cd[A1] = -a1 / a0;
270  b->cd[A2] = -a2 / a0;
271 
272  b->cf[B0] = b->cd[B0];
273  b->cf[B1] = b->cd[B1];
274  b->cf[B2] = b->cd[B2];
275  b->cf[A1] = b->cd[A1];
276  b->cf[A2] = b->cd[A2];
277 }
278 
279 static void set_ap1(BiquadCoeffs *b, double fc, double sr)
280 {
281  double omega = 2. * M_PI * fc / sr;
282 
283  b->cd[A1] = exp(-omega);
284  b->cd[A2] = 0.;
285  b->cd[B0] = -b->cd[A1];
286  b->cd[B1] = 1.;
287  b->cd[B2] = 0.;
288 
289  b->cf[B0] = b->cd[B0];
290  b->cf[B1] = b->cd[B1];
291  b->cf[B2] = b->cd[B2];
292  b->cf[A1] = b->cd[A1];
293  b->cf[A2] = b->cd[A2];
294 }
295 
296 static void calc_q_factors(int order, double *q)
297 {
298  double n = order / 2.;
299 
300  for (int i = 0; i < n / 2; i++)
301  q[i] = 1. / (-2. * cos(M_PI * (2. * (i + 1) + n - 1.) / (2. * n)));
302 }
303 
304 #define BIQUAD_PROCESS(name, type) \
305 static void biquad_process_## name(const type *const c, \
306  type *b, \
307  type *dst, const type *src, \
308  int nb_samples) \
309 { \
310  const type b0 = c[B0]; \
311  const type b1 = c[B1]; \
312  const type b2 = c[B2]; \
313  const type a1 = c[A1]; \
314  const type a2 = c[A2]; \
315  type z1 = b[0]; \
316  type z2 = b[1]; \
317  \
318  for (int n = 0; n + 1 < nb_samples; n++) { \
319  type in = src[n]; \
320  type out; \
321  \
322  out = in * b0 + z1; \
323  z1 = b1 * in + z2 + a1 * out; \
324  z2 = b2 * in + a2 * out; \
325  dst[n] = out; \
326  \
327  n++; \
328  in = src[n]; \
329  out = in * b0 + z1; \
330  z1 = b1 * in + z2 + a1 * out; \
331  z2 = b2 * in + a2 * out; \
332  dst[n] = out; \
333  } \
334  \
335  if (nb_samples & 1) { \
336  const int n = nb_samples - 1; \
337  const type in = src[n]; \
338  type out; \
339  \
340  out = in * b0 + z1; \
341  z1 = b1 * in + z2 + a1 * out; \
342  z2 = b2 * in + a2 * out; \
343  dst[n] = out; \
344  } \
345  \
346  b[0] = z1; \
347  b[1] = z2; \
348 }
349 
350 BIQUAD_PROCESS(fltp, float)
351 BIQUAD_PROCESS(dblp, double)
352 
353 #define XOVER_PROCESS(name, type, one, ff) \
354 static int filter_channels_## name(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) \
355 { \
356  AudioCrossoverContext *s = ctx->priv; \
357  AVFrame *in = s->input_frame; \
358  AVFrame **frames = s->frames; \
359  const int start = (in->channels * jobnr) / nb_jobs; \
360  const int end = (in->channels * (jobnr+1)) / nb_jobs; \
361  const int nb_samples = in->nb_samples; \
362  const int nb_outs = ctx->nb_outputs; \
363  const int first_order = s->first_order; \
364  \
365  for (int ch = start; ch < end; ch++) { \
366  const type *src = (const type *)in->extended_data[ch]; \
367  type *xover = (type *)s->xover->extended_data[ch]; \
368  \
369  s->fdsp->vector_## ff ##mul_scalar((type *)frames[0]->extended_data[ch], src, \
370  s->level_in, FFALIGN(nb_samples, sizeof(type))); \
371  \
372  for (int band = 0; band < nb_outs; band++) { \
373  for (int f = 0; band + 1 < nb_outs && f < s->filter_count; f++) { \
374  const type *prv = (const type *)frames[band]->extended_data[ch]; \
375  type *dst = (type *)frames[band + 1]->extended_data[ch]; \
376  const type *hsrc = f == 0 ? prv : dst; \
377  type *hp = xover + nb_outs * 20 + band * 20 + f * 2; \
378  const type *const hpc = (type *)&s->hp[band][f].c ## ff; \
379  \
380  biquad_process_## name(hpc, hp, dst, hsrc, nb_samples); \
381  } \
382  \
383  for (int f = 0; band + 1 < nb_outs && f < s->filter_count; f++) { \
384  type *dst = (type *)frames[band]->extended_data[ch]; \
385  const type *lsrc = dst; \
386  type *lp = xover + band * 20 + f * 2; \
387  const type *const lpc = (type *)&s->lp[band][f].c ## ff; \
388  \
389  biquad_process_## name(lpc, lp, dst, lsrc, nb_samples); \
390  } \
391  \
392  for (int aband = band + 1; aband + 1 < nb_outs; aband++) { \
393  if (first_order) { \
394  const type *asrc = (const type *)frames[band]->extended_data[ch]; \
395  type *dst = (type *)frames[band]->extended_data[ch]; \
396  type *ap = xover + nb_outs * 40 + (aband * nb_outs + band) * 20; \
397  const type *const apc = (type *)&s->ap[aband][0].c ## ff; \
398  \
399  biquad_process_## name(apc, ap, dst, asrc, nb_samples); \
400  } \
401  \
402  for (int f = first_order; f < s->ap_filter_count; f++) { \
403  const type *asrc = (const type *)frames[band]->extended_data[ch]; \
404  type *dst = (type *)frames[band]->extended_data[ch]; \
405  type *ap = xover + nb_outs * 40 + (aband * nb_outs + band) * 20 + f * 2;\
406  const type *const apc = (type *)&s->ap[aband][f].c ## ff; \
407  \
408  biquad_process_## name(apc, ap, dst, asrc, nb_samples); \
409  } \
410  } \
411  } \
412  \
413  for (int band = 0; band < nb_outs; band++) { \
414  const type gain = s->gains[band] * ((band & 1 && first_order) ? -one : one); \
415  type *dst = (type *)frames[band]->extended_data[ch]; \
416  \
417  s->fdsp->vector_## ff ##mul_scalar(dst, dst, gain, \
418  FFALIGN(nb_samples, sizeof(type))); \
419  } \
420  } \
421  \
422  return 0; \
423 }
424 
425 XOVER_PROCESS(fltp, float, 1.f, f)
426 XOVER_PROCESS(dblp, double, 1.0, d)
427 
429 {
430  AVFilterContext *ctx = inlink->dst;
431  AudioCrossoverContext *s = ctx->priv;
432  int sample_rate = inlink->sample_rate;
433  double q[16];
434 
435  s->order = (s->order_opt + 1) * 2;
436  s->filter_count = s->order / 2;
437  s->first_order = s->filter_count & 1;
438  s->ap_filter_count = s->filter_count / 2 + s->first_order;
439  calc_q_factors(s->order, q);
440 
441  for (int band = 0; band <= s->nb_splits; band++) {
442  if (s->first_order) {
443  set_lp(&s->lp[band][0], s->splits[band], 0.5, sample_rate);
444  set_hp(&s->hp[band][0], s->splits[band], 0.5, sample_rate);
445  }
446 
447  for (int n = s->first_order; n < s->filter_count; n++) {
448  const int idx = s->filter_count / 2 - ((n + s->first_order) / 2 - s->first_order) - 1;
449 
450  set_lp(&s->lp[band][n], s->splits[band], q[idx], sample_rate);
451  set_hp(&s->hp[band][n], s->splits[band], q[idx], sample_rate);
452  }
453 
454  if (s->first_order)
455  set_ap1(&s->ap[band][0], s->splits[band], sample_rate);
456 
457  for (int n = s->first_order; n < s->ap_filter_count; n++) {
458  const int idx = (s->filter_count / 2 - ((n * 2 + s->first_order) / 2 - s->first_order) - 1);
459 
460  set_ap(&s->ap[band][n], s->splits[band], q[idx], sample_rate);
461  }
462  }
463 
464  switch (inlink->format) {
465  case AV_SAMPLE_FMT_FLTP: s->filter_channels = filter_channels_fltp; break;
466  case AV_SAMPLE_FMT_DBLP: s->filter_channels = filter_channels_dblp; break;
467  default: return AVERROR_BUG;
468  }
469 
470  s->xover = ff_get_audio_buffer(inlink, 2 * (ctx->nb_outputs * 10 + ctx->nb_outputs * 10 +
471  ctx->nb_outputs * ctx->nb_outputs * 10));
472  if (!s->xover)
473  return AVERROR(ENOMEM);
474 
475  return 0;
476 }
477 
479 {
480  AVFilterContext *ctx = inlink->dst;
481  AudioCrossoverContext *s = ctx->priv;
482  AVFrame **frames = s->frames;
483  int i, ret = 0;
484 
485  for (i = 0; i < ctx->nb_outputs; i++) {
486  frames[i] = ff_get_audio_buffer(ctx->outputs[i], in->nb_samples);
487 
488  if (!frames[i]) {
489  ret = AVERROR(ENOMEM);
490  break;
491  }
492 
493  frames[i]->pts = in->pts;
494  }
495 
496  if (ret < 0)
497  goto fail;
498 
499  s->input_frame = in;
500  ff_filter_execute(ctx, s->filter_channels, NULL, NULL,
502 
503  for (i = 0; i < ctx->nb_outputs; i++) {
504  ret = ff_filter_frame(ctx->outputs[i], frames[i]);
505  frames[i] = NULL;
506  if (ret < 0)
507  break;
508  }
509 
510 fail:
511  for (i = 0; i < ctx->nb_outputs; i++)
513  av_frame_free(&in);
514  s->input_frame = NULL;
515 
516  return ret;
517 }
518 
520 {
521  AudioCrossoverContext *s = ctx->priv;
522 
523  av_freep(&s->fdsp);
524  av_frame_free(&s->xover);
525 }
526 
527 static const AVFilterPad inputs[] = {
528  {
529  .name = "default",
530  .type = AVMEDIA_TYPE_AUDIO,
531  .filter_frame = filter_frame,
532  .config_props = config_input,
533  },
534 };
535 
537  .name = "acrossover",
538  .description = NULL_IF_CONFIG_SMALL("Split audio into per-bands streams."),
539  .priv_size = sizeof(AudioCrossoverContext),
540  .priv_class = &acrossover_class,
541  .init = init,
542  .uninit = uninit,
544  .outputs = NULL,
548 };
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:88
AV_SAMPLE_FMT_FLTP
@ AV_SAMPLE_FMT_FLTP
float, planar
Definition: samplefmt.h:69
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:84
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:50
AudioCrossoverContext::lp
BiquadCoeffs lp[MAX_BANDS][20]
Definition: af_acrossover.c:70
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1018
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:113
AudioCrossoverContext::hp
BiquadCoeffs hp[MAX_BANDS][20]
Definition: af_acrossover.c:71
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:109
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:317
AVFrame::pts
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:424
AVOption
AVOption.
Definition: opt.h:247
b
#define b
Definition: input.c:40
MAX_SPLITS
#define MAX_SPLITS
Definition: af_acrossover.c:39
expf
#define expf(x)
Definition: libm.h:283
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(acrossover)
fc
#define fc(width, name, range_min, range_max)
Definition: cbs_av1.c:551
B2
#define B2
Definition: af_acrossover.c:44
BIQUAD_PROCESS
#define BIQUAD_PROCESS(name, type)
Definition: af_acrossover.c:304
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:169
AudioCrossoverContext::frames
AVFrame * frames[MAX_BANDS]
Definition: af_acrossover.c:77
sample_rate
sample_rate
Definition: ffmpeg_filter.c:153
AudioCrossoverContext::filter_channels
int(* filter_channels)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: af_acrossover.c:79
AudioCrossoverContext::input_frame
AVFrame * input_frame
Definition: af_acrossover.c:76
formats.h
AF
#define AF
Definition: af_acrossover.c:85
BiquadCoeffs
Definition: af_acrossover.c:48
b1
static double b1(void *priv, double x, double y)
Definition: vf_xfade.c:1703
acrossover_options
static const AVOption acrossover_options[]
Definition: af_acrossover.c:87
fail
#define fail()
Definition: checkasm.h:127
frames
if it could not because there are no more frames
Definition: filter_design.txt:266
AudioCrossoverContext::xover
AVFrame * xover
Definition: af_acrossover.c:74
parse_gains
static int parse_gains(AVFilterContext *ctx)
Definition: af_acrossover.c:107
set_hp
static void set_hp(BiquadCoeffs *b, double fc, double q, double sr)
Definition: af_acrossover.c:227
AudioCrossoverContext
Definition: af_acrossover.c:53
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:50
B1
#define B1
Definition: af_acrossover.c:43
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
s
#define s(width, name)
Definition: cbs_vp9.c:257
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:186
ff_af_acrossover
const AVFilter ff_af_acrossover
Definition: af_acrossover.c:536
AudioCrossoverContext::first_order
int first_order
Definition: af_acrossover.c:63
ctx
AVFormatContext * ctx
Definition: movenc.c:48
A2
#define A2
Definition: af_acrossover.c:46
f
#define f(width, name)
Definition: cbs_vp9.c:255
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: internal.h:191
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:960
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:42
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: af_acrossover.c:478
AudioCrossoverContext::nb_splits
int nb_splits
Definition: af_acrossover.c:65
exp
int8_t exp
Definition: eval.c:72
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:72
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:116
eval.h
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:117
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: af_acrossover.c:519
AudioCrossoverContext::splits
float splits[MAX_SPLITS]
Definition: af_acrossover.c:66
AVFloatDSPContext
Definition: float_dsp.h:24
b2
static double b2(void *priv, double x, double y)
Definition: vf_xfade.c:1704
calc_q_factors
static void calc_q_factors(int order, double *q)
Definition: af_acrossover.c:296
attributes.h
AudioCrossoverContext::order
int order
Definition: af_acrossover.c:61
a0
#define a0
Definition: regdef.h:46
M_PI
#define M_PI
Definition: mathematics.h:52
internal.h
AV_OPT_TYPE_FLOAT
@ AV_OPT_TYPE_FLOAT
Definition: opt.h:227
AVFrame::nb_samples
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:397
AudioCrossoverContext::filter_count
int filter_count
Definition: af_acrossover.c:62
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:271
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:803
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:56
set_lp
static void set_lp(BiquadCoeffs *b, double fc, double q, double sr)
Definition: af_acrossover.c:201
inputs
static const AVFilterPad inputs[]
Definition: af_acrossover.c:527
AudioCrossoverContext::ap_filter_count
int ap_filter_count
Definition: af_acrossover.c:64
AVFilter
Filter definition.
Definition: avfilter.h:165
set_ap
static void set_ap(BiquadCoeffs *b, double fc, double q, double sr)
Definition: af_acrossover.c:253
ret
ret
Definition: filter_design.txt:187
AVFilterPad::type
enum AVMediaType type
AVFilterPad type.
Definition: internal.h:61
set_ap1
static void set_ap1(BiquadCoeffs *b, double fc, double sr)
Definition: af_acrossover.c:279
AudioCrossoverContext::gains_str
char * gains_str
Definition: af_acrossover.c:57
init
static av_cold int init(AVFilterContext *ctx)
Definition: af_acrossover.c:142
channel_layout.h
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:224
avfilter.h
MAX_BANDS
#define MAX_BANDS
Definition: af_acrossover.c:40
AudioCrossoverContext::fdsp
AVFloatDSPContext * fdsp
Definition: af_acrossover.c:81
AV_SAMPLE_FMT_DBLP
@ AV_SAMPLE_FMT_DBLP
double, planar
Definition: samplefmt.h:70
AVFilterContext
An instance of a filter.
Definition: avfilter.h:402
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:121
A1
#define A1
Definition: af_acrossover.c:45
AudioCrossoverContext::gains
float gains[MAX_BANDS]
Definition: af_acrossover.c:68
audio.h
M_LN10
#define M_LN10
Definition: mathematics.h:43
config_input
static int config_input(AVFilterLink *inlink)
Definition: af_acrossover.c:428
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:155
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
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:153
XOVER_PROCESS
#define XOVER_PROCESS(name, type, one, ff)
Definition: af_acrossover.c:353
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:28
AudioCrossoverContext::level_in
float level_in
Definition: af_acrossover.c:59
b0
static double b0(void *priv, double x, double y)
Definition: vf_xfade.c:1702
AudioCrossoverContext::order_opt
int order_opt
Definition: af_acrossover.c:58
BiquadCoeffs::cd
double cd[5]
Definition: af_acrossover.c:49
avstring.h
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:228
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:143
int
int
Definition: ffmpeg_filter.c:153
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:233
AudioCrossoverContext::splits_str
char * splits_str
Definition: af_acrossover.c:56
FILTER_SAMPLEFMTS
#define FILTER_SAMPLEFMTS(...)
Definition: internal.h:179