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.
This commit is contained in:
Paul B Mahol 2023-05-27 13:59:24 +02:00
parent 8d662adcc9
commit e8e4863325
3 changed files with 50 additions and 18 deletions

View File

@ -6419,15 +6419,16 @@ trimming. Default is 0, which is equal to trimming all samples detected
as silence. as silence.
@item start_mode @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}. Can be @var{any} or @var{all}. Default is @var{any}.
With @var{any}, any sample that is detected as non-silence will cause With @var{any}, any sample from any channel that is detected as non-silence
stopped trimming of silence. will trigger end of silence trimming at start of audio stream.
With @var{all}, only if all channels are detected as non-silence will cause With @var{all}, only if every sample from every channel is detected as non-silence
stopped trimming of silence. will trigger end of silence trimming at start of audio stream, limited usage.
@item stop_periods @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} 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 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 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. as silence.
@item stop_mode @item stop_mode
Specify mode of detection of silence start in end of multi-channel audio. Specify mode of detection of silence start after start of multi-channel audio.
Can be @var{any} or @var{all}. Default is @var{any}. Can be @var{any} or @var{all}. Default is @var{all}.
With @var{any}, any sample that is detected as non-silence will cause With @var{any}, any sample from any channel that is detected as silence
stopped trimming of silence. will trigger start of silence trimming after start of audio stream, limited usage.
With @var{all}, only if all channels are detected as non-silence will cause With @var{all}, only if every sample from every channel is detected as silence
stopped trimming of silence. will trigger start of silence trimming after start of audio stream.
@item detection @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}. Default value is @code{rms}.
@item window @item window
Set duration in number of seconds used to calculate size of window in number 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}. Default value is @code{0.02}. Allowed range is from @code{0} to @code{10}.
@end table @end table
@ -6495,6 +6510,25 @@ silence is detected in all channels at same positions in stream:
@example @example
silenceremove=window=0:detection=peak:stop_mode=all:start_mode=all:stop_periods=-1:stop_threshold=0 silenceremove=window=0:detection=peak:stop_mode=all:start_mode=all:stop_periods=-1:stop_threshold=0
@end example @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 @end itemize
@subsection Commands @subsection Commands

View File

@ -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_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_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_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" }, { "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" }, { "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" }, { "rms", "use root mean squared values of samples", 0, AV_OPT_TYPE_CONST, {.i64=D_RMS}, 0, 0, AF, "detection" },

View File

@ -403,10 +403,8 @@ static void fn(filter_stop)(AVFilterContext *ctx,
s->stop_found_periods = 0; s->stop_found_periods = 0;
if (s->stop_found_periods >= 0 || ctx->is_disabled) { 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;
s->stop_sample_count *= stop_thres;
}
} else if (s->stop_silence_count > 0) { } else if (s->stop_silence_count > 0) {
const int dst_pos = out_nb_samples * nb_channels; const int dst_pos = out_nb_samples * nb_channels;
for (int ch = 0; ch < nb_channels; ch++) for (int ch = 0; ch < nb_channels; ch++)