Page 1 of 1

Surround Sound Matrix encoding (dolby compatible)

Posted: Wed Mar 15, 2006 3:36 am
by Rescator
Code updated For 5.20+

Briefly explained:
The routine below is the core math that you would use to surround encode
from 5 seperate sound channels/samples to 2 channel stereo.

For more info check http://en.wikipedia.org/wiki/Dolby_Pro_Logic and related articles.
BeSweet and a lot of other tools use similar routines.
http://forum.doom9.org/showthread.php?s=&threadid=27936

Code: Select all

;http://en.wikipedia.org/wiki/Dolby_Pro_Logic
;http://forum.doom9.org/showthread.php?s=&threadid=27936

;surround matrix encoder
;compatible with Dolby Surround/Dolby Pro Logic, Dolby Pro Logic II
;SRS, dts:Neo, Circle Surround, Circle Surround II, Sensaura, and so on.

;convert the sample points to float or doubles (or just float but do math as doubles)

;1.0 is max positive sample point
;-1.0 is max negative sample point
;0.0 is silence (infinity)

;to convert 16bit where max/min sample points are 32767 to -32768
;for positive numbers do l.f=32767/32767
;and for negatives numbers do l.f=-32768/-32768

;To convert back from float to 16bit
;for positives nunbers do left.w=dlt*32767
;and for negatives numbersdo left.w=dlt*-32768

;If you plan to further process the audio,
;it might be wise to store it on disk as float instead.
;32bit float samples with a range of 1.0 to -1.0 is known as normalized float
;(Wave float type 3 stores it same wey if I remember correctly).
;Some software may even support wavs or raw pcm with 64bit/doubles.
 

;dl is left
;dr is right
;dc is center

;dsl is left surround
;dsr is right surround

;dlt is left total (the result)
;drt is right total (the result)

Define.d dl,dr,dc,dsl,dsr,dlt,drt

;EmSai Surround, (C) EmSai, Roger Hågensen 2006
dl.d=1.0
dr.d=1.0
dc.d=1.0
dsl.d=1.0
dsr.d=1.0

dlt=((-dsl)+(-0.70710678118654757*(dsr*0.5))+dl+(dc*0.5))*0.35044026276028173
drt=((dsr)+(0.70710678118654757*(dsl*0.5))+dr+(dc*0.5))*0.35044026276028173

Debug dlt
Debug drt
Ok! Now the math seems to work as intended.

Note! The coefficients used are derived from myself,
Dolby nor any of the other surround technology companies has released the exact info needed to replicate their tech.
If you use the above math I'd prefer to be credited somewhere,
other than that consider the code to be free for any use, including commercial.

Also, my math result in a much louder result,
that is, if all the 5 inputs are at maximum (1.0) then the output will also be
the same, so there should be no need to correct the volume before or after, it is part of the routine itself.
Other routines tend to end up with a lower level,
my philosphy is that if all the input it cranked to the max, so should the output be.

PS! one of the channels will seem to be limping if the surround input channels has sound in them, this is intentional. And caused by the phase.

Note! if the input values is above 1.0 then the output might also end up above 1.0
So make sure that the input is in the valid -1.0 to 1.0 range.

For more speed you could use single precision floats rather than doubles,
obviously the precision will be lower, but still good though.
The math will not need to be changed wether you use singles or doubles.

Posted: Wed Mar 15, 2006 8:50 am
by blueznl
euh, don't get it, are you saying this code is turning any normal stereo signal into a dolby surrond (3d) signal?

Posted: Wed Mar 15, 2006 10:26 am
by KarLKoX
No, Dolby Surround is not 3D sound, you will have to use the HRTF (read this) to achieve this, here, the signal is sent to the appropriate speaker to simulate a multichannel sound.
Btw, nice code :)

Posted: Thu Mar 16, 2006 1:32 pm
by Rescator
Ok, first post updated!

Hey KarLKoX was it you that where working on a sound editing program?
Maybe try this routine with that?

I'm working on a Matrixing and also a passive dematrixing tool,
but it's going to be a while until they are finished, and they will be using BASS.dll for sound loading/streaming as I do not have any WAV reading code myself yet. (I know PB does but that is full reads only, not stream reads)

Also I found this rather cool plugin for winamp etc.
http://www.andrewlabs.com/atsurround/downloads.php
It allows winamp to decode (de-matrix) 2ch to 5ch (the reverse of my routine) so it should be easy to test.

Other software that has surround dematrix ability should be various DVD and media players like PowerDVD, creatives Audigy drivers has similar features too.

The final goal for me and this routine is a ASM loop implementation unless someone beats me to it :P
My guess is that using singles and ASM would give the most speed.

Posted: Thu Mar 16, 2006 4:48 pm
by KarLKoX
Yeah, this is a must have for a sound editing tool, i ve seen a surround matrix sound wich works quite well inside the MPlayer sourcecode :)

Posted: Thu Mar 16, 2006 6:26 pm
by Rescator
I actually made my first surround decoding speaker setup myself by hand, on the Amiga no less.

You need 4 speakers, preferably same make and model.
And this is how you do it.

Code: Select all

Left               Right
Output             Output

+ & - cable        + & - cable
Left front         Right front
speaker            speaker
  |                  |
  |                  |
 - cable           + cable
Left rear          Right rear
speaker            speaker
  |                  |
  |                  |
  + cable  ------  - cable
That's it, you've now hooked up
what is comparable to a
Passive Surround decoder.

Left speaker is hooked up normaly,
right speaker is hooked up normally.

The - cable from left speaker is connected to
the - connector on the left surround speaker.

The + cable from right speaker is connected to
the + connector on the right surround speaker.

Now just connect a cable between the two surround
speakers, connecting the cable to the two connectors
that are "free".

The interesting thing here is that as the audio signal
passes "through" the surround speakers it is phase rotated
by 180 degrees, but since the opposite poles/connectors
of the surround speakers are connected to each other.
the cable between them becomes in phase,
and forces the surround speakers to create sound
that is 90 degrees out of phase of the other surround speaker.

This is very rudimentary, and a passive matrix decoder
does not match even the simplest dolby pro logic.
(well, maybe the very first dolby implementation)


For a optimal setup all cable lengths should be equal in length obviously,
and same thickness and type of cable.


For electronic wizards out there you might want to add a delay circuit
between the left speaker and surround left,
and between right speaker and right surround speaker.
Use a delay of aprox. 15ms for both circuits.

And if you truly wish to match the behaviour of classic dolby surround,
add a lowpass filter with a cutoff around 7khz to the two circuits.
Altough I do not really see the point in the filter,
Dolby Prologic II no longer does this and passes full bandwidth to the surround.

And that's all there is to it, you've made a passive surround decoder. wow!
At the fraction of the cost of a commercial one.
The cool thing is, that any stereo recordings,
even if they where not surround matrix encoded will actualy have
sounds coming out your surround speakers.


There will obviously be some "leakage" between the speakers since it's passive.
But you will get that "cool" surround feel when listing to music, watching movies
or playing games.

If you drop the circuit, and the speakers do not require soldering of wires.
You can easily do all this by simply connecting cables.

Obviously it would be best if you got a amplifier with 4 speakers outputs.
Usually labeled as A and B outputs.
Since you can then more easily adjust the volume
for A (front speakers) and B (rear speakers).
The sound might be a tad cleaner as well as you wil be using a seperate
feed for the surrounds. (but the hookup will be similar to the example above)