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;
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 
85  int (*detector)(struct AudioDeclickContext *s, DeclickChannel *c,
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 
126  formats = ff_make_format_list(sample_fmts);
127  if (!formats)
128  return AVERROR(ENOMEM);
129  ret = ff_set_common_formats(ctx, formats);
130  if (ret < 0)
131  return ret;
132 
133  layouts = ff_all_channel_counts();
134  if (!layouts)
135  return AVERROR(ENOMEM);
136 
137  ret = ff_set_common_channel_layouts(ctx, layouts);
138  if (ret < 0)
139  return ret;
140 
141  formats = ff_all_samplerates();
142  return ff_set_common_samplerates(ctx, formats);
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 
162  if (!s->window_func_lut)
163  return AVERROR(ENOMEM);
164  for (i = 0; i < s->window_size; i++)
165  s->window_func_lut[i] = sin(M_PI * i / s->window_size) *
166  (1. - (s->overlap / 100.)) * M_PI_2;
167 
168  av_frame_free(&s->in);
169  av_frame_free(&s->out);
170  av_frame_free(&s->buffer);
171  av_frame_free(&s->is);
172  s->enabled = ff_get_audio_buffer(inlink, s->window_size);
173  s->in = ff_get_audio_buffer(inlink, s->window_size);
174  s->out = ff_get_audio_buffer(inlink, s->window_size);
175  s->buffer = ff_get_audio_buffer(inlink, s->window_size * 2);
176  s->is = ff_get_audio_buffer(inlink, s->window_size);
177  if (!s->in || !s->out || !s->buffer || !s->is || !s->enabled)
178  return AVERROR(ENOMEM);
179 
180  s->efifo = av_audio_fifo_alloc(inlink->format, 1, s->window_size);
181  if (!s->efifo)
182  return AVERROR(ENOMEM);
183  s->fifo = av_audio_fifo_alloc(inlink->format, inlink->channels, s->window_size);
184  if (!s->fifo)
185  return AVERROR(ENOMEM);
186  s->overlap_skip = s->method ? (s->window_size - s->hop_size) / 2 : 0;
187  if (s->overlap_skip > 0) {
188  av_audio_fifo_write(s->fifo, (void **)s->in->extended_data,
189  s->overlap_skip);
190  }
191 
192  s->nb_channels = inlink->channels;
193  s->chan = av_calloc(inlink->channels, sizeof(*s->chan));
194  if (!s->chan)
195  return AVERROR(ENOMEM);
196 
197  for (i = 0; i < inlink->channels; i++) {
198  DeclickChannel *c = &s->chan[i];
199 
200  c->detection = av_calloc(s->window_size, sizeof(*c->detection));
201  c->auxiliary = av_calloc(s->ar_order + 1, sizeof(*c->auxiliary));
202  c->acoefficients = av_calloc(s->ar_order + 1, sizeof(*c->acoefficients));
203  c->acorrelation = av_calloc(s->ar_order + 1, sizeof(*c->acorrelation));
204  c->tmp = av_calloc(s->ar_order, sizeof(*c->tmp));
205  c->click = av_calloc(s->window_size, sizeof(*c->click));
206  c->index = av_calloc(s->window_size, sizeof(*c->index));
207  c->interpolated = av_calloc(s->window_size, sizeof(*c->interpolated));
208  if (!c->auxiliary || !c->acoefficients || !c->detection || !c->click ||
209  !c->index || !c->interpolated || !c->acorrelation || !c->tmp)
210  return AVERROR(ENOMEM);
211  }
212 
213  return 0;
214 }
215 
216 static void autocorrelation(const double *input, int order, int size,
217  double *output, double scale)
218 {
219  int i, j;
220 
221  for (i = 0; i <= order; i++) {
222  double value = 0.;
223 
224  for (j = i; j < size; j++)
225  value += input[j] * input[j - i];
226 
227  output[i] = value * scale;
228  }
229 }
230 
231 static double autoregression(const double *samples, int ar_order,
232  int nb_samples, double *k, double *r, double *a)
233 {
234  double alpha;
235  int i, j;
236 
237  memset(a, 0, ar_order * sizeof(*a));
238 
239  autocorrelation(samples, ar_order, nb_samples, r, 1. / nb_samples);
240 
241  /* Levinson-Durbin algorithm */
242  k[0] = a[0] = -r[1] / r[0];
243  alpha = r[0] * (1. - k[0] * k[0]);
244  for (i = 1; i < ar_order; i++) {
245  double epsilon = 0.;
246 
247  for (j = 0; j < i; j++)
248  epsilon += a[j] * r[i - j];
249  epsilon += r[i + 1];
250 
251  k[i] = -epsilon / alpha;
252  alpha *= (1. - k[i] * k[i]);
253  for (j = i - 1; j >= 0; j--)
254  k[j] = a[j] + k[i] * a[i - j - 1];
255  for (j = 0; j <= i; j++)
256  a[j] = k[j];
257  }
258 
259  k[0] = 1.;
260  for (i = 1; i <= ar_order; i++)
261  k[i] = a[i - 1];
262 
263  return sqrt(alpha);
264 }
265 
266 static int isfinite_array(double *samples, int nb_samples)
267 {
268  int i;
269 
270  for (i = 0; i < nb_samples; i++)
271  if (!isfinite(samples[i]))
272  return 0;
273 
274  return 1;
275 }
276 
277 static int find_index(int *index, int value, int size)
278 {
279  int i, start, end;
280 
281  if ((value < index[0]) || (value > index[size - 1]))
282  return 1;
283 
284  i = start = 0;
285  end = size - 1;
286 
287  while (start <= end) {
288  i = (end + start) / 2;
289  if (index[i] == value)
290  return 0;
291  if (value < index[i])
292  end = i - 1;
293  if (value > index[i])
294  start = i + 1;
295  }
296 
297  return 1;
298 }
299 
300 static int factorization(double *matrix, int n)
301 {
302  int i, j, k;
303 
304  for (i = 0; i < n; i++) {
305  const int in = i * n;
306  double value;
307 
308  value = matrix[in + i];
309  for (j = 0; j < i; j++)
310  value -= matrix[j * n + j] * matrix[in + j] * matrix[in + j];
311 
312  if (value == 0.) {
313  return -1;
314  }
315 
316  matrix[in + i] = value;
317  for (j = i + 1; j < n; j++) {
318  const int jn = j * n;
319  double x;
320 
321  x = matrix[jn + i];
322  for (k = 0; k < i; k++)
323  x -= matrix[k * n + k] * matrix[in + k] * matrix[jn + k];
324  matrix[jn + i] = x / matrix[in + i];
325  }
326  }
327 
328  return 0;
329 }
330 
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 
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 
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)
622  }
623 
624 fail:
625  if (ret < 0)
626  av_frame_free(&out);
627  return ret;
628 }
629 
631 {
632  AVFilterLink *inlink = ctx->inputs[0];
633  AVFilterLink *outlink = ctx->outputs[0];
634  AudioDeclickContext *s = ctx->priv;
635  AVFrame *in;
636  int ret, status;
637  int64_t pts;
638 
639  FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink);
640 
641  ret = ff_inlink_consume_samples(inlink, s->window_size, s->window_size, &in);
642  if (ret < 0)
643  return ret;
644  if (ret > 0) {
645  double *e = (double *)s->enabled->extended_data[0];
646 
647  if (s->pts == AV_NOPTS_VALUE)
648  s->pts = in->pts;
649 
650  ret = av_audio_fifo_write(s->fifo, (void **)in->extended_data,
651  in->nb_samples);
652  for (int i = 0; i < in->nb_samples; i++)
653  e[i] = !ctx->is_disabled;
654 
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;
674  ff_filter_set_ready(ctx, 100);
675  return 0;
676  }
677  }
678 
679  if (s->eof && s->samples_left <= 0) {
680  ff_outlink_set_status(outlink, AVERROR_EOF, s->pts);
681  return 0;
682  }
683 
684  if (!s->eof)
685  FF_FILTER_FORWARD_WANTED(outlink, inlink);
686 
687  return FFERROR_NOT_READY;
688 }
689 
691 {
692  AudioDeclickContext *s = ctx->priv;
693 
694  s->is_declip = !strcmp(ctx->filter->name, "adeclip");
695  if (s->is_declip) {
696  s->detector = detect_clips;
697  } else {
698  s->detector = detect_clicks;
699  }
700 
701  return 0;
702 }
703 
705 {
706  AudioDeclickContext *s = ctx->priv;
707  int i;
708 
709  av_log(ctx, AV_LOG_INFO, "Detected %s in %"PRId64" of %"PRId64" samples (%g%%).\n",
710  s->is_declip ? "clips" : "clicks", s->detected_errors,
711  s->nb_samples, 100. * s->detected_errors / s->nb_samples);
712 
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 };
#define NULL
Definition: coverity.c:32
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
#define OFFSET(x)
Definition: af_adeclick.c:91
AVFrame * out
Definition: af_adeclick.c:502
AVAudioFifo * av_audio_fifo_alloc(enum AVSampleFormat sample_fmt, int channels, int nb_samples)
Allocate an AVAudioFifo.
Definition: audio_fifo.c:59
This structure describes decoded (raw) audio or video data.
Definition: frame.h:314
AVOption.
Definition: opt.h:248
static const AVFilterPad outputs[]
Definition: af_adeclick.c:757
Main libavfilter public API header.
void av_audio_fifo_free(AVAudioFifo *af)
Free an AVAudioFifo.
Definition: audio_fifo.c:45
double, planar
Definition: samplefmt.h:70
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:36
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:569
static int config_input(AVFilterLink *inlink)
Definition: af_adeclick.c:145
return FFERROR_NOT_READY
static av_cold int init(AVFilterContext *ctx)
Definition: af_adeclick.c:690
int is_disabled
the enabled state from the last expression evaluation
Definition: avfilter.h:388
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
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
Definition: mem.c:245
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:287
DeclickChannel * chan
Definition: af_adeclick.c:72
const char * name
Pad name.
Definition: internal.h:60
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:349
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1093
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
uint8_t
#define av_cold
Definition: attributes.h:88
AVOptions.
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
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
GLsizei GLboolean const GLfloat * value
Definition: opengl_enc.c:108
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:407
uint8_t * click
Definition: af_adeclick.c:42
#define AVERROR_EOF
End of file.
Definition: error.h:55
ptrdiff_t size
Definition: opengl_enc.c:100
#define av_log(a,...)
#define FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink)
Forward the status on an output link to an input link.
Definition: filters.h:199
A filter pad used for either input or output.
Definition: internal.h:54
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
#define src
Definition: vp8dsp.c:255
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:1446
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:588
#define td
Definition: regdef.h:70
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
static __device__ float fabs(float a)
Definition: cuda_runtime.h:182
#define isfinite(x)
Definition: libm.h:359
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:203
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:115
const char * r
Definition: vf_curves.c:116
void * priv
private data for use by the filter
Definition: avfilter.h:356
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
Definition: avfilter.h:117
const char * arg
Definition: jacosubdec.c:66
static int find_index(int *index, int value, int size)
Definition: af_adeclick.c:277
double * window_func_lut
Definition: af_adeclick.c:83
#define FFMAX(a, b)
Definition: common.h:103
#define fail()
Definition: checkasm.h:133
Context for an Audio FIFO Buffer.
Definition: audio_fifo.c:34
void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size)
Allocate a buffer, reusing the given one if large enough.
Definition: mem.c:502
int av_audio_fifo_size(AVAudioFifo *af)
Get the current number of samples in the AVAudioFifo available for reading.
Definition: audio_fifo.c:228
int channels
number of audio channels, only used for audio.
Definition: frame.h:620
#define FFMIN(a, b)
Definition: common.h:105
unsigned * histogram
Definition: af_adeclick.c:44
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
uint8_t w
Definition: llviddspenc.c:39
#define M_PI_2
Definition: mathematics.h:55
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
AVFormatContext * ctx
Definition: movenc.c:48
static int activate(AVFilterContext *ctx)
Definition: af_adeclick.c:630
#define s(width, name)
Definition: cbs_vp9.c:257
AVAudioFifo * fifo
Definition: af_adeclick.c:82
static const AVOption adeclip_options[]
Definition: af_adeclick.c:779
AVFilter ff_af_adeclick
Definition: af_adeclick.c:765
A list of supported channel layouts.
Definition: formats.h:86
if(ret)
double * detection
Definition: af_adeclick.c:31
double * y
Definition: af_adeclick.c:40
#define AV_LOG_INFO
Standard information.
Definition: log.h:205
double * acoefficients
Definition: af_adeclick.c:32
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:58
static int filter_frame(AVFilterLink *inlink)
Definition: af_adeclick.c:570
Used for passing data between threads.
Definition: dsddec.c:67
#define abs(x)
Definition: cuda_runtime.h:35
int ff_inlink_consume_samples(AVFilterLink *link, unsigned min, unsigned max, AVFrame **rframe)
Take samples from the link&#39;s FIFO and update the link&#39;s stats.
Definition: avfilter.c:1510
static const int16_t alpha[]
Definition: ilbcdata.h:55
static av_cold void uninit(AVFilterContext *ctx)
Definition: af_adeclick.c:704
static int filter_channel(AVFilterContext *ctx, void *arg, int ch, int nb_jobs)
Definition: af_adeclick.c:505
static const AVOption adeclick_options[]
Definition: af_adeclick.c:94
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31))))#define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac){}void ff_audio_convert_free(AudioConvert **ac){if(!*ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);}AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map){AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method!=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2){ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc){av_free(ac);return NULL;}return ac;}in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar){ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar?ac->channels:1;}else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;}int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in){int use_generic=1;int len=in->nb_samples;int p;if(ac->dc){av_log(ac->avr, AV_LOG_TRACE,"%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
Describe the class of an AVClass context structure.
Definition: log.h:67
Filter definition.
Definition: avfilter.h:145
double * vector
Definition: af_adeclick.c:38
static void autocorrelation(const double *input, int order, int size, double *output, double scale)
Definition: af_adeclick.c:216
Rational number (pair of numerator and denominator).
Definition: rational.h:58
#define AF
Definition: af_adeclick.c:92
AVFilter ff_af_adeclip
Definition: af_adeclick.c:801
float im
Definition: fft.c:82
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
const char * name
Filter name.
Definition: avfilter.h:149
double * interpolated
Definition: af_adeclick.c:35
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
#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
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:353
enum MovChannelLayoutTag * layouts
Definition: mov_chan.c:434
AVFilterFormats * ff_all_samplerates(void)
Definition: formats.c:422
static int64_t pts
#define flags(name, subs,...)
Definition: cbs_av1.c:561
AVFilterInternal * internal
An opaque struct for libavfilter internal use.
Definition: avfilter.h:381
int av_audio_fifo_write(AVAudioFifo *af, void **data, int nb_samples)
Write data to an AVAudioFifo.
Definition: audio_fifo.c:112
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
int av_audio_fifo_drain(AVAudioFifo *af, int nb_samples)
Drain data from an AVAudioFifo.
Definition: audio_fifo.c:201
double * acorrelation
Definition: af_adeclick.c:33
int
double * matrix
Definition: af_adeclick.c:36
static int isfinite_array(double *samples, int nb_samples)
Definition: af_adeclick.c:266
static double clip(void *opaque, double val)
Clip value val in the minval - maxval range.
Definition: vf_lut.c:162
static int factorization(double *matrix, int n)
Definition: af_adeclick.c:300
void ff_filter_set_ready(AVFilterContext *filter, unsigned priority)
Mark a filter ready and schedule it for activation.
Definition: avfilter.c:193
static const AVFilterPad inputs[]
Definition: af_adeclick.c:748
double fmin(double, double)
avfilter_execute_func * execute
Definition: internal.h:136
FF_FILTER_FORWARD_WANTED(outlink, inlink)
static int do_interpolation(DeclickChannel *c, double *matrix, double *vector, int n, double *out)
Definition: af_adeclick.c:331
uint64_t detected_errors
Definition: af_adeclick.c:77
double * tmp
Definition: af_adeclick.c:34
Audio FIFO Buffer.
double * auxiliary
Definition: af_adeclick.c:30
The official guide to swscale for confused that is
Definition: swscale.txt:2
A list of supported formats for one end of a filter link.
Definition: formats.h:65
int av_audio_fifo_peek(AVAudioFifo *af, void **data, int nb_samples)
Peek data from an AVAudioFifo.
Definition: audio_fifo.c:138
An instance of a filter.
Definition: avfilter.h:341
static int query_formats(AVFilterContext *ctx)
Definition: af_adeclick.c:116
static enum AVSampleFormat sample_fmts[]
Definition: adpcmenc.c:940
FILE * out
Definition: movenc.c:54
Filter the word “frame” indicates either a video frame or a group of audio samples
#define av_freep(p)
AVFILTER_DEFINE_CLASS(adeclick)
#define M_PI
Definition: mathematics.h:52
formats
Definition: signature.h:48
internal API functions
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
AVFilterChannelLayouts * ff_all_channel_counts(void)
Construct an AVFilterChannelLayouts coding for any channel layout, with known or unknown disposition...
Definition: formats.c:437
uint8_t ** extended_data
pointers to the data planes/channels.
Definition: frame.h:361
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:380
const AVFilter * filter
the AVFilter of which this is an instance
Definition: avfilter.h:344
for(j=16;j >0;--j)
int ff_set_common_samplerates(AVFilterContext *ctx, AVFilterFormats *samplerates)
Definition: formats.c:576
int i
Definition: input.c:407
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
AVAudioFifo * efifo
Definition: af_adeclick.c:81
static double autoregression(const double *samples, int ar_order, int nb_samples, double *k, double *r, double *a)
Definition: af_adeclick.c:231