From e8e486332571347dd55822c842ba67276ac308e2 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Sat, 27 May 2023 13:59:24 +0200 Subject: [PATCH] avfilter/af_silenceremove: fix the any/all confusion and change default 'any' stop mode is now correctly implemented for end trimming and is of limited usage. Extend examples and other documentation of this filter. --- doc/filters.texi | 62 +++++++++++++++++++++------- libavfilter/af_silenceremove.c | 2 +- libavfilter/silenceremove_template.c | 4 +- 3 files changed, 50 insertions(+), 18 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index 975a506352..4d9a3cf0b4 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -6419,15 +6419,16 @@ trimming. Default is 0, which is equal to trimming all samples detected as silence. @item start_mode -Specify mode of detection of silence end in start of multi-channel audio. +Specify mode of detection of silence end at start of multi-channel audio. Can be @var{any} or @var{all}. Default is @var{any}. -With @var{any}, any sample that is detected as non-silence will cause -stopped trimming of silence. -With @var{all}, only if all channels are detected as non-silence will cause -stopped trimming of silence. +With @var{any}, any sample from any channel that is detected as non-silence +will trigger end of silence trimming at start of audio stream. +With @var{all}, only if every sample from every channel is detected as non-silence +will trigger end of silence trimming at start of audio stream, limited usage. @item stop_periods -Set the count for trimming silence from the end of audio. +Set the count for trimming silence from the end of audio. When specifying a +positive value, it trims audio after it finds specified silence period. To remove silence from the middle of a file, specify a @var{stop_periods} that is negative. This value is then treated as a positive value and is used to indicate the effect should restart processing as specified by @@ -6453,20 +6454,34 @@ trimming. Default is 0, which is equal to trimming all samples detected as silence. @item stop_mode -Specify mode of detection of silence start in end of multi-channel audio. -Can be @var{any} or @var{all}. Default is @var{any}. -With @var{any}, any sample that is detected as non-silence will cause -stopped trimming of silence. -With @var{all}, only if all channels are detected as non-silence will cause -stopped trimming of silence. +Specify mode of detection of silence start after start of multi-channel audio. +Can be @var{any} or @var{all}. Default is @var{all}. +With @var{any}, any sample from any channel that is detected as silence +will trigger start of silence trimming after start of audio stream, limited usage. +With @var{all}, only if every sample from every channel is detected as silence +will trigger start of silence trimming after start of audio stream. @item detection -Set how is silence detected. Can be @code{avg}, @code{rms}, @code{median} or @code{peak}. +Set how is silence detected. +@table @option +@item avg +Mean of absolute values of samples in moving window. +@item rms +Root squared mean of absolute values of samples in moving window. +@item peak +Maximum of absolute values of samples in moving window. +@item median +Median of absolute values of samples in moving window. +@end table Default value is @code{rms}. @item window Set duration in number of seconds used to calculate size of window in number -of samples for detecting silence. +of samples for detecting silence. Using @code{0} will effectively disable +any windowing and use only single sample per channel for silence detection. +In that case it may be needed to also set @option{start_silence} and/or +@option{stop_silence} to nonzero values with also @option{start_duration} and/or +@option{stop_duration} to nonzero values. Default value is @code{0.02}. Allowed range is from @code{0} to @code{10}. @end table @@ -6495,6 +6510,25 @@ silence is detected in all channels at same positions in stream: @example silenceremove=window=0:detection=peak:stop_mode=all:start_mode=all:stop_periods=-1:stop_threshold=0 @end example + +@item +Trim every 2nd encountered silence period from beginning to end where there is +more than 1 second of silence per silence period in audio: +@example +silenceremove=stop_periods=-2:stop_duration=1:stop_threshold=-90dB +@end example + +@item +Similar as above, but keep maximum of 0.5 seconds of silence from each trimmed period: +@example +silenceremove=stop_periods=-2:stop_duration=1:stop_threshold=-90dB:stop_silence=0.5 +@end example + +@item +Similar as above, but keep maximum of 1.5 seconds of silence from start of audio: +@example +silenceremove=stop_periods=-2:stop_duration=1:stop_threshold=-90dB:stop_silence=0.5:start_periods=1:start_duration=1:start_silence=1.5:stop_threshold=-90dB +@end example @end itemize @subsection Commands diff --git a/libavfilter/af_silenceremove.c b/libavfilter/af_silenceremove.c index 8398eeadb2..752a362203 100644 --- a/libavfilter/af_silenceremove.c +++ b/libavfilter/af_silenceremove.c @@ -129,7 +129,7 @@ static const AVOption silenceremove_options[] = { { "stop_duration", "set stop duration of silence part", OFFSET(stop_duration_opt), AV_OPT_TYPE_DURATION, {.i64=0}, 0, INT32_MAX, AF }, { "stop_threshold", "set threshold for stop silence detection", OFFSET(stop_threshold), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, DBL_MAX, AFR }, { "stop_silence", "set stop duration of silence part to keep", OFFSET(stop_silence_opt), AV_OPT_TYPE_DURATION, {.i64=0}, 0, INT32_MAX, AF }, - { "stop_mode", "set which channel will trigger trimming from end", OFFSET(stop_mode), AV_OPT_TYPE_INT, {.i64=T_ANY}, T_ANY, T_ALL, AFR, "mode" }, + { "stop_mode", "set which channel will trigger trimming from end", OFFSET(stop_mode), AV_OPT_TYPE_INT, {.i64=T_ALL}, T_ANY, T_ALL, AFR, "mode" }, { "detection", "set how silence is detected", OFFSET(detection), AV_OPT_TYPE_INT, {.i64=D_RMS}, 0, D_NB-1, AF, "detection" }, { "avg", "use mean absolute values of samples", 0, AV_OPT_TYPE_CONST, {.i64=D_AVG}, 0, 0, AF, "detection" }, { "rms", "use root mean squared values of samples", 0, AV_OPT_TYPE_CONST, {.i64=D_RMS}, 0, 0, AF, "detection" }, diff --git a/libavfilter/silenceremove_template.c b/libavfilter/silenceremove_template.c index e07a615ae7..901361d7eb 100644 --- a/libavfilter/silenceremove_template.c +++ b/libavfilter/silenceremove_template.c @@ -403,10 +403,8 @@ static void fn(filter_stop)(AVFilterContext *ctx, s->stop_found_periods = 0; if (s->stop_found_periods >= 0 || ctx->is_disabled) { - if (s->found_nonsilence) { + if (s->found_nonsilence) s->stop_sample_count += stop_thres; - s->stop_sample_count *= stop_thres; - } } else if (s->stop_silence_count > 0) { const int dst_pos = out_nb_samples * nb_channels; for (int ch = 0; ch < nb_channels; ch++)