History

avfilter/af_silenceremove: add median silence detector

Paul B Mahol committed 3 years ago

Commit 5a13b131 parent 68d0b883 files · +74 −3Browse files

Unified · Split

3 files
  1. doc/filters.texi +1 −1
  2. libavfilter/af_silenceremove.c +6 −0
  3. libavfilter/silenceremove_template.c +67 −2
doc/filters.texi+1−1
@@ -6461,7 +6461,7 @@ With @var{all}, only if all channels are detected as non-silence will cause · 6460 unmodified lines
6461stopped trimming of silence.6461stopped trimming of silence.
6462 6462
6463@item detection6463@item detection
6464Set how is silence detected. Can be @code{avg}, @code{rms} or @code{peak}.6464Set how is silence detected. Can be @code{avg}, @code{rms}, @code{median} or @code{peak}.
6465Default value is @code{rms}.6465Default value is @code{rms}.
6466 6466
6467@item window6467@item window
libavfilter/af_silenceremove.c+6−0
@@ -36,6 +36,7 @@ enum SilenceDetect { · 35 unmodified lines
36 D_AVG,36 D_AVG,
37 D_RMS,37 D_RMS,
38 D_PEAK,38 D_PEAK,
39 D_MEDIAN,
39 D_NB40 D_NB
40};41};
41 42
@@ -132,6 +133,7 @@ static const AVOption silenceremove_options[] = { · 90 unmodified lines
132 { "avg", "use mean absolute values of samples", 0, AV_OPT_TYPE_CONST, {.i64=D_AVG}, 0, 0, AF, "detection" },133 { "avg", "use mean absolute values of samples", 0, AV_OPT_TYPE_CONST, {.i64=D_AVG}, 0, 0, AF, "detection" },
133 { "rms", "use root mean squared values of samples", 0, AV_OPT_TYPE_CONST, {.i64=D_RMS}, 0, 0, AF, "detection" },134 { "rms", "use root mean squared values of samples", 0, AV_OPT_TYPE_CONST, {.i64=D_RMS}, 0, 0, AF, "detection" },
134 { "peak", "use max absolute values of samples", 0, AV_OPT_TYPE_CONST, {.i64=D_PEAK},0, 0, AF, "detection" },135 { "peak", "use max absolute values of samples", 0, AV_OPT_TYPE_CONST, {.i64=D_PEAK},0, 0, AF, "detection" },
136 { "median", "use median of absolute values of samples", 0, AV_OPT_TYPE_CONST, {.i64=D_MEDIAN},0, 0, AF, "detection" },
135 { "window", "set duration of window for silence detection", OFFSET(window_duration_opt), AV_OPT_TYPE_DURATION, {.i64=20000}, 0, 100000000, AF },137 { "window", "set duration of window for silence detection", OFFSET(window_duration_opt), AV_OPT_TYPE_DURATION, {.i64=20000}, 0, 100000000, AF },
136 { NULL }138 { NULL }
137};139};
@@ -234,6 +236,10 @@ static int config_output(AVFilterLink *outlink) · 96 unmodified lines
234 s->compute_flt = compute_avg_flt;236 s->compute_flt = compute_avg_flt;
235 s->compute_dbl = compute_avg_dbl;237 s->compute_dbl = compute_avg_dbl;
236 break;238 break;
239 case D_MEDIAN:
240 s->compute_flt = compute_median_flt;
241 s->compute_dbl = compute_median_dbl;
242 break;
237 case D_PEAK:243 case D_PEAK:
238 s->compute_flt = compute_peak_flt;244 s->compute_flt = compute_peak_flt;
239 s->compute_dbl = compute_peak_dbl;245 s->compute_dbl = compute_peak_dbl;
libavfilter/silenceremove_template.c+67−2
@@ -22,6 +22,7 @@ · 21 unmodified lines
22#undef SAMPLE_FORMAT22#undef SAMPLE_FORMAT
23#undef SQRT23#undef SQRT
24#undef ZERO24#undef ZERO
25#undef ONE
25#if DEPTH == 3226#if DEPTH == 32
26#define SAMPLE_FORMAT flt27#define SAMPLE_FORMAT flt
27#define SQRT sqrtf28#define SQRT sqrtf
@@ -29,6 +30,7 @@ · 1 unmodified line
29#define FABS fabsf30#define FABS fabsf
30#define ftype float31#define ftype float
31#define ZERO 0.f32#define ZERO 0.f
33#define ONE 1.f
32#else34#else
33#define SAMPLE_FORMAT dbl35#define SAMPLE_FORMAT dbl
34#define SQRT sqrt36#define SQRT sqrt
@@ -36,6 +38,7 @@ · 1 unmodified line
36#define FABS fabs38#define FABS fabs
37#define ftype double39#define ftype double
38#define ZERO 0.040#define ZERO 0.0
41#define ONE 1.0
39#endif42#endif
40 43
41#define fn3(a,b) a##_##b44#define fn3(a,b) a##_##b
@@ -111,6 +114,68 @@ static ftype fn(compute_avg)(ftype *cache, ftype sample, ftype wsample, · 69 unmodified lines
111 return r / window_size;114 return r / window_size;
112}115}
113 116
117static ftype fn(compute_median)(ftype *peak, ftype sample, ftype wsample,
118 int size, int *ffront, int *bback)
119{
120 ftype r, abs_sample = FABS(sample);
121 int front = *ffront;
122 int back = *bback;
123 int empty = front == back && peak[front] == -ONE;
124 int idx;
125
126 if (!empty && FABS(wsample) == peak[front]) {
127 peak[front] = -ONE;
128 if (back != front) {
129 front--;
130 if (front < 0)
131 front = size - 1;
132 }
133 empty = front == back;
134 }
135
136 if (!empty && abs_sample > peak[front]) {
137 while (1) {
138 peak[front] = -ONE;
139 if (back == front) {
140 empty = 1;
141 break;
142 }
143 front--;
144 if (front < 0)
145 front = size - 1;
146 }
147 }
148
149 while (!empty && abs_sample > peak[back]) {
150 peak[back] = -ONE;
151 if (back == front) {
152 empty = 1;
153 break;
154 }
155 back++;
156 if (back >= size)
157 back = 0;
158 }
159
160 if (!empty) {
161 back--;
162 if (back < 0)
163 back = size - 1;
164 }
165
166 peak[back] = abs_sample;
167 idx = (back <= front) ? back + (front - back + 1) / 2 : back + (size + front - back + 1) / 2;
168 if (idx >= size)
169 idx -= size;
170 av_assert2(idx >= 0 && idx < size);
171 r = peak[idx];
172
173 *ffront = front;
174 *bback = back;
175
176 return r;
177}
178
114static ftype fn(compute_peak)(ftype *peak, ftype sample, ftype wsample,179static ftype fn(compute_peak)(ftype *peak, ftype sample, ftype wsample,
115 int size, int *ffront, int *bback)180 int size, int *ffront, int *bback)
116{181{
@@ -216,7 +281,7 @@ static void fn(filter_start)(AVFilterContext *ctx, · 99 unmodified lines
216 if (s->start_found_periods < 0)281 if (s->start_found_periods < 0)
217 goto skip;282 goto skip;
218 283
219 if (s->detection != D_PEAK)284 if (s->detection != D_PEAK && s->detection != D_MEDIAN)
220 window_size = s->start_window_size;285 window_size = s->start_window_size;
221 286
222 for (int ch = 0; ch < nb_channels; ch++) {287 for (int ch = 0; ch < nb_channels; ch++) {
@@ -308,7 +373,7 @@ static void fn(filter_stop)(AVFilterContext *ctx, · 85 unmodified lines
308 stop_nb_samples,373 stop_nb_samples,
309 stop_window_nb_samples);374 stop_window_nb_samples);
310 375
311 if (s->detection != D_PEAK)376 if (s->detection != D_PEAK && s->detection != D_MEDIAN)
312 window_size = s->stop_window_size;377 window_size = s->stop_window_size;
313 378
314 for (int ch = 0; ch < nb_channels; ch++) {379 for (int ch = 0; ch < nb_channels; ch++) {

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t