mirror of https://github.com/PCSX2/pcsx2.git
SPU2-X: Improved dplII decoder algorithm, it now generates more defined positional balance.
It's still most probably very wrong, but its sounding nice at least. ;P git-svn-id: http://pcsx2.googlecode.com/svn/trunk@4860 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
a4a40441c9
commit
08b2cac8aa
|
@ -22,9 +22,8 @@ static const u8 sLogTable[256] = {
|
|||
static float Gfl=0,Gfr=0;
|
||||
static float LMax=0,RMax=0;
|
||||
|
||||
static float LAccum=0;
|
||||
static float RAccum=0;
|
||||
static s32 ANum=0;
|
||||
static float AccL=0;
|
||||
static float AccR=0;
|
||||
|
||||
const float Scale = 4294967296.0f; // tweak this value to change the overall output volume
|
||||
|
||||
|
@ -46,61 +45,52 @@ extern void ResetDplIIDecoder()
|
|||
Gfr=0;
|
||||
LMax=0;
|
||||
RMax=0;
|
||||
LAccum=0;
|
||||
RAccum=0;
|
||||
ANum=0;
|
||||
AccL=0;
|
||||
AccR=0;
|
||||
}
|
||||
|
||||
void ProcessDplIISample32( const StereoOut32& src, Stereo51Out32DplII * s)
|
||||
{
|
||||
float ValL = src.Left / (float)(1<<(SndOutVolumeShift+16));
|
||||
float ValR = src.Right / (float)(1<<(SndOutVolumeShift+16));
|
||||
float IL = src.Left / (float)(1<<(SndOutVolumeShift+16));
|
||||
float IR = src.Right / (float)(1<<(SndOutVolumeShift+16));
|
||||
|
||||
float XL = abs(ValL);
|
||||
float XR = abs(ValR);
|
||||
// Calculate center channel and LFE
|
||||
float C = (IL+IR) * 0.5f;
|
||||
float SUB = C; // no need to lowpass, the speaker amplifier should take care of it
|
||||
|
||||
if(XL>LMax) LMax = XL; // 23
|
||||
if(XR>RMax) RMax = XR;
|
||||
float L = IL - C; // Effective L/R data
|
||||
float R = IR - C;
|
||||
|
||||
ANum++;
|
||||
if(ANum>=128)
|
||||
{
|
||||
ANum=0;
|
||||
LAccum = (LAccum * 0.9f + LMax * 0.1f);
|
||||
RAccum = (RAccum * 0.9f + RMax * 0.1f);
|
||||
// Peak L/R
|
||||
float PL = abs(L);
|
||||
float PR = abs(R);
|
||||
|
||||
LMax = 0;
|
||||
RMax = 0;
|
||||
AccL += (PL-AccL)*0.1f;
|
||||
AccR += (PR-AccR)*0.1f;
|
||||
|
||||
// Calculate power balance
|
||||
float Balance = (AccR-AccL); // -1 .. 1
|
||||
|
||||
float Tfl=RAccum/std::max(1.0f,LAccum);
|
||||
float Tfr=LAccum/std::max(1.0f,RAccum);
|
||||
// If the power levels are different, then the audio is meant for the front speakers
|
||||
float Frontness = abs(Balance);
|
||||
float Rearness = 1-Frontness; // And the other way around
|
||||
|
||||
float gMax = std::max(1.0f,std::max(Tfl,Tfr));
|
||||
Tfl = Tfl/gMax;
|
||||
Tfr = Tfr/gMax;
|
||||
// Equalize the power levels for L/R
|
||||
float B = std::min(0.5f,std::max(-0.5f,Balance));
|
||||
|
||||
if(Tfl<0.00001f) Tfl=0.00001f;
|
||||
if(Tfr<0.00001f) Tfr=0.00001f;
|
||||
float VL = L / (1-B); // if B>0, it means R>L, so increase L, else decrease L
|
||||
float VR = R / (1+B); // vice-versa
|
||||
|
||||
Gfl = Gfl * 0.78f + Tfl * 0.22f;
|
||||
Gfr = Gfr * 0.78f + Tfr * 0.22f;
|
||||
}
|
||||
// 1.73+1.22 = 2.94; 2.94 = 0.34 = 0.9996; Close enough... xcept VL/VR are equalized to < 1
|
||||
const float RearScale = 0.34f * 2;
|
||||
|
||||
float C = (ValL+ValR) * 0.5f;
|
||||
float SL = (VR*1.73f - VL*1.22f) * RearScale * Rearness;
|
||||
float SR = (VR*1.22f - VL*1.73f) * RearScale * Rearness;
|
||||
// Possible experiment: Play with stereo expension levels on rear
|
||||
|
||||
float L = ValL - C;
|
||||
float R = ValR - C;
|
||||
|
||||
float SUB = C;
|
||||
|
||||
float Cfl = (1+log(Gfl+1)/log(2.0f));
|
||||
float Cfr = (1+log(Gfr+1)/log(2.0f));
|
||||
|
||||
float VL = L * Cfl;
|
||||
float VR = R * Cfr;
|
||||
|
||||
float SL = (VR*1.73f - VL*1.22f)*0.25*Cfr; // not sure about this
|
||||
float SR = (VR*1.22f - VL*1.73f)*0.25*Cfl;
|
||||
// Adjust the volume of the front speakers based on what we calculated above
|
||||
L *= Frontness;
|
||||
R *= Frontness;
|
||||
|
||||
s32 CX = (s32)(C * AddCLR);
|
||||
|
||||
|
|
Loading…
Reference in New Issue