diff options
author | Paul B Mahol <onemda@gmail.com> | 2017-05-15 19:56:55 +0200 |
---|---|---|
committer | Paul B Mahol <onemda@gmail.com> | 2017-05-15 19:58:15 +0200 |
commit | 9bebad86c7f8736f3534ece22cd8095059e2560d (patch) | |
tree | 59142f017e4785e58729a18660b6a018f99c6ebf | |
parent | 88896c46196e4cca2afa6df6e2bc37ecfc2c4e98 (diff) | |
download | ffmpeg-9bebad86c7f8736f3534ece22cd8095059e2560d.tar.gz |
avfilter/af_stereotools: introduce different balance modes
Signed-off-by: Paul B Mahol <onemda@gmail.com>
-rw-r--r-- | doc/filters.texi | 17 | ||||
-rw-r--r-- | libavfilter/af_stereotools.c | 54 |
2 files changed, 66 insertions, 5 deletions
diff --git a/doc/filters.texi b/doc/filters.texi index 0ea4e26998..a86127f261 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -3669,6 +3669,23 @@ Set S/C level. Default is 1. Allowed range is from 1 to 100. @item phase Set the stereo phase in degrees. Default is 0. Allowed range is from 0 to 360. + +@item bmode_in, bmode_out +Set balance mode for balance_in/balance_out option. + +Can be one of the following: + +@table @samp +@item balance +Classic balance mode. Attenuate one channel at time. +Gain is raised up to 1. + +@item amplitude +Similar as classic mode above but gain is raised up to 2. + +@item power +Equal power distribution, from -6dB to +6dB range. +@end table @end table @subsection Examples diff --git a/libavfilter/af_stereotools.c b/libavfilter/af_stereotools.c index 8ab184df11..2d2a9bd625 100644 --- a/libavfilter/af_stereotools.c +++ b/libavfilter/af_stereotools.c @@ -33,6 +33,8 @@ typedef struct StereoToolsContext { int phase_l; int phase_r; int mode; + int bmode_in; + int bmode_out; double slev; double sbal; double mlev; @@ -83,6 +85,11 @@ static const AVOption stereotools_options[] = { { "delay", "set delay", OFFSET(delay), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -20, 20, A }, { "sclevel", "set S/C level", OFFSET(sc_level), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 1, 100, A }, { "phase", "set stereo phase", OFFSET(phase), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, 360, A }, + { "bmode_in", "set balance in mode", OFFSET(bmode_in), AV_OPT_TYPE_INT, {.i64=0}, 0, 2, A, "bmode" }, + { "balance", 0, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, A, "bmode" }, + { "amplitude", 0, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, A, "bmode" }, + { "power", 0, 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, A, "bmode" }, + { "bmode_out", "set balance out mode", OFFSET(bmode_out), AV_OPT_TYPE_INT, {.i64=0}, 0, 2, A, "bmode" }, { NULL } }; @@ -167,13 +174,31 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) dst = (double *)out->data[0]; for (n = 0; n < in->nb_samples; n++, src += 2, dst += 2) { - double L = src[0], R = src[1], l, r, m, S; + double L = src[0], R = src[1], l, r, m, S, gl, gr, gd; L *= level_in; R *= level_in; - L *= 1. - FFMAX(0., balance_in); - R *= 1. + FFMIN(0., balance_in); + gl = 1. - FFMAX(0., balance_in); + gr = 1. + FFMIN(0., balance_in); + switch (s->bmode_in) { + case 1: + gd = gl - gr; + gl = 1. + gd; + gr = 1. - gd; + break; + case 2: + if (balance_in < 0.) { + gr = FFMAX(0.5, gr); + gl = 1. / gr; + } else if (balance_in > 0.) { + gl = FFMAX(0.5, gl); + gr = 1. / gl; + } + break; + } + L *= gl; + R *= gr; if (s->softclip) { R = s->inv_atan_shape * atan(R * sc_level); @@ -253,8 +278,27 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) s->pos = (s->pos + 2) % s->length; - L *= 1. - FFMAX(0., balance_out); - R *= 1. + FFMIN(0., balance_out); + gl = 1. - FFMAX(0., balance_out); + gr = 1. + FFMIN(0., balance_out); + switch (s->bmode_out) { + case 1: + gd = gl - gr; + gl = 1. + gd; + gr = 1. - gd; + break; + case 2: + if (balance_out < 0.) { + gr = FFMAX(0.5, gr); + gl = 1. / gr; + } else if (balance_out > 0.) { + gl = FFMAX(0.5, gl); + gr = 1. / gl; + } + break; + } + L *= gl; + R *= gr; + L *= level_out; R *= level_out; |