diff --git a/plugins/spu2ghz/config.cpp b/plugins/spu2ghz/config.cpp index 9baf30fae7..88b1e0fa3b 100644 --- a/plugins/spu2ghz/config.cpp +++ b/plugins/spu2ghz/config.cpp @@ -252,6 +252,7 @@ void ReadSettings() CfgFindName( "MIXING", "Enable_Effects" ) ? "MIXING" : "EFFECTS", "Enable_Effects", false ); + EffectsEnabled = false; // force disabled for now. SampleRate=CfgReadInt("OUTPUT","Sample_Rate",48000); SndOutLatencyMS=CfgReadInt("OUTPUT","Latency", 140); diff --git a/plugins/spu2ghz/defs.h b/plugins/spu2ghz/defs.h index ed7f0d0f37..98b6be3cbb 100644 --- a/plugins/spu2ghz/defs.h +++ b/plugins/spu2ghz/defs.h @@ -32,7 +32,7 @@ typedef struct { u16 Reg_ADSR1; u16 Reg_ADSR2; //also Reg_ENVX - u32 Value; + s32 Value; // [Air] : Ranges from 0 to 0x7fffffff (signed values are clamped to 0) // Phase u8 Phase; //Attack Rate diff --git a/plugins/spu2ghz/dma.cpp b/plugins/spu2ghz/dma.cpp index e8ea61efd9..fe5a3dc593 100644 --- a/plugins/spu2ghz/dma.cpp +++ b/plugins/spu2ghz/dma.cpp @@ -244,8 +244,10 @@ void DoDMAWrite(int core,u16 *pMem,u32 size) // Traverse from start to finish in 8*32 word blocks, // and clear all the the pcm cache flags for each block. - for(; Cores[core].TDA>= (3+5); // 8 words per block, 32 blocks per int. memset( &pcm_cache_flags[nexta], 0, sizeof( u32 ) * (buff1end-nexta) ); @@ -258,34 +260,60 @@ void DoDMAWrite(int core,u16 *pMem,u32 size) const u32 endpt2 = buff2end >> (3+5); // 8 words per block, 32 blocks per int. memset( pcm_cache_flags, 0, sizeof( u32 ) * endpt2 ); - for(Cores[core].TDA=0; Cores[core].TDA<(u32)buff2end; ++Cores[core].TDA, ++pMem) - *GetMemPtr( Cores[core].TDA ) = *pMem; + memcpy( GetMemPtr( 0 ), &pMem[buff1size], buff2end*2 ); + //for(Cores[core].TDA=0; Cores[core].TDA<(u32)buff2end; ++Cores[core].TDA, ++pMem) + // *GetMemPtr( Cores[core].TDA ) = *pMem; - rightsidebit = ( buff2end >> 3 ); + rightsidebit = buff2end >> 3; nexta = endpt2; + + if(Cores[core].IRQEnable) + { + // Flag interrupt? + // If IRQA occurs between start and dest, flag it. + // Since the buffer wraps, the conditional might seem odd, but it works. + + if( ( Cores[core].IRQA >= Cores[core].TDA ) || + ( Cores[core].IRQA <= buff2end ) ) + { + Spdif.Info=4<> 3); + rightsidebit = buff1end >> 3; nexta = buff1end; + + Cores[core].TDA = buff1end; + + if(Cores[core].IRQEnable) + { + // Flag interrupt? + // If IRQA occurs between start and dest, flag it: + + if( ( Cores[core].IRQA >= Cores[core].TSA ) && + ( Cores[core].IRQA <= Cores[core].TDA ) ) + { + Spdif.Info=4<0xFFFFF)||((Cores[core].TDA>=Cores[core].IRQA)&&(i<=Cores[core].IRQA))) { - if(Cores[core].IRQEnable) - { - Spdif.Info=4<>28)&7]; + s32 SLevel = ((s32)env.Sl)<<27; jASSUME( SLevel >= 0 ); if(env.Releasing) { - // [Air] : Simplified conditional, as phase cannot be zero here. - // (zeros get trapped above) - if(/*(env.Phase>0)&&*/(env.Phase<5)) + if( env.Phase < 5) { env.Phase=5; } @@ -334,7 +331,7 @@ static void __forceinline CalculateADSR( V_Voice& vc ) switch (env.Phase) { case 1: // attack - if( env.Value == 0x7fffffff ) + if( env.Value == ADSR_MAX_VOL ) { // Already maxed out. Progress phase and nothing more: env.Phase++; @@ -361,13 +358,15 @@ static void __forceinline CalculateADSR( V_Voice& vc ) { // We hit the ceiling. env.Phase++; - env.Value=0x7fffffff; + env.Value = ADSR_MAX_VOL; } break; case 2: // decay - env.Value-=PsxRates[((env.Dr^0x1f)<<2)-0x18+off+32]; + { + u32 off = InvExpOffsets[(env.Value>>28)&7]; + env.Value -= PsxRates[((env.Dr^0x1f)<<2)-0x18+off+32]; if(env.Value <= SLevel) { @@ -381,17 +380,19 @@ static void __forceinline CalculateADSR( V_Voice& vc ) } break; + } case 3: // sustain if (env.Sm&2) // decreasing { if (env.Sm&4) // exponential { - env.Value-=PsxRates[(env.Sr^0x7f)-0x1b+off+32]; + u32 off = InvExpOffsets[(env.Value>>28)&7]; + env.Value -= PsxRates[(env.Sr^0x7f)-0x1b+off+32]; } else // linear { - env.Value-=PsxRates[(env.Sr^0x7f)-0xf+32]; + env.Value -= PsxRates[(env.Sr^0x7f)-0xf+32]; } if( env.Value < 0 ) { @@ -421,7 +422,7 @@ static void __forceinline CalculateADSR( V_Voice& vc ) if( env.Value < 0 ) { - env.Value = 0x7fffffff; + env.Value = ADSR_MAX_VOL; env.Phase++; } } @@ -429,7 +430,7 @@ static void __forceinline CalculateADSR( V_Voice& vc ) break; case 4: // sustain end - env.Value = (env.Sm&2) ? 0 : 0x7fffffff; + env.Value = (env.Sm&2) ? 0 : ADSR_MAX_VOL; if(env.Value==0) env.Phase=6; break; @@ -438,6 +439,7 @@ static void __forceinline CalculateADSR( V_Voice& vc ) if (env.Rm) // exponential { + u32 off=InvExpOffsets[(env.Value>>28)&7]; env.Value-=PsxRates[((env.Rr^0x1f)<<2)-0x18+off+32]; } else // linear @@ -542,26 +544,25 @@ static void __forceinline GetVoiceValues_Linear(V_Core& thiscore, V_Voice& vc, s vc.SP-=4096; } - CalculateADSR( vc ); - - if(vc.ADSR.Phase==0) + if( vc.ADSR.Phase==0 ) { Value = 0; + return; } - else - { - jASSUME( vc.ADSR.Value >= 0 ); // ADSR should never be negative... - if(Interpolation==0) - { - Value = MulShr32( vc.PV1, vc.ADSR.Value ); - } - else //if(Interpolation==1) //must be linear - { - s32 t0 = vc.PV2 - vc.PV1; - s32 t1 = vc.PV1; - Value = MulShr32( t1 - ((t0*vc.SP)>>12), vc.ADSR.Value ); - } + CalculateADSR( vc ); + + jASSUME( vc.ADSR.Value >= 0 ); // ADSR should never be negative... + + if(Interpolation==0) + { + Value = MulShr32( vc.PV1, vc.ADSR.Value ); + } + else //if(Interpolation==1) //must be linear + { + s32 t0 = vc.PV2 - vc.PV1; + s32 t1 = vc.PV1; + Value = MulShr32( t1 - ((t0*vc.SP)>>12), vc.ADSR.Value ); } } @@ -580,43 +581,28 @@ static void __forceinline GetVoiceValues_Cubic(V_Core& thiscore, V_Voice& vc, s3 vc.SP-=4096; } - CalculateADSR( vc ); - - if(vc.ADSR.Phase==0) + if( vc.ADSR.Phase==0 ) { Value = 0; - } - else - { - jASSUME( vc.ADSR.Value >= 0 ); // ADSR should never be negative... - - s32 z0 = vc.PV3 - vc.PV4 + vc.PV1 - vc.PV2; - s32 z1 = (vc.PV4 - vc.PV3 - z0); - s32 z2 = (vc.PV2 - vc.PV4); - - s32 mu = vc.SPc; - - s32 val = (z0 * mu) >> 12; - val = ((val + z1) * mu) >> 12; - val = ((val + z2) * mu) >> 12; - val += vc.PV2; - - /* - s64 a0 = vc.PV1 - vc.PV2 - vc.PV4 + vc.PV3; - s64 a1 = vc.PV4 - vc.PV3 - a0; - s64 a2 = vc.PV1 - vc.PV4; - s64 a3 = vc.PV2; - s64 mu = 4096+vc.SP; - - s64 t0 = ((a0 )*mu)>>12; - s64 t1 = ((t0-a1)*mu)>>12; - s64 t2 = ((t1-a2)*mu)>>12; - s64 t3 = ((t2-a3));*/ - - Value = MulShr32( val, vc.ADSR.Value>>3 ); + return; } - //Value=(s32)((Data*vc.ADSR.Value)>>40); //32bit ADSR + convert to 16bit + CalculateADSR( vc ); + + jASSUME( vc.ADSR.Value >= 0 ); // ADSR should never be negative... + + s32 z0 = vc.PV3 - vc.PV4 + vc.PV1 - vc.PV2; + s32 z1 = (vc.PV4 - vc.PV3 - z0); + s32 z2 = (vc.PV2 - vc.PV4); + + s32 mu = vc.SPc; + + s32 val = (z0 * mu) >> 12; + val = ((val + z1) * mu) >> 12; + val = ((val + z2) * mu) >> 12; + val += vc.PV2; + + Value = MulShr32( val, vc.ADSR.Value>>3 ); } // [Air]: Noise values need to be mixed without going through interpolation, since it diff --git a/plugins/spu2ghz/spu2.cpp b/plugins/spu2ghz/spu2.cpp index cd582bfdef..c1d0f3aa2f 100644 --- a/plugins/spu2ghz/spu2.cpp +++ b/plugins/spu2ghz/spu2.cpp @@ -1310,7 +1310,9 @@ static __forceinline void SPU2_FastWrite( u32 rmem, u16 value ) Cores[core].Voices[voice].ADSR.Rm=(value & 0x20)>>5; Cores[core].Voices[voice].ADSR.Rr=(value & 0x1F); Cores[core].Voices[voice].ADSR.Reg_ADSR2 = value; break; - case 5: Cores[core].Voices[voice].ADSR.Value=value; break; + // [Air] [TODO] : value is 16 bit but ADSR.value is 32 bit. + // Should this be shifted up by 16? Seems like it. + case 5: Cores[core].Voices[voice].ADSR.Value=value; break; case 6: Cores[core].Voices[voice].VolumeL.Value=value; break; case 7: Cores[core].Voices[voice].VolumeR.Value=value; break;