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