You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

754 lines
22KB

  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. #include "libavutil/audio_fifo.h"
  21. #include "libavutil/opt.h"
  22. #include "avfilter.h"
  23. #include "audio.h"
  24. #include "formats.h"
  25. typedef struct DeclickChannel {
  26. double *auxiliary;
  27. double *detection;
  28. double *acoefficients;
  29. double *acorrelation;
  30. double *tmp;
  31. double *interpolated;
  32. double *matrix;
  33. int matrix_size;
  34. double *vector;
  35. int vector_size;
  36. double *y;
  37. int y_size;
  38. uint8_t *click;
  39. int *index;
  40. unsigned *histogram;
  41. int histogram_size;
  42. } DeclickChannel;
  43. typedef struct AudioDeclickContext {
  44. const AVClass *class;
  45. double w;
  46. double overlap;
  47. double threshold;
  48. double ar;
  49. double burst;
  50. int method;
  51. int nb_hbins;
  52. int is_declip;
  53. int ar_order;
  54. int nb_burst_samples;
  55. int window_size;
  56. int hop_size;
  57. int overlap_skip;
  58. AVFrame *in;
  59. AVFrame *out;
  60. AVFrame *buffer;
  61. AVFrame *is;
  62. DeclickChannel *chan;
  63. int64_t pts;
  64. int nb_channels;
  65. uint64_t nb_samples;
  66. uint64_t detected_errors;
  67. int samples_left;
  68. AVAudioFifo *fifo;
  69. double *window_func_lut;
  70. int (*detector)(struct AudioDeclickContext *s, DeclickChannel *c,
  71. double sigmae, double *detection,
  72. double *acoefficients, uint8_t *click, int *index,
  73. const double *src, double *dst);
  74. } AudioDeclickContext;
  75. #define OFFSET(x) offsetof(AudioDeclickContext, x)
  76. #define AF AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
  77. static const AVOption adeclick_options[] = {
  78. { "w", "set window size", OFFSET(w), AV_OPT_TYPE_DOUBLE, {.dbl=55}, 10, 100, AF },
  79. { "o", "set window overlap", OFFSET(overlap), AV_OPT_TYPE_DOUBLE, {.dbl=75}, 50, 95, AF },
  80. { "a", "set autoregression order", OFFSET(ar), AV_OPT_TYPE_DOUBLE, {.dbl=2}, 0, 25, AF },
  81. { "t", "set threshold", OFFSET(threshold), AV_OPT_TYPE_DOUBLE, {.dbl=2}, 1, 100, AF },
  82. { "b", "set burst fusion", OFFSET(burst), AV_OPT_TYPE_DOUBLE, {.dbl=2}, 0, 10, AF },
  83. { "m", "set overlap method", OFFSET(method), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, AF, "m" },
  84. { "a", "overlap-add", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "m" },
  85. { "s", "overlap-save", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "m" },
  86. { NULL }
  87. };
  88. AVFILTER_DEFINE_CLASS(adeclick);
  89. static int query_formats(AVFilterContext *ctx)
  90. {
  91. AVFilterFormats *formats = NULL;
  92. AVFilterChannelLayouts *layouts = NULL;
  93. static const enum AVSampleFormat sample_fmts[] = {
  94. AV_SAMPLE_FMT_DBLP,
  95. AV_SAMPLE_FMT_NONE
  96. };
  97. int ret;
  98. formats = ff_make_format_list(sample_fmts);
  99. if (!formats)
  100. return AVERROR(ENOMEM);
  101. ret = ff_set_common_formats(ctx, formats);
  102. if (ret < 0)
  103. return ret;
  104. layouts = ff_all_channel_counts();
  105. if (!layouts)
  106. return AVERROR(ENOMEM);
  107. ret = ff_set_common_channel_layouts(ctx, layouts);
  108. if (ret < 0)
  109. return ret;
  110. formats = ff_all_samplerates();
  111. return ff_set_common_samplerates(ctx, formats);
  112. }
  113. static int config_input(AVFilterLink *inlink)
  114. {
  115. AVFilterContext *ctx = inlink->dst;
  116. AudioDeclickContext *s = ctx->priv;
  117. int i;
  118. s->pts = AV_NOPTS_VALUE;
  119. s->window_size = inlink->sample_rate * s->w / 1000.;
  120. if (s->window_size < 100)
  121. return AVERROR(EINVAL);
  122. s->ar_order = FFMAX(s->window_size * s->ar / 100., 1);
  123. s->nb_burst_samples = s->window_size * s->burst / 1000.;
  124. s->hop_size = s->window_size * (1. - (s->overlap / 100.));
  125. if (s->hop_size < 1)
  126. return AVERROR(EINVAL);
  127. s->window_func_lut = av_calloc(s->window_size, sizeof(*s->window_func_lut));
  128. if (!s->window_func_lut)
  129. return AVERROR(ENOMEM);
  130. for (i = 0; i < s->window_size; i++)
  131. s->window_func_lut[i] = sin(M_PI * i / s->window_size) *
  132. (1. - (s->overlap / 100.)) * M_PI_2;
  133. av_frame_free(&s->in);
  134. av_frame_free(&s->out);
  135. av_frame_free(&s->buffer);
  136. av_frame_free(&s->is);
  137. s->in = ff_get_audio_buffer(inlink, s->window_size);
  138. s->out = ff_get_audio_buffer(inlink, s->window_size);
  139. s->buffer = ff_get_audio_buffer(inlink, s->window_size * 2);
  140. s->is = ff_get_audio_buffer(inlink, s->window_size);
  141. if (!s->in || !s->out || !s->buffer || !s->is)
  142. return AVERROR(ENOMEM);
  143. s->fifo = av_audio_fifo_alloc(inlink->format, inlink->channels, s->window_size);
  144. if (!s->fifo)
  145. return AVERROR(ENOMEM);
  146. s->overlap_skip = s->method ? (s->window_size - s->hop_size) / 2 : 0;
  147. if (s->overlap_skip > 0) {
  148. av_audio_fifo_write(s->fifo, (void **)s->in->extended_data,
  149. s->overlap_skip);
  150. }
  151. s->nb_channels = inlink->channels;
  152. s->chan = av_calloc(inlink->channels, sizeof(*s->chan));
  153. if (!s->chan)
  154. return AVERROR(ENOMEM);
  155. for (i = 0; i < inlink->channels; i++) {
  156. DeclickChannel *c = &s->chan[i];
  157. c->detection = av_calloc(s->window_size, sizeof(*c->detection));
  158. c->auxiliary = av_calloc(s->ar_order + 1, sizeof(*c->auxiliary));
  159. c->acoefficients = av_calloc(s->ar_order + 1, sizeof(*c->acoefficients));
  160. c->acorrelation = av_calloc(s->ar_order + 1, sizeof(*c->acorrelation));
  161. c->tmp = av_calloc(s->ar_order, sizeof(*c->tmp));
  162. c->click = av_calloc(s->window_size, sizeof(*c->click));
  163. c->index = av_calloc(s->window_size, sizeof(*c->index));
  164. c->interpolated = av_calloc(s->window_size, sizeof(*c->interpolated));
  165. if (!c->auxiliary || !c->acoefficients || !c->detection || !c->click ||
  166. !c->index || !c->interpolated || !c->acorrelation || !c->tmp)
  167. return AVERROR(ENOMEM);
  168. }
  169. return 0;
  170. }
  171. static void autocorrelation(const double *input, int order, int size,
  172. double *output, double scale)
  173. {
  174. int i, j;
  175. for (i = 0; i <= order; i++) {
  176. double value = 0.;
  177. for (j = i; j < size; j++)
  178. value += input[j] * input[j - i];
  179. output[i] = value * scale;
  180. }
  181. }
  182. static double autoregression(const double *samples, int ar_order,
  183. int nb_samples, double *k, double *r, double *a)
  184. {
  185. double alpha;
  186. int i, j;
  187. memset(a, 0, ar_order * sizeof(*a));
  188. autocorrelation(samples, ar_order, nb_samples, r, 1. / nb_samples);
  189. /* Levinson-Durbin algorithm */
  190. k[0] = a[0] = -r[1] / r[0];
  191. alpha = r[0] * (1. - k[0] * k[0]);
  192. for (i = 1; i < ar_order; i++) {
  193. double epsilon = 0.;
  194. for (j = 0; j < i; j++)
  195. epsilon += a[j] * r[i - j];
  196. epsilon += r[i + 1];
  197. k[i] = -epsilon / alpha;
  198. alpha *= (1. - k[i] * k[i]);
  199. for (j = i - 1; j >= 0; j--)
  200. k[j] = a[j] + k[i] * a[i - j - 1];
  201. for (j = 0; j <= i; j++)
  202. a[j] = k[j];
  203. }
  204. k[0] = 1.;
  205. for (i = 1; i <= ar_order; i++)
  206. k[i] = a[i - 1];
  207. return sqrt(alpha);
  208. }
  209. static int isfinite_array(double *samples, int nb_samples)
  210. {
  211. int i;
  212. for (i = 0; i < nb_samples; i++)
  213. if (!isfinite(samples[i]))
  214. return 0;
  215. return 1;
  216. }
  217. static int find_index(int *index, int value, int size)
  218. {
  219. int i, start, end;
  220. if ((value < index[0]) || (value > index[size - 1]))
  221. return 1;
  222. i = start = 0;
  223. end = size - 1;
  224. while (start <= end) {
  225. i = (end + start) / 2;
  226. if (index[i] == value)
  227. return 0;
  228. if (value < index[i])
  229. end = i - 1;
  230. if (value > index[i])
  231. start = i + 1;
  232. }
  233. return 1;
  234. }
  235. static int factorization(double *matrix, int n)
  236. {
  237. int i, j, k;
  238. for (i = 0; i < n; i++) {
  239. const int in = i * n;
  240. double value;
  241. value = matrix[in + i];
  242. for (j = 0; j < i; j++)
  243. value -= matrix[j * n + j] * matrix[in + j] * matrix[in + j];
  244. if (value == 0.) {
  245. return -1;
  246. }
  247. matrix[in + i] = value;
  248. for (j = i + 1; j < n; j++) {
  249. const int jn = j * n;
  250. double x;
  251. x = matrix[jn + i];
  252. for (k = 0; k < i; k++)
  253. x -= matrix[k * n + k] * matrix[in + k] * matrix[jn + k];
  254. matrix[jn + i] = x / matrix[in + i];
  255. }
  256. }
  257. return 0;
  258. }
  259. static int do_interpolation(DeclickChannel *c, double *matrix,
  260. double *vector, int n, double *out)
  261. {
  262. int i, j, ret;
  263. double *y;
  264. ret = factorization(matrix, n);
  265. if (ret < 0)
  266. return ret;
  267. av_fast_malloc(&c->y, &c->y_size, n * sizeof(*c->y));
  268. y = c->y;
  269. if (!y)
  270. return AVERROR(ENOMEM);
  271. for (i = 0; i < n; i++) {
  272. const int in = i * n;
  273. double value;
  274. value = vector[i];
  275. for (j = 0; j < i; j++)
  276. value -= matrix[in + j] * y[j];
  277. y[i] = value;
  278. }
  279. for (i = n - 1; i >= 0; i--) {
  280. out[i] = y[i] / matrix[i * n + i];
  281. for (j = i + 1; j < n; j++)
  282. out[i] -= matrix[j * n + i] * out[j];
  283. }
  284. return 0;
  285. }
  286. static int interpolation(DeclickChannel *c, const double *src, int ar_order,
  287. double *acoefficients, int *index, int nb_errors,
  288. double *auxiliary, double *interpolated)
  289. {
  290. double *vector, *matrix;
  291. int i, j;
  292. av_fast_malloc(&c->matrix, &c->matrix_size, nb_errors * nb_errors * sizeof(*c->matrix));
  293. matrix = c->matrix;
  294. if (!matrix)
  295. return AVERROR(ENOMEM);
  296. av_fast_malloc(&c->vector, &c->vector_size, nb_errors * sizeof(*c->vector));
  297. vector = c->vector;
  298. if (!vector)
  299. return AVERROR(ENOMEM);
  300. autocorrelation(acoefficients, ar_order, ar_order + 1, auxiliary, 1.);
  301. for (i = 0; i < nb_errors; i++) {
  302. const int im = i * nb_errors;
  303. for (j = i; j < nb_errors; j++) {
  304. if (abs(index[j] - index[i]) <= ar_order) {
  305. matrix[j * nb_errors + i] = matrix[im + j] = auxiliary[abs(index[j] - index[i])];
  306. } else {
  307. matrix[j * nb_errors + i] = matrix[im + j] = 0;
  308. }
  309. }
  310. }
  311. for (i = 0; i < nb_errors; i++) {
  312. double value = 0.;
  313. for (j = -ar_order; j <= ar_order; j++)
  314. if (find_index(index, index[i] - j, nb_errors))
  315. value -= src[index[i] - j] * auxiliary[abs(j)];
  316. vector[i] = value;
  317. }
  318. return do_interpolation(c, matrix, vector, nb_errors, interpolated);
  319. }
  320. static int detect_clips(AudioDeclickContext *s, DeclickChannel *c,
  321. double unused0,
  322. double *unused1, double *unused2,
  323. uint8_t *clip, int *index,
  324. const double *src, double *dst)
  325. {
  326. const double threshold = s->threshold;
  327. double max_amplitude = 0;
  328. unsigned *histogram;
  329. int i, nb_clips = 0;
  330. av_fast_malloc(&c->histogram, &c->histogram_size, s->nb_hbins * sizeof(*c->histogram));
  331. if (!c->histogram)
  332. return AVERROR(ENOMEM);
  333. histogram = c->histogram;
  334. memset(histogram, 0, sizeof(*histogram) * s->nb_hbins);
  335. for (i = 0; i < s->window_size; i++) {
  336. const unsigned index = fmin(fabs(src[i]), 1) * (s->nb_hbins - 1);
  337. histogram[index]++;
  338. dst[i] = src[i];
  339. clip[i] = 0;
  340. }
  341. for (i = s->nb_hbins - 1; i > 1; i--) {
  342. if (histogram[i]) {
  343. if (histogram[i] / (double)FFMAX(histogram[i - 1], 1) > threshold) {
  344. max_amplitude = i / (double)s->nb_hbins;
  345. }
  346. break;
  347. }
  348. }
  349. if (max_amplitude > 0.) {
  350. for (i = 0; i < s->window_size; i++) {
  351. clip[i] = fabs(src[i]) >= max_amplitude;
  352. }
  353. }
  354. memset(clip, 0, s->ar_order * sizeof(*clip));
  355. memset(clip + (s->window_size - s->ar_order), 0, s->ar_order * sizeof(*clip));
  356. for (i = s->ar_order; i < s->window_size - s->ar_order; i++)
  357. if (clip[i])
  358. index[nb_clips++] = i;
  359. return nb_clips;
  360. }
  361. static int detect_clicks(AudioDeclickContext *s, DeclickChannel *c,
  362. double sigmae,
  363. double *detection, double *acoefficients,
  364. uint8_t *click, int *index,
  365. const double *src, double *dst)
  366. {
  367. const double threshold = s->threshold;
  368. int i, j, nb_clicks = 0, prev = -1;
  369. memset(detection, 0, s->window_size * sizeof(*detection));
  370. for (i = s->ar_order; i < s->window_size; i++) {
  371. for (j = 0; j <= s->ar_order; j++) {
  372. detection[i] += acoefficients[j] * src[i - j];
  373. }
  374. }
  375. for (i = 0; i < s->window_size; i++) {
  376. click[i] = fabs(detection[i]) > sigmae * threshold;
  377. dst[i] = src[i];
  378. }
  379. for (i = 0; i < s->window_size; i++) {
  380. if (!click[i])
  381. continue;
  382. if (prev >= 0 && (i > prev + 1) && (i <= s->nb_burst_samples + prev))
  383. for (j = prev + 1; j < i; j++)
  384. click[j] = 1;
  385. prev = i;
  386. }
  387. memset(click, 0, s->ar_order * sizeof(*click));
  388. memset(click + (s->window_size - s->ar_order), 0, s->ar_order * sizeof(*click));
  389. for (i = s->ar_order; i < s->window_size - s->ar_order; i++)
  390. if (click[i])
  391. index[nb_clicks++] = i;
  392. return nb_clicks;
  393. }
  394. typedef struct ThreadData {
  395. AVFrame *out;
  396. } ThreadData;
  397. static int filter_channel(AVFilterContext *ctx, void *arg, int ch, int nb_jobs)
  398. {
  399. AudioDeclickContext *s = ctx->priv;
  400. ThreadData *td = arg;
  401. AVFrame *out = td->out;
  402. const double *src = (const double *)s->in->extended_data[ch];
  403. double *is = (double *)s->is->extended_data[ch];
  404. double *dst = (double *)s->out->extended_data[ch];
  405. double *ptr = (double *)out->extended_data[ch];
  406. double *buf = (double *)s->buffer->extended_data[ch];
  407. const double *w = s->window_func_lut;
  408. DeclickChannel *c = &s->chan[ch];
  409. double sigmae;
  410. int j, ret;
  411. sigmae = autoregression(src, s->ar_order, s->window_size, c->acoefficients, c->acorrelation, c->tmp);
  412. if (isfinite_array(c->acoefficients, s->ar_order + 1)) {
  413. double *interpolated = c->interpolated;
  414. int *index = c->index;
  415. int nb_errors;
  416. nb_errors = s->detector(s, c, sigmae, c->detection, c->acoefficients,
  417. c->click, index, src, dst);
  418. if (nb_errors > 0) {
  419. ret = interpolation(c, src, s->ar_order, c->acoefficients, index,
  420. nb_errors, c->auxiliary, interpolated);
  421. if (ret < 0)
  422. return ret;
  423. for (j = 0; j < nb_errors; j++) {
  424. dst[index[j]] = interpolated[j];
  425. is[index[j]] = 1;
  426. }
  427. }
  428. } else {
  429. memcpy(dst, src, s->window_size * sizeof(*dst));
  430. }
  431. if (s->method == 0) {
  432. for (j = 0; j < s->window_size; j++)
  433. buf[j] += dst[j] * w[j];
  434. } else {
  435. const int skip = s->overlap_skip;
  436. for (j = 0; j < s->hop_size; j++)
  437. buf[j] = dst[skip + j];
  438. }
  439. for (j = 0; j < s->hop_size; j++)
  440. ptr[j] = buf[j];
  441. memmove(buf, buf + s->hop_size, (s->window_size * 2 - s->hop_size) * sizeof(*buf));
  442. memmove(is, is + s->hop_size, (s->window_size - s->hop_size) * sizeof(*is));
  443. memset(buf + s->window_size * 2 - s->hop_size, 0, s->hop_size * sizeof(*buf));
  444. memset(is + s->window_size - s->hop_size, 0, s->hop_size * sizeof(*is));
  445. return 0;
  446. }
  447. static int filter_frame(AVFilterLink *inlink, AVFrame *in)
  448. {
  449. AVFilterContext *ctx = inlink->dst;
  450. AVFilterLink *outlink = ctx->outputs[0];
  451. AudioDeclickContext *s = ctx->priv;
  452. AVFrame *out = NULL;
  453. int ret = 0;
  454. if (s->pts == AV_NOPTS_VALUE)
  455. s->pts = in->pts;
  456. ret = av_audio_fifo_write(s->fifo, (void **)in->extended_data,
  457. in->nb_samples);
  458. av_frame_free(&in);
  459. while (av_audio_fifo_size(s->fifo) >= s->window_size) {
  460. int j, ch, detected_errors = 0;
  461. ThreadData td;
  462. out = ff_get_audio_buffer(outlink, s->hop_size);
  463. if (!out)
  464. return AVERROR(ENOMEM);
  465. ret = av_audio_fifo_peek(s->fifo, (void **)s->in->extended_data,
  466. s->window_size);
  467. if (ret < 0)
  468. break;
  469. td.out = out;
  470. ret = ctx->internal->execute(ctx, filter_channel, &td, NULL, inlink->channels);
  471. if (ret < 0)
  472. goto fail;
  473. for (ch = 0; ch < s->in->channels; ch++) {
  474. double *is = (double *)s->is->extended_data[ch];
  475. for (j = 0; j < s->hop_size; j++) {
  476. if (is[j])
  477. detected_errors++;
  478. }
  479. }
  480. av_audio_fifo_drain(s->fifo, s->hop_size);
  481. if (s->samples_left > 0)
  482. out->nb_samples = FFMIN(s->hop_size, s->samples_left);
  483. out->pts = s->pts;
  484. s->pts += s->hop_size;
  485. s->detected_errors += detected_errors;
  486. s->nb_samples += out->nb_samples * inlink->channels;
  487. ret = ff_filter_frame(outlink, out);
  488. if (ret < 0)
  489. break;
  490. if (s->samples_left > 0) {
  491. s->samples_left -= s->hop_size;
  492. if (s->samples_left <= 0)
  493. av_audio_fifo_drain(s->fifo, av_audio_fifo_size(s->fifo));
  494. }
  495. }
  496. fail:
  497. if (ret < 0)
  498. av_frame_free(&out);
  499. return ret;
  500. }
  501. static int request_frame(AVFilterLink *outlink)
  502. {
  503. AVFilterContext *ctx = outlink->src;
  504. AudioDeclickContext *s = ctx->priv;
  505. int ret = 0;
  506. ret = ff_request_frame(ctx->inputs[0]);
  507. if (ret == AVERROR_EOF && av_audio_fifo_size(s->fifo) > 0) {
  508. if (!s->samples_left)
  509. s->samples_left = av_audio_fifo_size(s->fifo) - s->overlap_skip;
  510. if (s->samples_left > 0) {
  511. AVFrame *in = ff_get_audio_buffer(outlink, s->window_size - s->samples_left);
  512. if (!in)
  513. return AVERROR(ENOMEM);
  514. ret = filter_frame(ctx->inputs[0], in);
  515. }
  516. }
  517. return ret;
  518. }
  519. static av_cold int init(AVFilterContext *ctx)
  520. {
  521. AudioDeclickContext *s = ctx->priv;
  522. s->is_declip = !strcmp(ctx->filter->name, "adeclip");
  523. if (s->is_declip) {
  524. s->detector = detect_clips;
  525. } else {
  526. s->detector = detect_clicks;
  527. }
  528. return 0;
  529. }
  530. static av_cold void uninit(AVFilterContext *ctx)
  531. {
  532. AudioDeclickContext *s = ctx->priv;
  533. int i;
  534. av_log(ctx, AV_LOG_INFO, "Detected %s in %"PRId64" of %"PRId64" samples (%g%%).\n",
  535. s->is_declip ? "clips" : "clicks", s->detected_errors,
  536. s->nb_samples, 100. * s->detected_errors / s->nb_samples);
  537. av_audio_fifo_free(s->fifo);
  538. av_freep(&s->window_func_lut);
  539. av_frame_free(&s->in);
  540. av_frame_free(&s->out);
  541. av_frame_free(&s->buffer);
  542. av_frame_free(&s->is);
  543. if (s->chan) {
  544. for (i = 0; i < s->nb_channels; i++) {
  545. DeclickChannel *c = &s->chan[i];
  546. av_freep(&c->detection);
  547. av_freep(&c->auxiliary);
  548. av_freep(&c->acoefficients);
  549. av_freep(&c->acorrelation);
  550. av_freep(&c->tmp);
  551. av_freep(&c->click);
  552. av_freep(&c->index);
  553. av_freep(&c->interpolated);
  554. av_freep(&c->matrix);
  555. c->matrix_size = 0;
  556. av_freep(&c->histogram);
  557. c->histogram_size = 0;
  558. av_freep(&c->vector);
  559. c->vector_size = 0;
  560. av_freep(&c->y);
  561. c->y_size = 0;
  562. }
  563. }
  564. av_freep(&s->chan);
  565. s->nb_channels = 0;
  566. }
  567. static const AVFilterPad inputs[] = {
  568. {
  569. .name = "default",
  570. .type = AVMEDIA_TYPE_AUDIO,
  571. .filter_frame = filter_frame,
  572. .config_props = config_input,
  573. },
  574. { NULL }
  575. };
  576. static const AVFilterPad outputs[] = {
  577. {
  578. .name = "default",
  579. .type = AVMEDIA_TYPE_AUDIO,
  580. .request_frame = request_frame,
  581. },
  582. { NULL }
  583. };
  584. AVFilter ff_af_adeclick = {
  585. .name = "adeclick",
  586. .description = NULL_IF_CONFIG_SMALL("Remove impulsive noise from input audio."),
  587. .query_formats = query_formats,
  588. .priv_size = sizeof(AudioDeclickContext),
  589. .priv_class = &adeclick_class,
  590. .init = init,
  591. .uninit = uninit,
  592. .inputs = inputs,
  593. .outputs = outputs,
  594. .flags = AVFILTER_FLAG_SLICE_THREADS,
  595. };
  596. static const AVOption adeclip_options[] = {
  597. { "w", "set window size", OFFSET(w), AV_OPT_TYPE_DOUBLE, {.dbl=55}, 10, 100, AF },
  598. { "o", "set window overlap", OFFSET(overlap), AV_OPT_TYPE_DOUBLE, {.dbl=75}, 50, 95, AF },
  599. { "a", "set autoregression order", OFFSET(ar), AV_OPT_TYPE_DOUBLE, {.dbl=8}, 0, 25, AF },
  600. { "t", "set threshold", OFFSET(threshold), AV_OPT_TYPE_DOUBLE, {.dbl=10}, 1, 100, AF },
  601. { "n", "set histogram size", OFFSET(nb_hbins), AV_OPT_TYPE_INT, {.i64=1000}, 100, 9999, AF },
  602. { "m", "set overlap method", OFFSET(method), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, AF, "m" },
  603. { "a", "overlap-add", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "m" },
  604. { "s", "overlap-save", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "m" },
  605. { NULL }
  606. };
  607. AVFILTER_DEFINE_CLASS(adeclip);
  608. AVFilter ff_af_adeclip = {
  609. .name = "adeclip",
  610. .description = NULL_IF_CONFIG_SMALL("Remove clipping from input audio."),
  611. .query_formats = query_formats,
  612. .priv_size = sizeof(AudioDeclickContext),
  613. .priv_class = &adeclip_class,
  614. .init = init,
  615. .uninit = uninit,
  616. .inputs = inputs,
  617. .outputs = outputs,
  618. .flags = AVFILTER_FLAG_SLICE_THREADS,
  619. };