FFmpeg
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;
42  uint8_t *click;
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 
114 AVFILTER_DEFINE_CLASS(adeclick);
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 
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 
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 
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 
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)
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 
799 AVFILTER_DEFINE_CLASS(adeclip);
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 };
av_audio_fifo_free
void av_audio_fifo_free(AVAudioFifo *af)
Free an AVAudioFifo.
Definition: audio_fifo.c:45
formats
formats
Definition: signature.h:48
ff_get_audio_buffer
AVFrame * ff_get_audio_buffer(AVFilterLink *link, int nb_samples)
Request an audio samples buffer with a specific set of permissions.
Definition: audio.c:86
DeclickChannel::histogram_size
int histogram_size
Definition: af_adeclick.c:45
AVFilterChannelLayouts
A list of supported channel layouts.
Definition: formats.h:86
td
#define td
Definition: regdef.h:70
query_formats
static int query_formats(AVFilterContext *ctx)
Definition: af_adeclick.c:116
status
they must not be accessed directly The fifo field contains the frames that are queued in the input for processing by the filter The status_in and status_out fields contains the queued status(EOF or error) of the link
outputs
static const AVFilterPad outputs[]
Definition: af_adeclick.c:757
AudioDeclickContext::threshold
double threshold
Definition: af_adeclick.c:53
r
const char * r
Definition: vf_curves.c:116
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
ff_make_format_list
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:286
AudioDeclickContext::method
int method
Definition: af_adeclick.c:56
out
FILE * out
Definition: movenc.c:54
is
The official guide to swscale for confused that is
Definition: swscale.txt:28
AudioDeclickContext::nb_burst_samples
int nb_burst_samples
Definition: af_adeclick.c:61
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:978
sample_fmts
static enum AVSampleFormat sample_fmts[]
Definition: adpcmenc.c:953
DeclickChannel::y_size
int y_size
Definition: af_adeclick.c:41
layouts
enum MovChannelLayoutTag * layouts
Definition: mov_chan.c:434
DeclickChannel::vector_size
int vector_size
Definition: af_adeclick.c:39
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:55
FFERROR_NOT_READY
return FFERROR_NOT_READY
Definition: filter_design.txt:204
DeclickChannel::histogram
unsigned * histogram
Definition: af_adeclick.c:44
output
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce output
Definition: filter_design.txt:225
inlink
The exact code depends on how similar the blocks are and how related they are to the and needs to apply these operations to the correct inlink or outlink if there are several Macros are available to factor that when no extra processing is inlink
Definition: filter_design.txt:212
DeclickChannel::click
uint8_t * click
Definition: af_adeclick.c:42
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:111
ff_all_channel_counts
AVFilterChannelLayouts * ff_all_channel_counts(void)
Construct an AVFilterChannelLayouts coding for any channel layout, with known or unknown disposition.
Definition: formats.c:429
im
float im
Definition: fft.c:82
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:303
AVFrame::pts
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:396
index
fg index
Definition: ffmpeg_filter.c:168
w
uint8_t w
Definition: llviddspenc.c:39
M_PI_2
#define M_PI_2
Definition: mathematics.h:55
AudioDeclickContext::window_func_lut
double * window_func_lut
Definition: af_adeclick.c:83
AVOption
AVOption.
Definition: opt.h:248
AudioDeclickContext::buffer
AVFrame * buffer
Definition: af_adeclick.c:69
init
static av_cold int init(AVFilterContext *ctx)
Definition: af_adeclick.c:690
AudioDeclickContext::is_declip
int is_declip
Definition: af_adeclick.c:59
AudioDeclickContext::ar
double ar
Definition: af_adeclick.c:54
DeclickChannel::interpolated
double * interpolated
Definition: af_adeclick.c:35
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:149
ThreadData::out
AVFrame * out
Definition: af_adeclick.c:502
AudioDeclickContext::hop_size
int hop_size
Definition: af_adeclick.c:63
DeclickChannel::acorrelation
double * acorrelation
Definition: af_adeclick.c:33
AVFormatContext::internal
AVFormatInternal * internal
An opaque field for libavformat internal usage.
Definition: avformat.h:1554
activate
static int activate(AVFilterContext *ctx)
Definition: af_adeclick.c:630
FF_FILTER_FORWARD_STATUS_BACK
#define FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink)
Forward the status on an output link to an input link.
Definition: filters.h:199
ff_af_adeclip
const AVFilter ff_af_adeclip
Definition: af_adeclick.c:801
AVFilterFormats
A list of supported formats for one end of a filter link.
Definition: formats.h:65
formats.h
AudioDeclickContext::ar_order
int ar_order
Definition: af_adeclick.c:60
AudioDeclickContext::enabled
AVFrame * enabled
Definition: af_adeclick.c:66
AVAudioFifo
Context for an Audio FIFO Buffer.
Definition: audio_fifo.c:34
av_audio_fifo_drain
int av_audio_fifo_drain(AVAudioFifo *af, int nb_samples)
Drain data from an AVAudioFifo.
Definition: audio_fifo.c:201
fail
#define fail()
Definition: checkasm.h:134
DeclickChannel::acoefficients
double * acoefficients
Definition: af_adeclick.c:32
pts
static int64_t pts
Definition: transcode_aac.c:652
AudioDeclickContext::nb_channels
int nb_channels
Definition: af_adeclick.c:75
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:54
AudioDeclickContext::detected_errors
uint64_t detected_errors
Definition: af_adeclick.c:77
AudioDeclickContext::overlap
double overlap
Definition: af_adeclick.c:52
av_cold
#define av_cold
Definition: attributes.h:90
ff_set_common_formats
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:580
ff_outlink_set_status
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
s
#define s(width, name)
Definition: cbs_vp9.c:257
av_audio_fifo_write
int av_audio_fifo_write(AVAudioFifo *af, void **data, int nb_samples)
Write data to an AVAudioFifo.
Definition: audio_fifo.c:112
AV_OPT_TYPE_DOUBLE
@ AV_OPT_TYPE_DOUBLE
Definition: opt.h:227
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
filters.h
ctx
AVFormatContext * ctx
Definition: movenc.c:48
DeclickChannel
Definition: af_adeclick.c:29
av_rescale_q
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
detect_clicks
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
isfinite
#define isfinite(x)
Definition: libm.h:359
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: af_adeclick.c:704
config_input
static int config_input(AVFilterLink *inlink)
Definition: af_adeclick.c:145
arg
const char * arg
Definition: jacosubdec.c:67
if
if(ret)
Definition: filter_design.txt:179
AudioDeclickContext::w
double w
Definition: af_adeclick.c:51
autocorrelation
static void autocorrelation(const double *input, int order, int size, double *output, double scale)
Definition: af_adeclick.c:216
AudioDeclickContext
Definition: af_adeclick.c:48
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:67
fabs
static __device__ float fabs(float a)
Definition: cuda_runtime.h:182
ff_inlink_consume_samples
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:1395
NULL
#define NULL
Definition: coverity.c:32
DeclickChannel::y
double * y
Definition: af_adeclick.c:40
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
av_audio_fifo_alloc
AVAudioFifo * av_audio_fifo_alloc(enum AVSampleFormat sample_fmt, int channels, int nb_samples)
Allocate an AVAudioFifo.
Definition: audio_fifo.c:59
AudioDeclickContext::out
AVFrame * out
Definition: af_adeclick.c:68
AudioDeclickContext::burst
double burst
Definition: af_adeclick.c:55
DeclickChannel::detection
double * detection
Definition: af_adeclick.c:31
src
#define src
Definition: vp8dsp.c:255
AudioDeclickContext::samples_left
int samples_left
Definition: af_adeclick.c:78
abs
#define abs(x)
Definition: cuda_runtime.h:35
DeclickChannel::matrix_size
int matrix_size
Definition: af_adeclick.c:37
AudioDeclickContext::window_size
int window_size
Definition: af_adeclick.c:62
AudioDeclickContext::detector
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
ff_inlink_acknowledge_status
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:1331
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
AudioDeclickContext::eof
int eof
Definition: af_adeclick.c:79
for
for(j=16;j >0;--j)
Definition: h264pred_template.c:469
filter_channel
static int filter_channel(AVFilterContext *ctx, void *arg, int ch, int nb_jobs)
Definition: af_adeclick.c:505
DeclickChannel::auxiliary
double * auxiliary
Definition: af_adeclick.c:30
adeclick_options
static const AVOption adeclick_options[]
Definition: af_adeclick.c:94
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:117
FFMAX
#define FFMAX(a, b)
Definition: common.h:103
fmin
double fmin(double, double)
AV_SAMPLE_FMT_NONE
@ AV_SAMPLE_FMT_NONE
Definition: samplefmt.h:59
size
int size
Definition: twinvq_data.h:10344
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
DeclickChannel::vector
double * vector
Definition: af_adeclick.c:38
AudioDeclickContext::overlap_skip
int overlap_skip
Definition: af_adeclick.c:64
FFMIN
#define FFMIN(a, b)
Definition: common.h:105
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
FF_FILTER_FORWARD_WANTED
FF_FILTER_FORWARD_WANTED(outlink, inlink)
AudioDeclickContext::efifo
AVAudioFifo * efifo
Definition: af_adeclick.c:81
AudioDeclickContext::in
AVFrame * in
Definition: af_adeclick.c:67
av_audio_fifo_size
int av_audio_fifo_size(AVAudioFifo *af)
Get the current number of samples in the AVAudioFifo available for reading.
Definition: audio_fifo.c:228
input
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some input
Definition: filter_design.txt:172
autoregression
static double autoregression(const double *samples, int ar_order, int nb_samples, double *k, double *r, double *a)
Definition: af_adeclick.c:231
interpolation
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
M_PI
#define M_PI
Definition: mathematics.h:52
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:192
internal.h
detect_clips
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
OFFSET
#define OFFSET(x)
Definition: af_adeclick.c:91
AVFrame::nb_samples
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:369
i
int i
Definition: input.c:407
filter_frame
static int filter_frame(AVFilterLink *inlink)
Definition: af_adeclick.c:570
find_index
static int find_index(int *index, int value, int size)
Definition: af_adeclick.c:277
DeclickChannel::matrix
double * matrix
Definition: af_adeclick.c:36
adeclip_options
static const AVOption adeclip_options[]
Definition: af_adeclick.c:779
AVFrame::extended_data
uint8_t ** extended_data
pointers to the data planes/channels.
Definition: frame.h:350
AVSampleFormat
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:58
ThreadData
Used for passing data between threads.
Definition: dsddec.c:67
value
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default value
Definition: writing_filters.txt:86
audio_fifo.h
AudioDeclickContext::is
AVFrame * is
Definition: af_adeclick.c:70
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:60
DeclickChannel::index
int * index
Definition: af_adeclick.c:43
AF
#define AF
Definition: af_adeclick.c:92
AVFilter
Filter definition.
Definition: avfilter.h:145
ret
ret
Definition: filter_design.txt:187
DeclickChannel::tmp
double * tmp
Definition: af_adeclick.c:34
factorization
static int factorization(double *matrix, int n)
Definition: af_adeclick.c:300
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(adeclick)
AudioDeclickContext::fifo
AVAudioFifo * fifo
Definition: af_adeclick.c:82
ff_all_samplerates
AVFilterFormats * ff_all_samplerates(void)
Definition: formats.c:414
inputs
static const AVFilterPad inputs[]
Definition: af_adeclick.c:748
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
Definition: mem.c:251
AudioDeclickContext::chan
DeclickChannel * chan
Definition: af_adeclick.c:72
AudioDeclickContext::nb_samples
uint64_t nb_samples
Definition: af_adeclick.c:76
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:225
avfilter.h
AV_SAMPLE_FMT_DBLP
@ AV_SAMPLE_FMT_DBLP
double, planar
Definition: samplefmt.h:70
samples
Filter the word “frame” indicates either a video frame or a group of audio samples
Definition: filter_design.txt:8
AudioDeclickContext::pts
int64_t pts
Definition: af_adeclick.c:74
AVFilterContext
An instance of a filter.
Definition: avfilter.h:333
AVFILTER_FLAG_SLICE_THREADS
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
Definition: avfilter.h:117
audio.h
alpha
static const int16_t alpha[]
Definition: ilbcdata.h:55
do_interpolation
static int do_interpolation(DeclickChannel *c, double *matrix, double *vector, int n, double *out)
Definition: af_adeclick.c:331
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
av_fast_malloc
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:508
AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL
#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
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:561
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
ff_set_common_samplerates
int ff_set_common_samplerates(AVFilterContext *ctx, AVFilterFormats *samplerates)
Definition: formats.c:568
ff_af_adeclick
const AVFilter ff_af_adeclick
Definition: af_adeclick.c:765
isfinite_array
static int isfinite_array(double *samples, int nb_samples)
Definition: af_adeclick.c:266
AudioDeclickContext::nb_hbins
int nb_hbins
Definition: af_adeclick.c:57
int
int
Definition: ffmpeg_filter.c:156
av_audio_fifo_peek
int av_audio_fifo_peek(AVAudioFifo *af, void **data, int nb_samples)
Peek data from an AVAudioFifo.
Definition: audio_fifo.c:138
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:234
clip
static double clip(void *opaque, double val)
Clip value val in the minval - maxval range.
Definition: vf_lut.c:162
ff_filter_set_ready
void ff_filter_set_ready(AVFilterContext *filter, unsigned priority)
Mark a filter ready and schedule it for activation.
Definition: avfilter.c:186
ff_set_common_channel_layouts
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:561