FFmpeg  4.4.6
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 
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  for (k = 0; k < FFMIN(nb_attacks / 2, outlink->channels); k++) {
388  char *tstr3 = av_strtok(p3, ",", &saveptr3);
389 
390  p3 = NULL;
391  sscanf(tstr3, "%lf", &s->bands[i].attack_rate[k]);
392  tstr3 = av_strtok(p3, ",", &saveptr3);
393  sscanf(tstr3, "%lf", &s->bands[i].decay_rate[k]);
394 
395  if (s->bands[i].attack_rate[k] > 1.0 / outlink->sample_rate) {
396  s->bands[i].attack_rate[k] = 1.0 - exp(-1.0 / (outlink->sample_rate * s->bands[i].attack_rate[k]));
397  } else {
398  s->bands[i].attack_rate[k] = 1.0;
399  }
400 
401  if (s->bands[i].decay_rate[k] > 1.0 / outlink->sample_rate) {
402  s->bands[i].decay_rate[k] = 1.0 - exp(-1.0 / (outlink->sample_rate * s->bands[i].decay_rate[k]));
403  } else {
404  s->bands[i].decay_rate[k] = 1.0;
405  }
406  }
407 
408  for (ch = k; ch < outlink->channels; ch++) {
409  s->bands[i].attack_rate[ch] = s->bands[i].attack_rate[k - 1];
410  s->bands[i].decay_rate[ch] = s->bands[i].decay_rate[k - 1];
411  }
412 
413  tstr2 = av_strtok(p2, " ", &saveptr2);
414  if (!tstr2) {
415  av_log(ctx, AV_LOG_ERROR, "transfer function curve in dB must be set\n");
416  return AVERROR(EINVAL);
417  }
418  sscanf(tstr2, "%lf", &s->bands[i].transfer_fn.curve_dB);
419 
420  radius = s->bands[i].transfer_fn.curve_dB * M_LN10 / 20.0;
421 
422  tstr2 = av_strtok(p2, " ", &saveptr2);
423  if (!tstr2) {
424  av_log(ctx, AV_LOG_ERROR, "transfer points missing\n");
425  return AVERROR(EINVAL);
426  }
427 
428  count_items(tstr2, &nb_points, ',');
429  s->bands[i].transfer_fn.nb_segments = (nb_points + 4) * 2;
430  s->bands[i].transfer_fn.segments = av_calloc(s->bands[i].transfer_fn.nb_segments,
431  sizeof(CompandSegment));
432  if (!s->bands[i].transfer_fn.segments)
433  return AVERROR(ENOMEM);
434 
435  ret = parse_points(tstr2, nb_points, radius, &s->bands[i].transfer_fn, ctx);
436  if (ret < 0) {
437  av_log(ctx, AV_LOG_ERROR, "transfer points parsing failed\n");
438  return ret;
439  }
440 
441  tstr2 = av_strtok(p2, " ", &saveptr2);
442  if (!tstr2) {
443  av_log(ctx, AV_LOG_ERROR, "crossover_frequency is missing\n");
444  return AVERROR(EINVAL);
445  }
446 
447  new_nb_items += sscanf(tstr2, "%lf", &s->bands[i].topfreq) == 1;
448  if (s->bands[i].topfreq < 0 || s->bands[i].topfreq >= outlink->sample_rate / 2.0) {
449  av_log(ctx, AV_LOG_ERROR, "crossover_frequency: %f, should be >=0 and lower than half of sample rate: %f.\n", s->bands[i].topfreq, outlink->sample_rate / 2.0);
450  return AVERROR(EINVAL);
451  }
452 
453  if (s->bands[i].topfreq != 0) {
454  ret = crossover_setup(outlink, &s->bands[i].filter, s->bands[i].topfreq);
455  if (ret < 0)
456  return ret;
457  }
458 
459  tstr2 = av_strtok(p2, " ", &saveptr2);
460  if (tstr2) {
461  sscanf(tstr2, "%lf", &s->bands[i].delay);
462  max_delay_size = FFMAX(max_delay_size, s->bands[i].delay * outlink->sample_rate);
463 
464  tstr2 = av_strtok(p2, " ", &saveptr2);
465  if (tstr2) {
466  double initial_volume;
467 
468  sscanf(tstr2, "%lf", &initial_volume);
469  initial_volume = pow(10.0, initial_volume / 20);
470 
471  for (k = 0; k < outlink->channels; k++) {
472  s->bands[i].volume[k] = initial_volume;
473  }
474 
475  tstr2 = av_strtok(p2, " ", &saveptr2);
476  if (tstr2) {
477  sscanf(tstr2, "%lf", &s->bands[i].transfer_fn.gain_dB);
478  }
479  }
480  }
481  }
482  s->nb_bands = new_nb_items;
483 
484  for (i = 0; max_delay_size > 0 && i < s->nb_bands; i++) {
485  s->bands[i].delay_buf = ff_get_audio_buffer(outlink, max_delay_size);
486  if (!s->bands[i].delay_buf)
487  return AVERROR(ENOMEM);
488  }
489  s->delay_buf_size = max_delay_size;
490 
491  return 0;
492 }
493 
494 #define CONVOLVE _ _ _ _
495 
496 static void crossover(int ch, Crossover *p,
497  double *ibuf, double *obuf_low,
498  double *obuf_high, size_t len)
499 {
500  double out_low, out_high;
501 
502  while (len--) {
503  p->pos = p->pos ? p->pos - 1 : N - 1;
504 #define _ out_low += p->coefs[j] * p->previous[ch][p->pos + j].in \
505  - p->coefs[2*N+2 + j] * p->previous[ch][p->pos + j].out_low, j++;
506  {
507  int j = 1;
508  out_low = p->coefs[0] * *ibuf;
509  CONVOLVE
510  *obuf_low++ = out_low;
511  }
512 #undef _
513 #define _ out_high += p->coefs[j+N+1] * p->previous[ch][p->pos + j].in \
514  - p->coefs[2*N+2 + j] * p->previous[ch][p->pos + j].out_high, j++;
515  {
516  int j = 1;
517  out_high = p->coefs[N+1] * *ibuf;
518  CONVOLVE
519  *obuf_high++ = out_high;
520  }
521  p->previous[ch][p->pos + N].in = p->previous[ch][p->pos].in = *ibuf++;
522  p->previous[ch][p->pos + N].out_low = p->previous[ch][p->pos].out_low = out_low;
523  p->previous[ch][p->pos + N].out_high = p->previous[ch][p->pos].out_high = out_high;
524  }
525 }
526 
527 static int mcompand_channel(MCompandContext *c, CompBand *l, double *ibuf, double *obuf, int len, int ch)
528 {
529  int i;
530 
531  for (i = 0; i < len; i++) {
532  double level_in_lin, level_out_lin, checkbuf;
533  /* Maintain the volume fields by simulating a leaky pump circuit */
534  update_volume(l, fabs(ibuf[i]), ch);
535 
536  /* Volume memory is updated: perform compand */
537  level_in_lin = l->volume[ch];
538  level_out_lin = get_volume(&l->transfer_fn, level_in_lin);
539 
540  if (c->delay_buf_size <= 0) {
541  checkbuf = ibuf[i] * level_out_lin;
542  obuf[i] = checkbuf;
543  } else {
544  double *delay_buf = (double *)l->delay_buf->extended_data[ch];
545 
546  /* FIXME: note that this lookahead algorithm is really lame:
547  the response to a peak is released before the peak
548  arrives. */
549 
550  /* because volume application delays differ band to band, but
551  total delay doesn't, the volume is applied in an iteration
552  preceding that in which the sample goes to obuf, except in
553  the band(s) with the longest vol app delay.
554 
555  the offset between delay_buf_ptr and the sample to apply
556  vol to, is a constant equal to the difference between this
557  band's delay and the longest delay of all the bands. */
558 
559  if (l->delay_buf_cnt >= l->delay_size) {
560  checkbuf =
561  delay_buf[(l->delay_buf_ptr +
562  c->delay_buf_size -
563  l->delay_size) % c->delay_buf_size] * level_out_lin;
564  delay_buf[(l->delay_buf_ptr + c->delay_buf_size -
565  l->delay_size) % c->delay_buf_size] = checkbuf;
566  }
567  if (l->delay_buf_cnt >= c->delay_buf_size) {
568  obuf[i] = delay_buf[l->delay_buf_ptr];
569  } else {
570  l->delay_buf_cnt++;
571  }
572  delay_buf[l->delay_buf_ptr++] = ibuf[i];
573  l->delay_buf_ptr %= c->delay_buf_size;
574  }
575  }
576 
577  return 0;
578 }
579 
580 static int filter_frame(AVFilterLink *inlink, AVFrame *in)
581 {
582  AVFilterContext *ctx = inlink->dst;
583  AVFilterLink *outlink = ctx->outputs[0];
584  MCompandContext *s = ctx->priv;
585  AVFrame *out, *abuf, *bbuf, *cbuf;
586  int ch, band, i;
587 
588  out = ff_get_audio_buffer(outlink, in->nb_samples);
589  if (!out) {
590  av_frame_free(&in);
591  return AVERROR(ENOMEM);
592  }
593 
594  if (s->band_samples < in->nb_samples) {
595  av_frame_free(&s->band_buf1);
596  av_frame_free(&s->band_buf2);
597  av_frame_free(&s->band_buf3);
598 
599  s->band_buf1 = ff_get_audio_buffer(outlink, in->nb_samples);
600  s->band_buf2 = ff_get_audio_buffer(outlink, in->nb_samples);
601  s->band_buf3 = ff_get_audio_buffer(outlink, in->nb_samples);
602  s->band_samples = in->nb_samples;
603  }
604 
605  for (ch = 0; ch < outlink->channels; ch++) {
606  double *a, *dst = (double *)out->extended_data[ch];
607 
608  for (band = 0, abuf = in, bbuf = s->band_buf2, cbuf = s->band_buf1; band < s->nb_bands; band++) {
609  CompBand *b = &s->bands[band];
610 
611  if (b->topfreq) {
612  crossover(ch, &b->filter, (double *)abuf->extended_data[ch],
613  (double *)bbuf->extended_data[ch], (double *)cbuf->extended_data[ch], in->nb_samples);
614  } else {
615  bbuf = abuf;
616  abuf = cbuf;
617  }
618 
619  if (abuf == in)
620  abuf = s->band_buf3;
621  mcompand_channel(s, b, (double *)bbuf->extended_data[ch], (double *)abuf->extended_data[ch], out->nb_samples, ch);
622  a = (double *)abuf->extended_data[ch];
623  for (i = 0; i < out->nb_samples; i++) {
624  dst[i] += a[i];
625  }
626 
627  FFSWAP(AVFrame *, abuf, cbuf);
628  }
629  }
630 
631  out->pts = in->pts;
632  av_frame_free(&in);
633  return ff_filter_frame(outlink, out);
634 }
635 
636 static int request_frame(AVFilterLink *outlink)
637 {
638  AVFilterContext *ctx = outlink->src;
639  int ret;
640 
641  ret = ff_request_frame(ctx->inputs[0]);
642 
643  return ret;
644 }
645 
646 static const AVFilterPad mcompand_inputs[] = {
647  {
648  .name = "default",
649  .type = AVMEDIA_TYPE_AUDIO,
650  .filter_frame = filter_frame,
651  },
652  { NULL }
653 };
654 
655 static const AVFilterPad mcompand_outputs[] = {
656  {
657  .name = "default",
658  .type = AVMEDIA_TYPE_AUDIO,
659  .request_frame = request_frame,
660  .config_props = config_output,
661  },
662  { NULL }
663 };
664 
665 
667  .name = "mcompand",
668  .description = NULL_IF_CONFIG_SMALL(
669  "Multiband Compress or expand audio dynamic range."),
670  .query_formats = query_formats,
671  .priv_size = sizeof(MCompandContext),
672  .priv_class = &mcompand_class,
673  .uninit = uninit,
676 };
static enum AVSampleFormat sample_fmts[]
Definition: adpcmenc.c:925
static const AVFilterPad inputs[]
Definition: af_acontrast.c:193
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
#define N
Definition: af_mcompand.c:54
static const AVFilterPad mcompand_outputs[]
Definition: af_mcompand.c:655
static void square_quadratic(double const *x, double *y)
Definition: af_mcompand.c:300
static void update_volume(CompBand *cb, double in, int ch)
Definition: af_mcompand.c:167
static int mcompand_channel(MCompandContext *c, CompBand *l, double *ibuf, double *obuf, int len, int ch)
Definition: af_mcompand.c:527
static int query_formats(AVFilterContext *ctx)
Definition: af_mcompand.c:126
static int parse_points(char *points, int nb_points, double radius, CompandT *s, AVFilterContext *ctx)
Definition: af_mcompand.c:198
static int crossover_setup(AVFilterLink *outlink, Crossover *p, double frequency)
Definition: af_mcompand.c:309
static int request_frame(AVFilterLink *outlink)
Definition: af_mcompand.c:636
#define L(x)
static const AVFilterPad mcompand_inputs[]
Definition: af_mcompand.c:646
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: af_mcompand.c:580
#define A
Definition: af_mcompand.c:95
AVFilter ff_af_mcompand
Definition: af_mcompand.c:666
static void count_items(char *item_str, int *nb_items, char delimiter)
Definition: af_mcompand.c:156
AVFILTER_DEFINE_CLASS(mcompand)
static double get_volume(CompandT *s, double in_lin)
Definition: af_mcompand.c:177
#define CONVOLVE
Definition: af_mcompand.c:494
static av_cold void uninit(AVFilterContext *ctx)
Definition: af_mcompand.c:104
#define S(x)
static void crossover(int ch, Crossover *p, double *ibuf, double *obuf_low, double *obuf_high, size_t len)
Definition: af_mcompand.c:496
#define OFFSET(x)
Definition: af_mcompand.c:94
static int config_output(AVFilterLink *outlink)
Definition: af_mcompand.c:343
static const AVOption mcompand_options[]
Definition: af_mcompand.c:97
#define av_cold
Definition: attributes.h:88
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
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) #define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac) { } void ff_audio_convert_free(AudioConvert **ac) { if(! *ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);} AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map) { AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method !=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2) { ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc) { av_free(ac);return NULL;} return ac;} in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar) { ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar ? ac->channels :1;} else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;} int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in) { int use_generic=1;int len=in->nb_samples;int p;if(ac->dc) { av_log(ac->avr, AV_LOG_TRACE, "%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
simple assert() macros that are a bit more flexible than ISO C assert().
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1096
int ff_request_frame(AVFilterLink *link)
Request an input frame from the filter at the other end of the link.
Definition: avfilter.c:408
Main libavfilter public API header.
#define s(width, name)
Definition: cbs_vp9.c:257
#define FFSWAP(type, a, b)
Definition: common.h:108
#define FFMIN(a, b)
Definition: common.h:105
#define FFMAX(a, b)
Definition: common.h:103
#define NULL
Definition: coverity.c:32
static __device__ float fabs(float a)
Definition: cuda_runtime.h:182
int8_t exp
Definition: eval.c:72
internal math functions header
AVFilterChannelLayouts * ff_all_channel_counts(void)
Construct an AVFilterChannelLayouts coding for any channel layout, with known or unknown disposition.
Definition: formats.c:436
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:587
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:286
int ff_set_common_samplerates(AVFilterContext *ctx, AVFilterFormats *samplerates)
Definition: formats.c:575
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:568
AVFilterFormats * ff_all_samplerates(void)
Definition: formats.c:421
@ AV_OPT_TYPE_STRING
Definition: opt.h:229
#define AVERROR(e)
Definition: error.h:43
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:203
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:215
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
Definition: mem.c:245
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:58
@ AV_SAMPLE_FMT_NONE
Definition: samplefmt.h:59
@ AV_SAMPLE_FMT_DBLP
double, planar
Definition: samplefmt.h:70
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
for(j=16;j >0;--j)
static const int16_t alpha[]
Definition: ilbcdata.h:55
int i
Definition: input.c:407
common internal API header
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:117
static av_const double hypot(double x, double y)
Definition: libm.h:366
#define M_LN10
Definition: mathematics.h:43
#define M_PI
Definition: mathematics.h:52
enum MovChannelLayoutTag * layouts
Definition: mov_chan.c:434
AVOptions.
formats
Definition: signature.h:48
Describe the class of an AVClass context structure.
Definition: log.h:67
A list of supported channel layouts.
Definition: formats.h:86
An instance of a filter.
Definition: avfilter.h:341
A list of supported formats for one end of a filter link.
Definition: formats.h:65
A filter pad used for either input or output.
Definition: internal.h:54
const char * name
Pad name.
Definition: internal.h:60
Filter definition.
Definition: avfilter.h:145
const char * name
Filter name.
Definition: avfilter.h:149
This structure describes decoded (raw) audio or video data.
Definition: frame.h:318
uint8_t ** extended_data
pointers to the data planes/channels.
Definition: frame.h:365
AVOption.
Definition: opt.h:248
double topfreq
Definition: af_mcompand.c:74
ptrdiff_t delay_buf_ptr
Definition: af_mcompand.c:78
CompandT transfer_fn
Definition: af_mcompand.c:69
double * attack_rate
Definition: af_mcompand.c:70
double delay
Definition: af_mcompand.c:73
size_t delay_size
Definition: af_mcompand.c:77
double * decay_rate
Definition: af_mcompand.c:71
size_t delay_buf_cnt
Definition: af_mcompand.c:79
double * volume
Definition: af_mcompand.c:72
AVFrame * delay_buf
Definition: af_mcompand.c:76
Crossover filter
Definition: af_mcompand.c:75
double gain_dB
Definition: af_mcompand.c:51
double out_min_lin
Definition: af_mcompand.c:49
CompandSegment * segments
Definition: af_mcompand.c:46
int nb_segments
Definition: af_mcompand.c:47
double curve_dB
Definition: af_mcompand.c:50
double in_min_lin
Definition: af_mcompand.c:48
double coefs[3 *(N+1)]
Definition: af_mcompand.c:65
PrevCrossover * previous
Definition: af_mcompand.c:63
size_t pos
Definition: af_mcompand.c:64
CompBand * bands
Definition: af_mcompand.c:88
AVFrame * band_buf2
Definition: af_mcompand.c:89
AVFrame * band_buf1
Definition: af_mcompand.c:89
size_t delay_buf_size
Definition: af_mcompand.c:91
AVFrame * band_buf3
Definition: af_mcompand.c:89
double out_high
Definition: af_mcompand.c:59
double out_low
Definition: af_mcompand.c:58
#define av_freep(p)
#define av_log(a,...)
FILE * out
Definition: movenc.c:54
AVFormatContext * ctx
Definition: movenc.c:48
const char * b
Definition: vf_curves.c:118
const char * r
Definition: vf_curves.c:116
static double cb(void *priv, double x, double y)
Definition: vf_geq.c:215
if(ret< 0)
Definition: vf_mcdeint.c:282
float delta
int len
static double c[64]