Browse code

avfilter/af_agate: add level_sc option for sidechaingate filter

Also correct usage of input gain for both filters.

Signed-off-by: Paul B Mahol <onemda@gmail.com>

Paul B Mahol authored on 2015/12/03 17:55:30
Showing 2 changed files
... ...
@@ -2656,6 +2656,9 @@ Default is peak. Can be peak or rms.
2656 2656
 Choose if the average level between all channels or the louder channel affects
2657 2657
 the reduction.
2658 2658
 Default is average. Can be average or maximum.
2659
+
2660
+@item level_sc
2661
+Set sidechain gain. Default is 1. Range is from 0.015625 to 64.
2659 2662
 @end table
2660 2663
 
2661 2664
 @section silencedetect
... ...
@@ -35,6 +35,7 @@ typedef struct AudioGateContext {
35 35
     const AVClass *class;
36 36
 
37 37
     double level_in;
38
+    double level_sc;
38 39
     double attack;
39 40
     double release;
40 41
     double threshold;
... ...
@@ -74,6 +75,7 @@ static const AVOption options[] = {
74 74
     { "link",      "set link",               OFFSET(link),      AV_OPT_TYPE_INT,    {.i64=0},           0,    1, A, "link" },
75 75
     {   "average", 0,                        0,                 AV_OPT_TYPE_CONST,  {.i64=0},           0,    0, A, "link" },
76 76
     {   "maximum", 0,                        0,                 AV_OPT_TYPE_CONST,  {.i64=1},           0,    0, A, "link" },
77
+    { "level_sc",  "set sidechain gain",     OFFSET(level_sc),  AV_OPT_TYPE_DOUBLE, {.dbl=1},           0.015625,   64, A },
77 78
     { NULL }
78 79
 };
79 80
 
... ...
@@ -158,27 +160,25 @@ static double output_gain(double lin_slope, double ratio, double thres,
158 158
     return 1.;
159 159
 }
160 160
 
161
-static void gate(AudioGateContext *s, const double *src, double *dst, const double *scsrc,
162
-                 int nb_samples, AVFilterLink *inlink, AVFilterLink *sclink)
161
+static void gate(AudioGateContext *s,
162
+                 const double *src, double *dst, const double *scsrc,
163
+                 int nb_samples, double level_in, double level_sc,
164
+                 AVFilterLink *inlink, AVFilterLink *sclink)
163 165
 {
164 166
     const double makeup = s->makeup;
165 167
     const double attack_coeff = s->attack_coeff;
166 168
     const double release_coeff = s->release_coeff;
167
-    const double level_in = s->level_in;
168 169
     int n, c;
169 170
 
170 171
     for (n = 0; n < nb_samples; n++, src += inlink->channels, dst += inlink->channels, scsrc += sclink->channels) {
171
-        double abs_sample = fabs(scsrc[0]), gain = 1.0;
172
-
173
-        for (c = 0; c < inlink->channels; c++)
174
-            dst[c] = src[c] * level_in;
172
+        double abs_sample = fabs(scsrc[0] * level_sc), gain = 1.0;
175 173
 
176 174
         if (s->link == 1) {
177 175
             for (c = 1; c < sclink->channels; c++)
178
-                abs_sample = FFMAX(fabs(scsrc[c]), abs_sample);
176
+                abs_sample = FFMAX(fabs(scsrc[c] * level_sc), abs_sample);
179 177
         } else {
180 178
             for (c = 1; c < sclink->channels; c++)
181
-                abs_sample += fabs(scsrc[c]);
179
+                abs_sample += fabs(scsrc[c] * level_sc);
182 180
 
183 181
             abs_sample /= sclink->channels;
184 182
         }
... ...
@@ -193,7 +193,7 @@ static void gate(AudioGateContext *s, const double *src, double *dst, const doub
193 193
                                s->lin_knee_stop, s->range);
194 194
 
195 195
         for (c = 0; c < inlink->channels; c++)
196
-            dst[c] *= gain * makeup;
196
+            dst[c] = src[c] * level_in * gain * makeup;
197 197
     }
198 198
 }
199 199
 
... ...
@@ -218,7 +218,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
218 218
     }
219 219
     dst = (double *)out->data[0];
220 220
 
221
-    gate(s, src, dst, src, in->nb_samples, inlink, inlink);
221
+    gate(s, src, dst, src, in->nb_samples,
222
+         s->level_in, s->level_in, inlink, inlink);
222 223
 
223 224
     if (out != in)
224 225
         av_frame_free(&in);
... ...
@@ -284,6 +285,7 @@ static int scfilter_frame(AVFilterLink *link, AVFrame *in)
284 284
     scsrc = (const double *)s->input_frame[1]->data[0];
285 285
 
286 286
     gate(s, sample, sample, scsrc, nb_samples,
287
+         s->level_in, s->level_sc,
287 288
          ctx->inputs[0], ctx->inputs[1]);
288 289
     ret = ff_filter_frame(outlink, s->input_frame[0]);
289 290