History

avfilter/af_adynamicequalizer: add auto option

Paul B Mahol committed 3 years ago

Commit 40512db1 parent 6869a802 files · +42 −6Browse files

Unified · Split

2 files
  1. doc/filters.texi +18 −2
  2. libavfilter/af_adynamicequalizer.c +24 −4
doc/filters.texi+18−2
@@ -1034,11 +1034,27 @@ Default type is @samp{bell}. · 1033 unmodified lines
1034Set processing direction relative to threshold.1034Set processing direction relative to threshold.
1035@table @samp1035@table @samp
1036@item downward1036@item downward
1037Boost or cut if threshhold is higher than detected volume.1037Boost/Cut if threshold is higher/lower than detected volume.
1038@item upward1038@item upward
1039Boost or cut if threshhold is lower than detected volume.1039Boost/Cut if threshold is lower/higher than detected volume.
1040@end table1040@end table
1041Default direction is @samp{downward}.1041Default direction is @samp{downward}.
1042
1043@item auto
1044Automatically gather threshold from detection filter. By default
1045is @samp{disabled}.
1046This option is useful to detect threshold in certain time frame of
1047input audio stream, in such case option value is changed at runtime.
1048
1049Available values are:
1050@table @samp
1051@item disabled
1052Disable using automatically gathered threshold value.
1053@item off
1054Stop picking threshold value.
1055@item on
1056Start picking threshold value.
1057@end table
1042@end table1058@end table
1043 1059
1044@subsection Commands1060@subsection Commands
libavfilter/af_adynamicequalizer.c+24−4
@@ -40,6 +40,7 @@ typedef struct AudioDynamicEqualizerContext { · 39 unmodified lines
40 double release_coef;40 double release_coef;
41 int mode;41 int mode;
42 int direction;42 int direction;
43 int detection;
43 int type;44 int type;
44 45
45 AVFrame *state;46 AVFrame *state;
@@ -92,7 +93,6 @@ static int filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo · 46 unmodified lines
92 const double range = s->range;93 const double range = s->range;
93 const double dfrequency = fmin(s->dfrequency, sample_rate * 0.5);94 const double dfrequency = fmin(s->dfrequency, sample_rate * 0.5);
94 const double tfrequency = fmin(s->tfrequency, sample_rate * 0.5);95 const double tfrequency = fmin(s->tfrequency, sample_rate * 0.5);
95 const double threshold = s->threshold;
96 const double release = s->release_coef;96 const double release = s->release_coef;
97 const double irelease = 1. - release;97 const double irelease = 1. - release;
98 const double attack = s->attack_coef;98 const double attack = s->attack_coef;
@@ -103,6 +103,7 @@ static int filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo · 4 unmodified lines
103 const double dg = tan(M_PI * dfrequency / sample_rate);103 const double dg = tan(M_PI * dfrequency / sample_rate);
104 const int start = (in->ch_layout.nb_channels * jobnr) / nb_jobs;104 const int start = (in->ch_layout.nb_channels * jobnr) / nb_jobs;
105 const int end = (in->ch_layout.nb_channels * (jobnr+1)) / nb_jobs;105 const int end = (in->ch_layout.nb_channels * (jobnr+1)) / nb_jobs;
106 const int detection = s->detection;
106 const int direction = s->direction;107 const int direction = s->direction;
107 const int mode = s->mode;108 const int mode = s->mode;
108 const int type = s->type;109 const int type = s->type;
@@ -124,6 +125,10 @@ static int filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo · 15 unmodified lines
124 const double *src = (const double *)in->extended_data[ch];125 const double *src = (const double *)in->extended_data[ch];
125 double *dst = (double *)out->extended_data[ch];126 double *dst = (double *)out->extended_data[ch];
126 double *state = (double *)s->state->extended_data[ch];127 double *state = (double *)s->state->extended_data[ch];
128 const double threshold = detection == 0 ? state[5] : s->threshold;
129
130 if (detection < 0)
131 state[5] = threshold;
127 132
128 for (int n = 0; n < out->nb_samples; n++) {133 for (int n = 0; n < out->nb_samples; n++) {
129 double detect, gain, v, listen;134 double detect, gain, v, listen;
@@ -133,6 +138,9 @@ static int filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo · 3 unmodified lines
133 detect = listen = get_svf(src[n], dm, da, state);138 detect = listen = get_svf(src[n], dm, da, state);
134 detect = fabs(detect);139 detect = fabs(detect);
135 140
141 if (detection > 0)
142 state[5] = fmax(state[5], detect);
143
136 if (direction == 0 && mode == 0 && detect < threshold)144 if (direction == 0 && mode == 0 && detect < threshold)
137 detect = 1. / av_clipd(1. + makeup + (threshold - detect) * ratio, 1., range);145 detect = 1. / av_clipd(1. + makeup + (threshold - detect) * ratio, 1., range);
138 else if (direction == 0 && mode == 1 && detect < threshold)146 else if (direction == 0 && mode == 1 && detect < threshold)
@@ -144,10 +152,18 @@ static int filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo · 5 unmodified lines
144 else152 else
145 detect = 1.;153 detect = 1.;
146 154
147 if (detect < state[4]) {155 if (direction == 0) {
148 detect = iattack * detect + attack * state[4];156 if (detect > state[4]) {
157 detect = iattack * detect + attack * state[4];
158 } else {
159 detect = irelease * detect + release * state[4];
160 }
149 } else {161 } else {
150 detect = irelease * detect + release * state[4];162 if (detect < state[4]) {
163 detect = iattack * detect + attack * state[4];
164 } else {
165 detect = irelease * detect + release * state[4];
166 }
151 }167 }
152 168
153 if (state[4] != detect || n == 0) {169 if (state[4] != detect || n == 0) {
@@ -270,6 +286,10 @@ static const AVOption adynamicequalizer_options[] = { · 116 unmodified lines
270 { "direction", "set direction", OFFSET(direction), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, "direction" },286 { "direction", "set direction", OFFSET(direction), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, "direction" },
271 { "downward", 0, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "direction" },287 { "downward", 0, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "direction" },
272 { "upward", 0, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "direction" },288 { "upward", 0, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "direction" },
289 { "auto", "set auto threshold", OFFSET(detection), AV_OPT_TYPE_INT, {.i64=-1}, -1, 1, FLAGS, "auto" },
290 { "disabled", 0, 0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, FLAGS, "auto" },
291 { "off", 0, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "auto" },
292 { "on", 0, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "auto" },
273 { NULL }293 { NULL }
274};294};
275 295

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