History

avfilter/af_dynaudnorm: allow to filter subset of channels

Paul B Mahol committed 4 years ago

Commit a9124a71 parent b9f91a72 files · +24 −4Browse files

Unified · Split

2 files
  1. doc/filters.texi +3 −0
  2. libavfilter/af_dynaudnorm.c +21 −4
doc/filters.texi+3−0
@@ -4389,6 +4389,9 @@ If input frame volume is above this value frame will be normalized. · 4388 unmodified lines
43894389 Otherwise frame may not be normalized at all. The default value is set
43904390 to 0, which means all input frames will be normalized.
43914391 This option is mostly useful if digital noise is not wanted to be amplified.
4392+
4393+@item channels, h
4394+Specify which channels to filter, by default all available channels are filtered.
43924395 @end table
43934396
43944397 @subsection Commands
libavfilter/af_dynaudnorm.c+21−4
@@ -27,6 +27,7 @@ · 26 unmodified lines
2727 #include <float.h>
2828
2929 #include "libavutil/avassert.h"
30+#include "libavutil/channel_layout.h"
3031 #include "libavutil/opt.h"
3132
3233 #define MIN_FILTER_SIZE 3
@@ -76,6 +77,7 @@ typedef struct DynamicAudioNormalizerContext { · 43 unmodified lines
7677
7778 int channels;
7879 int eof;
80+ uint64_t channels_to_filter;
7981 int64_t pts;
8082
8183 cqueue **gain_history_original;
@@ -110,6 +112,8 @@ static const AVOption dynaudnorm_options[] = { · 28 unmodified lines
110112 { "s", "set the compress factor", OFFSET(compress_factor), AV_OPT_TYPE_DOUBLE, {.dbl = 0.0}, 0.0, 30.0, FLAGS },
111113 { "threshold", "set the threshold value", OFFSET(threshold), AV_OPT_TYPE_DOUBLE, {.dbl = 0.0}, 0.0, 1.0, FLAGS },
112114 { "t", "set the threshold value", OFFSET(threshold), AV_OPT_TYPE_DOUBLE, {.dbl = 0.0}, 0.0, 1.0, FLAGS },
115+ { "channels", "set channels to filter", OFFSET(channels_to_filter),AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS },
116+ { "h", "set channels to filter", OFFSET(channels_to_filter),AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS },
113117 { NULL }
114118 };
115119
@@ -514,6 +518,11 @@ static inline double update_value(double new, double old, double aggressiveness) · 398 unmodified lines
514518 return aggressiveness * new + (1.0 - aggressiveness) * old;
515519 }
516520
521+static inline int bypass_channel(DynamicAudioNormalizerContext *s, AVFrame *frame, int ch)
522+{
523+ return !(av_channel_layout_extract_channel(frame->channel_layout, ch) & s->channels_to_filter);
524+}
525+
517526 static void perform_dc_correction(DynamicAudioNormalizerContext *s, AVFrame *frame)
518527 {
519528 const double diff = 1.0 / frame->nb_samples;
@@ -521,6 +530,7 @@ static void perform_dc_correction(DynamicAudioNormalizerContext *s, AVFrame *fra · 1 unmodified line
521530 int c, i;
522531
523532 for (c = 0; c < s->channels; c++) {
533+ const int bypass = bypass_channel(s, frame, c);
524534 double *dst_ptr = (double *)frame->extended_data[c];
525535 double current_average_value = 0.0;
526536 double prev_value;
@@ -531,7 +541,7 @@ static void perform_dc_correction(DynamicAudioNormalizerContext *s, AVFrame *fra · 4 unmodified lines
531541 prev_value = is_first_frame ? current_average_value : s->dc_correction_value[c];
532542 s->dc_correction_value[c] = is_first_frame ? current_average_value : update_value(current_average_value, s->dc_correction_value[c], 0.1);
533543
534− for (i = 0; i < frame->nb_samples; i++) {
544+ for (i = 0; i < frame->nb_samples && !bypass; i++) {
535545 dst_ptr[i] -= fade(prev_value, s->dc_correction_value[c], i, frame->nb_samples);
536546 }
537547 }
@@ -604,6 +614,11 @@ static void perform_compression(DynamicAudioNormalizerContext *s, AVFrame *frame · 66 unmodified lines
604614
605615 for (c = 0; c < s->channels; c++) {
606616 double *const dst_ptr = (double *)frame->extended_data[c];
617+ const int bypass = bypass_channel(s, frame, c);
618+
619+ if (bypass)
620+ continue;
621+
607622 for (i = 0; i < frame->nb_samples; i++) {
608623 const double localThresh = fade(prev_actual_thresh, curr_actual_thresh, i, frame->nb_samples);
609624 dst_ptr[i] = copysign(bound(localThresh, fabs(dst_ptr[i])), dst_ptr[i]);
@@ -611,19 +626,20 @@ static void perform_compression(DynamicAudioNormalizerContext *s, AVFrame *frame · 1 unmodified line
611626 }
612627 } else {
613628 for (c = 0; c < s->channels; c++) {
629+ const int bypass = bypass_channel(s, frame, c);
614630 const double standard_deviation = compute_frame_std_dev(s, frame, c);
615631 const double current_threshold = setup_compress_thresh(FFMIN(1.0, s->compress_factor * standard_deviation));
616−
617632 const double prev_value = is_first_frame ? current_threshold : s->compress_threshold[c];
618633 double prev_actual_thresh, curr_actual_thresh;
619634 double *dst_ptr;
635+
620636 s->compress_threshold[c] = is_first_frame ? current_threshold : update_value(current_threshold, s->compress_threshold[c], 1.0/3.0);
621637
622638 prev_actual_thresh = setup_compress_thresh(prev_value);
623639 curr_actual_thresh = setup_compress_thresh(s->compress_threshold[c]);
624640
625641 dst_ptr = (double *)frame->extended_data[c];
626− for (i = 0; i < frame->nb_samples; i++) {
642+ for (i = 0; i < frame->nb_samples && !bypass; i++) {
627643 const double localThresh = fade(prev_actual_thresh, curr_actual_thresh, i, frame->nb_samples);
628644 dst_ptr[i] = copysign(bound(localThresh, fabs(dst_ptr[i])), dst_ptr[i]);
629645 }
@@ -668,13 +684,14 @@ static void amplify_frame(DynamicAudioNormalizerContext *s, AVFrame *in, · 38 unmodified lines
668684 int c, i;
669685
670686 for (c = 0; c < s->channels; c++) {
687+ const int bypass = bypass_channel(s, frame, c);
671688 const double *src_ptr = (const double *)in->extended_data[c];
672689 double *dst_ptr = (double *)frame->extended_data[c];
673690 double current_amplification_factor;
674691
675692 cqueue_dequeue(s->gain_history_smoothed[c], &current_amplification_factor);
676693
677− for (i = 0; i < frame->nb_samples && enabled; i++) {
694+ for (i = 0; i < frame->nb_samples && enabled && !bypass; i++) {
678695 const double amplification_factor = fade(s->prev_amplification_factor[c],
679696 current_amplification_factor, i,
680697 frame->nb_samples);

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