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