From: Paul B Mahol <onemda@gmail.com> To: FFmpeg development discussions and patches <ffmpeg-devel@ffmpeg.org> Subject: [FFmpeg-devel] [PATCH] new audio filter and misc improvements Date: Wed, 9 Aug 2023 23:36:16 +0200 Message-ID: <CAPYw7P5SYPrr=t=Nn9nNp9rp5DeyNP+MmjBJC33JKafBuLkBWQ@mail.gmail.com> (raw) [-- Attachment #1: Type: text/plain, Size: 18 bytes --] Patches attached. [-- Attachment #2: 0003-avfilter-af_adeclick-do-not-output-pointless-message.patch --] [-- Type: text/x-patch, Size: 1198 bytes --] From 2d8c330f543397642fa1afe0a01a67155008d4e1 Mon Sep 17 00:00:00 2001 From: Paul B Mahol <onemda@gmail.com> Date: Wed, 9 Aug 2023 21:53:04 +0200 Subject: [PATCH 3/3] avfilter/af_adeclick: do not output pointless message Signed-off-by: Paul B Mahol <onemda@gmail.com> --- libavfilter/af_adeclick.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libavfilter/af_adeclick.c b/libavfilter/af_adeclick.c index fd0438d252..3401028c6b 100644 --- a/libavfilter/af_adeclick.c +++ b/libavfilter/af_adeclick.c @@ -721,9 +721,10 @@ static av_cold void uninit(AVFilterContext *ctx) { AudioDeclickContext *s = ctx->priv; - av_log(ctx, AV_LOG_INFO, "Detected %s in %"PRId64" of %"PRId64" samples (%g%%).\n", - filter_modes[s->mode], s->detected_errors, - s->nb_samples, 100. * s->detected_errors / s->nb_samples); + if (s->nb_samples > 0) + av_log(ctx, AV_LOG_INFO, "Detected %s in %"PRId64" of %"PRId64" samples (%g%%).\n", + filter_modes[s->mode], s->detected_errors, + s->nb_samples, 100. * s->detected_errors / s->nb_samples); av_audio_fifo_free(s->fifo); av_audio_fifo_free(s->efifo); -- 2.39.1 [-- Attachment #3: 0002-avfilter-af_adeclick-refactor-and-cleanup.patch --] [-- Type: text/x-patch, Size: 15328 bytes --] From 0a6de9b1482ece4402b1c7274501b43e43f5f56a Mon Sep 17 00:00:00 2001 From: Paul B Mahol <onemda@gmail.com> Date: Wed, 9 Aug 2023 21:49:19 +0200 Subject: [PATCH 2/3] avfilter/af_adeclick: refactor and cleanup Signed-off-by: Paul B Mahol <onemda@gmail.com> --- libavfilter/af_adeclick.c | 136 +++++++++++++++++++------------------- 1 file changed, 67 insertions(+), 69 deletions(-) diff --git a/libavfilter/af_adeclick.c b/libavfilter/af_adeclick.c index 1137dbe25b..fd0438d252 100644 --- a/libavfilter/af_adeclick.c +++ b/libavfilter/af_adeclick.c @@ -119,7 +119,6 @@ static int config_input(AVFilterLink *inlink) { AVFilterContext *ctx = inlink->dst; AudioDeclickContext *s = ctx->priv; - int i; s->pts = AV_NOPTS_VALUE; s->window_size = inlink->sample_rate * s->w / 1000.; @@ -134,7 +133,7 @@ static int config_input(AVFilterLink *inlink) s->window_func_lut = av_calloc(s->window_size, sizeof(*s->window_func_lut)); if (!s->window_func_lut) return AVERROR(ENOMEM); - for (i = 0; i < s->window_size; i++) + for (int i = 0; i < s->window_size; i++) s->window_func_lut[i] = sin(M_PI * i / s->window_size) * (1. - (s->overlap / 100.)) * M_PI_2; @@ -167,7 +166,7 @@ static int config_input(AVFilterLink *inlink) if (!s->chan) return AVERROR(ENOMEM); - for (i = 0; i < inlink->ch_layout.nb_channels; i++) { + for (int i = 0; i < inlink->ch_layout.nb_channels; i++) { DeclickChannel *c = &s->chan[i]; c->detection = av_calloc(s->window_size, sizeof(*c->detection)); @@ -189,13 +188,13 @@ static int config_input(AVFilterLink *inlink) static void autocorrelation(const double *input, int order, int size, double *output, double scale) { - int i, j; - - for (i = 0; i <= order; i++) { + for (int i = 0; i <= order; i++) { + const double *ninput = input + i; + const int isize = size - i; double value = 0.; - for (j = i; j < size; j++) - value += input[j] * input[j - i]; + for (int j = 0; j < isize; j++) + value += ninput[j] * input[j]; output[i] = value * scale; } @@ -205,7 +204,6 @@ static double autoregression(const double *samples, int ar_order, int nb_samples, double *k, double *r, double *a) { double alpha; - int i, j; memset(a, 0, ar_order * sizeof(*a)); @@ -214,23 +212,23 @@ static double autoregression(const double *samples, int ar_order, /* Levinson-Durbin algorithm */ k[0] = a[0] = -r[1] / r[0]; alpha = r[0] * (1. - k[0] * k[0]); - for (i = 1; i < ar_order; i++) { + for (int i = 1; i < ar_order; i++) { double epsilon = 0.; - for (j = 0; j < i; j++) + for (int j = 0; j < i; j++) epsilon += a[j] * r[i - j]; epsilon += r[i + 1]; k[i] = -epsilon / alpha; alpha *= (1. - k[i] * k[i]); - for (j = i - 1; j >= 0; j--) + for (int j = i - 1; j >= 0; j--) k[j] = a[j] + k[i] * a[i - j - 1]; - for (j = 0; j <= i; j++) + for (int j = 0; j <= i; j++) a[j] = k[j]; } k[0] = 1.; - for (i = 1; i <= ar_order; i++) + for (int i = 1; i <= ar_order; i++) k[i] = a[i - 1]; return sqrt(alpha); @@ -238,9 +236,7 @@ static double autoregression(const double *samples, int ar_order, static int isfinite_array(double *samples, int nb_samples) { - int i; - - for (i = 0; i < nb_samples; i++) + for (int i = 0; i < nb_samples; i++) if (!isfinite(samples[i])) return 0; @@ -272,14 +268,12 @@ static int find_index(int *index, int value, int size) static int factorization(double *matrix, int n) { - int i, j, k; - - for (i = 0; i < n; i++) { + for (int i = 0; i < n; i++) { const int in = i * n; double value; value = matrix[in + i]; - for (j = 0; j < i; j++) + for (int j = 0; j < i; j++) value -= matrix[j * n + j] * matrix[in + j] * matrix[in + j]; if (value == 0.) { @@ -287,12 +281,12 @@ static int factorization(double *matrix, int n) } matrix[in + i] = value; - for (j = i + 1; j < n; j++) { + for (int j = i + 1; j < n; j++) { const int jn = j * n; double x; x = matrix[jn + i]; - for (k = 0; k < i; k++) + for (int k = 0; k < i; k++) x -= matrix[k * n + k] * matrix[in + k] * matrix[jn + k]; matrix[jn + i] = x / matrix[in + i]; } @@ -304,8 +298,8 @@ static int factorization(double *matrix, int n) static int do_interpolation(DeclickChannel *c, double *matrix, double *vector, int n, double *out) { - int i, j, ret; double *y; + int ret; ret = factorization(matrix, n); if (ret < 0) @@ -316,19 +310,19 @@ static int do_interpolation(DeclickChannel *c, double *matrix, if (!y) return AVERROR(ENOMEM); - for (i = 0; i < n; i++) { + for (int i = 0; i < n; i++) { const int in = i * n; double value; value = vector[i]; - for (j = 0; j < i; j++) + for (int j = 0; j < i; j++) value -= matrix[in + j] * y[j]; y[i] = value; } - for (i = n - 1; i >= 0; i--) { + for (int i = n - 1; i >= 0; i--) { out[i] = y[i] / matrix[i * n + i]; - for (j = i + 1; j < n; j++) + for (int j = i + 1; j < n; j++) out[i] -= matrix[j * n + i] * out[j]; } @@ -340,7 +334,6 @@ static int interpolation(DeclickChannel *c, const double *src, int ar_order, double *auxiliary, double *interpolated) { double *vector, *matrix; - int i, j; av_fast_malloc(&c->matrix, &c->matrix_size, nb_errors * nb_errors * sizeof(*c->matrix)); matrix = c->matrix; @@ -354,10 +347,10 @@ static int interpolation(DeclickChannel *c, const double *src, int ar_order, autocorrelation(acoefficients, ar_order, ar_order + 1, auxiliary, 1.); - for (i = 0; i < nb_errors; i++) { + for (int i = 0; i < nb_errors; i++) { const int im = i * nb_errors; - for (j = i; j < nb_errors; j++) { + for (int j = i; j < nb_errors; j++) { if (abs(index[j] - index[i]) <= ar_order) { matrix[j * nb_errors + i] = matrix[im + j] = auxiliary[abs(index[j] - index[i])]; } else { @@ -366,10 +359,10 @@ static int interpolation(DeclickChannel *c, const double *src, int ar_order, } } - for (i = 0; i < nb_errors; i++) { + for (int i = 0; i < nb_errors; i++) { double value = 0.; - for (j = -ar_order; j <= ar_order; j++) + for (int j = -ar_order; j <= ar_order; j++) if (find_index(index, index[i] - j, nb_errors)) value -= src[index[i] - j] * auxiliary[abs(j)]; @@ -386,9 +379,11 @@ static int detect_clips(AudioDeclickContext *s, DeclickChannel *c, const double *src, double *dst) { const double threshold = s->threshold; + const int window_size = s->window_size; + const int ar_order = s->ar_order; double max_amplitude = 0; unsigned *histogram; - int i, nb_clips = 0; + int nb_clips = 0; av_fast_malloc(&c->histogram, &c->histogram_size, s->nb_hbins * sizeof(*c->histogram)); if (!c->histogram) @@ -396,7 +391,7 @@ static int detect_clips(AudioDeclickContext *s, DeclickChannel *c, histogram = c->histogram; memset(histogram, 0, sizeof(*histogram) * s->nb_hbins); - for (i = 0; i < s->window_size; i++) { + for (int i = 0; i < window_size; i++) { const unsigned index = fmin(fabs(src[i]), 1) * (s->nb_hbins - 1); histogram[index]++; @@ -404,7 +399,7 @@ static int detect_clips(AudioDeclickContext *s, DeclickChannel *c, clip[i] = 0; } - for (i = s->nb_hbins - 1; i > 1; i--) { + for (int i = s->nb_hbins - 1; i > 1; i--) { if (histogram[i]) { if (histogram[i] / (double)FFMAX(histogram[i - 1], 1) > threshold) { max_amplitude = i / (double)s->nb_hbins; @@ -414,15 +409,15 @@ static int detect_clips(AudioDeclickContext *s, DeclickChannel *c, } if (max_amplitude > 0.) { - for (i = 0; i < s->window_size; i++) { + for (int i = 0; i < window_size; i++) { clip[i] = fabs(src[i]) >= max_amplitude; } } - memset(clip, 0, s->ar_order * sizeof(*clip)); - memset(clip + (s->window_size - s->ar_order), 0, s->ar_order * sizeof(*clip)); + memset(clip, 0, ar_order * sizeof(*clip)); + memset(clip + (window_size - ar_order), 0, ar_order * sizeof(*clip)); - for (i = s->ar_order; i < s->window_size - s->ar_order; i++) + for (int i = ar_order; i < window_size - ar_order; i++) if (clip[i]) index[nb_clips++] = i; @@ -436,35 +431,37 @@ static int detect_clicks(AudioDeclickContext *s, DeclickChannel *c, const double *src, double *dst) { const double threshold = s->threshold; - int i, j, nb_clicks = 0, prev = -1; + const int window_size = s->window_size; + int nb_clicks = 0, prev = -1; + const int ar_order = s->ar_order; - memset(detection, 0, s->window_size * sizeof(*detection)); + memset(detection, 0, window_size * sizeof(*detection)); - for (i = s->ar_order; i < s->window_size; i++) { - for (j = 0; j <= s->ar_order; j++) { + for (int i = ar_order; i < window_size; i++) { + for (int j = 0; j <= ar_order; j++) { detection[i] += acoefficients[j] * src[i - j]; } } - for (i = 0; i < s->window_size; i++) { + for (int i = 0; i < window_size; i++) { click[i] = fabs(detection[i]) > sigmae * threshold; dst[i] = src[i]; } - for (i = 0; i < s->window_size; i++) { + for (int i = 0; i < window_size; i++) { if (!click[i]) continue; if (prev >= 0 && (i > prev + 1) && (i <= s->nb_burst_samples + prev)) - for (j = prev + 1; j < i; j++) + for (int j = prev + 1; j < i; j++) click[j] = 1; prev = i; } - memset(click, 0, s->ar_order * sizeof(*click)); - memset(click + (s->window_size - s->ar_order), 0, s->ar_order * sizeof(*click)); + memset(click, 0, ar_order * sizeof(*click)); + memset(click + (window_size - ar_order), 0, ar_order * sizeof(*click)); - for (i = s->ar_order; i < s->window_size - s->ar_order; i++) + for (int i = ar_order; i < window_size - ar_order; i++) if (click[i]) index[nb_clicks++] = i; @@ -478,33 +475,35 @@ static int detect_surges(AudioDeclickContext *s, DeclickChannel *c, const double *src, double *dst) { const double threshold = s->threshold; + const int window_size = s->window_size; const int size = s->nb_surge_samples * 2; - int i, j, nb_surges = 0; + const int ar_order = s->ar_order; + int nb_surges = 0; - memset(detection, 0, s->window_size * sizeof(*detection)); + memset(detection, 0, window_size * sizeof(*detection)); - for (i = s->ar_order; i < s->window_size; i++) { - for (j = 0; j <= s->ar_order; j++) { + for (int i = ar_order; i < window_size; i++) { + for (int j = 0; j <= ar_order; j++) { detection[i] += acoefficients[j] * src[i - j]; } } - for (i = 0; i < s->window_size; i++) { + for (int i = 0; i < window_size; i++) { surge[i] = fabs(detection[i]) > sigmae * threshold; dst[i] = src[i]; } - for (i = 0; i < s->window_size;) { + for (int i = 0; i < window_size;) { if (!surge[i++]) continue; - memset(surge + FFMAX(i - size/2, 0), 1, FFMIN(size, s->window_size - i)); + memset(surge + FFMAX(i - size/2, 0), 1, FFMIN(size, window_size - i)); i += size/2; } - memset(surge, 0, s->ar_order * sizeof(*surge)); - memset(surge + (s->window_size - s->ar_order), 0, s->ar_order * sizeof(*surge)); + memset(surge, 0, ar_order * sizeof(*surge)); + memset(surge + (window_size - ar_order), 0, ar_order * sizeof(*surge)); - for (i = s->ar_order; i < s->window_size - s->ar_order; i++) + for (int i = ar_order; i < window_size - ar_order; i++) if (surge[i]) index[nb_surges++] = i; @@ -528,7 +527,7 @@ static int filter_channel(AVFilterContext *ctx, void *arg, int ch, int nb_jobs) const double *w = s->window_func_lut; DeclickChannel *c = &s->chan[ch]; double sigmae; - int j, ret; + int ret; sigmae = autoregression(src, s->ar_order, s->window_size, c->acoefficients, c->acorrelation, c->tmp); @@ -549,7 +548,7 @@ static int filter_channel(AVFilterContext *ctx, void *arg, int ch, int nb_jobs) av_audio_fifo_peek(s->efifo, (void**)s->enabled->extended_data, s->window_size); - for (j = 0; j < nb_errors; j++) { + for (int j = 0; j < nb_errors; j++) { if (enabled[index[j]]) { dst[index[j]] = interpolated[j]; is[index[j]] = 1; @@ -561,15 +560,15 @@ static int filter_channel(AVFilterContext *ctx, void *arg, int ch, int nb_jobs) } if (s->method == 0) { - for (j = 0; j < s->window_size; j++) + for (int j = 0; j < s->window_size; j++) buf[j] += dst[j] * w[j]; } else { const int skip = s->overlap_skip; - for (j = 0; j < s->hop_size; j++) + for (int j = 0; j < s->hop_size; j++) buf[j] = dst[skip + j]; } - for (j = 0; j < s->hop_size; j++) + for (int j = 0; j < s->hop_size; j++) ptr[j] = buf[j]; memmove(buf, buf + s->hop_size, (s->window_size * 2 - s->hop_size) * sizeof(*buf)); @@ -586,7 +585,7 @@ static int filter_frame(AVFilterLink *inlink) AVFilterLink *outlink = ctx->outputs[0]; AudioDeclickContext *s = ctx->priv; AVFrame *out = NULL; - int ret = 0, j, ch, detected_errors = 0; + int ret = 0, ch, detected_errors = 0; ThreadData td; out = ff_get_audio_buffer(outlink, s->hop_size); @@ -606,7 +605,7 @@ static int filter_frame(AVFilterLink *inlink) for (ch = 0; ch < s->in->ch_layout.nb_channels; ch++) { double *is = (double *)s->is->extended_data[ch]; - for (j = 0; j < s->hop_size; j++) { + for (int j = 0; j < s->hop_size; j++) { if (is[j]) detected_errors++; } @@ -721,7 +720,6 @@ static av_cold int init(AVFilterContext *ctx) static av_cold void uninit(AVFilterContext *ctx) { AudioDeclickContext *s = ctx->priv; - int i; av_log(ctx, AV_LOG_INFO, "Detected %s in %"PRId64" of %"PRId64" samples (%g%%).\n", filter_modes[s->mode], s->detected_errors, @@ -737,7 +735,7 @@ static av_cold void uninit(AVFilterContext *ctx) av_frame_free(&s->is); if (s->chan) { - for (i = 0; i < s->nb_channels; i++) { + for (int i = 0; i < s->nb_channels; i++) { DeclickChannel *c = &s->chan[i]; av_freep(&c->detection); -- 2.39.1 [-- Attachment #4: 0001-avfilter-add-adesurge-filter.patch --] [-- Type: text/x-patch, Size: 9480 bytes --] From af565f57f733af327edc1e1724e31a3c5f1fe44f Mon Sep 17 00:00:00 2001 From: Paul B Mahol <onemda@gmail.com> Date: Wed, 9 Aug 2023 18:21:25 +0200 Subject: [PATCH 1/3] avfilter: add adesurge filter Signed-off-by: Paul B Mahol <onemda@gmail.com> --- doc/filters.texi | 51 ++++++++++++++++++++++ libavfilter/Makefile | 1 + libavfilter/af_adeclick.c | 91 +++++++++++++++++++++++++++++++++++++-- libavfilter/allfilters.c | 1 + 4 files changed, 140 insertions(+), 4 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index b30ff8240b..e041adc40f 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -913,6 +913,57 @@ Compute derivative/integral of audio stream. Applying both filters one after another produces original audio. +@section adesurge +Remove big surge in audio samples from input audio. + +Samples detected as instant increase or decrease of volume are replaced by +interpolated samples using autoregressive modelling. + +@table @option +@item window, w +Set window size, in milliseconds. Allowed range is from @code{10} to +@code{100}. Default value is @code{85} milliseconds. +This sets size of window which will be processed at once. + +@item overlap, o +Set window overlap, in percentage of window size. Allowed range is from +@code{50} to @code{95}. Default value is @code{75} percent. +Setting this to a very high value may increases surges removal but makes +whole process much slower. + +@item arorder, a +Set autoregression order, in percentage of window size. Allowed range is from +@code{0} to @code{25}. Default value is @code{0.5} percent. This option also +controls quality of interpolated samples using neighbour good samples. + +@item threshold, t +Set threshold value. Allowed range is from @code{1} to @code{100}. +Default value is @code{20}. +This controls the strength of surges which is going to be removed. +The lower value, the more samples will be detected as surges. + +@item surges, s +Set surges size, in number of samples. Allowed range is @code{1} to +@code{50}. Default value is @code{5}. +For any sample detected as surge then also its surrounding samples of this size +will be interpolated also. + +@item method, m +Set overlap method. + +It accepts the following values: +@table @option +@item add, a +Select overlap-add method. Even not interpolated samples are slightly +changed with this method. + +@item save, s +Select overlap-save method. Not interpolated samples remain unchanged. +@end table + +Default value is @code{s}. +@end table + @section adrc Apply spectral dynamic range controller filter to input audio stream. diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 30a0e22ef8..b26a85a7d2 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -49,6 +49,7 @@ OBJS-$(CONFIG_ADECORRELATE_FILTER) += af_adecorrelate.o OBJS-$(CONFIG_ADELAY_FILTER) += af_adelay.o OBJS-$(CONFIG_ADENORM_FILTER) += af_adenorm.o OBJS-$(CONFIG_ADERIVATIVE_FILTER) += af_aderivative.o +OBJS-$(CONFIG_ADESURGE_FILTER) += af_adesurge.o OBJS-$(CONFIG_ADRC_FILTER) += af_adrc.o OBJS-$(CONFIG_ADYNAMICEQUALIZER_FILTER) += af_adynamicequalizer.o OBJS-$(CONFIG_ADYNAMICSMOOTH_FILTER) += af_adynamicsmooth.o diff --git a/libavfilter/af_adeclick.c b/libavfilter/af_adeclick.c index 822f3065b8..1137dbe25b 100644 --- a/libavfilter/af_adeclick.c +++ b/libavfilter/af_adeclick.c @@ -25,6 +25,8 @@ #include "filters.h" #include "internal.h" +static const char *filter_modes[] = {"clicks", "clips", "surges" }; + typedef struct DeclickChannel { double *auxiliary; double *detection; @@ -55,8 +57,9 @@ typedef struct AudioDeclickContext { int method; int nb_hbins; - int is_declip; + int mode; int ar_order; + int nb_surge_samples; int nb_burst_samples; int window_size; int hop_size; @@ -468,6 +471,46 @@ static int detect_clicks(AudioDeclickContext *s, DeclickChannel *c, return nb_clicks; } +static int detect_surges(AudioDeclickContext *s, DeclickChannel *c, + double sigmae, + double *detection, double *acoefficients, + uint8_t *surge, int *index, + const double *src, double *dst) +{ + const double threshold = s->threshold; + const int size = s->nb_surge_samples * 2; + int i, j, nb_surges = 0; + + memset(detection, 0, s->window_size * sizeof(*detection)); + + for (i = s->ar_order; i < s->window_size; i++) { + for (j = 0; j <= s->ar_order; j++) { + detection[i] += acoefficients[j] * src[i - j]; + } + } + + for (i = 0; i < s->window_size; i++) { + surge[i] = fabs(detection[i]) > sigmae * threshold; + dst[i] = src[i]; + } + + for (i = 0; i < s->window_size;) { + if (!surge[i++]) + continue; + memset(surge + FFMAX(i - size/2, 0), 1, FFMIN(size, s->window_size - i)); + i += size/2; + } + + memset(surge, 0, s->ar_order * sizeof(*surge)); + memset(surge + (s->window_size - s->ar_order), 0, s->ar_order * sizeof(*surge)); + + for (i = s->ar_order; i < s->window_size - s->ar_order; i++) + if (surge[i]) + index[nb_surges++] = i; + + return nb_surges; +} + typedef struct ThreadData { AVFrame *out; } ThreadData; @@ -661,10 +704,14 @@ static av_cold int init(AVFilterContext *ctx) { AudioDeclickContext *s = ctx->priv; - s->is_declip = !strcmp(ctx->filter->name, "adeclip"); - if (s->is_declip) { + if (!strcmp(ctx->filter->name, "adesurge")) { + s->mode = 2; + s->detector = detect_surges; + } else if (!strcmp(ctx->filter->name, "adeclip")) { + s->mode = 1; s->detector = detect_clips; } else { + s->mode = 0; s->detector = detect_clicks; } @@ -677,7 +724,7 @@ static av_cold void uninit(AVFilterContext *ctx) int i; av_log(ctx, AV_LOG_INFO, "Detected %s in %"PRId64" of %"PRId64" samples (%g%%).\n", - s->is_declip ? "clips" : "clicks", s->detected_errors, + filter_modes[s->mode], s->detected_errors, s->nb_samples, 100. * s->detected_errors / s->nb_samples); av_audio_fifo_free(s->fifo); @@ -772,3 +819,39 @@ const AVFilter ff_af_adeclip = { FILTER_SINGLE_SAMPLEFMT(AV_SAMPLE_FMT_DBLP), .flags = AVFILTER_FLAG_SLICE_THREADS | AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL, }; + +static const AVOption adesurge_options[] = { + { "window", "set window size", OFFSET(w), AV_OPT_TYPE_DOUBLE, {.dbl=85}, 10, 100, AF }, + { "w", "set window size", OFFSET(w), AV_OPT_TYPE_DOUBLE, {.dbl=85}, 10, 100, AF }, + { "overlap", "set window overlap", OFFSET(overlap), AV_OPT_TYPE_DOUBLE, {.dbl=75}, 50, 95, AF }, + { "o", "set window overlap", OFFSET(overlap), AV_OPT_TYPE_DOUBLE, {.dbl=75}, 50, 95, AF }, + { "arorder", "set autoregression order", OFFSET(ar), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 25, AF }, + { "a", "set autoregression order", OFFSET(ar), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 25, AF }, + { "threshold", "set threshold", OFFSET(threshold), AV_OPT_TYPE_DOUBLE, {.dbl=20}, 1, 100, AF }, + { "t", "set threshold", OFFSET(threshold), AV_OPT_TYPE_DOUBLE, {.dbl=20}, 1, 100, AF }, + { "surges", "set surge size", OFFSET(nb_surge_samples), AV_OPT_TYPE_INT, {.i64=5}, 1, 50, AF }, + { "s", "set surge size", OFFSET(nb_surge_samples), AV_OPT_TYPE_INT, {.i64=5}, 1, 50, AF }, + { "method", "set overlap method", OFFSET(method), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, AF, "m" }, + { "m", "set overlap method", OFFSET(method), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, AF, "m" }, + { "add", "overlap-add", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "m" }, + { "a", "overlap-add", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "m" }, + { "save", "overlap-save", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "m" }, + { "s", "overlap-save", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "m" }, + { NULL } +}; + +AVFILTER_DEFINE_CLASS(adesurge); + +const AVFilter ff_af_adesurge = { + .name = "adesurge", + .description = NULL_IF_CONFIG_SMALL("Remove surges from input audio."), + .priv_size = sizeof(AudioDeclickContext), + .priv_class = &adesurge_class, + .init = init, + .activate = activate, + .uninit = uninit, + FILTER_INPUTS(inputs), + FILTER_OUTPUTS(ff_audio_default_filterpad), + FILTER_SINGLE_SAMPLEFMT(AV_SAMPLE_FMT_DBLP), + .flags = AVFILTER_FLAG_SLICE_THREADS | AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL, +}; diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index 089ad3a0ed..286e601799 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -35,6 +35,7 @@ extern const AVFilter ff_af_adecorrelate; extern const AVFilter ff_af_adelay; extern const AVFilter ff_af_adenorm; extern const AVFilter ff_af_aderivative; +extern const AVFilter ff_af_adesurge; extern const AVFilter ff_af_adrc; extern const AVFilter ff_af_adynamicequalizer; extern const AVFilter ff_af_adynamicsmooth; -- 2.39.1 [-- Attachment #5: Type: text/plain, Size: 251 bytes --] _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
next reply other threads:[~2023-08-09 21:29 UTC|newest] Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top 2023-08-09 21:36 Paul B Mahol [this message] 2023-08-10 9:47 ` Michael Niedermayer 2023-08-10 10:10 ` Paul B Mahol 2023-08-10 15:13 ` Michael Niedermayer 2023-08-10 16:49 ` Paul B Mahol 2023-08-12 10:09 ` Michael Niedermayer
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to='CAPYw7P5SYPrr=t=Nn9nNp9rp5DeyNP+MmjBJC33JKafBuLkBWQ@mail.gmail.com' \ --to=onemda@gmail.com \ --cc=ffmpeg-devel@ffmpeg.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel This inbox may be cloned and mirrored by anyone: git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \ ffmpegdev@gitmailbox.com public-inbox-index ffmpegdev Example config snippet for mirrors. AGPL code for this site: git clone https://public-inbox.org/public-inbox.git