# [MPlayer-dev-eng] Re: PATCH 4/5: substract surround from front in pl_surround

Tobias Diedrich td at informatik.uni-hannover.de
Mon Dec 10 19:18:14 CET 2001

```Stephen Davies wrote:

> Hi Tobias,
>
> I don't think this manipulation is OK - remember that, by nature of the
> matrix decoding process, the decoded surround output includes L-R
> crosstalk too.  If you subtract this surround off L and R you will have a
> big effect on the front sound.
>
> This would be OK for a sound strongly to the rear (and, in fact, a Pro
> Logic decoder would do something like this for that case).
>
> The math is as follows:
>
>   The input tracks are
>     Lt = L + (C-3dB) + (S-3dB)
>     Rt = R + (C-3dB) - (S-3dB)
>   Basic decoded outputs are:
>     Lout = Lt
>          = L + (C-3dB) + (S-3dB)
>     Rout = Rt
>          = R + (C-3dB) - (S-3dB)
>     Cout = Lt+Rt
>          = C + L + R
>     Sout = Lt-Rt
>          = S + (L - R)

/me thinks you really want to have Lout/Rout approximate L/R, not be Lt/Rt

(although the original surround circuit would just pass through Lt/Rt,
judging from the information at www.dolby.com)

Ignoring center, the input tracks are

Lt = L + S*0.707 (1)
<=> L = Lt - S*0.707

Rt = R - S*0.707 (2)
<=> R = Rt + S*0.707

For surround (1) - (2) results in:

Lt - Rt = L - R + S*1.5
<=> S = ((Lt - L) - (Rt - R))*0.707

Because we can't calculate this with just Lt and Rt we simplify
this to:

S = (Lt - Rt)*0.707

And for removing Surround from the front channels:

L = Lt - S*0.707
<=> L = Lt - (Lt*0.707 - Rt*0.707)*0.707
<=> L = Lt*0.5 + Rt*0.5

R = Rt + S*0.707
<=> R = Rt + (Lt*0.707 - Rt*0.707)*0.707
<=> R = Rt*0.5 + Lt*0.5

Now this would mean we have downgraded front to mono :-(
But remembering that Surround is supposed to be low-pass filtered,
this is not really true, as mostly the high frequency carry
directional information, whereas you can't locate very low
frequencies.

So if we lowpass-filter the surround signal before substraction,
it might be ok to do it, even though it is still missing the
other pro-logic features.

>   Your manipulation is (using Left as an example):
>     Lout = L + (C-3dB) + (S-3dB) - (S + (L - R))
>          = L + (C-3dB) + (S-3dB) - S - L + R
>          = (C-3dB) - (S-10dB) + R
>
> The output doesn't bear much relation to the input "L".

Well I forgot the .707 scaling and as seen above even with it,
it will not work without the lowpass. Then again, surround just
does mess a whole lot with your signals...

I basically did this because I wanted it to behave a bit more like my
Dolby Prologic Amplifier (Which is in a different room than my computer
system...) to test the effects of pl_invert on the Kenshin DVD.

I probably should not have posted that version, oh well ^^;

But unless you can convince me otherwise, at least this part of the
patch should be applied:

out[2] = pl_surround.delaybuf[pl_surround.delaybuf_ptr];
-    out[3] = -out[2];
+    out[3] = out[2];

Or alternatively (inverted sourround output):

-    out[2] = pl_surround.delaybuf[pl_surround.delaybuf_ptr];
+    out[2] = -pl_surround.delaybuf[pl_surround.delaybuf_ptr];
-    out[3] = -out[2];
+    out[3] = out[2];

Otherwise you output surround to both rear-speakers and one is in
anti-phase to the other, so low frequencies will cancel out each other...

Now, the first attached patch is this bugfix.

The second patch is the alternative version (with inverted surround).

The third patch implements a very simple lowpass filter.
I don't know how to calculate the factor right, 0.3 is a guess...

The fourth patch is the alternatvie version (with inverted surround).

The fifth patch, if you choose to accept it, implements the
surround from front removal (with the 0.707 scalefactor that was
missing). It includes the third patch.

The sixth patch is the alternative version (with inverted surround)
and includes the fourth patch.

--
Tobias								PGP: 0x9AC7E0BC
Hannover Fantreffen ML: mailto:fantreffen-request at mantrha.de?subject=subscribe
Manga & Anime Treff Hannover: http://www.mantrha.de/
-------------- next part --------------
--- main/libao2/pl_surround.c	Mon Dec 10 01:10:47 2001
+++ main-20011210/libao2/pl_surround.c	Mon Dec 10 19:03:53 2001
@@ -176,7 +176,7 @@
// calculate and save surround for 15msecs time
surround = (in[0]/2 - in[1]/2);
pl_surround.delaybuf[pl_surround.delaybuf_ptr++] = surround;
-    pl_surround.delaybuf[pl_surround.delaybuf_ptr++] = - surround;
+    pl_surround.delaybuf[pl_surround.delaybuf_ptr++] = surround;
pl_surround.delaybuf_ptr %= pl_surround.delaybuf_len;
// next samples...
in = &in[pl_surround.input_channels];  out = &out[4];
-------------- next part --------------
--- main/libao2/pl_surround.c	Mon Dec 10 01:10:47 2001
+++ main-20011210/libao2/pl_surround.c	Mon Dec 10 19:05:32 2001
@@ -175,8 +175,8 @@
out[3] = pl_surround.delaybuf[pl_surround.delaybuf_ptr+1];
// calculate and save surround for 15msecs time
surround = (in[0]/2 - in[1]/2);
-    pl_surround.delaybuf[pl_surround.delaybuf_ptr++] = surround;
-    pl_surround.delaybuf[pl_surround.delaybuf_ptr++] = - surround;
+    pl_surround.delaybuf[pl_surround.delaybuf_ptr++] = -surround;
+    pl_surround.delaybuf[pl_surround.delaybuf_ptr++] = -surround;
pl_surround.delaybuf_ptr %= pl_surround.delaybuf_len;
// next samples...
in = &in[pl_surround.input_channels];  out = &out[4];
-------------- next part --------------
--- main/libao2/pl_surround.c	Mon Dec 10 19:12:32 2001
+++ main-20011210/libao2/pl_surround.c	Mon Dec 10 19:13:02 2001
@@ -145,7 +145,7 @@
static int play(){
int16_t *in, *out;
int i, samples;
-  int surround;
+  static int surround;

if (pl_surround.passthrough) return 1;

@@ -174,7 +174,7 @@
out[2] = pl_surround.delaybuf[pl_surround.delaybuf_ptr];
out[3] = pl_surround.delaybuf[pl_surround.delaybuf_ptr+1];
// calculate and save surround for 15msecs time
-    surround = (in[0]/2 - in[1]/2);
+    surround += (surround - (in[0]/2 - in[1]/2)) * 0.3;
pl_surround.delaybuf[pl_surround.delaybuf_ptr++] = surround;
pl_surround.delaybuf[pl_surround.delaybuf_ptr++] = surround;
pl_surround.delaybuf_ptr %= pl_surround.delaybuf_len;
-------------- next part --------------
--- main/libao2/pl_surround.c	Mon Dec 10 19:13:44 2001
+++ main-20011210/libao2/pl_surround.c	Mon Dec 10 19:13:35 2001
@@ -145,7 +145,7 @@
static int play(){
int16_t *in, *out;
int i, samples;
-  int surround;
+  static int surround;

if (pl_surround.passthrough) return 1;

@@ -174,7 +174,7 @@
out[2] = pl_surround.delaybuf[pl_surround.delaybuf_ptr];
out[3] = pl_surround.delaybuf[pl_surround.delaybuf_ptr+1];
// calculate and save surround for 15msecs time
-    surround = (in[0]/2 - in[1]/2);
+    surround += (surround - (in[0]/2 - in[1]/2)) * 0.3;
pl_surround.delaybuf[pl_surround.delaybuf_ptr++] = -surround;
pl_surround.delaybuf[pl_surround.delaybuf_ptr++] = -surround;
pl_surround.delaybuf_ptr %= pl_surround.delaybuf_len;
-------------- next part --------------
--- main/libao2/pl_surround.c	Mon Dec 10 19:10:22 2001
+++ main-20011210/libao2/pl_surround.c	Mon Dec 10 19:09:40 2001
@@ -145,7 +145,7 @@
static int play(){
int16_t *in, *out;
int i, samples;
-  int surround;
+  static int surround;

if (pl_surround.passthrough) return 1;

@@ -167,14 +167,15 @@
//   Trouble is, Lt could be +32767, Rt -32768, so possibility that S will
//   clip.  So to compensate, we cut L/R by 3dB (*.707), and S by 6dB (/2).

+    // calculate surround
+    surround += (surround - (in[0]/2 - in[1]/2)) * 0.3;
// output front left and right
-    out[0] = in[0]*.707;
-    out[1] = in[1]*.707;
+    out[0] = in[0]*.707 - surround*.707;
+    out[1] = in[1]*.707 + surround*.707;
// output Ls and Rs - from 15msec ago
out[2] = pl_surround.delaybuf[pl_surround.delaybuf_ptr];
out[3] = pl_surround.delaybuf[pl_surround.delaybuf_ptr+1];
-    // calculate and save surround for 15msecs time
-    surround = (in[0]/2 - in[1]/2);
+    // save surround for 15msecs time
pl_surround.delaybuf[pl_surround.delaybuf_ptr++] = surround;
pl_surround.delaybuf[pl_surround.delaybuf_ptr++] = surround;
pl_surround.delaybuf_ptr %= pl_surround.delaybuf_len;
-------------- next part --------------
--- main/libao2/pl_surround.c	Mon Dec 10 19:11:32 2001
+++ main-20011210/libao2/pl_surround.c	Mon Dec 10 19:12:04 2001
@@ -145,7 +145,7 @@
static int play(){
int16_t *in, *out;
int i, samples;
-  int surround;
+  static int surround;

if (pl_surround.passthrough) return 1;

@@ -167,14 +167,15 @@
//   Trouble is, Lt could be +32767, Rt -32768, so possibility that S will
//   clip.  So to compensate, we cut L/R by 3dB (*.707), and S by 6dB (/2).

+    // calculate surround
+    surround += (surround - (in[0]/2 - in[1]/2)) * 0.3;
// output front left and right
-    out[0] = in[0]*.707;
-    out[1] = in[1]*.707;
+    out[0] = in[0]*.707 - surround*.707;
+    out[1] = in[1]*.707 + surround*.707;
// output Ls and Rs - from 15msec ago
out[2] = pl_surround.delaybuf[pl_surround.delaybuf_ptr];
out[3] = pl_surround.delaybuf[pl_surround.delaybuf_ptr+1];
-    // calculate and save surround for 15msecs time
-    surround = (in[0]/2 - in[1]/2);
+    // save surround for 15msecs time
pl_surround.delaybuf[pl_surround.delaybuf_ptr++] = -surround;
pl_surround.delaybuf[pl_surround.delaybuf_ptr++] = -surround;
pl_surround.delaybuf_ptr %= pl_surround.delaybuf_len;
```