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 {
118  static const enum AVSampleFormat sample_fmts[] = {
121  };
122  int ret;
123 
125  if (ret < 0)
126  return ret;
127 
129  if (ret < 0)
130  return ret;
131 
133 }
134 
136 {
137  AVFilterContext *ctx = inlink->dst;
138  AudioDeclickContext *s = ctx->priv;
139  int i;
140 
141  s->pts = AV_NOPTS_VALUE;
142  s->window_size = inlink->sample_rate * s->w / 1000.;
143  if (s->window_size < 100)
144  return AVERROR(EINVAL);
145  s->ar_order = FFMAX(s->window_size * s->ar / 100., 1);
146  s->nb_burst_samples = s->window_size * s->burst / 1000.;
147  s->hop_size = s->window_size * (1. - (s->overlap / 100.));
148  if (s->hop_size < 1)
149  return AVERROR(EINVAL);
150 
151  s->window_func_lut = av_calloc(s->window_size, sizeof(*s->window_func_lut));
152  if (!s->window_func_lut)
153  return AVERROR(ENOMEM);
154  for (i = 0; i < s->window_size; i++)
155  s->window_func_lut[i] = sin(M_PI * i / s->window_size) *
156  (1. - (s->overlap / 100.)) * M_PI_2;
157 
158  av_frame_free(&s->in);
159  av_frame_free(&s->out);
160  av_frame_free(&s->buffer);
161  av_frame_free(&s->is);
162  s->enabled = ff_get_audio_buffer(inlink, s->window_size);
163  s->in = ff_get_audio_buffer(inlink, s->window_size);
164  s->out = ff_get_audio_buffer(inlink, s->window_size);
165  s->buffer = ff_get_audio_buffer(inlink, s->window_size * 2);
166  s->is = ff_get_audio_buffer(inlink, s->window_size);
167  if (!s->in || !s->out || !s->buffer || !s->is || !s->enabled)
168  return AVERROR(ENOMEM);
169 
170  s->efifo = av_audio_fifo_alloc(inlink->format, 1, s->window_size);
171  if (!s->efifo)
172  return AVERROR(ENOMEM);
173  s->fifo = av_audio_fifo_alloc(inlink->format, inlink->channels, s->window_size);
174  if (!s->fifo)
175  return AVERROR(ENOMEM);
176  s->overlap_skip = s->method ? (s->window_size - s->hop_size) / 2 : 0;
177  if (s->overlap_skip > 0) {
178  av_audio_fifo_write(s->fifo, (void **)s->in->extended_data,
179  s->overlap_skip);
180  }
181 
182  s->nb_channels = inlink->channels;
183  s->chan = av_calloc(inlink->channels, sizeof(*s->chan));
184  if (!s->chan)
185  return AVERROR(ENOMEM);
186 
187  for (i = 0; i < inlink->channels; i++) {
188  DeclickChannel *c = &s->chan[i];
189 
190  c->detection = av_calloc(s->window_size, sizeof(*c->detection));
191  c->auxiliary = av_calloc(s->ar_order + 1, sizeof(*c->auxiliary));
192  c->acoefficients = av_calloc(s->ar_order + 1, sizeof(*c->acoefficients));
193  c->acorrelation = av_calloc(s->ar_order + 1, sizeof(*c->acorrelation));
194  c->tmp = av_calloc(s->ar_order, sizeof(*c->tmp));
195  c->click = av_calloc(s->window_size, sizeof(*c->click));
196  c->index = av_calloc(s->window_size, sizeof(*c->index));
197  c->interpolated = av_calloc(s->window_size, sizeof(*c->interpolated));
198  if (!c->auxiliary || !c->acoefficients || !c->detection || !c->click ||
199  !c->index || !c->interpolated || !c->acorrelation || !c->tmp)
200  return AVERROR(ENOMEM);
201  }
202 
203  return 0;
204 }
205 
206 static void autocorrelation(const double *input, int order, int size,
207  double *output, double scale)
208 {
209  int i, j;
210 
211  for (i = 0; i <= order; i++) {
212  double value = 0.;
213 
214  for (j = i; j < size; j++)
215  value += input[j] * input[j - i];
216 
217  output[i] = value * scale;
218  }
219 }
220 
221 static double autoregression(const double *samples, int ar_order,
222  int nb_samples, double *k, double *r, double *a)
223 {
224  double alpha;
225  int i, j;
226 
227  memset(a, 0, ar_order * sizeof(*a));
228 
230 
231  /* Levinson-Durbin algorithm */
232  k[0] = a[0] = -r[1] / r[0];
233  alpha = r[0] * (1. - k[0] * k[0]);
234  for (i = 1; i < ar_order; i++) {
235  double epsilon = 0.;
236 
237  for (j = 0; j < i; j++)
238  epsilon += a[j] * r[i - j];
239  epsilon += r[i + 1];
240 
241  k[i] = -epsilon / alpha;
242  alpha *= (1. - k[i] * k[i]);
243  for (j = i - 1; j >= 0; j--)
244  k[j] = a[j] + k[i] * a[i - j - 1];
245  for (j = 0; j <= i; j++)
246  a[j] = k[j];
247  }
248 
249  k[0] = 1.;
250  for (i = 1; i <= ar_order; i++)
251  k[i] = a[i - 1];
252 
253  return sqrt(alpha);
254 }
255 
256 static int isfinite_array(double *samples, int nb_samples)
257 {
258  int i;
259 
260  for (i = 0; i < nb_samples; i++)
261  if (!isfinite(samples[i]))
262  return 0;
263 
264  return 1;
265 }
266 
267 static int find_index(int *index, int value, int size)
268 {
269  int i, start, end;
270 
271  if ((value < index[0]) || (value > index[size - 1]))
272  return 1;
273 
274  i = start = 0;
275  end = size - 1;
276 
277  while (start <= end) {
278  i = (end + start) / 2;
279  if (index[i] == value)
280  return 0;
281  if (value < index[i])
282  end = i - 1;
283  if (value > index[i])
284  start = i + 1;
285  }
286 
287  return 1;
288 }
289 
290 static int factorization(double *matrix, int n)
291 {
292  int i, j, k;
293 
294  for (i = 0; i < n; i++) {
295  const int in = i * n;
296  double value;
297 
298  value = matrix[in + i];
299  for (j = 0; j < i; j++)
300  value -= matrix[j * n + j] * matrix[in + j] * matrix[in + j];
301 
302  if (value == 0.) {
303  return -1;
304  }
305 
306  matrix[in + i] = value;
307  for (j = i + 1; j < n; j++) {
308  const int jn = j * n;
309  double x;
310 
311  x = matrix[jn + i];
312  for (k = 0; k < i; k++)
313  x -= matrix[k * n + k] * matrix[in + k] * matrix[jn + k];
314  matrix[jn + i] = x / matrix[in + i];
315  }
316  }
317 
318  return 0;
319 }
320 
321 static int do_interpolation(DeclickChannel *c, double *matrix,
322  double *vector, int n, double *out)
323 {
324  int i, j, ret;
325  double *y;
326 
327  ret = factorization(matrix, n);
328  if (ret < 0)
329  return ret;
330 
331  av_fast_malloc(&c->y, &c->y_size, n * sizeof(*c->y));
332  y = c->y;
333  if (!y)
334  return AVERROR(ENOMEM);
335 
336  for (i = 0; i < n; i++) {
337  const int in = i * n;
338  double value;
339 
340  value = vector[i];
341  for (j = 0; j < i; j++)
342  value -= matrix[in + j] * y[j];
343  y[i] = value;
344  }
345 
346  for (i = n - 1; i >= 0; i--) {
347  out[i] = y[i] / matrix[i * n + i];
348  for (j = i + 1; j < n; j++)
349  out[i] -= matrix[j * n + i] * out[j];
350  }
351 
352  return 0;
353 }
354 
355 static int interpolation(DeclickChannel *c, const double *src, int ar_order,
356  double *acoefficients, int *index, int nb_errors,
357  double *auxiliary, double *interpolated)
358 {
359  double *vector, *matrix;
360  int i, j;
361 
362  av_fast_malloc(&c->matrix, &c->matrix_size, nb_errors * nb_errors * sizeof(*c->matrix));
363  matrix = c->matrix;
364  if (!matrix)
365  return AVERROR(ENOMEM);
366 
367  av_fast_malloc(&c->vector, &c->vector_size, nb_errors * sizeof(*c->vector));
368  vector = c->vector;
369  if (!vector)
370  return AVERROR(ENOMEM);
371 
372  autocorrelation(acoefficients, ar_order, ar_order + 1, auxiliary, 1.);
373 
374  for (i = 0; i < nb_errors; i++) {
375  const int im = i * nb_errors;
376 
377  for (j = i; j < nb_errors; j++) {
378  if (abs(index[j] - index[i]) <= ar_order) {
379  matrix[j * nb_errors + i] = matrix[im + j] = auxiliary[abs(index[j] - index[i])];
380  } else {
381  matrix[j * nb_errors + i] = matrix[im + j] = 0;
382  }
383  }
384  }
385 
386  for (i = 0; i < nb_errors; i++) {
387  double value = 0.;
388 
389  for (j = -ar_order; j <= ar_order; j++)
390  if (find_index(index, index[i] - j, nb_errors))
391  value -= src[index[i] - j] * auxiliary[abs(j)];
392 
393  vector[i] = value;
394  }
395 
396  return do_interpolation(c, matrix, vector, nb_errors, interpolated);
397 }
398 
400  double unused0,
401  double *unused1, double *unused2,
402  uint8_t *clip, int *index,
403  const double *src, double *dst)
404 {
405  const double threshold = s->threshold;
406  double max_amplitude = 0;
407  unsigned *histogram;
408  int i, nb_clips = 0;
409 
410  av_fast_malloc(&c->histogram, &c->histogram_size, s->nb_hbins * sizeof(*c->histogram));
411  if (!c->histogram)
412  return AVERROR(ENOMEM);
413  histogram = c->histogram;
414  memset(histogram, 0, sizeof(*histogram) * s->nb_hbins);
415 
416  for (i = 0; i < s->window_size; i++) {
417  const unsigned index = fmin(fabs(src[i]), 1) * (s->nb_hbins - 1);
418 
419  histogram[index]++;
420  dst[i] = src[i];
421  clip[i] = 0;
422  }
423 
424  for (i = s->nb_hbins - 1; i > 1; i--) {
425  if (histogram[i]) {
426  if (histogram[i] / (double)FFMAX(histogram[i - 1], 1) > threshold) {
427  max_amplitude = i / (double)s->nb_hbins;
428  }
429  break;
430  }
431  }
432 
433  if (max_amplitude > 0.) {
434  for (i = 0; i < s->window_size; i++) {
435  clip[i] = fabs(src[i]) >= max_amplitude;
436  }
437  }
438 
439  memset(clip, 0, s->ar_order * sizeof(*clip));
440  memset(clip + (s->window_size - s->ar_order), 0, s->ar_order * sizeof(*clip));
441 
442  for (i = s->ar_order; i < s->window_size - s->ar_order; i++)
443  if (clip[i])
444  index[nb_clips++] = i;
445 
446  return nb_clips;
447 }
448 
450  double sigmae,
451  double *detection, double *acoefficients,
452  uint8_t *click, int *index,
453  const double *src, double *dst)
454 {
455  const double threshold = s->threshold;
456  int i, j, nb_clicks = 0, prev = -1;
457 
458  memset(detection, 0, s->window_size * sizeof(*detection));
459 
460  for (i = s->ar_order; i < s->window_size; i++) {
461  for (j = 0; j <= s->ar_order; j++) {
462  detection[i] += acoefficients[j] * src[i - j];
463  }
464  }
465 
466  for (i = 0; i < s->window_size; i++) {
467  click[i] = fabs(detection[i]) > sigmae * threshold;
468  dst[i] = src[i];
469  }
470 
471  for (i = 0; i < s->window_size; i++) {
472  if (!click[i])
473  continue;
474 
475  if (prev >= 0 && (i > prev + 1) && (i <= s->nb_burst_samples + prev))
476  for (j = prev + 1; j < i; j++)
477  click[j] = 1;
478  prev = i;
479  }
480 
481  memset(click, 0, s->ar_order * sizeof(*click));
482  memset(click + (s->window_size - s->ar_order), 0, s->ar_order * sizeof(*click));
483 
484  for (i = s->ar_order; i < s->window_size - s->ar_order; i++)
485  if (click[i])
486  index[nb_clicks++] = i;
487 
488  return nb_clicks;
489 }
490 
491 typedef struct ThreadData {
493 } ThreadData;
494 
495 static int filter_channel(AVFilterContext *ctx, void *arg, int ch, int nb_jobs)
496 {
497  AudioDeclickContext *s = ctx->priv;
498  ThreadData *td = arg;
499  AVFrame *out = td->out;
500  const double *src = (const double *)s->in->extended_data[ch];
501  double *is = (double *)s->is->extended_data[ch];
502  double *dst = (double *)s->out->extended_data[ch];
503  double *ptr = (double *)out->extended_data[ch];
504  double *buf = (double *)s->buffer->extended_data[ch];
505  const double *w = s->window_func_lut;
506  DeclickChannel *c = &s->chan[ch];
507  double sigmae;
508  int j, ret;
509 
510  sigmae = autoregression(src, s->ar_order, s->window_size, c->acoefficients, c->acorrelation, c->tmp);
511 
512  if (isfinite_array(c->acoefficients, s->ar_order + 1)) {
513  double *interpolated = c->interpolated;
514  int *index = c->index;
515  int nb_errors;
516 
517  nb_errors = s->detector(s, c, sigmae, c->detection, c->acoefficients,
518  c->click, index, src, dst);
519  if (nb_errors > 0) {
520  double *enabled = (double *)s->enabled->extended_data[0];
521 
522  ret = interpolation(c, src, s->ar_order, c->acoefficients, index,
523  nb_errors, c->auxiliary, interpolated);
524  if (ret < 0)
525  return ret;
526 
527  av_audio_fifo_peek(s->efifo, (void**)s->enabled->extended_data, s->window_size);
528 
529  for (j = 0; j < nb_errors; j++) {
530  if (enabled[index[j]]) {
531  dst[index[j]] = interpolated[j];
532  is[index[j]] = 1;
533  }
534  }
535  }
536  } else {
537  memcpy(dst, src, s->window_size * sizeof(*dst));
538  }
539 
540  if (s->method == 0) {
541  for (j = 0; j < s->window_size; j++)
542  buf[j] += dst[j] * w[j];
543  } else {
544  const int skip = s->overlap_skip;
545 
546  for (j = 0; j < s->hop_size; j++)
547  buf[j] = dst[skip + j];
548  }
549  for (j = 0; j < s->hop_size; j++)
550  ptr[j] = buf[j];
551 
552  memmove(buf, buf + s->hop_size, (s->window_size * 2 - s->hop_size) * sizeof(*buf));
553  memmove(is, is + s->hop_size, (s->window_size - s->hop_size) * sizeof(*is));
554  memset(buf + s->window_size * 2 - s->hop_size, 0, s->hop_size * sizeof(*buf));
555  memset(is + s->window_size - s->hop_size, 0, s->hop_size * sizeof(*is));
556 
557  return 0;
558 }
559 
561 {
562  AVFilterContext *ctx = inlink->dst;
563  AVFilterLink *outlink = ctx->outputs[0];
564  AudioDeclickContext *s = ctx->priv;
565  AVFrame *out = NULL;
566  int ret = 0, j, ch, detected_errors = 0;
567  ThreadData td;
568 
569  out = ff_get_audio_buffer(outlink, s->hop_size);
570  if (!out)
571  return AVERROR(ENOMEM);
572 
573  ret = av_audio_fifo_peek(s->fifo, (void **)s->in->extended_data,
574  s->window_size);
575  if (ret < 0)
576  goto fail;
577 
578  td.out = out;
580  if (ret < 0)
581  goto fail;
582 
583  for (ch = 0; ch < s->in->channels; ch++) {
584  double *is = (double *)s->is->extended_data[ch];
585 
586  for (j = 0; j < s->hop_size; j++) {
587  if (is[j])
588  detected_errors++;
589  }
590  }
591 
592  av_audio_fifo_drain(s->fifo, s->hop_size);
593  av_audio_fifo_drain(s->efifo, s->hop_size);
594 
595  if (s->samples_left > 0)
596  out->nb_samples = FFMIN(s->hop_size, s->samples_left);
597 
598  out->pts = s->pts;
599  s->pts += av_rescale_q(s->hop_size, (AVRational){1, outlink->sample_rate}, outlink->time_base);
600 
601  s->detected_errors += detected_errors;
602  s->nb_samples += out->nb_samples * inlink->channels;
603 
604  ret = ff_filter_frame(outlink, out);
605  if (ret < 0)
606  return ret;
607 
608  if (s->samples_left > 0) {
609  s->samples_left -= s->hop_size;
610  if (s->samples_left <= 0)
611  av_audio_fifo_drain(s->fifo, av_audio_fifo_size(s->fifo));
612  }
613 
614 fail:
615  if (ret < 0)
616  av_frame_free(&out);
617  return ret;
618 }
619 
621 {
622  AVFilterLink *inlink = ctx->inputs[0];
623  AVFilterLink *outlink = ctx->outputs[0];
624  AudioDeclickContext *s = ctx->priv;
625  AVFrame *in;
626  int ret, status;
627  int64_t pts;
628 
630 
631  ret = ff_inlink_consume_samples(inlink, s->window_size, s->window_size, &in);
632  if (ret < 0)
633  return ret;
634  if (ret > 0) {
635  double *e = (double *)s->enabled->extended_data[0];
636 
637  if (s->pts == AV_NOPTS_VALUE)
638  s->pts = in->pts;
639 
640  ret = av_audio_fifo_write(s->fifo, (void **)in->extended_data,
641  in->nb_samples);
642  for (int i = 0; i < in->nb_samples; i++)
643  e[i] = !ctx->is_disabled;
644 
645  av_audio_fifo_write(s->efifo, (void**)s->enabled->extended_data, in->nb_samples);
646  av_frame_free(&in);
647  if (ret < 0)
648  return ret;
649  }
650 
651  if (av_audio_fifo_size(s->fifo) >= s->window_size ||
652  s->samples_left > 0)
653  return filter_frame(inlink);
654 
655  if (av_audio_fifo_size(s->fifo) >= s->window_size) {
656  ff_filter_set_ready(ctx, 100);
657  return 0;
658  }
659 
660  if (!s->eof && ff_inlink_acknowledge_status(inlink, &status, &pts)) {
661  if (status == AVERROR_EOF) {
662  s->eof = 1;
663  s->samples_left = av_audio_fifo_size(s->fifo) - s->overlap_skip;
664  ff_filter_set_ready(ctx, 100);
665  return 0;
666  }
667  }
668 
669  if (s->eof && s->samples_left <= 0) {
670  ff_outlink_set_status(outlink, AVERROR_EOF, s->pts);
671  return 0;
672  }
673 
674  if (!s->eof)
676 
677  return FFERROR_NOT_READY;
678 }
679 
681 {
682  AudioDeclickContext *s = ctx->priv;
683 
684  s->is_declip = !strcmp(ctx->filter->name, "adeclip");
685  if (s->is_declip) {
686  s->detector = detect_clips;
687  } else {
688  s->detector = detect_clicks;
689  }
690 
691  return 0;
692 }
693 
695 {
696  AudioDeclickContext *s = ctx->priv;
697  int i;
698 
699  av_log(ctx, AV_LOG_INFO, "Detected %s in %"PRId64" of %"PRId64" samples (%g%%).\n",
700  s->is_declip ? "clips" : "clicks", s->detected_errors,
701  s->nb_samples, 100. * s->detected_errors / s->nb_samples);
702 
703  av_audio_fifo_free(s->fifo);
704  av_audio_fifo_free(s->efifo);
705  av_freep(&s->window_func_lut);
706  av_frame_free(&s->enabled);
707  av_frame_free(&s->in);
708  av_frame_free(&s->out);
709  av_frame_free(&s->buffer);
710  av_frame_free(&s->is);
711 
712  if (s->chan) {
713  for (i = 0; i < s->nb_channels; i++) {
714  DeclickChannel *c = &s->chan[i];
715 
716  av_freep(&c->detection);
717  av_freep(&c->auxiliary);
718  av_freep(&c->acoefficients);
719  av_freep(&c->acorrelation);
720  av_freep(&c->tmp);
721  av_freep(&c->click);
722  av_freep(&c->index);
723  av_freep(&c->interpolated);
724  av_freep(&c->matrix);
725  c->matrix_size = 0;
726  av_freep(&c->histogram);
727  c->histogram_size = 0;
728  av_freep(&c->vector);
729  c->vector_size = 0;
730  av_freep(&c->y);
731  c->y_size = 0;
732  }
733  }
734  av_freep(&s->chan);
735  s->nb_channels = 0;
736 }
737 
738 static const AVFilterPad inputs[] = {
739  {
740  .name = "default",
741  .type = AVMEDIA_TYPE_AUDIO,
742  .config_props = config_input,
743  },
744 };
745 
746 static const AVFilterPad outputs[] = {
747  {
748  .name = "default",
749  .type = AVMEDIA_TYPE_AUDIO,
750  },
751 };
752 
754  .name = "adeclick",
755  .description = NULL_IF_CONFIG_SMALL("Remove impulsive noise from input audio."),
756  .query_formats = query_formats,
757  .priv_size = sizeof(AudioDeclickContext),
758  .priv_class = &adeclick_class,
759  .init = init,
760  .activate = activate,
761  .uninit = uninit,
765 };
766 
767 static const AVOption adeclip_options[] = {
768  { "window", "set window size", OFFSET(w), AV_OPT_TYPE_DOUBLE, {.dbl=55}, 10, 100, AF },
769  { "w", "set window size", OFFSET(w), AV_OPT_TYPE_DOUBLE, {.dbl=55}, 10, 100, AF },
770  { "overlap", "set window overlap", OFFSET(overlap), AV_OPT_TYPE_DOUBLE, {.dbl=75}, 50, 95, AF },
771  { "o", "set window overlap", OFFSET(overlap), AV_OPT_TYPE_DOUBLE, {.dbl=75}, 50, 95, AF },
772  { "arorder", "set autoregression order", OFFSET(ar), AV_OPT_TYPE_DOUBLE, {.dbl=8}, 0, 25, AF },
773  { "a", "set autoregression order", OFFSET(ar), AV_OPT_TYPE_DOUBLE, {.dbl=8}, 0, 25, AF },
774  { "threshold", "set threshold", OFFSET(threshold), AV_OPT_TYPE_DOUBLE, {.dbl=10}, 1, 100, AF },
775  { "t", "set threshold", OFFSET(threshold), AV_OPT_TYPE_DOUBLE, {.dbl=10}, 1, 100, AF },
776  { "hsize", "set histogram size", OFFSET(nb_hbins), AV_OPT_TYPE_INT, {.i64=1000}, 100, 9999, AF },
777  { "n", "set histogram size", OFFSET(nb_hbins), AV_OPT_TYPE_INT, {.i64=1000}, 100, 9999, AF },
778  { "method", "set overlap method", OFFSET(method), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, AF, "m" },
779  { "m", "set overlap method", OFFSET(method), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, AF, "m" },
780  { "add", "overlap-add", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "m" },
781  { "a", "overlap-add", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "m" },
782  { "save", "overlap-save", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "m" },
783  { "s", "overlap-save", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "m" },
784  { NULL }
785 };
786 
787 AVFILTER_DEFINE_CLASS(adeclip);
788 
790  .name = "adeclip",
791  .description = NULL_IF_CONFIG_SMALL("Remove clipping from input audio."),
792  .query_formats = query_formats,
793  .priv_size = sizeof(AudioDeclickContext),
794  .priv_class = &adeclip_class,
795  .init = init,
796  .activate = activate,
797  .uninit = uninit,
801 };
av_audio_fifo_free
void av_audio_fifo_free(AVAudioFifo *af)
Free an AVAudioFifo.
Definition: audio_fifo.c:45
ff_get_audio_buffer
AVFrame * ff_get_audio_buffer(AVFilterLink *link, int nb_samples)
Request an audio samples buffer with a specific set of permissions.
Definition: audio.c:88
DeclickChannel::histogram_size
int histogram_size
Definition: af_adeclick.c:45
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:746
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
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:1019
sample_fmts
static enum AVSampleFormat sample_fmts[]
Definition: adpcmenc.c:948
DeclickChannel::y_size
int y_size
Definition: af_adeclick.c:41
DeclickChannel::vector_size
int vector_size
Definition: af_adeclick.c:39
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
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:112
im
float im
Definition: fft.c:78
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:38
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:247
AudioDeclickContext::buffer
AVFrame * buffer
Definition: af_adeclick.c:69
init
static av_cold int init(AVFilterContext *ctx)
Definition: af_adeclick.c:680
AudioDeclickContext::is_declip
int is_declip
Definition: af_adeclick.c:59
ff_set_common_all_samplerates
int ff_set_common_all_samplerates(AVFilterContext *ctx)
Equivalent to ff_set_common_samplerates(ctx, ff_all_samplerates())
Definition: formats.c:687
AudioDeclickContext::ar
double ar
Definition: af_adeclick.c:54
DeclickChannel::interpolated
double * interpolated
Definition: af_adeclick.c:35
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:153
ThreadData::out
AVFrame * out
Definition: af_adeclick.c:492
AudioDeclickContext::hop_size
int hop_size
Definition: af_adeclick.c:63
DeclickChannel::acorrelation
double * acorrelation
Definition: af_adeclick.c:33
activate
static int activate(AVFilterContext *ctx)
Definition: af_adeclick.c:620
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:789
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:127
DeclickChannel::acoefficients
double * acoefficients
Definition: af_adeclick.c:32
pts
static int64_t pts
Definition: transcode_aac.c:653
AudioDeclickContext::nb_channels
int nb_channels
Definition: af_adeclick.c:75
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:50
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_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:226
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
ff_set_common_formats_from_list
int ff_set_common_formats_from_list(AVFilterContext *ctx, const int *fmts)
Equivalent to ff_set_common_formats(ctx, ff_make_format_list(fmts))
Definition: formats.c:703
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:141
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:449
isfinite
#define isfinite(x)
Definition: libm.h:359
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: af_adeclick.c:694
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: internal.h:152
config_input
static int config_input(AVFilterLink *inlink)
Definition: af_adeclick.c:135
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:206
AudioDeclickContext
Definition: af_adeclick.c:48
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
fabs
static __device__ float fabs(float a)
Definition: cuda_runtime.h:182
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:1437
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
ff_set_common_all_channel_counts
int ff_set_common_all_channel_counts(AVFilterContext *ctx)
Equivalent to ff_set_common_channel_layouts(ctx, ff_all_channel_counts())
Definition: formats.c:669
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:1372
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:495
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
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
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:221
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:355
M_PI
#define M_PI
Definition: mathematics.h:52
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:191
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:399
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:406
filter_frame
static int filter_frame(AVFilterLink *inlink)
Definition: af_adeclick.c:560
find_index
static int find_index(int *index, int value, int size)
Definition: af_adeclick.c:267
DeclickChannel::matrix
double * matrix
Definition: af_adeclick.c:36
adeclip_options
static const AVOption adeclip_options[]
Definition: af_adeclick.c:767
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
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
audio_fifo.h
AudioDeclickContext::is
AVFrame * is
Definition: af_adeclick.c:70
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:56
DeclickChannel::index
int * index
Definition: af_adeclick.c:43
AF
#define AF
Definition: af_adeclick.c:92
AVFilter
Filter definition.
Definition: avfilter.h:149
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:290
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(adeclick)
AudioDeclickContext::fifo
AVAudioFifo * fifo
Definition: af_adeclick.c:82
inputs
static const AVFilterPad inputs[]
Definition: af_adeclick.c:738
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Equivalent of av_mallocz_array().
Definition: mem.c:269
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:224
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:346
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:121
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:321
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: internal.h:153
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:558
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:138
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
ff_af_adeclick
const AVFilter ff_af_adeclick
Definition: af_adeclick.c:753
isfinite_array
static int isfinite_array(double *samples, int nb_samples)
Definition: af_adeclick.c:256
AudioDeclickContext::nb_hbins
int nb_hbins
Definition: af_adeclick.c:57
ff_filter_execute
static av_always_inline int ff_filter_execute(AVFilterContext *ctx, avfilter_action_func *func, void *arg, int *ret, int nb_jobs)
Definition: internal.h:143
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:233
clip
static double clip(void *opaque, double val)
Clip value val in the minval - maxval range.
Definition: vf_lut.c:159
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:212