mirror of https://github.com/PCSX2/pcsx2.git
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:
parent
54baa99158
commit
18566548f6
|
@ -26,9 +26,36 @@ static const s32 ADSR_MAX_VOL = 0x7fffffff;
|
||||||
static const int InvExpOffsets[] = { 0,4,6,8,9,10,11,12 };
|
static const int InvExpOffsets[] = { 0,4,6,8,9,10,11,12 };
|
||||||
static u32 PsxRates[160];
|
static u32 PsxRates[160];
|
||||||
|
|
||||||
|
|
||||||
|
extern u32 core, voice;
|
||||||
|
|
||||||
void InitADSR() // INIT ADSR
|
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;
|
int shift=(i-32)>>2;
|
||||||
s64 rate=(i&3)+4;
|
s64 rate=(i&3)+4;
|
||||||
|
@ -38,7 +65,7 @@ void InitADSR() // INIT ADSR
|
||||||
rate <<= shift;
|
rate <<= shift;
|
||||||
|
|
||||||
PsxRates[i] = (int)min( rate, 0x3fffffffLL );
|
PsxRates[i] = (int)min( rate, 0x3fffffffLL );
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
#define VOL(x) (((s32)x)) //24.8 volume
|
#define VOL(x) (((s32)x)) //24.8 volume
|
||||||
|
@ -77,9 +104,8 @@ bool V_ADSR::Calculate()
|
||||||
|
|
||||||
if (AttackMode && (Value>=0x60000000))
|
if (AttackMode && (Value>=0x60000000))
|
||||||
Value += PsxRates[(AttackRate^0x7f)-0x18+32];
|
Value += PsxRates[(AttackRate^0x7f)-0x18+32];
|
||||||
else //if( AttackRate < 0x7f )
|
else
|
||||||
Value += PsxRates[(AttackRate^0x7f)-0x10+32];
|
Value += PsxRates[(AttackRate^0x7f)-0x10+32];
|
||||||
//Value += GetLinearSrAr( AttackRate );
|
|
||||||
|
|
||||||
if( Value < 0 )
|
if( Value < 0 )
|
||||||
{
|
{
|
||||||
|
@ -120,10 +146,7 @@ bool V_ADSR::Calculate()
|
||||||
Value -= PsxRates[(SustainRate^0x7f)-0x1b+off+32];
|
Value -= PsxRates[(SustainRate^0x7f)-0x1b+off+32];
|
||||||
}
|
}
|
||||||
else // linear
|
else // linear
|
||||||
{
|
|
||||||
Value -= PsxRates[(SustainRate^0x7f)-0xf+32];
|
Value -= PsxRates[(SustainRate^0x7f)-0xf+32];
|
||||||
//Value -= GetLinearSrAr( SustainRate );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( Value <= 0 )
|
if( Value <= 0 )
|
||||||
{
|
{
|
||||||
|
@ -136,11 +159,8 @@ bool V_ADSR::Calculate()
|
||||||
if( (SustainMode&4) && (Value>=0x60000000) )
|
if( (SustainMode&4) && (Value>=0x60000000) )
|
||||||
Value += PsxRates[(SustainRate^0x7f)-0x18+32];
|
Value += PsxRates[(SustainRate^0x7f)-0x18+32];
|
||||||
else
|
else
|
||||||
{
|
|
||||||
// linear / Pseudo below 75% (they're the same)
|
// linear / Pseudo below 75% (they're the same)
|
||||||
Value += PsxRates[(SustainRate^0x7f)-0x10+32];
|
Value += PsxRates[(SustainRate^0x7f)-0x10+32];
|
||||||
//Value += GetLinearSrAr( SustainRate );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( Value < 0 )
|
if( Value < 0 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -240,7 +240,7 @@ static void __forceinline __fastcall GetNextDataBuffered( V_Core& thiscore, V_Vo
|
||||||
s16* sbuffer = cacheLine.Sampledata;
|
s16* sbuffer = cacheLine.Sampledata;
|
||||||
|
|
||||||
// saturated decoder
|
// 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)
|
// [Air]: Testing use of a new unsaturated decoder. (benchmark needed)
|
||||||
// Chances are the saturation isn't needed, but for a very few exception games.
|
// 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
|
// 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.
|
// 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;
|
vc.SCurrent = 0;
|
||||||
|
@ -358,7 +358,7 @@ static void __forceinline GetVoiceValues_Linear(V_Core& thiscore, V_Voice& vc, s
|
||||||
|
|
||||||
if(Interpolation==0)
|
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
|
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] );
|
V_Core& thiscore( Cores[core] );
|
||||||
|
|
||||||
for (voice=0;voice<24;voice++)
|
for( voice=0; voice<24; ++voice )
|
||||||
{
|
{
|
||||||
s32 VValL,VValR;
|
s32 VValL,VValR;
|
||||||
|
|
||||||
|
|
|
@ -395,29 +395,39 @@ void SPU_ps1_write(u32 mem, u16 value)
|
||||||
case 0: //VOLL (Volume L)
|
case 0: //VOLL (Volume L)
|
||||||
Cores[0].Voices[voice].VolumeL.Mode = 0;
|
Cores[0].Voices[voice].VolumeL.Mode = 0;
|
||||||
Cores[0].Voices[voice].VolumeL.Value = GetVol32( value<<1 );
|
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)
|
case 1: //VOLR (Volume R)
|
||||||
Cores[0].Voices[voice].VolumeR.Mode = 0;
|
Cores[0].Voices[voice].VolumeR.Mode = 0;
|
||||||
Cores[0].Voices[voice].VolumeR.Value = GetVol32( value<<1 );
|
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 2: Cores[0].Voices[voice].Pitch = value; break;
|
||||||
case 3: Cores[0].Voices[voice].StartA = (u32)value<<8; break;
|
case 3: Cores[0].Voices[voice].StartA = (u32)value<<8; break;
|
||||||
|
|
||||||
case 4: // ADSR1 (Envelope)
|
case 4: // ADSR1 (Envelope)
|
||||||
Cores[0].Voices[voice].ADSR.AttackMode = (value & 0x8000)>>15;
|
Cores[0].Voices[voice].ADSR.AttackMode = (value & 0x8000)>>15;
|
||||||
Cores[0].Voices[voice].ADSR.AttackRate = (value & 0x7F00)>>8;
|
Cores[0].Voices[voice].ADSR.AttackRate = (value & 0x7F00)>>8;
|
||||||
Cores[0].Voices[voice].ADSR.DecayRate = (value & 0xF0)>>4;
|
Cores[0].Voices[voice].ADSR.DecayRate = (value & 0xF0)>>4;
|
||||||
Cores[0].Voices[voice].ADSR.SustainLevel = (value & 0xF);
|
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)
|
case 5: // ADSR2 (Envelope)
|
||||||
Cores[0].Voices[voice].ADSR.SustainMode = (value & 0xE000)>>13;
|
Cores[0].Voices[voice].ADSR.SustainMode = (value & 0xE000)>>13;
|
||||||
Cores[0].Voices[voice].ADSR.SustainRate = (value & 0x1FC0)>>6;
|
Cores[0].Voices[voice].ADSR.SustainRate = (value & 0x1FC0)>>6;
|
||||||
Cores[0].Voices[voice].ADSR.ReleaseMode = (value & 0x20)>>5;
|
Cores[0].Voices[voice].ADSR.ReleaseMode = (value & 0x20)>>5;
|
||||||
Cores[0].Voices[voice].ADSR.ReleaseRate = (value & 0x1F);
|
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:
|
case 6:
|
||||||
Cores[0].Voices[voice].ADSR.Value = ((s32)value<<16) | value;
|
Cores[0].Voices[voice].ADSR.Value = ((s32)value<<16) | value;
|
||||||
ConLog( "* SPU2: Mysterious ADSR Volume Set to 0x%x", value );
|
ConLog( "* SPU2: Mysterious ADSR Volume Set to 0x%x", value );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 7: Cores[0].Voices[voice].LoopStartA = (u32)value <<8; break;
|
case 7: Cores[0].Voices[voice].LoopStartA = (u32)value <<8; break;
|
||||||
|
|
||||||
jNO_DEFAULT;
|
jNO_DEFAULT;
|
||||||
|
|
Loading…
Reference in New Issue