SPU2-X: Switched over to what appears to be a much better ADSR table (we'll be testing it to see what impact it has across all games).

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@512 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2009-02-16 22:14:17 +00:00
parent 54baa99158
commit 18566548f6
3 changed files with 82 additions and 52 deletions

View File

@ -26,9 +26,36 @@ static const s32 ADSR_MAX_VOL = 0x7fffffff;
static const int InvExpOffsets[] = { 0,4,6,8,9,10,11,12 };
static u32 PsxRates[160];
extern u32 core, voice;
void InitADSR() // INIT ADSR
{
for (int i=0; i<(32+128); i++)
int r=3;
int rs=1;
int rd=0;
memset( PsxRates, 0, sizeof( PsxRates ) );
for( int i=32; i<160; ++i )
{
if( r < 0x3FFFFFFF )
{
r += rs;
rd++;
if( rd == 5 )
{
rd = 1;
rs <<= 1;
}
}
if( r > 0x3FFFFFFF ) r = 0x3FFFFFFF;
PsxRates[i] = r;
}
/*for (int i=0; i<(32+128); i++)
{
int shift=(i-32)>>2;
s64 rate=(i&3)+4;
@ -38,7 +65,7 @@ void InitADSR() // INIT ADSR
rate <<= shift;
PsxRates[i] = (int)min( rate, 0x3fffffffLL );
}
}*/
}
#define VOL(x) (((s32)x)) //24.8 volume
@ -77,9 +104,8 @@ bool V_ADSR::Calculate()
if (AttackMode && (Value>=0x60000000))
Value += PsxRates[(AttackRate^0x7f)-0x18+32];
else //if( AttackRate < 0x7f )
else
Value += PsxRates[(AttackRate^0x7f)-0x10+32];
//Value += GetLinearSrAr( AttackRate );
if( Value < 0 )
{
@ -120,10 +146,7 @@ bool V_ADSR::Calculate()
Value -= PsxRates[(SustainRate^0x7f)-0x1b+off+32];
}
else // linear
{
Value -= PsxRates[(SustainRate^0x7f)-0xf+32];
//Value -= GetLinearSrAr( SustainRate );
}
if( Value <= 0 )
{
@ -136,11 +159,8 @@ bool V_ADSR::Calculate()
if( (SustainMode&4) && (Value>=0x60000000) )
Value += PsxRates[(SustainRate^0x7f)-0x18+32];
else
{
// linear / Pseudo below 75% (they're the same)
Value += PsxRates[(SustainRate^0x7f)-0x10+32];
//Value += GetLinearSrAr( SustainRate );
}
if( Value < 0 )
{

View File

@ -240,7 +240,7 @@ static void __forceinline __fastcall GetNextDataBuffered( V_Core& thiscore, V_Vo
s16* sbuffer = cacheLine.Sampledata;
// saturated decoder
XA_decode_block( sbuffer, memptr, vc.Prev1, vc.Prev2 );
//XA_decode_block( sbuffer, memptr, vc.Prev1, vc.Prev2 );
// [Air]: Testing use of a new unsaturated decoder. (benchmark needed)
// Chances are the saturation isn't needed, but for a very few exception games.
@ -248,7 +248,7 @@ static void __forceinline __fastcall GetNextDataBuffered( V_Core& thiscore, V_Vo
// merit possible lower compatibility? Especially now that games that make
// heavy use of the SPU2 via music or sfx will mostly use the cache anyway.
//XA_decode_block_unsaturated( vc.SBuffer, memptr, vc.Prev1, vc.Prev2 );
XA_decode_block_unsaturated( vc.SBuffer, memptr, vc.Prev1, vc.Prev2 );
}
vc.SCurrent = 0;
@ -358,7 +358,7 @@ static void __forceinline GetVoiceValues_Linear(V_Core& thiscore, V_Voice& vc, s
if(Interpolation==0)
{
Value = MulShr32( vc.PV1<<1, vc.ADSR.Value );
Value = ApplyVolume( vc.PV1, vc.ADSR.Value );
}
else //if(Interpolation==1) //must be linear
{
@ -693,7 +693,7 @@ static void __fastcall MixCore(s32& OutL, s32& OutR, s32 ExtL, s32 ExtR)
V_Core& thiscore( Cores[core] );
for (voice=0;voice<24;voice++)
for( voice=0; voice<24; ++voice )
{
s32 VValL,VValR;

View File

@ -395,29 +395,39 @@ void SPU_ps1_write(u32 mem, u16 value)
case 0: //VOLL (Volume L)
Cores[0].Voices[voice].VolumeL.Mode = 0;
Cores[0].Voices[voice].VolumeL.Value = GetVol32( value<<1 );
Cores[0].Voices[voice].VolumeL.Reg_VOL = value; break;
Cores[0].Voices[voice].VolumeL.Reg_VOL = value;
break;
case 1: //VOLR (Volume R)
Cores[0].Voices[voice].VolumeR.Mode = 0;
Cores[0].Voices[voice].VolumeR.Value = GetVol32( value<<1 );
Cores[0].Voices[voice].VolumeR.Reg_VOL = value; break;
Cores[0].Voices[voice].VolumeR.Reg_VOL = value;
break;
case 2: Cores[0].Voices[voice].Pitch = value; break;
case 3: Cores[0].Voices[voice].StartA = (u32)value<<8; break;
case 4: // ADSR1 (Envelope)
Cores[0].Voices[voice].ADSR.AttackMode = (value & 0x8000)>>15;
Cores[0].Voices[voice].ADSR.AttackRate = (value & 0x7F00)>>8;
Cores[0].Voices[voice].ADSR.DecayRate = (value & 0xF0)>>4;
Cores[0].Voices[voice].ADSR.SustainLevel = (value & 0xF);
Cores[0].Voices[voice].ADSR.Reg_ADSR1 = value; break;
Cores[0].Voices[voice].ADSR.Reg_ADSR1 = value;
break;
case 5: // ADSR2 (Envelope)
Cores[0].Voices[voice].ADSR.SustainMode = (value & 0xE000)>>13;
Cores[0].Voices[voice].ADSR.SustainRate = (value & 0x1FC0)>>6;
Cores[0].Voices[voice].ADSR.ReleaseMode = (value & 0x20)>>5;
Cores[0].Voices[voice].ADSR.ReleaseRate = (value & 0x1F);
Cores[0].Voices[voice].ADSR.Reg_ADSR2 = value; break;
Cores[0].Voices[voice].ADSR.Reg_ADSR2 = value;
break;
case 6:
Cores[0].Voices[voice].ADSR.Value = ((s32)value<<16) | value;
ConLog( "* SPU2: Mysterious ADSR Volume Set to 0x%x", value );
break;
case 7: Cores[0].Voices[voice].LoopStartA = (u32)value <<8; break;
jNO_DEFAULT;