summaryrefslogtreecommitdiff
path: root/libavfilter/af_stereotools.c
diff options
context:
space:
mode:
authorPaul B Mahol <onemda@gmail.com>2017-05-15 19:56:55 +0200
committerPaul B Mahol <onemda@gmail.com>2017-05-15 19:58:15 +0200
commit9bebad86c7f8736f3534ece22cd8095059e2560d (patch)
tree59142f017e4785e58729a18660b6a018f99c6ebf /libavfilter/af_stereotools.c
parent88896c46196e4cca2afa6df6e2bc37ecfc2c4e98 (diff)
avfilter/af_stereotools: introduce different balance modes
Signed-off-by: Paul B Mahol <onemda@gmail.com>
Diffstat (limited to 'libavfilter/af_stereotools.c')
-rw-r--r--libavfilter/af_stereotools.c54
1 files changed, 49 insertions, 5 deletions
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;