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/avstring.h"
32 #include "libavutil/ffmath.h"
33 #include "libavutil/mem.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 
126 static void count_items(char *item_str, int *nb_items, char delimiter)
127 {
128  char *p;
129 
130  *nb_items = 1;
131  for (p = item_str; *p; p++) {
132  if (*p == delimiter)
133  (*nb_items)++;
134  }
135 }
136 
137 static void update_volume(CompBand *cb, double in, int ch)
138 {
139  double delta = in - cb->volume[ch];
140 
141  if (delta > 0.0)
142  cb->volume[ch] += delta * cb->attack_rate[ch];
143  else
144  cb->volume[ch] += delta * cb->decay_rate[ch];
145 }
146 
147 static double get_volume(CompandT *s, double in_lin)
148 {
149  CompandSegment *cs;
150  double in_log, out_log;
151  int i;
152 
153  if (in_lin <= s->in_min_lin)
154  return s->out_min_lin;
155 
156  in_log = log(in_lin);
157 
158  for (i = 1; i < s->nb_segments; i++)
159  if (in_log <= s->segments[i].x)
160  break;
161  cs = &s->segments[i - 1];
162  in_log -= cs->x;
163  out_log = cs->y + in_log * (cs->a * in_log + cs->b);
164 
165  return exp(out_log);
166 }
167 
168 static int parse_points(char *points, int nb_points, double radius,
170 {
171  int new_nb_items, num;
172  char *saveptr = NULL;
173  char *p = points;
174  int i;
175 
176 #define S(x) s->segments[2 * ((x) + 1)]
177  for (i = 0, new_nb_items = 0; i < nb_points; i++) {
178  char *tstr = av_strtok(p, ",", &saveptr);
179  p = NULL;
180  if (!tstr || sscanf(tstr, "%lf/%lf", &S(i).x, &S(i).y) != 2) {
182  "Invalid and/or missing input/output value.\n");
183  return AVERROR(EINVAL);
184  }
185  if (i && S(i - 1).x > S(i).x) {
187  "Transfer function input values must be increasing.\n");
188  return AVERROR(EINVAL);
189  }
190  S(i).y -= S(i).x;
191  av_log(ctx, AV_LOG_DEBUG, "%d: x=%f y=%f\n", i, S(i).x, S(i).y);
192  new_nb_items++;
193  }
194  num = new_nb_items;
195 
196  /* Add 0,0 if necessary */
197  if (num == 0 || S(num - 1).x)
198  num++;
199 
200 #undef S
201 #define S(x) s->segments[2 * (x)]
202  /* Add a tail off segment at the start */
203  S(0).x = S(1).x - 2 * s->curve_dB;
204  S(0).y = S(1).y;
205  num++;
206 
207  /* Join adjacent colinear segments */
208  for (i = 2; i < num; i++) {
209  double g1 = (S(i - 1).y - S(i - 2).y) * (S(i - 0).x - S(i - 1).x);
210  double g2 = (S(i - 0).y - S(i - 1).y) * (S(i - 1).x - S(i - 2).x);
211  int j;
212 
213  if (fabs(g1 - g2))
214  continue;
215  num--;
216  for (j = --i; j < num; j++)
217  S(j) = S(j + 1);
218  }
219 
220  for (i = 0; i < s->nb_segments; i += 2) {
221  s->segments[i].y += s->gain_dB;
222  s->segments[i].x *= M_LN10 / 20;
223  s->segments[i].y *= M_LN10 / 20;
224  }
225 
226 #define L(x) s->segments[i - (x)]
227  for (i = 4; i < s->nb_segments; i += 2) {
228  double x, y, cx, cy, in1, in2, out1, out2, theta, len, r;
229 
230  L(4).a = 0;
231  L(4).b = (L(2).y - L(4).y) / (L(2).x - L(4).x);
232 
233  L(2).a = 0;
234  L(2).b = (L(0).y - L(2).y) / (L(0).x - L(2).x);
235 
236  theta = atan2(L(2).y - L(4).y, L(2).x - L(4).x);
237  len = hypot(L(2).x - L(4).x, L(2).y - L(4).y);
238  r = FFMIN(radius, len);
239  L(3).x = L(2).x - r * cos(theta);
240  L(3).y = L(2).y - r * sin(theta);
241 
242  theta = atan2(L(0).y - L(2).y, L(0).x - L(2).x);
243  len = hypot(L(0).x - L(2).x, L(0).y - L(2).y);
244  r = FFMIN(radius, len / 2);
245  x = L(2).x + r * cos(theta);
246  y = L(2).y + r * sin(theta);
247 
248  cx = (L(3).x + L(2).x + x) / 3;
249  cy = (L(3).y + L(2).y + y) / 3;
250 
251  L(2).x = x;
252  L(2).y = y;
253 
254  in1 = cx - L(3).x;
255  out1 = cy - L(3).y;
256  in2 = L(2).x - L(3).x;
257  out2 = L(2).y - L(3).y;
258  L(3).a = (out2 / in2 - out1 / in1) / (in2 - in1);
259  L(3).b = out1 / in1 - L(3).a * in1;
260  }
261  L(3).x = 0;
262  L(3).y = L(2).y;
263 
264  s->in_min_lin = exp(s->segments[1].x);
265  s->out_min_lin = exp(s->segments[1].y);
266 
267  return 0;
268 }
269 
270 static void square_quadratic(double const *x, double *y)
271 {
272  y[0] = x[0] * x[0];
273  y[1] = 2 * x[0] * x[1];
274  y[2] = 2 * x[0] * x[2] + x[1] * x[1];
275  y[3] = 2 * x[1] * x[2];
276  y[4] = x[2] * x[2];
277 }
278 
279 static int crossover_setup(AVFilterLink *outlink, Crossover *p, double frequency)
280 {
281  double w0 = 2 * M_PI * frequency / outlink->sample_rate;
282  double Q = sqrt(.5), alpha = sin(w0) / (2*Q);
283  double x[9], norm;
284  int i;
285 
286  if (w0 > M_PI)
287  return AVERROR(EINVAL);
288 
289  x[0] = (1 - cos(w0))/2; /* Cf. filter_LPF in biquads.c */
290  x[1] = 1 - cos(w0);
291  x[2] = (1 - cos(w0))/2;
292  x[3] = (1 + cos(w0))/2; /* Cf. filter_HPF in biquads.c */
293  x[4] = -(1 + cos(w0));
294  x[5] = (1 + cos(w0))/2;
295  x[6] = 1 + alpha;
296  x[7] = -2*cos(w0);
297  x[8] = 1 - alpha;
298 
299  for (norm = x[6], i = 0; i < 9; ++i)
300  x[i] /= norm;
301 
302  square_quadratic(x , p->coefs);
303  square_quadratic(x + 3, p->coefs + 5);
304  square_quadratic(x + 6, p->coefs + 10);
305 
306  p->previous = av_calloc(outlink->ch_layout.nb_channels, sizeof(*p->previous));
307  if (!p->previous)
308  return AVERROR(ENOMEM);
309 
310  return 0;
311 }
312 
313 static int config_output(AVFilterLink *outlink)
314 {
315  AVFilterContext *ctx = outlink->src;
316  MCompandContext *s = ctx->priv;
317  int ret, ch, i, k, new_nb_items, nb_bands;
318  char *p = s->args, *saveptr = NULL;
319  int max_delay_size = 0;
320 
321  count_items(s->args, &nb_bands, '|');
322  s->nb_bands = FFMAX(1, nb_bands);
323 
324  s->bands = av_calloc(nb_bands, sizeof(*s->bands));
325  if (!s->bands)
326  return AVERROR(ENOMEM);
327 
328  for (i = 0, new_nb_items = 0; i < nb_bands; i++) {
329  int nb_points, nb_attacks, nb_items = 0;
330  char *tstr2, *tstr = av_strtok(p, "|", &saveptr);
331  char *p2, *p3, *saveptr2 = NULL, *saveptr3 = NULL;
332  double radius;
333 
334  if (!tstr)
335  return AVERROR(EINVAL);
336  p = NULL;
337 
338  p2 = tstr;
339  count_items(tstr, &nb_items, ' ');
340  tstr2 = av_strtok(p2, " ", &saveptr2);
341  if (!tstr2) {
342  av_log(ctx, AV_LOG_ERROR, "at least one attacks/decays rate is mandatory\n");
343  return AVERROR(EINVAL);
344  }
345  p2 = NULL;
346  p3 = tstr2;
347 
348  count_items(tstr2, &nb_attacks, ',');
349  if (!nb_attacks || nb_attacks & 1) {
350  av_log(ctx, AV_LOG_ERROR, "number of attacks rate plus decays rate must be even\n");
351  return AVERROR(EINVAL);
352  }
353 
354  s->bands[i].attack_rate = av_calloc(outlink->ch_layout.nb_channels, sizeof(double));
355  s->bands[i].decay_rate = av_calloc(outlink->ch_layout.nb_channels, sizeof(double));
356  s->bands[i].volume = av_calloc(outlink->ch_layout.nb_channels, sizeof(double));
357  if (!s->bands[i].attack_rate || !s->bands[i].decay_rate || !s->bands[i].volume)
358  return AVERROR(ENOMEM);
359 
360  for (k = 0; k < FFMIN(nb_attacks / 2, outlink->ch_layout.nb_channels); k++) {
361  char *tstr3 = av_strtok(p3, ",", &saveptr3);
362 
363  p3 = NULL;
364  sscanf(tstr3, "%lf", &s->bands[i].attack_rate[k]);
365  tstr3 = av_strtok(p3, ",", &saveptr3);
366  sscanf(tstr3, "%lf", &s->bands[i].decay_rate[k]);
367 
368  if (s->bands[i].attack_rate[k] > 1.0 / outlink->sample_rate) {
369  s->bands[i].attack_rate[k] = 1.0 - exp(-1.0 / (outlink->sample_rate * s->bands[i].attack_rate[k]));
370  } else {
371  s->bands[i].attack_rate[k] = 1.0;
372  }
373 
374  if (s->bands[i].decay_rate[k] > 1.0 / outlink->sample_rate) {
375  s->bands[i].decay_rate[k] = 1.0 - exp(-1.0 / (outlink->sample_rate * s->bands[i].decay_rate[k]));
376  } else {
377  s->bands[i].decay_rate[k] = 1.0;
378  }
379  }
380 
381  for (ch = k; ch < outlink->ch_layout.nb_channels; ch++) {
382  s->bands[i].attack_rate[ch] = s->bands[i].attack_rate[k - 1];
383  s->bands[i].decay_rate[ch] = s->bands[i].decay_rate[k - 1];
384  }
385 
386  tstr2 = av_strtok(p2, " ", &saveptr2);
387  if (!tstr2) {
388  av_log(ctx, AV_LOG_ERROR, "transfer function curve in dB must be set\n");
389  return AVERROR(EINVAL);
390  }
391  sscanf(tstr2, "%lf", &s->bands[i].transfer_fn.curve_dB);
392 
393  radius = s->bands[i].transfer_fn.curve_dB * M_LN10 / 20.0;
394 
395  tstr2 = av_strtok(p2, " ", &saveptr2);
396  if (!tstr2) {
397  av_log(ctx, AV_LOG_ERROR, "transfer points missing\n");
398  return AVERROR(EINVAL);
399  }
400 
401  count_items(tstr2, &nb_points, ',');
402  s->bands[i].transfer_fn.nb_segments = (nb_points + 4) * 2;
403  s->bands[i].transfer_fn.segments = av_calloc(s->bands[i].transfer_fn.nb_segments,
404  sizeof(CompandSegment));
405  if (!s->bands[i].transfer_fn.segments)
406  return AVERROR(ENOMEM);
407 
408  ret = parse_points(tstr2, nb_points, radius, &s->bands[i].transfer_fn, ctx);
409  if (ret < 0) {
410  av_log(ctx, AV_LOG_ERROR, "transfer points parsing failed\n");
411  return ret;
412  }
413 
414  tstr2 = av_strtok(p2, " ", &saveptr2);
415  if (!tstr2) {
416  av_log(ctx, AV_LOG_ERROR, "crossover_frequency is missing\n");
417  return AVERROR(EINVAL);
418  }
419 
420  new_nb_items += sscanf(tstr2, "%lf", &s->bands[i].topfreq) == 1;
421  if (s->bands[i].topfreq < 0 || s->bands[i].topfreq >= outlink->sample_rate / 2) {
422  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);
423  return AVERROR(EINVAL);
424  }
425 
426  if (s->bands[i].topfreq != 0) {
427  ret = crossover_setup(outlink, &s->bands[i].filter, s->bands[i].topfreq);
428  if (ret < 0)
429  return ret;
430  }
431 
432  tstr2 = av_strtok(p2, " ", &saveptr2);
433  if (tstr2) {
434  sscanf(tstr2, "%lf", &s->bands[i].delay);
435  max_delay_size = FFMAX(max_delay_size, s->bands[i].delay * outlink->sample_rate);
436 
437  tstr2 = av_strtok(p2, " ", &saveptr2);
438  if (tstr2) {
439  double initial_volume;
440 
441  sscanf(tstr2, "%lf", &initial_volume);
442  initial_volume = pow(10.0, initial_volume / 20);
443 
444  for (k = 0; k < outlink->ch_layout.nb_channels; k++) {
445  s->bands[i].volume[k] = initial_volume;
446  }
447 
448  tstr2 = av_strtok(p2, " ", &saveptr2);
449  if (tstr2) {
450  sscanf(tstr2, "%lf", &s->bands[i].transfer_fn.gain_dB);
451  }
452  }
453  }
454  }
455  s->nb_bands = new_nb_items;
456 
457  for (i = 0; max_delay_size > 0 && i < s->nb_bands; i++) {
458  s->bands[i].delay_buf = ff_get_audio_buffer(outlink, max_delay_size);
459  if (!s->bands[i].delay_buf)
460  return AVERROR(ENOMEM);
461  }
462  s->delay_buf_size = max_delay_size;
463 
464  return 0;
465 }
466 
467 #define CONVOLVE _ _ _ _
468 
469 static void crossover(int ch, Crossover *p,
470  double *ibuf, double *obuf_low,
471  double *obuf_high, size_t len)
472 {
473  double out_low, out_high;
474 
475  while (len--) {
476  p->pos = p->pos ? p->pos - 1 : N - 1;
477 #define _ out_low += p->coefs[j] * p->previous[ch][p->pos + j].in \
478  - p->coefs[2*N+2 + j] * p->previous[ch][p->pos + j].out_low, j++;
479  {
480  int j = 1;
481  out_low = p->coefs[0] * *ibuf;
482  CONVOLVE
483  *obuf_low++ = out_low;
484  }
485 #undef _
486 #define _ out_high += p->coefs[j+N+1] * p->previous[ch][p->pos + j].in \
487  - p->coefs[2*N+2 + j] * p->previous[ch][p->pos + j].out_high, j++;
488  {
489  int j = 1;
490  out_high = p->coefs[N+1] * *ibuf;
491  CONVOLVE
492  *obuf_high++ = out_high;
493  }
494  p->previous[ch][p->pos + N].in = p->previous[ch][p->pos].in = *ibuf++;
495  p->previous[ch][p->pos + N].out_low = p->previous[ch][p->pos].out_low = out_low;
496  p->previous[ch][p->pos + N].out_high = p->previous[ch][p->pos].out_high = out_high;
497  }
498 }
499 
500 static int mcompand_channel(MCompandContext *c, CompBand *l, double *ibuf, double *obuf, int len, int ch)
501 {
502  int i;
503 
504  for (i = 0; i < len; i++) {
505  double level_in_lin, level_out_lin, checkbuf;
506  /* Maintain the volume fields by simulating a leaky pump circuit */
507  update_volume(l, fabs(ibuf[i]), ch);
508 
509  /* Volume memory is updated: perform compand */
510  level_in_lin = l->volume[ch];
511  level_out_lin = get_volume(&l->transfer_fn, level_in_lin);
512 
513  if (c->delay_buf_size <= 0) {
514  checkbuf = ibuf[i] * level_out_lin;
515  obuf[i] = checkbuf;
516  } else {
517  double *delay_buf = (double *)l->delay_buf->extended_data[ch];
518 
519  /* FIXME: note that this lookahead algorithm is really lame:
520  the response to a peak is released before the peak
521  arrives. */
522 
523  /* because volume application delays differ band to band, but
524  total delay doesn't, the volume is applied in an iteration
525  preceding that in which the sample goes to obuf, except in
526  the band(s) with the longest vol app delay.
527 
528  the offset between delay_buf_ptr and the sample to apply
529  vol to, is a constant equal to the difference between this
530  band's delay and the longest delay of all the bands. */
531 
532  if (l->delay_buf_cnt >= l->delay_size) {
533  checkbuf =
534  delay_buf[(l->delay_buf_ptr +
535  c->delay_buf_size -
536  l->delay_size) % c->delay_buf_size] * level_out_lin;
537  delay_buf[(l->delay_buf_ptr + c->delay_buf_size -
538  l->delay_size) % c->delay_buf_size] = checkbuf;
539  }
540  if (l->delay_buf_cnt >= c->delay_buf_size) {
541  obuf[i] = delay_buf[l->delay_buf_ptr];
542  } else {
543  l->delay_buf_cnt++;
544  }
545  delay_buf[l->delay_buf_ptr++] = ibuf[i];
546  l->delay_buf_ptr %= c->delay_buf_size;
547  }
548  }
549 
550  return 0;
551 }
552 
554 {
555  AVFilterContext *ctx = inlink->dst;
556  AVFilterLink *outlink = ctx->outputs[0];
557  MCompandContext *s = ctx->priv;
558  AVFrame *out, *abuf, *bbuf, *cbuf;
559  int ch, band, i;
560 
561  out = ff_get_audio_buffer(outlink, in->nb_samples);
562  if (!out) {
563  av_frame_free(&in);
564  return AVERROR(ENOMEM);
565  }
566 
567  if (s->band_samples < in->nb_samples) {
568  av_frame_free(&s->band_buf1);
569  av_frame_free(&s->band_buf2);
570  av_frame_free(&s->band_buf3);
571 
572  s->band_buf1 = ff_get_audio_buffer(outlink, in->nb_samples);
573  s->band_buf2 = ff_get_audio_buffer(outlink, in->nb_samples);
574  s->band_buf3 = ff_get_audio_buffer(outlink, in->nb_samples);
575  s->band_samples = in->nb_samples;
576  }
577 
578  for (ch = 0; ch < outlink->ch_layout.nb_channels; ch++) {
579  double *a, *dst = (double *)out->extended_data[ch];
580 
581  for (band = 0, abuf = in, bbuf = s->band_buf2, cbuf = s->band_buf1; band < s->nb_bands; band++) {
582  CompBand *b = &s->bands[band];
583 
584  if (b->topfreq) {
585  crossover(ch, &b->filter, (double *)abuf->extended_data[ch],
586  (double *)bbuf->extended_data[ch], (double *)cbuf->extended_data[ch], in->nb_samples);
587  } else {
588  bbuf = abuf;
589  abuf = cbuf;
590  }
591 
592  if (abuf == in)
593  abuf = s->band_buf3;
594  mcompand_channel(s, b, (double *)bbuf->extended_data[ch], (double *)abuf->extended_data[ch], out->nb_samples, ch);
595  a = (double *)abuf->extended_data[ch];
596  for (i = 0; i < out->nb_samples; i++) {
597  dst[i] += a[i];
598  }
599 
600  FFSWAP(AVFrame *, abuf, cbuf);
601  }
602  }
603 
604  out->pts = in->pts;
605  av_frame_free(&in);
606  return ff_filter_frame(outlink, out);
607 }
608 
609 static int request_frame(AVFilterLink *outlink)
610 {
611  AVFilterContext *ctx = outlink->src;
612  int ret;
613 
614  ret = ff_request_frame(ctx->inputs[0]);
615 
616  return ret;
617 }
618 
619 static const AVFilterPad mcompand_inputs[] = {
620  {
621  .name = "default",
622  .type = AVMEDIA_TYPE_AUDIO,
623  .filter_frame = filter_frame,
624  },
625 };
626 
627 static const AVFilterPad mcompand_outputs[] = {
628  {
629  .name = "default",
630  .type = AVMEDIA_TYPE_AUDIO,
631  .request_frame = request_frame,
632  .config_props = config_output,
633  },
634 };
635 
636 
638  .name = "mcompand",
639  .description = NULL_IF_CONFIG_SMALL(
640  "Multiband Compress or expand audio dynamic range."),
641  .priv_size = sizeof(MCompandContext),
642  .priv_class = &mcompand_class,
643  .uninit = uninit,
647 };
MCompandContext::bands
CompBand * bands
Definition: af_mcompand.c:88
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:97
request_frame
static int request_frame(AVFilterLink *outlink)
Definition: af_mcompand.c:609
CompandT
Definition: af_mcompand.c:45
mcompand_outputs
static const AVFilterPad mcompand_outputs[]
Definition: af_mcompand.c:627
r
const char * r
Definition: vf_curves.c:127
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
out
FILE * out
Definition: movenc.c:55
cb
static double cb(void *priv, double x, double y)
Definition: vf_geq.c:242
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1015
CompBand::attack_rate
double * attack_rate
Definition: af_mcompand.c:70
FILTER_SINGLE_SAMPLEFMT
#define FILTER_SINGLE_SAMPLEFMT(sample_fmt_)
Definition: internal.h:175
CompandSegment::b
double b
Definition: af_compand.c:48
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
normalize.log
log
Definition: normalize.py:21
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:160
CompBand::decay_rate
double * decay_rate
Definition: af_mcompand.c:71
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:374
AVFrame::pts
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:486
PrevCrossover::out_high
double out_high
Definition: af_mcompand.c:59
AVOption
AVOption.
Definition: opt.h:346
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:463
mcompand_inputs
static const AVFilterPad mcompand_inputs[]
Definition: af_mcompand.c:619
Crossover::coefs
double coefs[3 *(N+1)]
Definition: af_mcompand.c:65
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
CompandSegment::x
double x
Definition: af_compand.c:47
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:170
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:313
CompandSegment
Definition: af_compand.c:46
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(mcompand)
MCompandContext::band_samples
int band_samples
Definition: af_mcompand.c:90
config_output
static int config_output(AVFilterLink *outlink)
Definition: af_mcompand.c:313
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:33
CompBand::transfer_fn
CompandT transfer_fn
Definition: af_mcompand.c:69
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
CompandT::curve_dB
double curve_dB
Definition: af_mcompand.c:50
s
#define s(width, name)
Definition: cbs_vp9.c:198
CONVOLVE
#define CONVOLVE
Definition: af_mcompand.c:467
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
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
ctx
AVFormatContext * ctx
Definition: movenc.c:49
CompBand::volume
double * volume
Definition: af_mcompand.c:72
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: internal.h:182
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:147
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
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:469
CompandT::out_min_lin
double out_min_lin
Definition: af_mcompand.c:49
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:279
CompandT::nb_segments
int nb_segments
Definition: af_mcompand.c:47
exp
int8_t exp
Definition: eval.c:73
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
square_quadratic
static void square_quadratic(double const *x, double *y)
Definition: af_mcompand.c:270
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:94
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: af_mcompand.c:553
for
for(k=2;k<=8;++k)
Definition: h264pred_template.c:425
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
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:168
M_PI
#define M_PI
Definition: mathematics.h:67
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:454
Crossover
Definition: af_mcompand.c:62
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
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:126
AVFrame::extended_data
uint8_t ** extended_data
pointers to the data planes/channels.
Definition: frame.h:435
S
#define S(x)
CompBand::topfreq
double topfreq
Definition: af_mcompand.c:74
delta
float delta
Definition: vorbis_enc_data.h:430
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
len
int len
Definition: vorbis_enc_data.h:426
CompandSegment::y
double y
Definition: af_compand.c:47
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:39
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
AVFilter
Filter definition.
Definition: avfilter.h:166
PrevCrossover::out_low
double out_low
Definition: af_mcompand.c:58
ret
ret
Definition: filter_design.txt:187
FFSWAP
#define FFSWAP(type, a, b)
Definition: macros.h:52
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
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:67
ffmath.h
AVFilterContext
An instance of a filter.
Definition: avfilter.h:407
mem.h
audio.h
M_LN10
#define M_LN10
Definition: mathematics.h:49
ff_af_mcompand
const AVFilter ff_af_mcompand
Definition: af_mcompand.c:637
alpha
static const int16_t alpha[]
Definition: ilbcdata.h:55
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: internal.h:183
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
mcompand_channel
static int mcompand_channel(MCompandContext *c, CompBand *l, double *ibuf, double *obuf, int len, int ch)
Definition: af_mcompand.c:500
Q
#define Q(x)
Definition: filter_template.c:433
A
#define A
Definition: af_mcompand.c:95
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
avstring.h
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:239
update_volume
static void update_volume(CompBand *cb, double in, int ch)
Definition: af_mcompand.c:137
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:48
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
CompandT::gain_dB
double gain_dB
Definition: af_mcompand.c:51