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