FFmpeg
af_mcompand.c
Go to the documentation of this file.
1 /*
2  * COpyright (c) 2002 Daniel Pouzzner
3  * Copyright (c) 1999 Chris Bagwell
4  * Copyright (c) 1999 Nick Bailey
5  * Copyright (c) 2007 Rob Sykes <robs@users.sourceforge.net>
6  * Copyright (c) 2013 Paul B Mahol
7  * Copyright (c) 2014 Andrew Kelley
8  *
9  * This file is part of FFmpeg.
10  *
11  * FFmpeg is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2.1 of the License, or (at your option) any later version.
15  *
16  * FFmpeg is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with FFmpeg; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24  */
25 
26 /**
27  * @file
28  * audio multiband compand filter
29  */
30 
31 #include "libavutil/avassert.h"
32 #include "libavutil/avstring.h"
33 #include "libavutil/ffmath.h"
34 #include "libavutil/opt.h"
35 #include "libavutil/samplefmt.h"
36 #include "audio.h"
37 #include "avfilter.h"
38 #include "internal.h"
39 
40 typedef struct CompandSegment {
41  double x, y;
42  double a, b;
44 
45 typedef struct CompandT {
48  double in_min_lin;
49  double out_min_lin;
50  double curve_dB;
51  double gain_dB;
52 } CompandT;
53 
54 #define N 4
55 
56 typedef struct PrevCrossover {
57  double in;
58  double out_low;
59  double out_high;
60 } PrevCrossover[N * 2];
61 
62 typedef struct Crossover {
64  size_t pos;
65  double coefs[3 *(N+1)];
66 } Crossover;
67 
68 typedef struct CompBand {
70  double *attack_rate;
71  double *decay_rate;
72  double *volume;
73  double delay;
74  double topfreq;
77  size_t delay_size;
78  ptrdiff_t delay_buf_ptr;
79  size_t delay_buf_cnt;
80 } CompBand;
81 
82 typedef struct MCompandContext {
83  const AVClass *class;
84 
85  char *args;
86 
87  int nb_bands;
93 
94 #define OFFSET(x) offsetof(MCompandContext, x)
95 #define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
96 
97 static const AVOption mcompand_options[] = {
98  { "args", "set parameters for each band", OFFSET(args), AV_OPT_TYPE_STRING, { .str = "0.005,0.1 6 -47/-40,-34/-34,-17/-33 100 | 0.003,0.05 6 -47/-40,-34/-34,-17/-33 400 | 0.000625,0.0125 6 -47/-40,-34/-34,-15/-33 1600 | 0.0001,0.025 6 -47/-40,-34/-34,-31/-31,-0/-30 6400 | 0,0.025 6 -38/-31,-28/-28,-0/-25 22000" }, 0, 0, A },
99  { NULL }
100 };
101 
102 AVFILTER_DEFINE_CLASS(mcompand);
103 
105 {
106  MCompandContext *s = ctx->priv;
107  int i;
108 
109  av_frame_free(&s->band_buf1);
110  av_frame_free(&s->band_buf2);
111  av_frame_free(&s->band_buf3);
112 
113  if (s->bands) {
114  for (i = 0; i < s->nb_bands; i++) {
115  av_freep(&s->bands[i].attack_rate);
116  av_freep(&s->bands[i].decay_rate);
117  av_freep(&s->bands[i].volume);
118  av_freep(&s->bands[i].transfer_fn.segments);
119  av_freep(&s->bands[i].filter.previous);
120  av_frame_free(&s->bands[i].delay_buf);
121  }
122  }
123  av_freep(&s->bands);
124 }
125 
127 {
130  static const enum AVSampleFormat sample_fmts[] = {
133  };
134  int ret;
135 
137  if (!layouts)
138  return AVERROR(ENOMEM);
140  if (ret < 0)
141  return ret;
142 
144  if (!formats)
145  return AVERROR(ENOMEM);
147  if (ret < 0)
148  return ret;
149 
151  if (!formats)
152  return AVERROR(ENOMEM);
154 }
155 
156 static void count_items(char *item_str, int *nb_items, char delimiter)
157 {
158  char *p;
159 
160  *nb_items = 1;
161  for (p = item_str; *p; p++) {
162  if (*p == delimiter)
163  (*nb_items)++;
164  }
165 }
166 
167 static void update_volume(CompBand *cb, double in, int ch)
168 {
169  double delta = in - cb->volume[ch];
170 
171  if (delta > 0.0)
172  cb->volume[ch] += delta * cb->attack_rate[ch];
173  else
174  cb->volume[ch] += delta * cb->decay_rate[ch];
175 }
176 
177 static double get_volume(CompandT *s, double in_lin)
178 {
179  CompandSegment *cs;
180  double in_log, out_log;
181  int i;
182 
183  if (in_lin <= s->in_min_lin)
184  return s->out_min_lin;
185 
186  in_log = log(in_lin);
187 
188  for (i = 1; i < s->nb_segments; i++)
189  if (in_log <= s->segments[i].x)
190  break;
191  cs = &s->segments[i - 1];
192  in_log -= cs->x;
193  out_log = cs->y + in_log * (cs->a * in_log + cs->b);
194 
195  return exp(out_log);
196 }
197 
198 static int parse_points(char *points, int nb_points, double radius,
200 {
201  int new_nb_items, num;
202  char *saveptr = NULL;
203  char *p = points;
204  int i;
205 
206 #define S(x) s->segments[2 * ((x) + 1)]
207  for (i = 0, new_nb_items = 0; i < nb_points; i++) {
208  char *tstr = av_strtok(p, ",", &saveptr);
209  p = NULL;
210  if (!tstr || sscanf(tstr, "%lf/%lf", &S(i).x, &S(i).y) != 2) {
212  "Invalid and/or missing input/output value.\n");
213  return AVERROR(EINVAL);
214  }
215  if (i && S(i - 1).x > S(i).x) {
217  "Transfer function input values must be increasing.\n");
218  return AVERROR(EINVAL);
219  }
220  S(i).y -= S(i).x;
221  av_log(ctx, AV_LOG_DEBUG, "%d: x=%f y=%f\n", i, S(i).x, S(i).y);
222  new_nb_items++;
223  }
224  num = new_nb_items;
225 
226  /* Add 0,0 if necessary */
227  if (num == 0 || S(num - 1).x)
228  num++;
229 
230 #undef S
231 #define S(x) s->segments[2 * (x)]
232  /* Add a tail off segment at the start */
233  S(0).x = S(1).x - 2 * s->curve_dB;
234  S(0).y = S(1).y;
235  num++;
236 
237  /* Join adjacent colinear segments */
238  for (i = 2; i < num; i++) {
239  double g1 = (S(i - 1).y - S(i - 2).y) * (S(i - 0).x - S(i - 1).x);
240  double g2 = (S(i - 0).y - S(i - 1).y) * (S(i - 1).x - S(i - 2).x);
241  int j;
242 
243  if (fabs(g1 - g2))
244  continue;
245  num--;
246  for (j = --i; j < num; j++)
247  S(j) = S(j + 1);
248  }
249 
250  for (i = 0; i < s->nb_segments; i += 2) {
251  s->segments[i].y += s->gain_dB;
252  s->segments[i].x *= M_LN10 / 20;
253  s->segments[i].y *= M_LN10 / 20;
254  }
255 
256 #define L(x) s->segments[i - (x)]
257  for (i = 4; i < s->nb_segments; i += 2) {
258  double x, y, cx, cy, in1, in2, out1, out2, theta, len, r;
259 
260  L(4).a = 0;
261  L(4).b = (L(2).y - L(4).y) / (L(2).x - L(4).x);
262 
263  L(2).a = 0;
264  L(2).b = (L(0).y - L(2).y) / (L(0).x - L(2).x);
265 
266  theta = atan2(L(2).y - L(4).y, L(2).x - L(4).x);
267  len = hypot(L(2).x - L(4).x, L(2).y - L(4).y);
268  r = FFMIN(radius, len);
269  L(3).x = L(2).x - r * cos(theta);
270  L(3).y = L(2).y - r * sin(theta);
271 
272  theta = atan2(L(0).y - L(2).y, L(0).x - L(2).x);
273  len = hypot(L(0).x - L(2).x, L(0).y - L(2).y);
274  r = FFMIN(radius, len / 2);
275  x = L(2).x + r * cos(theta);
276  y = L(2).y + r * sin(theta);
277 
278  cx = (L(3).x + L(2).x + x) / 3;
279  cy = (L(3).y + L(2).y + y) / 3;
280 
281  L(2).x = x;
282  L(2).y = y;
283 
284  in1 = cx - L(3).x;
285  out1 = cy - L(3).y;
286  in2 = L(2).x - L(3).x;
287  out2 = L(2).y - L(3).y;
288  L(3).a = (out2 / in2 - out1 / in1) / (in2 - in1);
289  L(3).b = out1 / in1 - L(3).a * in1;
290  }
291  L(3).x = 0;
292  L(3).y = L(2).y;
293 
294  s->in_min_lin = exp(s->segments[1].x);
295  s->out_min_lin = exp(s->segments[1].y);
296 
297  return 0;
298 }
299 
300 static void square_quadratic(double const *x, double *y)
301 {
302  y[0] = x[0] * x[0];
303  y[1] = 2 * x[0] * x[1];
304  y[2] = 2 * x[0] * x[2] + x[1] * x[1];
305  y[3] = 2 * x[1] * x[2];
306  y[4] = x[2] * x[2];
307 }
308 
309 static int crossover_setup(AVFilterLink *outlink, Crossover *p, double frequency)
310 {
311  double w0 = 2 * M_PI * frequency / outlink->sample_rate;
312  double Q = sqrt(.5), alpha = sin(w0) / (2*Q);
313  double x[9], norm;
314  int i;
315 
316  if (w0 > M_PI)
317  return AVERROR(EINVAL);
318 
319  x[0] = (1 - cos(w0))/2; /* Cf. filter_LPF in biquads.c */
320  x[1] = 1 - cos(w0);
321  x[2] = (1 - cos(w0))/2;
322  x[3] = (1 + cos(w0))/2; /* Cf. filter_HPF in biquads.c */
323  x[4] = -(1 + cos(w0));
324  x[5] = (1 + cos(w0))/2;
325  x[6] = 1 + alpha;
326  x[7] = -2*cos(w0);
327  x[8] = 1 - alpha;
328 
329  for (norm = x[6], i = 0; i < 9; ++i)
330  x[i] /= norm;
331 
332  square_quadratic(x , p->coefs);
333  square_quadratic(x + 3, p->coefs + 5);
334  square_quadratic(x + 6, p->coefs + 10);
335 
336  p->previous = av_calloc(outlink->channels, sizeof(*p->previous));
337  if (!p->previous)
338  return AVERROR(ENOMEM);
339 
340  return 0;
341 }
342 
343 static int config_output(AVFilterLink *outlink)
344 {
345  AVFilterContext *ctx = outlink->src;
346  MCompandContext *s = ctx->priv;
347  int ret, ch, i, k, new_nb_items, nb_bands;
348  char *p = s->args, *saveptr = NULL;
349  int max_delay_size = 0;
350 
351  count_items(s->args, &nb_bands, '|');
352  s->nb_bands = FFMAX(1, nb_bands);
353 
354  s->bands = av_calloc(nb_bands, sizeof(*s->bands));
355  if (!s->bands)
356  return AVERROR(ENOMEM);
357 
358  for (i = 0, new_nb_items = 0; i < nb_bands; i++) {
359  int nb_points, nb_attacks, nb_items = 0;
360  char *tstr2, *tstr = av_strtok(p, "|", &saveptr);
361  char *p2, *p3, *saveptr2 = NULL, *saveptr3 = NULL;
362  double radius;
363 
364  if (!tstr)
365  return AVERROR(EINVAL);
366  p = NULL;
367 
368  p2 = tstr;
369  count_items(tstr, &nb_items, ' ');
370  tstr2 = av_strtok(p2, " ", &saveptr2);
371  if (!tstr2) {
372  av_log(ctx, AV_LOG_ERROR, "at least one attacks/decays rate is mandatory\n");
373  return AVERROR(EINVAL);
374  }
375  p2 = NULL;
376  p3 = tstr2;
377 
378  count_items(tstr2, &nb_attacks, ',');
379  if (!nb_attacks || nb_attacks & 1) {
380  av_log(ctx, AV_LOG_ERROR, "number of attacks rate plus decays rate must be even\n");
381  return AVERROR(EINVAL);
382  }
383 
384  s->bands[i].attack_rate = av_calloc(outlink->channels, sizeof(double));
385  s->bands[i].decay_rate = av_calloc(outlink->channels, sizeof(double));
386  s->bands[i].volume = av_calloc(outlink->channels, sizeof(double));
387  if (!s->bands[i].attack_rate || !s->bands[i].decay_rate || !s->bands[i].volume)
388  return AVERROR(ENOMEM);
389 
390  for (k = 0; k < FFMIN(nb_attacks / 2, outlink->channels); k++) {
391  char *tstr3 = av_strtok(p3, ",", &saveptr3);
392 
393  p3 = NULL;
394  sscanf(tstr3, "%lf", &s->bands[i].attack_rate[k]);
395  tstr3 = av_strtok(p3, ",", &saveptr3);
396  sscanf(tstr3, "%lf", &s->bands[i].decay_rate[k]);
397 
398  if (s->bands[i].attack_rate[k] > 1.0 / outlink->sample_rate) {
399  s->bands[i].attack_rate[k] = 1.0 - exp(-1.0 / (outlink->sample_rate * s->bands[i].attack_rate[k]));
400  } else {
401  s->bands[i].attack_rate[k] = 1.0;
402  }
403 
404  if (s->bands[i].decay_rate[k] > 1.0 / outlink->sample_rate) {
405  s->bands[i].decay_rate[k] = 1.0 - exp(-1.0 / (outlink->sample_rate * s->bands[i].decay_rate[k]));
406  } else {
407  s->bands[i].decay_rate[k] = 1.0;
408  }
409  }
410 
411  for (ch = k; ch < outlink->channels; ch++) {
412  s->bands[i].attack_rate[ch] = s->bands[i].attack_rate[k - 1];
413  s->bands[i].decay_rate[ch] = s->bands[i].decay_rate[k - 1];
414  }
415 
416  tstr2 = av_strtok(p2, " ", &saveptr2);
417  if (!tstr2) {
418  av_log(ctx, AV_LOG_ERROR, "transfer function curve in dB must be set\n");
419  return AVERROR(EINVAL);
420  }
421  sscanf(tstr2, "%lf", &s->bands[i].transfer_fn.curve_dB);
422 
423  radius = s->bands[i].transfer_fn.curve_dB * M_LN10 / 20.0;
424 
425  tstr2 = av_strtok(p2, " ", &saveptr2);
426  if (!tstr2) {
427  av_log(ctx, AV_LOG_ERROR, "transfer points missing\n");
428  return AVERROR(EINVAL);
429  }
430 
431  count_items(tstr2, &nb_points, ',');
432  s->bands[i].transfer_fn.nb_segments = (nb_points + 4) * 2;
433  s->bands[i].transfer_fn.segments = av_calloc(s->bands[i].transfer_fn.nb_segments,
434  sizeof(CompandSegment));
435  if (!s->bands[i].transfer_fn.segments)
436  return AVERROR(ENOMEM);
437 
438  ret = parse_points(tstr2, nb_points, radius, &s->bands[i].transfer_fn, ctx);
439  if (ret < 0) {
440  av_log(ctx, AV_LOG_ERROR, "transfer points parsing failed\n");
441  return ret;
442  }
443 
444  tstr2 = av_strtok(p2, " ", &saveptr2);
445  if (!tstr2) {
446  av_log(ctx, AV_LOG_ERROR, "crossover_frequency is missing\n");
447  return AVERROR(EINVAL);
448  }
449 
450  new_nb_items += sscanf(tstr2, "%lf", &s->bands[i].topfreq) == 1;
451  if (s->bands[i].topfreq < 0 || s->bands[i].topfreq >= outlink->sample_rate / 2) {
452  av_log(ctx, AV_LOG_ERROR, "crossover_frequency: %f, should be >=0 and lower than half of sample rate: %d.\n", s->bands[i].topfreq, outlink->sample_rate / 2);
453  return AVERROR(EINVAL);
454  }
455 
456  if (s->bands[i].topfreq != 0) {
457  ret = crossover_setup(outlink, &s->bands[i].filter, s->bands[i].topfreq);
458  if (ret < 0)
459  return ret;
460  }
461 
462  tstr2 = av_strtok(p2, " ", &saveptr2);
463  if (tstr2) {
464  sscanf(tstr2, "%lf", &s->bands[i].delay);
465  max_delay_size = FFMAX(max_delay_size, s->bands[i].delay * outlink->sample_rate);
466 
467  tstr2 = av_strtok(p2, " ", &saveptr2);
468  if (tstr2) {
469  double initial_volume;
470 
471  sscanf(tstr2, "%lf", &initial_volume);
472  initial_volume = pow(10.0, initial_volume / 20);
473 
474  for (k = 0; k < outlink->channels; k++) {
475  s->bands[i].volume[k] = initial_volume;
476  }
477 
478  tstr2 = av_strtok(p2, " ", &saveptr2);
479  if (tstr2) {
480  sscanf(tstr2, "%lf", &s->bands[i].transfer_fn.gain_dB);
481  }
482  }
483  }
484  }
485  s->nb_bands = new_nb_items;
486 
487  for (i = 0; max_delay_size > 0 && i < s->nb_bands; i++) {
488  s->bands[i].delay_buf = ff_get_audio_buffer(outlink, max_delay_size);
489  if (!s->bands[i].delay_buf)
490  return AVERROR(ENOMEM);
491  }
492  s->delay_buf_size = max_delay_size;
493 
494  return 0;
495 }
496 
497 #define CONVOLVE _ _ _ _
498 
499 static void crossover(int ch, Crossover *p,
500  double *ibuf, double *obuf_low,
501  double *obuf_high, size_t len)
502 {
503  double out_low, out_high;
504 
505  while (len--) {
506  p->pos = p->pos ? p->pos - 1 : N - 1;
507 #define _ out_low += p->coefs[j] * p->previous[ch][p->pos + j].in \
508  - p->coefs[2*N+2 + j] * p->previous[ch][p->pos + j].out_low, j++;
509  {
510  int j = 1;
511  out_low = p->coefs[0] * *ibuf;
512  CONVOLVE
513  *obuf_low++ = out_low;
514  }
515 #undef _
516 #define _ out_high += p->coefs[j+N+1] * p->previous[ch][p->pos + j].in \
517  - p->coefs[2*N+2 + j] * p->previous[ch][p->pos + j].out_high, j++;
518  {
519  int j = 1;
520  out_high = p->coefs[N+1] * *ibuf;
521  CONVOLVE
522  *obuf_high++ = out_high;
523  }
524  p->previous[ch][p->pos + N].in = p->previous[ch][p->pos].in = *ibuf++;
525  p->previous[ch][p->pos + N].out_low = p->previous[ch][p->pos].out_low = out_low;
526  p->previous[ch][p->pos + N].out_high = p->previous[ch][p->pos].out_high = out_high;
527  }
528 }
529 
530 static int mcompand_channel(MCompandContext *c, CompBand *l, double *ibuf, double *obuf, int len, int ch)
531 {
532  int i;
533 
534  for (i = 0; i < len; i++) {
535  double level_in_lin, level_out_lin, checkbuf;
536  /* Maintain the volume fields by simulating a leaky pump circuit */
537  update_volume(l, fabs(ibuf[i]), ch);
538 
539  /* Volume memory is updated: perform compand */
540  level_in_lin = l->volume[ch];
541  level_out_lin = get_volume(&l->transfer_fn, level_in_lin);
542 
543  if (c->delay_buf_size <= 0) {
544  checkbuf = ibuf[i] * level_out_lin;
545  obuf[i] = checkbuf;
546  } else {
547  double *delay_buf = (double *)l->delay_buf->extended_data[ch];
548 
549  /* FIXME: note that this lookahead algorithm is really lame:
550  the response to a peak is released before the peak
551  arrives. */
552 
553  /* because volume application delays differ band to band, but
554  total delay doesn't, the volume is applied in an iteration
555  preceding that in which the sample goes to obuf, except in
556  the band(s) with the longest vol app delay.
557 
558  the offset between delay_buf_ptr and the sample to apply
559  vol to, is a constant equal to the difference between this
560  band's delay and the longest delay of all the bands. */
561 
562  if (l->delay_buf_cnt >= l->delay_size) {
563  checkbuf =
564  delay_buf[(l->delay_buf_ptr +
565  c->delay_buf_size -
566  l->delay_size) % c->delay_buf_size] * level_out_lin;
567  delay_buf[(l->delay_buf_ptr + c->delay_buf_size -
568  l->delay_size) % c->delay_buf_size] = checkbuf;
569  }
570  if (l->delay_buf_cnt >= c->delay_buf_size) {
571  obuf[i] = delay_buf[l->delay_buf_ptr];
572  } else {
573  l->delay_buf_cnt++;
574  }
575  delay_buf[l->delay_buf_ptr++] = ibuf[i];
576  l->delay_buf_ptr %= c->delay_buf_size;
577  }
578  }
579 
580  return 0;
581 }
582 
584 {
585  AVFilterContext *ctx = inlink->dst;
586  AVFilterLink *outlink = ctx->outputs[0];
587  MCompandContext *s = ctx->priv;
588  AVFrame *out, *abuf, *bbuf, *cbuf;
589  int ch, band, i;
590 
591  out = ff_get_audio_buffer(outlink, in->nb_samples);
592  if (!out) {
593  av_frame_free(&in);
594  return AVERROR(ENOMEM);
595  }
596 
597  if (s->band_samples < in->nb_samples) {
598  av_frame_free(&s->band_buf1);
599  av_frame_free(&s->band_buf2);
600  av_frame_free(&s->band_buf3);
601 
602  s->band_buf1 = ff_get_audio_buffer(outlink, in->nb_samples);
603  s->band_buf2 = ff_get_audio_buffer(outlink, in->nb_samples);
604  s->band_buf3 = ff_get_audio_buffer(outlink, in->nb_samples);
605  s->band_samples = in->nb_samples;
606  }
607 
608  for (ch = 0; ch < outlink->channels; ch++) {
609  double *a, *dst = (double *)out->extended_data[ch];
610 
611  for (band = 0, abuf = in, bbuf = s->band_buf2, cbuf = s->band_buf1; band < s->nb_bands; band++) {
612  CompBand *b = &s->bands[band];
613 
614  if (b->topfreq) {
615  crossover(ch, &b->filter, (double *)abuf->extended_data[ch],
616  (double *)bbuf->extended_data[ch], (double *)cbuf->extended_data[ch], in->nb_samples);
617  } else {
618  bbuf = abuf;
619  abuf = cbuf;
620  }
621 
622  if (abuf == in)
623  abuf = s->band_buf3;
624  mcompand_channel(s, b, (double *)bbuf->extended_data[ch], (double *)abuf->extended_data[ch], out->nb_samples, ch);
625  a = (double *)abuf->extended_data[ch];
626  for (i = 0; i < out->nb_samples; i++) {
627  dst[i] += a[i];
628  }
629 
630  FFSWAP(AVFrame *, abuf, cbuf);
631  }
632  }
633 
634  out->pts = in->pts;
635  av_frame_free(&in);
636  return ff_filter_frame(outlink, out);
637 }
638 
639 static int request_frame(AVFilterLink *outlink)
640 {
641  AVFilterContext *ctx = outlink->src;
642  int ret;
643 
644  ret = ff_request_frame(ctx->inputs[0]);
645 
646  return ret;
647 }
648 
649 static const AVFilterPad mcompand_inputs[] = {
650  {
651  .name = "default",
652  .type = AVMEDIA_TYPE_AUDIO,
653  .filter_frame = filter_frame,
654  },
655  { NULL }
656 };
657 
658 static const AVFilterPad mcompand_outputs[] = {
659  {
660  .name = "default",
661  .type = AVMEDIA_TYPE_AUDIO,
662  .request_frame = request_frame,
663  .config_props = config_output,
664  },
665  { NULL }
666 };
667 
668 
670  .name = "mcompand",
671  .description = NULL_IF_CONFIG_SMALL(
672  "Multiband Compress or expand audio dynamic range."),
673  .query_formats = query_formats,
674  .priv_size = sizeof(MCompandContext),
675  .priv_class = &mcompand_class,
676  .uninit = uninit,
679 };
MCompandContext::bands
CompBand * bands
Definition: af_mcompand.c:88
formats
formats
Definition: signature.h:48
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:86
request_frame
static int request_frame(AVFilterLink *outlink)
Definition: af_mcompand.c:639
CompandT
Definition: af_mcompand.c:45
mcompand_outputs
static const AVFilterPad mcompand_outputs[]
Definition: af_mcompand.c:658
AVFilterChannelLayouts
A list of supported channel layouts.
Definition: formats.h:86
r
const char * r
Definition: vf_curves.c:116
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
ff_make_format_list
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:286
out
FILE * out
Definition: movenc.c:54
FFSWAP
#define FFSWAP(type, a, b)
Definition: common.h:108
cb
static double cb(void *priv, double x, double y)
Definition: vf_geq.c:215
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:953
layouts
enum MovChannelLayoutTag * layouts
Definition: mov_chan.c:434
CompBand::attack_rate
double * attack_rate
Definition: af_mcompand.c:70
CompandSegment::b
double b
Definition: af_compand.c:47
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
CompBand::delay_buf
AVFrame * delay_buf
Definition: af_mcompand.c:76
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:111
ff_all_channel_counts
AVFilterChannelLayouts * ff_all_channel_counts(void)
Construct an AVFilterChannelLayouts coding for any channel layout, with known or unknown disposition.
Definition: formats.c:429
CompBand::decay_rate
double * decay_rate
Definition: af_mcompand.c:71
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:303
AVFrame::pts
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:396
PrevCrossover::out_high
double out_high
Definition: af_mcompand.c:59
AVOption
AVOption.
Definition: opt.h:248
b
#define b
Definition: input.c:41
OFFSET
#define OFFSET(x)
Definition: af_mcompand.c:94
ff_request_frame
int ff_request_frame(AVFilterLink *link)
Request an input frame from the filter at the other end of the link.
Definition: avfilter.c:395
mcompand_inputs
static const AVFilterPad mcompand_inputs[]
Definition: af_mcompand.c:649
Crossover::coefs
double coefs[3 *(N+1)]
Definition: af_mcompand.c:65
CompandSegment::x
double x
Definition: af_compand.c:46
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:149
CompandSegment
Definition: af_compand.c:45
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(mcompand)
AVFilterFormats
A list of supported formats for one end of a filter link.
Definition: formats.h:65
MCompandContext::band_samples
int band_samples
Definition: af_mcompand.c:90
config_output
static int config_output(AVFilterLink *outlink)
Definition: af_mcompand.c:343
samplefmt.h
CompBand::delay_buf_ptr
ptrdiff_t delay_buf_ptr
Definition: af_mcompand.c:78
PrevCrossover
Definition: af_mcompand.c:56
MCompandContext
Definition: af_mcompand.c:82
CompBand
Definition: af_mcompand.c:68
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:54
CompBand::transfer_fn
CompandT transfer_fn
Definition: af_mcompand.c:69
avassert.h
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:181
av_cold
#define av_cold
Definition: attributes.h:90
inputs
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several inputs
Definition: filter_design.txt:243
ff_set_common_formats
int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
A helper for query_formats() which sets all links to the same list of formats.
Definition: formats.c:580
CompandT::curve_dB
double curve_dB
Definition: af_mcompand.c:50
s
#define s(width, name)
Definition: cbs_vp9.c:257
CONVOLVE
#define CONVOLVE
Definition: af_mcompand.c:497
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
outputs
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:202
ctx
AVFormatContext * ctx
Definition: movenc.c:48
CompBand::volume
double * volume
Definition: af_mcompand.c:72
CompBand::delay_size
size_t delay_size
Definition: af_mcompand.c:77
if
if(ret)
Definition: filter_design.txt:179
get_volume
static double get_volume(CompandT *s, double in_lin)
Definition: af_mcompand.c:177
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:67
fabs
static __device__ float fabs(float a)
Definition: cuda_runtime.h:182
NULL
#define NULL
Definition: coverity.c:32
crossover
static void crossover(int ch, Crossover *p, double *ibuf, double *obuf_low, double *obuf_high, size_t len)
Definition: af_mcompand.c:499
CompandT::out_min_lin
double out_min_lin
Definition: af_mcompand.c:49
query_formats
static int query_formats(AVFilterContext *ctx)
Definition: af_mcompand.c:126
CompBand::delay
double delay
Definition: af_mcompand.c:73
crossover_setup
static int crossover_setup(AVFilterLink *outlink, Crossover *p, double frequency)
Definition: af_mcompand.c:309
CompandT::nb_segments
int nb_segments
Definition: af_mcompand.c:47
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
for
for(j=16;j >0;--j)
Definition: h264pred_template.c:469
square_quadratic
static void square_quadratic(double const *x, double *y)
Definition: af_mcompand.c:300
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
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: af_mcompand.c:583
FFMAX
#define FFMAX(a, b)
Definition: common.h:103
AV_SAMPLE_FMT_NONE
@ AV_SAMPLE_FMT_NONE
Definition: samplefmt.h:59
hypot
static av_const double hypot(double x, double y)
Definition: libm.h:366
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: af_mcompand.c:104
CompandT::segments
CompandSegment * segments
Definition: af_mcompand.c:46
MCompandContext::band_buf2
AVFrame * band_buf2
Definition: af_mcompand.c:89
MCompandContext::delay_buf_size
size_t delay_buf_size
Definition: af_mcompand.c:91
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
FFMIN
#define FFMIN(a, b)
Definition: common.h:105
N
#define N
Definition: af_mcompand.c:54
CompBand::delay_buf_cnt
size_t delay_buf_cnt
Definition: af_mcompand.c:79
parse_points
static int parse_points(char *points, int nb_points, double radius, CompandT *s, AVFilterContext *ctx)
Definition: af_mcompand.c:198
M_PI
#define M_PI
Definition: mathematics.h:52
internal.h
L
#define L(x)
AVFrame::nb_samples
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:369
i
int i
Definition: input.c:407
Crossover
Definition: af_mcompand.c:62
mcompand_options
static const AVOption mcompand_options[]
Definition: af_mcompand.c:97
count_items
static void count_items(char *item_str, int *nb_items, char delimiter)
Definition: af_mcompand.c:156
AVFrame::extended_data
uint8_t ** extended_data
pointers to the data planes/channels.
Definition: frame.h:350
S
#define S(x)
CompBand::topfreq
double topfreq
Definition: af_mcompand.c:74
AVSampleFormat
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:58
delta
float delta
Definition: vorbis_enc_data.h:430
len
int len
Definition: vorbis_enc_data.h:426
CompandSegment::y
double y
Definition: af_compand.c:46
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:60
AVFilter
Filter definition.
Definition: avfilter.h:145
PrevCrossover::out_low
double out_low
Definition: af_mcompand.c:58
ret
ret
Definition: filter_design.txt:187
Crossover::pos
size_t pos
Definition: af_mcompand.c:64
CompandT::in_min_lin
double in_min_lin
Definition: af_mcompand.c:48
MCompandContext::nb_bands
int nb_bands
Definition: af_mcompand.c:87
ff_all_samplerates
AVFilterFormats * ff_all_samplerates(void)
Definition: formats.c:414
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
Definition: mem.c:252
avfilter.h
MCompandContext::band_buf1
AVFrame * band_buf1
Definition: af_mcompand.c:89
AV_SAMPLE_FMT_DBLP
@ AV_SAMPLE_FMT_DBLP
double, planar
Definition: samplefmt.h:70
ffmath.h
AVFilterContext
An instance of a filter.
Definition: avfilter.h:333
audio.h
M_LN10
#define M_LN10
Definition: mathematics.h:43
ff_af_mcompand
const AVFilter ff_af_mcompand
Definition: af_mcompand.c:669
alpha
static const int16_t alpha[]
Definition: ilbcdata.h:55
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
mcompand_channel
static int mcompand_channel(MCompandContext *c, CompBand *l, double *ibuf, double *obuf, int len, int ch)
Definition: af_mcompand.c:530
A
#define A
Definition: af_mcompand.c:95
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
ff_set_common_samplerates
int ff_set_common_samplerates(AVFilterContext *ctx, AVFilterFormats *samplerates)
Definition: formats.c:568
avstring.h
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:229
update_volume
static void update_volume(CompBand *cb, double in, int ch)
Definition: af_mcompand.c:167
MCompandContext::args
char * args
Definition: af_mcompand.c:85
CompBand::filter
Crossover filter
Definition: af_mcompand.c:75
CompandSegment::a
double a
Definition: af_compand.c:47
Crossover::previous
PrevCrossover * previous
Definition: af_mcompand.c:63
MCompandContext::band_buf3
AVFrame * band_buf3
Definition: af_mcompand.c:89
PrevCrossover::in
double in
Definition: af_mcompand.c:57
ff_set_common_channel_layouts
int ff_set_common_channel_layouts(AVFilterContext *ctx, AVFilterChannelLayouts *channel_layouts)
A helper for query_formats() which sets all links to the same list of channel layouts/sample rates.
Definition: formats.c:561
CompandT::gain_dB
double gain_dB
Definition: af_mcompand.c:51