2 * This file is part of FFmpeg.
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
28 #define SAMPLE_FORMAT flt
37 #define SAMPLE_FORMAT dbl
47 #define fn3(a,b) a##_##b
48 #define fn2(a,b) fn3(a,b)
49 #define fn(a) fn2(a, SAMPLE_FORMAT)
51 static void fn(flush
)(ftype
*dst
, const ftype
*src
, int src_pos
,
52 int nb_channels
, int count
, int src_nb_samples
,
55 int oidx
, out_count
= count
;
61 oidx
= *out_nb_samples
+ out_count
- 1;
62 *out_nb_samples
+= out_count
;
63 while (out_count
-- > 0) {
64 const int spos
= sidx
* nb_channels
;
65 const int opos
= oidx
* nb_channels
;
67 for (int ch
= 0; ch
< nb_channels
; ch
++)
68 dst
[opos
+ ch
] = src
[spos
+ ch
];
73 sidx
= src_nb_samples
- 1;
77 static void fn(queue_sample
)(AVFilterContext
*ctx
,
84 const int nb_channels
,
86 const int window_nb_samples
)
88 const int pos
= *queue_pos
* nb_channels
;
90 for (int ch
= 0; ch
< nb_channels
; ch
++)
91 queue
[pos
+ ch
] = src
[ch
];
94 if (*queue_pos
>= nb_samples
)
97 if (*queue_size
< nb_samples
)
100 if (*window_size
< window_nb_samples
)
104 if (*window_pos
>= window_nb_samples
)
108 static ftype
fn(compute_avg
)(ftype
*cache
, ftype x
, ftype px
,
109 int window_size
, int *unused
, int *unused2
)
114 cache
[0] -= FABS(px
);
115 cache
[0] = r
= FMAX(cache
[0], ZERO
);
117 return r
/ window_size
;
120 #define PEAKS(empty_value,op,sample, psample)\
121 if (!empty && psample == ss[front]) { \
122 ss[front] = empty_value; \
123 if (back != front) { \
128 empty = front == back; \
131 if (!empty && sample op ss[front]) { \
133 ss[front] = empty_value; \
134 if (back == front) { \
144 while (!empty && sample op ss[back]) { \
145 ss[back] = empty_value; \
146 if (back == front) { \
161 static ftype
fn(compute_median
)(ftype
*ss
, ftype x
, ftype px
,
162 int n
, int *ffront
, int *bback
)
164 ftype r
, ax
= FABS(x
);
167 int empty
= front
== back
&& ss
[front
] == -ONE
;
170 PEAKS(-ONE
, >, ax
, FABS(px
))
173 idx
= (back
<= front
) ? back
+ (front
- back
+ 1) / 2 : back
+ (n
+ front
- back
+ 1) / 2;
176 av_assert2(idx
>= 0 && idx
< n
);
185 static ftype
fn(compute_peak
)(ftype
*ss
, ftype x
, ftype px
,
186 int n
, int *ffront
, int *bback
)
188 ftype r
, ax
= FABS(x
);
191 int empty
= front
== back
&& ss
[front
] == ZERO
;
193 PEAKS(ZERO
, >=, ax
, FABS(px
))
204 static ftype
fn(compute_ptp
)(ftype
*ss
, ftype x
, ftype px
,
205 int n
, int *ffront
, int *bback
)
209 int empty
= front
== back
&& ss
[front
] == TMIN
;
212 PEAKS(TMIN
, >=, x
, px
)
217 r
= FABS(min
) + FABS(max
- min
);
225 static ftype
fn(compute_rms
)(ftype
*cache
, ftype x
, ftype px
,
226 int window_size
, int *unused
, int *unused2
)
232 cache
[0] = r
= FMAX(cache
[0], ZERO
);
234 return SQRT(r
/ window_size
);
237 static ftype
fn(compute_dev
)(ftype
*ss
, ftype x
, ftype px
,
238 int n
, int *unused
, int *unused2
)
247 ss
[1] = FMAX(ss
[1], ZERO
);
249 r
= FMAX(ss
[1] - ss
[0] * ss
[0] / n
, ZERO
) / n
;
254 static void fn(filter_start
)(AVFilterContext
*ctx
,
255 const ftype
*src
, ftype
*dst
,
257 const int nb_channels
)
259 SilenceRemoveContext
*s
= ctx
->priv
;
260 const int start_periods
= s
->start_periods
;
261 int out_nb_samples
= *nb_out_samples
;
262 const int start_window_nb_samples
= s
->start_window
->nb_samples
;
263 const int start_nb_samples
= s
->start_queuef
->nb_samples
;
264 const int start_wpos
= s
->start_window_pos
* nb_channels
;
265 const int start_pos
= s
->start_queue_pos
* nb_channels
;
266 ftype
*startw
= (ftype
*)s
->start_window
->data
[0];
267 ftype
*start
= (ftype
*)s
->start_queuef
->data
[0];
268 const ftype start_threshold
= s
->start_threshold
;
269 const int start_mode
= s
->start_mode
;
270 int start_thres
= (start_mode
== T_ANY
) ? 0 : 1;
271 const int start_duration
= s
->start_duration
;
272 ftype
*start_cache
= (ftype
*)s
->start_cache
;
273 const int start_silence
= s
->start_silence
;
274 int window_size
= start_window_nb_samples
;
275 const int cache_size
= s
->cache_size
;
276 int *front
= s
->start_front
;
277 int *back
= s
->start_back
;
279 fn(queue_sample
)(ctx
, src
, start
,
281 &s
->start_queue_size
,
282 &s
->start_window_pos
,
283 &s
->start_window_size
,
286 start_window_nb_samples
);
288 if (s
->start_found_periods
< 0)
291 if (s
->detection
!= D_PEAK
&& s
->detection
!= D_MEDIAN
&&
292 s
->detection
!= D_PTP
)
293 window_size
= s
->start_window_size
;
295 for (int ch
= 0; ch
< nb_channels
; ch
++) {
296 ftype start_sample
= start
[start_pos
+ ch
];
297 ftype start_ow
= startw
[start_wpos
+ ch
];
300 tstart
= fn(s
->compute
)(start_cache
+ ch
* cache_size
,
307 startw
[start_wpos
+ ch
] = start_sample
;
309 if (start_mode
== T_ANY
) {
310 start_thres
|= tstart
> start_threshold
;
312 start_thres
&= tstart
> start_threshold
;
316 if (s
->start_found_periods
>= 0) {
317 if (start_silence
> 0) {
318 s
->start_silence_count
++;
319 if (s
->start_silence_count
> start_silence
)
320 s
->start_silence_count
= start_silence
;
323 s
->start_sample_count
+= start_thres
;
326 if (s
->start_sample_count
> start_duration
) {
327 s
->start_found_periods
++;
328 if (s
->start_found_periods
>= start_periods
) {
329 if (!ctx
->is_disabled
)
330 fn(flush
)(dst
, start
, s
->start_queue_pos
, nb_channels
,
331 s
->start_silence_count
, start_nb_samples
,
333 s
->start_silence_count
= 0;
334 s
->start_found_periods
= -1;
337 s
->start_sample_count
= 0;
341 if (s
->start_found_periods
< 0 || ctx
->is_disabled
) {
342 const int dst_pos
= out_nb_samples
* nb_channels
;
343 for (int ch
= 0; ch
< nb_channels
; ch
++)
344 dst
[dst_pos
+ ch
] = start
[start_pos
+ ch
];
348 *nb_out_samples
= out_nb_samples
;
351 static void fn(filter_stop
)(AVFilterContext
*ctx
,
352 const ftype
*src
, ftype
*dst
,
354 const int nb_channels
)
356 SilenceRemoveContext
*s
= ctx
->priv
;
357 const int stop_periods
= s
->stop_periods
;
358 int out_nb_samples
= *nb_out_samples
;
359 const int stop_window_nb_samples
= s
->stop_window
->nb_samples
;
360 const int stop_nb_samples
= s
->stop_queuef
->nb_samples
;
361 const int stop_wpos
= s
->stop_window_pos
* nb_channels
;
362 const int stop_pos
= s
->stop_queue_pos
* nb_channels
;
363 ftype
*stopw
= (ftype
*)s
->stop_window
->data
[0];
364 const ftype stop_threshold
= s
->stop_threshold
;
365 ftype
*stop
= (ftype
*)s
->stop_queuef
->data
[0];
366 const int stop_mode
= s
->stop_mode
;
367 int stop_thres
= (stop_mode
== T_ANY
) ? 0 : 1;
368 const int stop_duration
= s
->stop_duration
;
369 ftype
*stop_cache
= (ftype
*)s
->stop_cache
;
370 const int stop_silence
= s
->stop_silence
;
371 int window_size
= stop_window_nb_samples
;
372 const int cache_size
= s
->cache_size
;
373 const int restart
= s
->restart
;
374 int *front
= s
->stop_front
;
375 int *back
= s
->stop_back
;
377 fn(queue_sample
)(ctx
, src
, stop
,
381 &s
->stop_window_size
,
384 stop_window_nb_samples
);
386 if (s
->detection
!= D_PEAK
&& s
->detection
!= D_MEDIAN
&&
387 s
->detection
!= D_PTP
)
388 window_size
= s
->stop_window_size
;
390 for (int ch
= 0; ch
< nb_channels
; ch
++) {
391 ftype stop_sample
= stop
[stop_pos
+ ch
];
392 ftype stop_ow
= stopw
[stop_wpos
+ ch
];
395 tstop
= fn(s
->compute
)(stop_cache
+ ch
* cache_size
,
402 stopw
[stop_wpos
+ ch
] = stop_sample
;
404 if (stop_mode
== T_ANY
) {
405 stop_thres
|= tstop
<= stop_threshold
;
407 stop_thres
&= tstop
<= stop_threshold
;
411 s
->found_nonsilence
= FFMAX(s
->found_nonsilence
, !stop_thres
);
412 if (restart
&& !stop_thres
)
413 s
->stop_found_periods
= 0;
415 if (s
->stop_found_periods
>= 0 || ctx
->is_disabled
) {
416 if (s
->found_nonsilence
) {
417 s
->stop_sample_count
+= stop_thres
;
418 s
->stop_sample_count
*= stop_thres
;
420 } else if (s
->stop_silence_count
> 0) {
421 const int dst_pos
= out_nb_samples
* nb_channels
;
422 for (int ch
= 0; ch
< nb_channels
; ch
++)
423 dst
[dst_pos
+ ch
] = stop
[stop_pos
+ ch
];
424 s
->stop_silence_count
--;
428 if (s
->stop_sample_count
> stop_duration
) {
429 s
->stop_found_periods
++;
430 if (s
->stop_found_periods
>= stop_periods
) {
431 s
->stop_found_periods
= -1;
432 s
->stop_silence_count
= stop_silence
;
435 s
->stop_sample_count
= 0;
438 if (s
->stop_found_periods
>= 0 || ctx
->is_disabled
) {
439 const int dst_pos
= out_nb_samples
* nb_channels
;
440 for (int ch
= 0; ch
< nb_channels
; ch
++)
441 dst
[dst_pos
+ ch
] = stop
[stop_pos
+ ch
];
445 *nb_out_samples
= out_nb_samples
;