diff options
author | Paul B Mahol <onemda@gmail.com> | 2023-05-26 14:10:38 +0200 |
---|---|---|
committer | Paul B Mahol <onemda@gmail.com> | 2023-05-27 00:34:37 +0200 |
commit | 5a13b133f8effe2a2bac07b17f591d8ca7f6c1de (patch) | |
tree | 4566d6141fadb23db355c99de8d1786b3d73aa8f /libavfilter/silenceremove_template.c | |
parent | 68d0b881dea35960275fb168030ae1f19dcf1a0f (diff) | |
download | ffmpeg-5a13b133f8effe2a2bac07b17f591d8ca7f6c1de.tar.gz |
avfilter/af_silenceremove: add median silence detector
Diffstat (limited to 'libavfilter/silenceremove_template.c')
-rw-r--r-- | libavfilter/silenceremove_template.c | 69 |
1 files changed, 67 insertions, 2 deletions
diff --git a/libavfilter/silenceremove_template.c b/libavfilter/silenceremove_template.c index be51beb300..143d399f9e 100644 --- a/libavfilter/silenceremove_template.c +++ b/libavfilter/silenceremove_template.c @@ -22,6 +22,7 @@ #undef SAMPLE_FORMAT #undef SQRT #undef ZERO +#undef ONE #if DEPTH == 32 #define SAMPLE_FORMAT flt #define SQRT sqrtf @@ -29,6 +30,7 @@ #define FABS fabsf #define ftype float #define ZERO 0.f +#define ONE 1.f #else #define SAMPLE_FORMAT dbl #define SQRT sqrt @@ -36,6 +38,7 @@ #define FABS fabs #define ftype double #define ZERO 0.0 +#define ONE 1.0 #endif #define fn3(a,b) a##_##b @@ -111,6 +114,68 @@ static ftype fn(compute_avg)(ftype *cache, ftype sample, ftype wsample, return r / window_size; } +static ftype fn(compute_median)(ftype *peak, ftype sample, ftype wsample, + int size, int *ffront, int *bback) +{ + ftype r, abs_sample = FABS(sample); + int front = *ffront; + int back = *bback; + int empty = front == back && peak[front] == -ONE; + int idx; + + if (!empty && FABS(wsample) == peak[front]) { + peak[front] = -ONE; + if (back != front) { + front--; + if (front < 0) + front = size - 1; + } + empty = front == back; + } + + if (!empty && abs_sample > peak[front]) { + while (1) { + peak[front] = -ONE; + if (back == front) { + empty = 1; + break; + } + front--; + if (front < 0) + front = size - 1; + } + } + + while (!empty && abs_sample > peak[back]) { + peak[back] = -ONE; + if (back == front) { + empty = 1; + break; + } + back++; + if (back >= size) + back = 0; + } + + if (!empty) { + back--; + if (back < 0) + back = size - 1; + } + + peak[back] = abs_sample; + idx = (back <= front) ? back + (front - back + 1) / 2 : back + (size + front - back + 1) / 2; + if (idx >= size) + idx -= size; + av_assert2(idx >= 0 && idx < size); + r = peak[idx]; + + *ffront = front; + *bback = back; + + return r; +} + static ftype fn(compute_peak)(ftype *peak, ftype sample, ftype wsample, int size, int *ffront, int *bback) { @@ -216,7 +281,7 @@ static void fn(filter_start)(AVFilterContext *ctx, if (s->start_found_periods < 0) goto skip; - if (s->detection != D_PEAK) + if (s->detection != D_PEAK && s->detection != D_MEDIAN) window_size = s->start_window_size; for (int ch = 0; ch < nb_channels; ch++) { @@ -308,7 +373,7 @@ static void fn(filter_stop)(AVFilterContext *ctx, stop_nb_samples, stop_window_nb_samples); - if (s->detection != D_PEAK) + if (s->detection != D_PEAK && s->detection != D_MEDIAN) window_size = s->stop_window_size; for (int ch = 0; ch < nb_channels; ch++) { |