FFmpeg  4.4
af_adeclick.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018 Paul B Mahol
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include "libavutil/audio_fifo.h"
22 #include "libavutil/opt.h"
23 #include "avfilter.h"
24 #include "audio.h"
25 #include "filters.h"
26 #include "formats.h"
27 #include "internal.h"
28 
29 typedef struct DeclickChannel {
30  double *auxiliary;
31  double *detection;
32  double *acoefficients;
33  double *acorrelation;
34  double *tmp;
35  double *interpolated;
36  double *matrix;
38  double *vector;
40  double *y;
41  int y_size;
43  int *index;
44  unsigned *histogram;
47 
48 typedef struct AudioDeclickContext {
49  const AVClass *class;
50 
51  double w;
52  double overlap;
53  double threshold;
54  double ar;
55  double burst;
56  int method;
57  int nb_hbins;
58 
59  int is_declip;
60  int ar_order;
63  int hop_size;
65 
71 
73 
74  int64_t pts;
76  uint64_t nb_samples;
77  uint64_t detected_errors;
79  int eof;
80 
83  double *window_func_lut;
84 
86  double sigmae, double *detection,
87  double *acoefficients, uint8_t *click, int *index,
88  const double *src, double *dst);
90 
91 #define OFFSET(x) offsetof(AudioDeclickContext, x)
92 #define AF AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
93 
94 static const AVOption adeclick_options[] = {
95  { "window", "set window size", OFFSET(w), AV_OPT_TYPE_DOUBLE, {.dbl=55}, 10, 100, AF },
96  { "w", "set window size", OFFSET(w), AV_OPT_TYPE_DOUBLE, {.dbl=55}, 10, 100, AF },
97  { "overlap", "set window overlap", OFFSET(overlap), AV_OPT_TYPE_DOUBLE, {.dbl=75}, 50, 95, AF },
98  { "o", "set window overlap", OFFSET(overlap), AV_OPT_TYPE_DOUBLE, {.dbl=75}, 50, 95, AF },
99  { "arorder", "set autoregression order", OFFSET(ar), AV_OPT_TYPE_DOUBLE, {.dbl=2}, 0, 25, AF },
100  { "a", "set autoregression order", OFFSET(ar), AV_OPT_TYPE_DOUBLE, {.dbl=2}, 0, 25, AF },
101  { "threshold", "set threshold", OFFSET(threshold), AV_OPT_TYPE_DOUBLE, {.dbl=2}, 1, 100, AF },
102  { "t", "set threshold", OFFSET(threshold), AV_OPT_TYPE_DOUBLE, {.dbl=2}, 1, 100, AF },
103  { "burst", "set burst fusion", OFFSET(burst), AV_OPT_TYPE_DOUBLE, {.dbl=2}, 0, 10, AF },
104  { "b", "set burst fusion", OFFSET(burst), AV_OPT_TYPE_DOUBLE, {.dbl=2}, 0, 10, AF },
105  { "method", "set overlap method", OFFSET(method), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, AF, "m" },
106  { "m", "set overlap method", OFFSET(method), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, AF, "m" },
107  { "add", "overlap-add", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "m" },
108  { "a", "overlap-add", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "m" },
109  { "save", "overlap-save", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "m" },
110  { "s", "overlap-save", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "m" },
111  { NULL }
112 };
113 
115 
117 {
120  static const enum AVSampleFormat sample_fmts[] = {
123  };
124  int ret;
125 
127  if (!formats)
128  return AVERROR(ENOMEM);
130  if (ret < 0)
131  return ret;
132 
134  if (!layouts)
135  return AVERROR(ENOMEM);
136 
138  if (ret < 0)
139  return ret;
140 
143 }
144 
145 static int config_input(AVFilterLink *inlink)
146 {
147  AVFilterContext *ctx = inlink->dst;
148  AudioDeclickContext *s = ctx->priv;
149  int i;
150 
151  s->pts = AV_NOPTS_VALUE;
152  s->window_size = inlink->sample_rate * s->w / 1000.;
153  if (s->window_size < 100)
154  return AVERROR(EINVAL);
155  s->ar_order = FFMAX(s->window_size * s->ar / 100., 1);
156  s->nb_burst_samples = s->window_size * s->burst / 1000.;
157  s->hop_size = s->window_size * (1. - (s->overlap / 100.));
158  if (s->hop_size < 1)
159  return AVERROR(EINVAL);
160 
161  s->window_func_lut = av_calloc(s->window_size, sizeof(*s->window_func_lut));
162  if (!s->window_func_lut)
163  return AVERROR(ENOMEM);
164  for (i = 0; i < s->window_size; i++)
165  s->window_func_lut[i] = sin(M_PI * i / s->window_size) *
166  (1. - (s->overlap / 100.)) * M_PI_2;
167 
168  av_frame_free(&s->in);
169  av_frame_free(&s->out);
170  av_frame_free(&s->buffer);
171  av_frame_free(&s->is);
172  s->enabled = ff_get_audio_buffer(inlink, s->window_size);
173  s->in = ff_get_audio_buffer(inlink, s->window_size);
174  s->out = ff_get_audio_buffer(inlink, s->window_size);
175  s->buffer = ff_get_audio_buffer(inlink, s->window_size * 2);
176  s->is = ff_get_audio_buffer(inlink, s->window_size);
177  if (!s->in || !s->out || !s->buffer || !s->is || !s->enabled)
178  return AVERROR(ENOMEM);
179 
180  s->efifo = av_audio_fifo_alloc(inlink->format, 1, s->window_size);
181  if (!s->efifo)
182  return AVERROR(ENOMEM);
183  s->fifo = av_audio_fifo_alloc(inlink->format, inlink->channels, s->window_size);
184  if (!s->fifo)
185  return AVERROR(ENOMEM);
186  s->overlap_skip = s->method ? (s->window_size - s->hop_size) / 2 : 0;
187  if (s->overlap_skip > 0) {
188  av_audio_fifo_write(s->fifo, (void **)s->in->extended_data,
189  s->overlap_skip);
190  }
191 
192  s->nb_channels = inlink->channels;
193  s->chan = av_calloc(inlink->channels, sizeof(*s->chan));
194  if (!s->chan)
195  return AVERROR(ENOMEM);
196 
197  for (i = 0; i < inlink->channels; i++) {
198  DeclickChannel *c = &s->chan[i];
199 
200  c->detection = av_calloc(s->window_size, sizeof(*c->detection));
201  c->auxiliary = av_calloc(s->ar_order + 1, sizeof(*c->auxiliary));
202  c->acoefficients = av_calloc(s->ar_order + 1, sizeof(*c->acoefficients));
203  c->acorrelation = av_calloc(s->ar_order + 1, sizeof(*c->acorrelation));
204  c->tmp = av_calloc(s->ar_order, sizeof(*c->tmp));
205  c->click = av_calloc(s->window_size, sizeof(*c->click));
206  c->index = av_calloc(s->window_size, sizeof(*c->index));
207  c->interpolated = av_calloc(s->window_size, sizeof(*c->interpolated));
208  if (!c->auxiliary || !c->acoefficients || !c->detection || !c->click ||
209  !c->index || !c->interpolated || !c->acorrelation || !c->tmp)
210  return AVERROR(ENOMEM);
211  }
212 
213  return 0;
214 }
215 
216 static void autocorrelation(const double *input, int order, int size,
217  double *output, double scale)
218 {
219  int i, j;
220 
221  for (i = 0; i <= order; i++) {
222  double value = 0.;
223 
224  for (j = i; j < size; j++)
225  value += input[j] * input[j - i];
226 
227  output[i] = value * scale;
228  }
229 }
230 
231 static double autoregression(const double *samples, int ar_order,
232  int nb_samples, double *k, double *r, double *a)
233 {
234  double alpha;
235  int i, j;
236 
237  memset(a, 0, ar_order * sizeof(*a));
238 
239  autocorrelation(samples, ar_order, nb_samples, r, 1. / nb_samples);
240 
241  /* Levinson-Durbin algorithm */
242  k[0] = a[0] = -r[1] / r[0];
243  alpha = r[0] * (1. - k[0] * k[0]);
244  for (i = 1; i < ar_order; i++) {
245  double epsilon = 0.;
246 
247  for (j = 0; j < i; j++)
248  epsilon += a[j] * r[i - j];
249  epsilon += r[i + 1];
250 
251  k[i] = -epsilon / alpha;
252  alpha *= (1. - k[i] * k[i]);
253  for (j = i - 1; j >= 0; j--)
254  k[j] = a[j] + k[i] * a[i - j - 1];
255  for (j = 0; j <= i; j++)
256  a[j] = k[j];
257  }
258 
259  k[0] = 1.;
260  for (i = 1; i <= ar_order; i++)
261  k[i] = a[i - 1];
262 
263  return sqrt(alpha);
264 }
265 
266 static int isfinite_array(double *samples, int nb_samples)
267 {
268  int i;
269 
270  for (i = 0; i < nb_samples; i++)
271  if (!isfinite(samples[i]))
272  return 0;
273 
274  return 1;
275 }
276 
277 static int find_index(int *index, int value, int size)
278 {
279  int i, start, end;
280 
281  if ((value < index[0]) || (value > index[size - 1]))
282  return 1;
283 
284  i = start = 0;
285  end = size - 1;
286 
287  while (start <= end) {
288  i = (end + start) / 2;
289  if (index[i] == value)
290  return 0;
291  if (value < index[i])
292  end = i - 1;
293  if (value > index[i])
294  start = i + 1;
295  }
296 
297  return 1;
298 }
299 
300 static int factorization(double *matrix, int n)
301 {
302  int i, j, k;
303 
304  for (i = 0; i < n; i++) {
305  const int in = i * n;
306  double value;
307 
308  value = matrix[in + i];
309  for (j = 0; j < i; j++)
310  value -= matrix[j * n + j] * matrix[in + j] * matrix[in + j];
311 
312  if (value == 0.) {
313  return -1;
314  }
315 
316  matrix[in + i] = value;
317  for (j = i + 1; j < n; j++) {
318  const int jn = j * n;
319  double x;
320 
321  x = matrix[jn + i];
322  for (k = 0; k < i; k++)
323  x -= matrix[k * n + k] * matrix[in + k] * matrix[jn + k];
324  matrix[jn + i] = x / matrix[in + i];
325  }
326  }
327 
328  return 0;
329 }
330 
331 static int do_interpolation(DeclickChannel *c, double *matrix,
332  double *vector, int n, double *out)
333 {
334  int i, j, ret;
335  double *y;
336 
337  ret = factorization(matrix, n);
338  if (ret < 0)
339  return ret;
340 
341  av_fast_malloc(&c->y, &c->y_size, n * sizeof(*c->y));
342  y = c->y;
343  if (!y)
344  return AVERROR(ENOMEM);
345 
346  for (i = 0; i < n; i++) {
347  const int in = i * n;
348  double value;
349 
350  value = vector[i];
351  for (j = 0; j < i; j++)
352  value -= matrix[in + j] * y[j];
353  y[i] = value;
354  }
355 
356  for (i = n - 1; i >= 0; i--) {
357  out[i] = y[i] / matrix[i * n + i];
358  for (j = i + 1; j < n; j++)
359  out[i] -= matrix[j * n + i] * out[j];
360  }
361 
362  return 0;
363 }
364 
365 static int interpolation(DeclickChannel *c, const double *src, int ar_order,
366  double *acoefficients, int *index, int nb_errors,
367  double *auxiliary, double *interpolated)
368 {
369  double *vector, *matrix;
370  int i, j;
371 
372  av_fast_malloc(&c->matrix, &c->matrix_size, nb_errors * nb_errors * sizeof(*c->matrix));
373  matrix = c->matrix;
374  if (!matrix)
375  return AVERROR(ENOMEM);
376 
377  av_fast_malloc(&c->vector, &c->vector_size, nb_errors * sizeof(*c->vector));
378  vector = c->vector;
379  if (!vector)
380  return AVERROR(ENOMEM);
381 
382  autocorrelation(acoefficients, ar_order, ar_order + 1, auxiliary, 1.);
383 
384  for (i = 0; i < nb_errors; i++) {
385  const int im = i * nb_errors;
386 
387  for (j = i; j < nb_errors; j++) {
388  if (abs(index[j] - index[i]) <= ar_order) {
389  matrix[j * nb_errors + i] = matrix[im + j] = auxiliary[abs(index[j] - index[i])];
390  } else {
391  matrix[j * nb_errors + i] = matrix[im + j] = 0;
392  }
393  }
394  }
395 
396  for (i = 0; i < nb_errors; i++) {
397  double value = 0.;
398 
399  for (j = -ar_order; j <= ar_order; j++)
400  if (find_index(index, index[i] - j, nb_errors))
401  value -= src[index[i] - j] * auxiliary[abs(j)];
402 
403  vector[i] = value;
404  }
405 
406  return do_interpolation(c, matrix, vector, nb_errors, interpolated);
407 }
408 
410  double unused0,
411  double *unused1, double *unused2,
412  uint8_t *clip, int *index,
413  const double *src, double *dst)
414 {
415  const double threshold = s->threshold;
416  double max_amplitude = 0;
417  unsigned *histogram;
418  int i, nb_clips = 0;
419 
420  av_fast_malloc(&c->histogram, &c->histogram_size, s->nb_hbins * sizeof(*c->histogram));
421  if (!c->histogram)
422  return AVERROR(ENOMEM);
423  histogram = c->histogram;
424  memset(histogram, 0, sizeof(*histogram) * s->nb_hbins);
425 
426  for (i = 0; i < s->window_size; i++) {
427  const unsigned index = fmin(fabs(src[i]), 1) * (s->nb_hbins - 1);
428 
429  histogram[index]++;
430  dst[i] = src[i];
431  clip[i] = 0;
432  }
433 
434  for (i = s->nb_hbins - 1; i > 1; i--) {
435  if (histogram[i]) {
436  if (histogram[i] / (double)FFMAX(histogram[i - 1], 1) > threshold) {
437  max_amplitude = i / (double)s->nb_hbins;
438  }
439  break;
440  }
441  }
442 
443  if (max_amplitude > 0.) {
444  for (i = 0; i < s->window_size; i++) {
445  clip[i] = fabs(src[i]) >= max_amplitude;
446  }
447  }
448 
449  memset(clip, 0, s->ar_order * sizeof(*clip));
450  memset(clip + (s->window_size - s->ar_order), 0, s->ar_order * sizeof(*clip));
451 
452  for (i = s->ar_order; i < s->window_size - s->ar_order; i++)
453  if (clip[i])
454  index[nb_clips++] = i;
455 
456  return nb_clips;
457 }
458 
460  double sigmae,
461  double *detection, double *acoefficients,
462  uint8_t *click, int *index,
463  const double *src, double *dst)
464 {
465  const double threshold = s->threshold;
466  int i, j, nb_clicks = 0, prev = -1;
467 
468  memset(detection, 0, s->window_size * sizeof(*detection));
469 
470  for (i = s->ar_order; i < s->window_size; i++) {
471  for (j = 0; j <= s->ar_order; j++) {
472  detection[i] += acoefficients[j] * src[i - j];
473  }
474  }
475 
476  for (i = 0; i < s->window_size; i++) {
477  click[i] = fabs(detection[i]) > sigmae * threshold;
478  dst[i] = src[i];
479  }
480 
481  for (i = 0; i < s->window_size; i++) {
482  if (!click[i])
483  continue;
484 
485  if (prev >= 0 && (i > prev + 1) && (i <= s->nb_burst_samples + prev))
486  for (j = prev + 1; j < i; j++)
487  click[j] = 1;
488  prev = i;
489  }
490 
491  memset(click, 0, s->ar_order * sizeof(*click));
492  memset(click + (s->window_size - s->ar_order), 0, s->ar_order * sizeof(*click));
493 
494  for (i = s->ar_order; i < s->window_size - s->ar_order; i++)
495  if (click[i])
496  index[nb_clicks++] = i;
497 
498  return nb_clicks;
499 }
500 
501 typedef struct ThreadData {
503 } ThreadData;
504 
505 static int filter_channel(AVFilterContext *ctx, void *arg, int ch, int nb_jobs)
506 {
507  AudioDeclickContext *s = ctx->priv;
508  ThreadData *td = arg;
509  AVFrame *out = td->out;
510  const double *src = (const double *)s->in->extended_data[ch];
511  double *is = (double *)s->is->extended_data[ch];
512  double *dst = (double *)s->out->extended_data[ch];
513  double *ptr = (double *)out->extended_data[ch];
514  double *buf = (double *)s->buffer->extended_data[ch];
515  const double *w = s->window_func_lut;
516  DeclickChannel *c = &s->chan[ch];
517  double sigmae;
518  int j, ret;
519 
520  sigmae = autoregression(src, s->ar_order, s->window_size, c->acoefficients, c->acorrelation, c->tmp);
521 
522  if (isfinite_array(c->acoefficients, s->ar_order + 1)) {
523  double *interpolated = c->interpolated;
524  int *index = c->index;
525  int nb_errors;
526 
527  nb_errors = s->detector(s, c, sigmae, c->detection, c->acoefficients,
528  c->click, index, src, dst);
529  if (nb_errors > 0) {
530  double *enabled = (double *)s->enabled->extended_data[0];
531 
532  ret = interpolation(c, src, s->ar_order, c->acoefficients, index,
533  nb_errors, c->auxiliary, interpolated);
534  if (ret < 0)
535  return ret;
536 
537  av_audio_fifo_peek(s->efifo, (void**)s->enabled->extended_data, s->window_size);
538 
539  for (j = 0; j < nb_errors; j++) {
540  if (enabled[index[j]]) {
541  dst[index[j]] = interpolated[j];
542  is[index[j]] = 1;
543  }
544  }
545  }
546  } else {
547  memcpy(dst, src, s->window_size * sizeof(*dst));
548  }
549 
550  if (s->method == 0) {
551  for (j = 0; j < s->window_size; j++)
552  buf[j] += dst[j] * w[j];
553  } else {
554  const int skip = s->overlap_skip;
555 
556  for (j = 0; j < s->hop_size; j++)
557  buf[j] = dst[skip + j];
558  }
559  for (j = 0; j < s->hop_size; j++)
560  ptr[j] = buf[j];
561 
562  memmove(buf, buf + s->hop_size, (s->window_size * 2 - s->hop_size) * sizeof(*buf));
563  memmove(is, is + s->hop_size, (s->window_size - s->hop_size) * sizeof(*is));
564  memset(buf + s->window_size * 2 - s->hop_size, 0, s->hop_size * sizeof(*buf));
565  memset(is + s->window_size - s->hop_size, 0, s->hop_size * sizeof(*is));
566 
567  return 0;
568 }
569 
570 static int filter_frame(AVFilterLink *inlink)
571 {
572  AVFilterContext *ctx = inlink->dst;
573  AVFilterLink *outlink = ctx->outputs[0];
574  AudioDeclickContext *s = ctx->priv;
575  AVFrame *out = NULL;
576  int ret = 0, j, ch, detected_errors = 0;
577  ThreadData td;
578 
579  out = ff_get_audio_buffer(outlink, s->hop_size);
580  if (!out)
581  return AVERROR(ENOMEM);
582 
583  ret = av_audio_fifo_peek(s->fifo, (void **)s->in->extended_data,
584  s->window_size);
585  if (ret < 0)
586  goto fail;
587 
588  td.out = out;
589  ret = ctx->internal->execute(ctx, filter_channel, &td, NULL, inlink->channels);
590  if (ret < 0)
591  goto fail;
592 
593  for (ch = 0; ch < s->in->channels; ch++) {
594  double *is = (double *)s->is->extended_data[ch];
595 
596  for (j = 0; j < s->hop_size; j++) {
597  if (is[j])
598  detected_errors++;
599  }
600  }
601 
602  av_audio_fifo_drain(s->fifo, s->hop_size);
603  av_audio_fifo_drain(s->efifo, s->hop_size);
604 
605  if (s->samples_left > 0)
606  out->nb_samples = FFMIN(s->hop_size, s->samples_left);
607 
608  out->pts = s->pts;
609  s->pts += av_rescale_q(s->hop_size, (AVRational){1, outlink->sample_rate}, outlink->time_base);
610 
611  s->detected_errors += detected_errors;
612  s->nb_samples += out->nb_samples * inlink->channels;
613 
614  ret = ff_filter_frame(outlink, out);
615  if (ret < 0)
616  return ret;
617 
618  if (s->samples_left > 0) {
619  s->samples_left -= s->hop_size;
620  if (s->samples_left <= 0)
621  av_audio_fifo_drain(s->fifo, av_audio_fifo_size(s->fifo));
622  }
623 
624 fail:
625  if (ret < 0)
626  av_frame_free(&out);
627  return ret;
628 }
629 
631 {
632  AVFilterLink *inlink = ctx->inputs[0];
633  AVFilterLink *outlink = ctx->outputs[0];
634  AudioDeclickContext *s = ctx->priv;
635  AVFrame *in;
636  int ret, status;
637  int64_t pts;
638 
639  FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink);
640 
641  ret = ff_inlink_consume_samples(inlink, s->window_size, s->window_size, &in);
642  if (ret < 0)
643  return ret;
644  if (ret > 0) {
645  double *e = (double *)s->enabled->extended_data[0];
646 
647  if (s->pts == AV_NOPTS_VALUE)
648  s->pts = in->pts;
649 
650  ret = av_audio_fifo_write(s->fifo, (void **)in->extended_data,
651  in->nb_samples);
652  for (int i = 0; i < in->nb_samples; i++)
653  e[i] = !ctx->is_disabled;
654 
655  av_audio_fifo_write(s->efifo, (void**)s->enabled->extended_data, in->nb_samples);
656  av_frame_free(&in);
657  if (ret < 0)
658  return ret;
659  }
660 
661  if (av_audio_fifo_size(s->fifo) >= s->window_size ||
662  s->samples_left > 0)
663  return filter_frame(inlink);
664 
665  if (av_audio_fifo_size(s->fifo) >= s->window_size) {
666  ff_filter_set_ready(ctx, 100);
667  return 0;
668  }
669 
670  if (!s->eof && ff_inlink_acknowledge_status(inlink, &status, &pts)) {
671  if (status == AVERROR_EOF) {
672  s->eof = 1;
673  s->samples_left = av_audio_fifo_size(s->fifo) - s->overlap_skip;
674  ff_filter_set_ready(ctx, 100);
675  return 0;
676  }
677  }
678 
679  if (s->eof && s->samples_left <= 0) {
680  ff_outlink_set_status(outlink, AVERROR_EOF, s->pts);
681  return 0;
682  }
683 
684  if (!s->eof)
685  FF_FILTER_FORWARD_WANTED(outlink, inlink);
686 
687  return FFERROR_NOT_READY;
688 }
689 
691 {
692  AudioDeclickContext *s = ctx->priv;
693 
694  s->is_declip = !strcmp(ctx->filter->name, "adeclip");
695  if (s->is_declip) {
696  s->detector = detect_clips;
697  } else {
698  s->detector = detect_clicks;
699  }
700 
701  return 0;
702 }
703 
705 {
706  AudioDeclickContext *s = ctx->priv;
707  int i;
708 
709  av_log(ctx, AV_LOG_INFO, "Detected %s in %"PRId64" of %"PRId64" samples (%g%%).\n",
710  s->is_declip ? "clips" : "clicks", s->detected_errors,
711  s->nb_samples, 100. * s->detected_errors / s->nb_samples);
712 
713  av_audio_fifo_free(s->fifo);
714  av_audio_fifo_free(s->efifo);
715  av_freep(&s->window_func_lut);
716  av_frame_free(&s->enabled);
717  av_frame_free(&s->in);
718  av_frame_free(&s->out);
719  av_frame_free(&s->buffer);
720  av_frame_free(&s->is);
721 
722  if (s->chan) {
723  for (i = 0; i < s->nb_channels; i++) {
724  DeclickChannel *c = &s->chan[i];
725 
726  av_freep(&c->detection);
727  av_freep(&c->auxiliary);
728  av_freep(&c->acoefficients);
729  av_freep(&c->acorrelation);
730  av_freep(&c->tmp);
731  av_freep(&c->click);
732  av_freep(&c->index);
733  av_freep(&c->interpolated);
734  av_freep(&c->matrix);
735  c->matrix_size = 0;
736  av_freep(&c->histogram);
737  c->histogram_size = 0;
738  av_freep(&c->vector);
739  c->vector_size = 0;
740  av_freep(&c->y);
741  c->y_size = 0;
742  }
743  }
744  av_freep(&s->chan);
745  s->nb_channels = 0;
746 }
747 
748 static const AVFilterPad inputs[] = {
749  {
750  .name = "default",
751  .type = AVMEDIA_TYPE_AUDIO,
752  .config_props = config_input,
753  },
754  { NULL }
755 };
756 
757 static const AVFilterPad outputs[] = {
758  {
759  .name = "default",
760  .type = AVMEDIA_TYPE_AUDIO,
761  },
762  { NULL }
763 };
764 
766  .name = "adeclick",
767  .description = NULL_IF_CONFIG_SMALL("Remove impulsive noise from input audio."),
768  .query_formats = query_formats,
769  .priv_size = sizeof(AudioDeclickContext),
770  .priv_class = &adeclick_class,
771  .init = init,
772  .activate = activate,
773  .uninit = uninit,
774  .inputs = inputs,
775  .outputs = outputs,
777 };
778 
779 static const AVOption adeclip_options[] = {
780  { "window", "set window size", OFFSET(w), AV_OPT_TYPE_DOUBLE, {.dbl=55}, 10, 100, AF },
781  { "w", "set window size", OFFSET(w), AV_OPT_TYPE_DOUBLE, {.dbl=55}, 10, 100, AF },
782  { "overlap", "set window overlap", OFFSET(overlap), AV_OPT_TYPE_DOUBLE, {.dbl=75}, 50, 95, AF },
783  { "o", "set window overlap", OFFSET(overlap), AV_OPT_TYPE_DOUBLE, {.dbl=75}, 50, 95, AF },
784  { "arorder", "set autoregression order", OFFSET(ar), AV_OPT_TYPE_DOUBLE, {.dbl=8}, 0, 25, AF },
785  { "a", "set autoregression order", OFFSET(ar), AV_OPT_TYPE_DOUBLE, {.dbl=8}, 0, 25, AF },
786  { "threshold", "set threshold", OFFSET(threshold), AV_OPT_TYPE_DOUBLE, {.dbl=10}, 1, 100, AF },
787  { "t", "set threshold", OFFSET(threshold), AV_OPT_TYPE_DOUBLE, {.dbl=10}, 1, 100, AF },
788  { "hsize", "set histogram size", OFFSET(nb_hbins), AV_OPT_TYPE_INT, {.i64=1000}, 100, 9999, AF },
789  { "n", "set histogram size", OFFSET(nb_hbins), AV_OPT_TYPE_INT, {.i64=1000}, 100, 9999, AF },
790  { "method", "set overlap method", OFFSET(method), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, AF, "m" },
791  { "m", "set overlap method", OFFSET(method), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, AF, "m" },
792  { "add", "overlap-add", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "m" },
793  { "a", "overlap-add", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "m" },
794  { "save", "overlap-save", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "m" },
795  { "s", "overlap-save", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "m" },
796  { NULL }
797 };
798 
800 
802  .name = "adeclip",
803  .description = NULL_IF_CONFIG_SMALL("Remove clipping from input audio."),
804  .query_formats = query_formats,
805  .priv_size = sizeof(AudioDeclickContext),
806  .priv_class = &adeclip_class,
807  .init = init,
808  .activate = activate,
809  .uninit = uninit,
810  .inputs = inputs,
811  .outputs = outputs,
813 };
static enum AVSampleFormat sample_fmts[]
Definition: adpcmenc.c:925
static void autocorrelation(const double *input, int order, int size, double *output, double scale)
Definition: af_adeclick.c:216
static int detect_clips(AudioDeclickContext *s, DeclickChannel *c, double unused0, double *unused1, double *unused2, uint8_t *clip, int *index, const double *src, double *dst)
Definition: af_adeclick.c:409
static int filter_channel(AVFilterContext *ctx, void *arg, int ch, int nb_jobs)
Definition: af_adeclick.c:505
static int find_index(int *index, int value, int size)
Definition: af_adeclick.c:277
static int isfinite_array(double *samples, int nb_samples)
Definition: af_adeclick.c:266
static int factorization(double *matrix, int n)
Definition: af_adeclick.c:300
static int query_formats(AVFilterContext *ctx)
Definition: af_adeclick.c:116
static int config_input(AVFilterLink *inlink)
Definition: af_adeclick.c:145
static double autoregression(const double *samples, int ar_order, int nb_samples, double *k, double *r, double *a)
Definition: af_adeclick.c:231
static const AVFilterPad inputs[]
Definition: af_adeclick.c:748
static int filter_frame(AVFilterLink *inlink)
Definition: af_adeclick.c:570
#define AF
Definition: af_adeclick.c:92
AVFilter ff_af_adeclip
Definition: af_adeclick.c:801
static const AVFilterPad outputs[]
Definition: af_adeclick.c:757
static const AVOption adeclip_options[]
Definition: af_adeclick.c:779
AVFilter ff_af_adeclick
Definition: af_adeclick.c:765
static int activate(AVFilterContext *ctx)
Definition: af_adeclick.c:630
static av_cold int init(AVFilterContext *ctx)
Definition: af_adeclick.c:690
static av_cold void uninit(AVFilterContext *ctx)
Definition: af_adeclick.c:704
static int detect_clicks(AudioDeclickContext *s, DeclickChannel *c, double sigmae, double *detection, double *acoefficients, uint8_t *click, int *index, const double *src, double *dst)
Definition: af_adeclick.c:459
static int do_interpolation(DeclickChannel *c, double *matrix, double *vector, int n, double *out)
Definition: af_adeclick.c:331
#define OFFSET(x)
Definition: af_adeclick.c:91
static int interpolation(DeclickChannel *c, const double *src, int ar_order, double *acoefficients, int *index, int nb_errors, double *auxiliary, double *interpolated)
Definition: af_adeclick.c:365
AVFILTER_DEFINE_CLASS(adeclick)
static const AVOption adeclick_options[]
Definition: af_adeclick.c:94
#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
uint8_t
Audio FIFO Buffer.
int ff_inlink_acknowledge_status(AVFilterLink *link, int *rstatus, int64_t *rpts)
Test and acknowledge the change of status on the link.
Definition: avfilter.c:1447
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1094
int ff_inlink_consume_samples(AVFilterLink *link, unsigned min, unsigned max, AVFrame **rframe)
Take samples from the link's FIFO and update the link's stats.
Definition: avfilter.c:1511
void ff_filter_set_ready(AVFilterContext *filter, unsigned priority)
Mark a filter ready and schedule it for activation.
Definition: avfilter.c:193
Main libavfilter public API header.
#define flags(name, subs,...)
Definition: cbs_av1.c:561
#define is(width, name, range_min, range_max, subs,...)
Definition: cbs_h2645.c:286
#define s(width, name)
Definition: cbs_vp9.c:257
#define fail()
Definition: checkasm.h:133
#define FFMIN(a, b)
Definition: common.h:105
#define FFMAX(a, b)
Definition: common.h:103
#define NULL
Definition: coverity.c:32
#define abs(x)
Definition: cuda_runtime.h:35
static __device__ float fabs(float a)
Definition: cuda_runtime.h:182
double fmin(double, double)
double value
Definition: eval.c:98
int
float im
Definition: fft.c:82
#define FF_FILTER_FORWARD_WANTED(outlink, inlink)
Forward the frame_wanted_out flag from an output link to an input link.
Definition: filters.h:254
static void ff_outlink_set_status(AVFilterLink *link, int status, int64_t pts)
Set the status field of a link from the source filter.
Definition: filters.h:189
#define FFERROR_NOT_READY
Filters implementation helper functions.
Definition: filters.h:34
#define FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink)
Forward the status on an output link to an input link.
Definition: filters.h:199
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_CONST
Definition: opt.h:234
@ AV_OPT_TYPE_INT
Definition: opt.h:225
@ AV_OPT_TYPE_DOUBLE
Definition: opt.h:227
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
Definition: avfilter.h:117
#define AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL
Same as AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, except that the filter will have its filter_frame() c...
Definition: avfilter.h:134
int av_audio_fifo_peek(AVAudioFifo *af, void **data, int nb_samples)
Peek data from an AVAudioFifo.
Definition: audio_fifo.c:138
int av_audio_fifo_write(AVAudioFifo *af, void **data, int nb_samples)
Write data to an AVAudioFifo.
Definition: audio_fifo.c:112
void av_audio_fifo_free(AVAudioFifo *af)
Free an AVAudioFifo.
Definition: audio_fifo.c:45
AVAudioFifo * av_audio_fifo_alloc(enum AVSampleFormat sample_fmt, int channels, int nb_samples)
Allocate an AVAudioFifo.
Definition: audio_fifo.c:59
int av_audio_fifo_size(AVAudioFifo *af)
Get the current number of samples in the AVAudioFifo available for reading.
Definition: audio_fifo.c:228
int av_audio_fifo_drain(AVAudioFifo *af, int nb_samples)
Drain data from an AVAudioFifo.
Definition: audio_fifo.c:201
#define AVERROR_EOF
End of file.
Definition: error.h:55
#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_INFO
Standard information.
Definition: log.h:205
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size)
Allocate a buffer, reusing the given one if large enough.
Definition: mem.c:502
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
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
int index
Definition: gxfenc.c:89
for(j=16;j >0;--j)
static const int16_t alpha[]
Definition: ilbcdata.h:55
int i
Definition: input.c:407
const char * arg
Definition: jacosubdec.c:66
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
#define isfinite(x)
Definition: libm.h:359
uint8_t w
Definition: llviddspenc.c:39
#define M_PI_2
Definition: mathematics.h:55
#define M_PI
Definition: mathematics.h:52
enum MovChannelLayoutTag * layouts
Definition: mov_chan.c:434
AVOptions.
#define td
Definition: regdef.h:70
formats
Definition: signature.h:48
Context for an Audio FIFO Buffer.
Definition: audio_fifo.c:34
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
AVFormatInternal * internal
An opaque field for libavformat internal usage.
Definition: avformat.h:1699
This structure describes decoded (raw) audio or video data.
Definition: frame.h:318
AVOption.
Definition: opt.h:248
Rational number (pair of numerator and denominator).
Definition: rational.h:58
AVAudioFifo * efifo
Definition: af_adeclick.c:81
uint64_t detected_errors
Definition: af_adeclick.c:77
AVAudioFifo * fifo
Definition: af_adeclick.c:82
DeclickChannel * chan
Definition: af_adeclick.c:72
double * window_func_lut
Definition: af_adeclick.c:83
int(* detector)(struct AudioDeclickContext *s, DeclickChannel *c, double sigmae, double *detection, double *acoefficients, uint8_t *click, int *index, const double *src, double *dst)
Definition: af_adeclick.c:85
double * auxiliary
Definition: af_adeclick.c:30
double * vector
Definition: af_adeclick.c:38
double * acorrelation
Definition: af_adeclick.c:33
double * y
Definition: af_adeclick.c:40
double * detection
Definition: af_adeclick.c:31
double * tmp
Definition: af_adeclick.c:34
double * matrix
Definition: af_adeclick.c:36
uint8_t * click
Definition: af_adeclick.c:42
double * acoefficients
Definition: af_adeclick.c:32
unsigned * histogram
Definition: af_adeclick.c:44
double * interpolated
Definition: af_adeclick.c:35
Used for passing data between threads.
Definition: dsddec.c:67
AVFrame * out
Definition: af_adeclick.c:502
#define av_freep(p)
#define av_log(a,...)
#define src
Definition: vp8dsp.c:255
FILE * out
Definition: movenc.c:54
AVFormatContext * ctx
Definition: movenc.c:48
static int64_t pts
int size
const char * r
Definition: vf_curves.c:116
static double clip(void *opaque, double val)
Clip value val in the minval - maxval range.
Definition: vf_lut.c:162
if(ret< 0)
Definition: vf_mcdeint.c:282
static double c[64]