FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
af_mcompand.c
Go to the documentation of this file.
1 /*
2  * COpyright (c) 2002 Daniel Pouzzner
3  * Copyright (c) 1999 Chris Bagwell
4  * Copyright (c) 1999 Nick Bailey
5  * Copyright (c) 2007 Rob Sykes <robs@users.sourceforge.net>
6  * Copyright (c) 2013 Paul B Mahol
7  * Copyright (c) 2014 Andrew Kelley
8  *
9  * This file is part of FFmpeg.
10  *
11  * FFmpeg is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2.1 of the License, or (at your option) any later version.
15  *
16  * FFmpeg is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with FFmpeg; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24  */
25 
26 /**
27  * @file
28  * audio multiband compand filter
29  */
30 
31 #include "libavutil/avassert.h"
32 #include "libavutil/avstring.h"
33 #include "libavutil/ffmath.h"
34 #include "libavutil/opt.h"
35 #include "libavutil/samplefmt.h"
36 #include "audio.h"
37 #include "avfilter.h"
38 #include "internal.h"
39 
40 typedef struct CompandSegment {
41  double x, y;
42  double a, b;
44 
45 typedef struct CompandT {
48  double in_min_lin;
49  double out_min_lin;
50  double curve_dB;
51  double gain_dB;
52 } CompandT;
53 
54 #define N 4
55 
56 typedef struct PrevCrossover {
57  double in;
58  double out_low;
59  double out_high;
60 } PrevCrossover[N * 2];
61 
62 typedef struct Crossover {
64  size_t pos;
65  double coefs[3 *(N+1)];
66 } Crossover;
67 
68 typedef struct CompBand {
70  double *attack_rate;
71  double *decay_rate;
72  double *volume;
73  double delay;
74  double topfreq;
77  size_t delay_size;
78  ptrdiff_t delay_buf_ptr;
79  size_t delay_buf_cnt;
80 } CompBand;
81 
82 typedef struct MCompandContext {
83  const AVClass *class;
84 
85  char *args;
86 
87  int nb_bands;
93 
94 #define OFFSET(x) offsetof(MCompandContext, x)
95 #define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
96 
97 static const AVOption mcompand_options[] = {
98  { "args", "set parameters for each band", OFFSET(args), AV_OPT_TYPE_STRING, { .str = "0.005,0.1 6 -47/-40,-34/-34,-17/-33 100 | 0.003,0.05 6 -47/-40,-34/-34,-17/-33 400 | 0.000625,0.0125 6 -47/-40,-34/-34,-15/-33 1600 | 0.0001,0.025 6 -47/-40,-34/-34,-31/-31,-0/-30 6400 | 0,0.025 6 -38/-31,-28/-28,-0/-25 22000" }, 0, 0, A },
99  { NULL }
100 };
101 
102 AVFILTER_DEFINE_CLASS(mcompand);
103 
105 {
106  MCompandContext *s = ctx->priv;
107  int i;
108 
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);
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 
136  layouts = ff_all_channel_counts();
137  if (!layouts)
138  return AVERROR(ENOMEM);
139  ret = ff_set_common_channel_layouts(ctx, layouts);
140  if (ret < 0)
141  return ret;
142 
143  formats = ff_make_format_list(sample_fmts);
144  if (!formats)
145  return AVERROR(ENOMEM);
146  ret = ff_set_common_formats(ctx, formats);
147  if (ret < 0)
148  return ret;
149 
150  formats = ff_all_samplerates();
151  if (!formats)
152  return AVERROR(ENOMEM);
153  return ff_set_common_samplerates(ctx, formats);
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) {
211  av_log(ctx, AV_LOG_ERROR,
212  "Invalid and/or missing input/output value.\n");
213  return AVERROR(EINVAL);
214  }
215  if (i && S(i - 1).x > S(i).x) {
216  av_log(ctx, AV_LOG_ERROR,
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  uninit(ctx);
366  return AVERROR(EINVAL);
367  }
368  p = NULL;
369 
370  p2 = tstr;
371  count_items(tstr, &nb_items, ' ');
372  tstr2 = av_strtok(p2, " ", &saveptr2);
373  if (!tstr2) {
374  av_log(ctx, AV_LOG_ERROR, "at least one attacks/decays rate is mandatory\n");
375  uninit(ctx);
376  return AVERROR(EINVAL);
377  }
378  p2 = NULL;
379  p3 = tstr2;
380 
381  count_items(tstr2, &nb_attacks, ',');
382  if (!nb_attacks || nb_attacks & 1) {
383  av_log(ctx, AV_LOG_ERROR, "number of attacks rate plus decays rate must be even\n");
384  uninit(ctx);
385  return AVERROR(EINVAL);
386  }
387 
388  s->bands[i].attack_rate = av_calloc(outlink->channels, sizeof(double));
389  s->bands[i].decay_rate = av_calloc(outlink->channels, sizeof(double));
390  s->bands[i].volume = av_calloc(outlink->channels, sizeof(double));
391  for (k = 0; k < FFMIN(nb_attacks / 2, outlink->channels); k++) {
392  char *tstr3 = av_strtok(p3, ",", &saveptr3);
393 
394  p3 = NULL;
395  sscanf(tstr3, "%lf", &s->bands[i].attack_rate[k]);
396  tstr3 = av_strtok(p3, ",", &saveptr3);
397  sscanf(tstr3, "%lf", &s->bands[i].decay_rate[k]);
398 
399  if (s->bands[i].attack_rate[k] > 1.0 / outlink->sample_rate) {
400  s->bands[i].attack_rate[k] = 1.0 - exp(-1.0 / (outlink->sample_rate * s->bands[i].attack_rate[k]));
401  } else {
402  s->bands[i].attack_rate[k] = 1.0;
403  }
404 
405  if (s->bands[i].decay_rate[k] > 1.0 / outlink->sample_rate) {
406  s->bands[i].decay_rate[k] = 1.0 - exp(-1.0 / (outlink->sample_rate * s->bands[i].decay_rate[k]));
407  } else {
408  s->bands[i].decay_rate[k] = 1.0;
409  }
410  }
411 
412  for (ch = k; ch < outlink->channels; ch++) {
413  s->bands[i].attack_rate[ch] = s->bands[i].attack_rate[k - 1];
414  s->bands[i].decay_rate[ch] = s->bands[i].decay_rate[k - 1];
415  }
416 
417  tstr2 = av_strtok(p2, " ", &saveptr2);
418  if (!tstr2) {
419  av_log(ctx, AV_LOG_ERROR, "transfer function curve in dB must be set\n");
420  uninit(ctx);
421  return AVERROR(EINVAL);
422  }
423  sscanf(tstr2, "%lf", &s->bands[i].transfer_fn.curve_dB);
424 
425  radius = s->bands[i].transfer_fn.curve_dB * M_LN10 / 20.0;
426 
427  tstr2 = av_strtok(p2, " ", &saveptr2);
428  if (!tstr2) {
429  av_log(ctx, AV_LOG_ERROR, "transfer points missing\n");
430  uninit(ctx);
431  return AVERROR(EINVAL);
432  }
433 
434  count_items(tstr2, &nb_points, ',');
435  s->bands[i].transfer_fn.nb_segments = (nb_points + 4) * 2;
437  sizeof(CompandSegment));
438  if (!s->bands[i].transfer_fn.segments) {
439  uninit(ctx);
440  return AVERROR(ENOMEM);
441  }
442 
443  ret = parse_points(tstr2, nb_points, radius, &s->bands[i].transfer_fn, ctx);
444  if (ret < 0) {
445  av_log(ctx, AV_LOG_ERROR, "transfer points parsing failed\n");
446  uninit(ctx);
447  return ret;
448  }
449 
450  tstr2 = av_strtok(p2, " ", &saveptr2);
451  if (!tstr2) {
452  av_log(ctx, AV_LOG_ERROR, "crossover_frequency is missing\n");
453  uninit(ctx);
454  return AVERROR(EINVAL);
455  }
456 
457  new_nb_items += sscanf(tstr2, "%lf", &s->bands[i].topfreq) == 1;
458  if (s->bands[i].topfreq < 0 || s->bands[i].topfreq >= outlink->sample_rate / 2) {
459  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);
460  uninit(ctx);
461  return AVERROR(EINVAL);
462  }
463 
464  if (s->bands[i].topfreq != 0) {
465  ret = crossover_setup(outlink, &s->bands[i].filter, s->bands[i].topfreq);
466  if (ret < 0) {
467  uninit(ctx);
468  return ret;
469  }
470  }
471 
472  tstr2 = av_strtok(p2, " ", &saveptr2);
473  if (tstr2) {
474  sscanf(tstr2, "%lf", &s->bands[i].delay);
475  max_delay_size = FFMAX(max_delay_size, s->bands[i].delay * outlink->sample_rate);
476 
477  tstr2 = av_strtok(p2, " ", &saveptr2);
478  if (tstr2) {
479  double initial_volume;
480 
481  sscanf(tstr2, "%lf", &initial_volume);
482  initial_volume = pow(10.0, initial_volume / 20);
483 
484  for (k = 0; k < outlink->channels; k++) {
485  s->bands[i].volume[k] = initial_volume;
486  }
487 
488  tstr2 = av_strtok(p2, " ", &saveptr2);
489  if (tstr2) {
490  sscanf(tstr2, "%lf", &s->bands[i].transfer_fn.gain_dB);
491  }
492  }
493  }
494  }
495  s->nb_bands = new_nb_items;
496 
497  for (i = 0; max_delay_size > 0 && i < s->nb_bands; i++) {
498  s->bands[i].delay_buf = ff_get_audio_buffer(outlink, max_delay_size);
499  if (!s->bands[i].delay_buf)
500  return AVERROR(ENOMEM);
501  }
502  s->delay_buf_size = max_delay_size;
503 
504  return 0;
505 }
506 
507 #define CONVOLVE _ _ _ _
508 
509 static void crossover(int ch, Crossover *p,
510  double *ibuf, double *obuf_low,
511  double *obuf_high, size_t len)
512 {
513  double out_low, out_high;
514 
515  while (len--) {
516  p->pos = p->pos ? p->pos - 1 : N - 1;
517 #define _ out_low += p->coefs[j] * p->previous[ch][p->pos + j].in \
518  - p->coefs[2*N+2 + j] * p->previous[ch][p->pos + j].out_low, j++;
519  {
520  int j = 1;
521  out_low = p->coefs[0] * *ibuf;
522  CONVOLVE
523  *obuf_low++ = out_low;
524  }
525 #undef _
526 #define _ out_high += p->coefs[j+N+1] * p->previous[ch][p->pos + j].in \
527  - p->coefs[2*N+2 + j] * p->previous[ch][p->pos + j].out_high, j++;
528  {
529  int j = 1;
530  out_high = p->coefs[N+1] * *ibuf;
531  CONVOLVE
532  *obuf_high++ = out_high;
533  }
534  p->previous[ch][p->pos + N].in = p->previous[ch][p->pos].in = *ibuf++;
535  p->previous[ch][p->pos + N].out_low = p->previous[ch][p->pos].out_low = out_low;
536  p->previous[ch][p->pos + N].out_high = p->previous[ch][p->pos].out_high = out_high;
537  }
538 }
539 
540 static int mcompand_channel(MCompandContext *c, CompBand *l, double *ibuf, double *obuf, int len, int ch)
541 {
542  int i;
543 
544  for (i = 0; i < len; i++) {
545  double level_in_lin, level_out_lin, checkbuf;
546  /* Maintain the volume fields by simulating a leaky pump circuit */
547  update_volume(l, fabs(ibuf[i]), ch);
548 
549  /* Volume memory is updated: perform compand */
550  level_in_lin = l->volume[ch];
551  level_out_lin = get_volume(&l->transfer_fn, level_in_lin);
552 
553  if (c->delay_buf_size <= 0) {
554  checkbuf = ibuf[i] * level_out_lin;
555  obuf[i] = checkbuf;
556  } else {
557  double *delay_buf = (double *)l->delay_buf->extended_data[ch];
558 
559  /* FIXME: note that this lookahead algorithm is really lame:
560  the response to a peak is released before the peak
561  arrives. */
562 
563  /* because volume application delays differ band to band, but
564  total delay doesn't, the volume is applied in an iteration
565  preceding that in which the sample goes to obuf, except in
566  the band(s) with the longest vol app delay.
567 
568  the offset between delay_buf_ptr and the sample to apply
569  vol to, is a constant equal to the difference between this
570  band's delay and the longest delay of all the bands. */
571 
572  if (l->delay_buf_cnt >= l->delay_size) {
573  checkbuf =
574  delay_buf[(l->delay_buf_ptr +
575  c->delay_buf_size -
576  l->delay_size) % c->delay_buf_size] * level_out_lin;
577  delay_buf[(l->delay_buf_ptr + c->delay_buf_size -
578  l->delay_size) % c->delay_buf_size] = checkbuf;
579  }
580  if (l->delay_buf_cnt >= c->delay_buf_size) {
581  obuf[i] = delay_buf[l->delay_buf_ptr];
582  } else {
583  l->delay_buf_cnt++;
584  }
585  delay_buf[l->delay_buf_ptr++] = ibuf[i];
586  l->delay_buf_ptr %= c->delay_buf_size;
587  }
588  }
589 
590  return 0;
591 }
592 
593 static int filter_frame(AVFilterLink *inlink, AVFrame *in)
594 {
595  AVFilterContext *ctx = inlink->dst;
596  AVFilterLink *outlink = ctx->outputs[0];
597  MCompandContext *s = ctx->priv;
598  AVFrame *out, *abuf, *bbuf, *cbuf;
599  int ch, band, i;
600 
601  out = ff_get_audio_buffer(outlink, in->nb_samples);
602  if (!out) {
603  av_frame_free(&in);
604  return AVERROR(ENOMEM);
605  }
606 
607  if (s->band_samples < in->nb_samples) {
611 
612  s->band_buf1 = ff_get_audio_buffer(outlink, in->nb_samples);
613  s->band_buf2 = ff_get_audio_buffer(outlink, in->nb_samples);
614  s->band_buf3 = ff_get_audio_buffer(outlink, in->nb_samples);
615  s->band_samples = in->nb_samples;
616  }
617 
618  for (ch = 0; ch < outlink->channels; ch++) {
619  double *a, *dst = (double *)out->extended_data[ch];
620 
621  for (band = 0, abuf = in, bbuf = s->band_buf2, cbuf = s->band_buf1; band < s->nb_bands; band++) {
622  CompBand *b = &s->bands[band];
623 
624  if (b->topfreq) {
625  crossover(ch, &b->filter, (double *)abuf->extended_data[ch],
626  (double *)bbuf->extended_data[ch], (double *)cbuf->extended_data[ch], in->nb_samples);
627  } else {
628  bbuf = abuf;
629  abuf = cbuf;
630  }
631 
632  if (abuf == in)
633  abuf = s->band_buf3;
634  mcompand_channel(s, b, (double *)bbuf->extended_data[ch], (double *)abuf->extended_data[ch], out->nb_samples, ch);
635  a = (double *)abuf->extended_data[ch];
636  for (i = 0; i < out->nb_samples; i++) {
637  dst[i] += a[i];
638  }
639 
640  FFSWAP(AVFrame *, abuf, cbuf);
641  }
642  }
643 
644  out->pts = in->pts;
645  av_frame_free(&in);
646  return ff_filter_frame(outlink, out);
647 }
648 
649 static int request_frame(AVFilterLink *outlink)
650 {
651  AVFilterContext *ctx = outlink->src;
652  int ret;
653 
654  ret = ff_request_frame(ctx->inputs[0]);
655 
656  return ret;
657 }
658 
659 static const AVFilterPad mcompand_inputs[] = {
660  {
661  .name = "default",
662  .type = AVMEDIA_TYPE_AUDIO,
663  .filter_frame = filter_frame,
664  },
665  { NULL }
666 };
667 
668 static const AVFilterPad mcompand_outputs[] = {
669  {
670  .name = "default",
671  .type = AVMEDIA_TYPE_AUDIO,
672  .request_frame = request_frame,
673  .config_props = config_output,
674  },
675  { NULL }
676 };
677 
678 
680  .name = "mcompand",
681  .description = NULL_IF_CONFIG_SMALL(
682  "Multiband Compress or expand audio dynamic range."),
683  .query_formats = query_formats,
684  .priv_size = sizeof(MCompandContext),
685  .priv_class = &mcompand_class,
686  .uninit = uninit,
687  .inputs = mcompand_inputs,
688  .outputs = mcompand_outputs,
689 };
#define NULL
Definition: coverity.c:32
int ff_set_common_channel_layouts(AVFilterContext *ctx, AVFilterChannelLayouts *layouts)
A helper for query_formats() which sets all links to the same list of channel layouts/sample rates...
Definition: formats.c:549
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: af_mcompand.c:593
AVFrame * band_buf2
Definition: af_mcompand.c:89
This structure describes decoded (raw) audio or video data.
Definition: frame.h:226
PrevCrossover * previous
Definition: af_mcompand.c:63
AVOption.
Definition: opt.h:246
double delay
Definition: af_mcompand.c:73
static double get_volume(CompandT *s, double in_lin)
Definition: af_mcompand.c:177
static void update_volume(CompBand *cb, double in, int ch)
Definition: af_mcompand.c:167
Main libavfilter public API header.
double in_min_lin
Definition: af_mcompand.c:48
CompandT transfer_fn
Definition: af_mcompand.c:69
static int query_formats(AVFilterContext *ctx)
Definition: af_mcompand.c:126
double out_low
Definition: af_mcompand.c:58
const char * b
Definition: vf_curves.c:116
double, planar
Definition: samplefmt.h:70
double out_min_lin
Definition: af_mcompand.c:49
static int config_output(AVFilterLink *outlink)
Definition: af_mcompand.c:343
size_t delay_buf_size
Definition: af_mcompand.c:91
#define N
Definition: af_mcompand.c:54
int nb_segments
Definition: af_mcompand.c:47
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
Definition: mem.c:244
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:283
const char * name
Pad name.
Definition: internal.h:60
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:346
static double cb(void *priv, double x, double y)
Definition: vf_geq.c:112
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1080
static void count_items(char *item_str, int *nb_items, char delimiter)
Definition: af_mcompand.c:156
static int request_frame(AVFilterLink *outlink)
Definition: af_mcompand.c:649
#define av_cold
Definition: attributes.h:82
size_t delay_buf_cnt
Definition: af_mcompand.c:79
float delta
AVOptions.
#define OFFSET(x)
Definition: af_mcompand.c:94
AVFilter ff_af_mcompand
Definition: af_mcompand.c:679
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:319
double * volume
Definition: af_mcompand.c:72
static void square_quadratic(double const *x, double *y)
Definition: af_mcompand.c:300
double * attack_rate
Definition: af_mcompand.c:70
double * decay_rate
Definition: af_mcompand.c:71
#define av_log(a,...)
A filter pad used for either input or output.
Definition: internal.h:54
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
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:568
AVFrame * band_buf1
Definition: af_mcompand.c:89
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
double topfreq
Definition: af_mcompand.c:74
#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:202
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
const char * r
Definition: vf_curves.c:114
void * priv
private data for use by the filter
Definition: avfilter.h:353
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
double coefs[3 *(N+1)]
Definition: af_mcompand.c:65
simple assert() macros that are a bit more flexible than ISO C assert().
size_t delay_size
Definition: af_mcompand.c:77
double curve_dB
Definition: af_mcompand.c:50
#define FFMAX(a, b)
Definition: common.h:94
int8_t exp
Definition: eval.c:72
CompandSegment * segments
Definition: af_mcompand.c:46
static av_const double hypot(double x, double y)
Definition: libm.h:366
#define FFMIN(a, b)
Definition: common.h:96
static int crossover_setup(AVFilterLink *outlink, Crossover *p, double frequency)
Definition: af_mcompand.c:309
AVFrame * band_buf3
Definition: af_mcompand.c:89
AVFormatContext * ctx
Definition: movenc.c:48
#define s(width, name)
Definition: cbs_vp9.c:257
CompBand * bands
Definition: af_mcompand.c:88
static const AVFilterPad inputs[]
Definition: af_acontrast.c:193
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
A list of supported channel layouts.
Definition: formats.h:85
Crossover filter
Definition: af_mcompand.c:75
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:58
static const int16_t alpha[]
Definition: ilbcdata.h:55
static const AVFilterPad mcompand_outputs[]
Definition: af_mcompand.c:668
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(constuint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(constuint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(constint16_t *) pi >>8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t,*(constint16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t,*(constint16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(constint32_t *) pi >>24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t,*(constint32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t,*(constint32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(constfloat *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(constfloat *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(constfloat *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(constdouble *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(constdouble *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(constdouble *) pi *(1U<< 31))))#defineSET_CONV_FUNC_GROUP(ofmt, ifmt) staticvoidset_generic_function(AudioConvert *ac){}voidff_audio_convert_free(AudioConvert **ac){if(!*ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);}AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enumAVSampleFormatout_fmt, enumAVSampleFormatin_fmt, intchannels, intsample_rate, intapply_map){AudioConvert *ac;intin_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) returnNULL;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);returnNULL;}returnac;}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;}elseif(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;elseac->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);returnac;}intff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in){intuse_generic=1;intlen=in->nb_samples;intp;if(ac->dc){av_log(ac->avr, AV_LOG_TRACE,"%dsamples-audio_convert:%sto%s(dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));returnff_convert_dither(ac-> in
double gain_dB
Definition: af_mcompand.c:51
Describe the class of an AVClass context structure.
Definition: log.h:67
#define L(x)
Filter definition.
Definition: avfilter.h:144
const char * name
Filter name.
Definition: avfilter.h:148
AVFILTER_DEFINE_CLASS(mcompand)
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:350
enum MovChannelLayoutTag * layouts
Definition: mov_chan.c:434
AVFilterFormats * ff_all_samplerates(void)
Definition: formats.c:395
#define A
Definition: af_mcompand.c:95
double out_high
Definition: af_mcompand.c:59
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:184
#define M_LN10
Definition: mathematics.h:43
internal math functions header
size_t pos
Definition: af_mcompand.c:64
static void crossover(int ch, Crossover *p, double *ibuf, double *obuf_low, double *obuf_high, size_t len)
Definition: af_mcompand.c:509
#define CONVOLVE
Definition: af_mcompand.c:507
static av_cold void uninit(AVFilterContext *ctx)
Definition: af_mcompand.c:104
ptrdiff_t delay_buf_ptr
Definition: af_mcompand.c:78
if(ret< 0)
Definition: vf_mcdeint.c:279
static double c[64]
int len
A list of supported formats for one end of a filter link.
Definition: formats.h:64
static int parse_points(char *points, int nb_points, double radius, CompandT *s, AVFilterContext *ctx)
Definition: af_mcompand.c:198
An instance of a filter.
Definition: avfilter.h:338
static const AVOption mcompand_options[]
Definition: af_mcompand.c:97
static enum AVSampleFormat sample_fmts[]
Definition: adpcmenc.c:701
FILE * out
Definition: movenc.c:54
#define av_freep(p)
#define M_PI
Definition: mathematics.h:52
int ff_request_frame(AVFilterLink *link)
Request an input frame from the filter at the other end of the link.
Definition: avfilter.c:407
formats
Definition: signature.h:48
#define FFSWAP(type, a, b)
Definition: common.h:99
static int mcompand_channel(MCompandContext *c, CompBand *l, double *ibuf, double *obuf, int len, int ch)
Definition: af_mcompand.c:540
internal API functions
AVFilterChannelLayouts * ff_all_channel_counts(void)
Construct an AVFilterChannelLayouts coding for any channel layout, with known or unknown disposition...
Definition: formats.c:410
uint8_t ** extended_data
pointers to the data planes/channels.
Definition: frame.h:273
#define S(x)
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:292
AVFrame * delay_buf
Definition: af_mcompand.c:76
for(j=16;j >0;--j)
int ff_set_common_samplerates(AVFilterContext *ctx, AVFilterFormats *samplerates)
Definition: formats.c:556
uint8_t pi<< 24) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_U8,(uint64_t)((*(constuint8_t *) pi-0x80U))<< 56) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8,(*(constuint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8,(*(constuint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16,(*(constint16_t *) pi >>8)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S16,(uint64_t)(*(constint16_t *) pi)<< 48) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16,*(constint16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16,*(constint16_t *) pi *(1.0/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32,(*(constint32_t *) pi >>24)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S32,(uint64_t)(*(constint32_t *) pi)<< 32) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32,*(constint32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32,*(constint32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S64,(*(constint64_t *) pi >>56)+0x80) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S64,*(constint64_t *) pi *(1.0f/(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S64,*(constint64_t *) pi *(1.0/(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, av_clip_uint8(lrintf(*(constfloat *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, av_clip_int16(lrintf(*(constfloat *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, av_clipl_int32(llrintf(*(constfloat *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_FLT, llrintf(*(constfloat *) pi *(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, av_clip_uint8(lrint(*(constdouble *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, av_clip_int16(lrint(*(constdouble *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, av_clipl_int32(llrint(*(constdouble *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_DBL, llrint(*(constdouble *) pi *(INT64_C(1)<< 63)))#defineFMT_PAIR_FUNC(out, in) staticconv_func_type *constfmt_pair_to_conv_functions[AV_SAMPLE_FMT_NB *AV_SAMPLE_FMT_NB]={FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S64),};staticvoidcpy1(uint8_t **dst, constuint8_t **src, intlen){memcpy(*dst,*src, len);}staticvoidcpy2(uint8_t **dst, constuint8_t **src, intlen){memcpy(*dst,*src, 2 *len);}staticvoidcpy4(uint8_t **dst, constuint8_t **src, intlen){memcpy(*dst,*src, 4 *len);}staticvoidcpy8(uint8_t **dst, constuint8_t **src, intlen){memcpy(*dst,*src, 8 *len);}AudioConvert *swri_audio_convert_alloc(enumAVSampleFormatout_fmt, enumAVSampleFormatin_fmt, intchannels, constint *ch_map, intflags){AudioConvert *ctx;conv_func_type *f=fmt_pair_to_conv_functions[av_get_packed_sample_fmt(out_fmt)+AV_SAMPLE_FMT_NB *av_get_packed_sample_fmt(in_fmt)];if(!f) returnNULL;ctx=av_mallocz(sizeof(*ctx));if(!ctx) returnNULL;if(channels==1){in_fmt=av_get_planar_sample_fmt(in_fmt);out_fmt=av_get_planar_sample_fmt(out_fmt);}ctx->channels=channels;ctx->conv_f=f;ctx->ch_map=ch_map;if(in_fmt==AV_SAMPLE_FMT_U8||in_fmt==AV_SAMPLE_FMT_U8P) memset(ctx->silence, 0x80, sizeof(ctx->silence));if(out_fmt==in_fmt &&!ch_map){switch(av_get_bytes_per_sample(in_fmt)){case1:ctx->simd_f=cpy1;break;case2:ctx->simd_f=cpy2;break;case4:ctx->simd_f=cpy4;break;case8:ctx->simd_f=cpy8;break;}}if(HAVE_X86ASM &&1) swri_audio_convert_init_x86(ctx, out_fmt, in_fmt, channels);if(ARCH_ARM) swri_audio_convert_init_arm(ctx, out_fmt, in_fmt, channels);if(ARCH_AARCH64) swri_audio_convert_init_aarch64(ctx, out_fmt, in_fmt, channels);returnctx;}voidswri_audio_convert_free(AudioConvert **ctx){av_freep(ctx);}intswri_audio_convert(AudioConvert *ctx, AudioData *out, AudioData *in, intlen){intch;intoff=0;constintos=(out->planar?1:out->ch_count)*out->bps;unsignedmisaligned=0;av_assert0(ctx->channels==out->ch_count);if(ctx->in_simd_align_mask){intplanes=in->planar?in->ch_count:1;unsignedm=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) in->ch[ch];misaligned|=m &ctx->in_simd_align_mask;}if(ctx->out_simd_align_mask){intplanes=out->planar?out->ch_count:1;unsignedm=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) out->ch[ch];misaligned|=m &ctx->out_simd_align_mask;}if(ctx->simd_f &&!ctx->ch_map &&!misaligned){off=len &~15;av_assert1(off >=0);av_assert1(off<=len);av_assert2(ctx->channels==SWR_CH_MAX||!in->ch[ctx->channels]);if(off >0){if(out->planar==in->planar){intplanes=out->planar?out->ch_count:1;for(ch=0;ch< planes;ch++){ctx->simd_f(out-> ch ch
Definition: audioconvert.c:56
static const AVFilterPad mcompand_inputs[]
Definition: af_mcompand.c:659