aboutsummaryrefslogtreecommitdiffstats
path: root/libavfilter/silenceremove_template.c
diff options
context:
space:
mode:
authorPaul B Mahol <onemda@gmail.com>2023-05-26 14:10:38 +0200
committerPaul B Mahol <onemda@gmail.com>2023-05-27 00:34:37 +0200
commit5a13b133f8effe2a2bac07b17f591d8ca7f6c1de (patch)
tree4566d6141fadb23db355c99de8d1786b3d73aa8f /libavfilter/silenceremove_template.c
parent68d0b881dea35960275fb168030ae1f19dcf1a0f (diff)
downloadffmpeg-5a13b133f8effe2a2bac07b17f591d8ca7f6c1de.tar.gz
avfilter/af_silenceremove: add median silence detector
Diffstat (limited to 'libavfilter/silenceremove_template.c')
-rw-r--r--libavfilter/silenceremove_template.c69
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++) {