From dc306bf64cf4402aa6e23f0da6a49f725e1ec4ee Mon Sep 17 00:00:00 2001 From: "Jake.Stine" Date: Wed, 18 Feb 2009 16:47:06 +0000 Subject: [PATCH] SPU2-X: more fixes to reverb. Digital Devil Saga sounds a lot nicer now. Updated savestate revision so that loading states from before my latest cleanup/optimization won't crash. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@529 96395faa-99c1-11dd-bbfe-3dabce05a288 --- plugins/spu2-x/src/3rdparty/liba52/parse.c | 2 +- plugins/spu2-x/src/Mixer.cpp | 4 +- plugins/spu2-x/src/Reverb.cpp | 62 +++++++++++++++------- plugins/spu2-x/src/SaveStateSPU.cpp | 3 +- 4 files changed, 46 insertions(+), 25 deletions(-) diff --git a/plugins/spu2-x/src/3rdparty/liba52/parse.c b/plugins/spu2-x/src/3rdparty/liba52/parse.c index 7245a315c9..3626944f65 100644 --- a/plugins/spu2-x/src/3rdparty/liba52/parse.c +++ b/plugins/spu2-x/src/3rdparty/liba52/parse.c @@ -39,7 +39,7 @@ void * memalign (size_t align, size_t size); #else /* assume malloc alignment is sufficient */ -#define memalign(align,m_size) malloc (m_size) +#define memalign(align,size) malloc (size) #endif typedef struct { diff --git a/plugins/spu2-x/src/Mixer.cpp b/plugins/spu2-x/src/Mixer.cpp index ed556afdfd..db038767c3 100644 --- a/plugins/spu2-x/src/Mixer.cpp +++ b/plugins/spu2-x/src/Mixer.cpp @@ -688,8 +688,8 @@ static __forceinline StereoOut32 MixVoice( V_Core& thiscore, V_Voice& vc ) // Write-back of raw voice data (post ADSR applied) - if (voice==1) spu2M_WriteFast( 0x400 + (core<<12) + OutPos, vc.OutX ); - else if (voice==3) spu2M_WriteFast( 0x600 + (core<<12) + OutPos, vc.OutX ); + if (voice==1) spu2M_WriteFast( 0x400 + (core<<12) + OutPos, Value ); + else if (voice==3) spu2M_WriteFast( 0x600 + (core<<12) + OutPos, Value ); return ApplyVolume( StereoOut32( Value, Value ), vc.Volume ); } diff --git a/plugins/spu2-x/src/Reverb.cpp b/plugins/spu2-x/src/Reverb.cpp index 124dfed56d..b5cd8b5445 100644 --- a/plugins/spu2-x/src/Reverb.cpp +++ b/plugins/spu2-x/src/Reverb.cpp @@ -40,12 +40,6 @@ static __forceinline s32 RevbGetIndexer( V_Core& thiscore, s32 offset ) return pos; } -/*void LowPass(s32& VL, s32& VR) -{ - VL = (s32)( lowpass_left.sample(VL/65536.0) * 65536.0 ); - VR = (s32)( lowpass_right.sample(VR/65536.0) * 65536.0 ); -}*/ - void Reverb_AdvanceBuffer( V_Core& thiscore ) { if( (Cycles & 1) && (thiscore.EffectsBufferSize > 0) ) @@ -53,7 +47,7 @@ void Reverb_AdvanceBuffer( V_Core& thiscore ) //thiscore.ReverbX = RevbGetIndexer( thiscore, 1 ); thiscore.ReverbX += 1; - if( thiscore.ReverbX >= thiscore.EffectsBufferSize ) thiscore.ReverbX = 0; + if( thiscore.ReverbX >= (u32)thiscore.EffectsBufferSize ) thiscore.ReverbX = 0; //thiscore.ReverbX += 1; //if(thiscore.ReverbX >= (u32)thiscore.EffectsBufferSize ) @@ -71,7 +65,14 @@ StereoOut32 DoReverb( V_Core& thiscore, const StereoOut32& Input ) if( (Cycles&1)==0 ) { StereoOut32 retval( thiscore.LastEffect ); - thiscore.LastEffect = Input/2; + + // Make sure and pass input through the LPF. The result can be discarded. + // This gives the LPF a better sampling from which to kill offending frequencies. + + lowpass_left.sample( Input.Left / 32768.0 ); + lowpass_right.sample( Input.Right / 32768.0 ); + + //thiscore.LastEffect = Input; return retval; } else @@ -83,7 +84,12 @@ StereoOut32 DoReverb( V_Core& thiscore, const StereoOut32& Input ) { // StartA is past EndA, so effects are disabled. //ConLog( " * SPU2: Effects disabled due to leapfrogged EffectsStart." ); - return Input; + + // Should we return zero here, or the input sample? + // Because reverb gets an *2 mul, returning input seems dangerous, so I opt for silence. + + //return Input; + return StereoOut32::Empty; } // Advance the current reverb buffer pointer, and cache the read/write addresses we'll be @@ -128,24 +134,39 @@ StereoOut32 DoReverb( V_Core& thiscore, const StereoOut32& Input ) // End Buffer Pointers, Begin Reverb! // ----------------------------------------- - StereoOut32 INPUT_SAMPLE( thiscore.LastEffect + Input ); + //StereoOut32 INPUT_SAMPLE( thiscore.LastEffect + Input ); + + // Note: LowPass on the input! Very important. Some games like DDS get terrible feedback otherwise. + // Decisions, Decisions! Should we mix in the 22khz sample skipped, or not? + // First one mixes in the 22hkz sample. Second one does not. + + /*StereoOut32 INPUT_SAMPLE( + (s32)(lowpass_left.sample( (Input.Left+thiscore.LastEffect.Left) / 32768.0 ) * 32768.0), + (s32)(lowpass_right.sample( (Input.Right+thiscore.LastEffect.Right) / 32768.0 ) * 32768.0) + );*/ + + StereoOut32 INPUT_SAMPLE( + (s32)(lowpass_left.sample( Input.Left / 32768.0 ) * 32768.0), + (s32)(lowpass_right.sample( Input.Right / 32768.0 ) * 32768.0) + ); const s32 IIR_INPUT_A0 = ((_spu2mem[src_a0] * thiscore.Revb.IIR_COEF) + (INPUT_SAMPLE.Left * thiscore.Revb.IN_COEF_L))>>16; const s32 IIR_INPUT_A1 = ((_spu2mem[src_a1] * thiscore.Revb.IIR_COEF) + (INPUT_SAMPLE.Right * thiscore.Revb.IN_COEF_R))>>16; const s32 IIR_INPUT_B0 = ((_spu2mem[src_b0] * thiscore.Revb.IIR_COEF) + (INPUT_SAMPLE.Left * thiscore.Revb.IN_COEF_L))>>16; const s32 IIR_INPUT_B1 = ((_spu2mem[src_b1] * thiscore.Revb.IIR_COEF) + (INPUT_SAMPLE.Right * thiscore.Revb.IN_COEF_R))>>16; - /*const s32 IIR_A0 = (IIR_INPUT_A0 * thiscore.Revb.IIR_ALPHA) + (_spu2mem[dest_a0] * (0x7fff - thiscore.Revb.IIR_ALPHA)); + const s32 IIR_A0 = (IIR_INPUT_A0 * thiscore.Revb.IIR_ALPHA) + (_spu2mem[dest_a0] * (0x7fff - thiscore.Revb.IIR_ALPHA)); const s32 IIR_A1 = (IIR_INPUT_A1 * thiscore.Revb.IIR_ALPHA) + (_spu2mem[dest_a1] * (0x7fff - thiscore.Revb.IIR_ALPHA)); const s32 IIR_B0 = (IIR_INPUT_B0 * thiscore.Revb.IIR_ALPHA) + (_spu2mem[dest_b0] * (0x7fff - thiscore.Revb.IIR_ALPHA)); const s32 IIR_B1 = (IIR_INPUT_B1 * thiscore.Revb.IIR_ALPHA) + (_spu2mem[dest_b1] * (0x7fff - thiscore.Revb.IIR_ALPHA)); _spu2mem[dest2_a0] = clamp_mix( IIR_A0 >> 16 ); _spu2mem[dest2_a1] = clamp_mix( IIR_A1 >> 16 ); _spu2mem[dest2_b0] = clamp_mix( IIR_B0 >> 16 ); - _spu2mem[dest2_b1] = clamp_mix( IIR_B1 >> 16 );*/ + _spu2mem[dest2_b1] = clamp_mix( IIR_B1 >> 16 ); // Faster single-mul approach to interpolation: - const s32 IIR_A0 = IIR_INPUT_A0 + (((_spu2mem[dest_a0]-IIR_INPUT_A0) * thiscore.Revb.IIR_ALPHA)>>16); + // (doesn't work yet -- breaks Digital Devil Saga badly) + /*const s32 IIR_A0 = IIR_INPUT_A0 + (((_spu2mem[dest_a0]-IIR_INPUT_A0) * thiscore.Revb.IIR_ALPHA)>>16); const s32 IIR_A1 = IIR_INPUT_A1 + (((_spu2mem[dest_a1]-IIR_INPUT_A1) * thiscore.Revb.IIR_ALPHA)>>16); const s32 IIR_B0 = IIR_INPUT_B0 + (((_spu2mem[dest_b0]-IIR_INPUT_B0) * thiscore.Revb.IIR_ALPHA)>>16); const s32 IIR_B1 = IIR_INPUT_B1 + (((_spu2mem[dest_b1]-IIR_INPUT_B1) * thiscore.Revb.IIR_ALPHA)>>16); @@ -153,7 +174,7 @@ StereoOut32 DoReverb( V_Core& thiscore, const StereoOut32& Input ) _spu2mem[dest2_a0] = clamp_mix( IIR_A0 ); _spu2mem[dest2_a1] = clamp_mix( IIR_A1 ); _spu2mem[dest2_b0] = clamp_mix( IIR_B0 ); - _spu2mem[dest2_b1] = clamp_mix( IIR_B1 ); + _spu2mem[dest2_b1] = clamp_mix( IIR_B1 );*/ const s32 ACC0 = ((_spu2mem[acc_src_a0] * thiscore.Revb.ACC_COEF_A)) + @@ -170,20 +191,21 @@ StereoOut32 DoReverb( V_Core& thiscore, const StereoOut32& Input ) const s32 FB_A0 = (_spu2mem[fb_src_a0] * thiscore.Revb.FB_ALPHA); const s32 FB_A1 = (_spu2mem[fb_src_a1] * thiscore.Revb.FB_ALPHA); - const s32 fb_xor_a0 = (_spu2mem[fb_src_a0] * ( thiscore.Revb.FB_ALPHA ^ 0x8000 ))>>2; - const s32 fb_xor_a1 = (_spu2mem[fb_src_a1] * ( thiscore.Revb.FB_ALPHA ^ 0x8000 ))>>2; + const s32 fb_xor_a0 = _spu2mem[fb_src_a0] * ( thiscore.Revb.FB_ALPHA ^ 0x8000 ); + const s32 fb_xor_a1 = _spu2mem[fb_src_a1] * ( thiscore.Revb.FB_ALPHA ^ 0x8000 ); _spu2mem[mix_dest_a0] = clamp_mix( (ACC0 - FB_A0) >> 16 ); _spu2mem[mix_dest_a1] = clamp_mix( (ACC1 - FB_A1) >> 16 ); - _spu2mem[mix_dest_b0] = clamp_mix( (MulShr32(thiscore.Revb.FB_ALPHA<<14, ACC0) - fb_xor_a0 - ((_spu2mem[fb_src_b0] * thiscore.Revb.FB_X)>>2)) >> 14 ); - _spu2mem[mix_dest_b1] = clamp_mix( (MulShr32(thiscore.Revb.FB_ALPHA<<14, ACC1) - fb_xor_a1 - ((_spu2mem[fb_src_b1] * thiscore.Revb.FB_X)>>2)) >> 14 ); + _spu2mem[mix_dest_b0] = clamp_mix( (MulShr32(thiscore.Revb.FB_ALPHA<<16, ACC0) - fb_xor_a0 - (_spu2mem[fb_src_b0] * thiscore.Revb.FB_X)) >> 16 ); + _spu2mem[mix_dest_b1] = clamp_mix( (MulShr32(thiscore.Revb.FB_ALPHA<<16, ACC1) - fb_xor_a1 - (_spu2mem[fb_src_b1] * thiscore.Revb.FB_X)) >> 16 ); thiscore.LastEffect.Left = _spu2mem[mix_dest_a0] + _spu2mem[mix_dest_b0]; thiscore.LastEffect.Right = _spu2mem[mix_dest_a1] + _spu2mem[mix_dest_b1]; + clamp_mix( thiscore.LastEffect ); - thiscore.LastEffect.Left = (s32)(lowpass_left.sample( thiscore.LastEffect.Left / 32768.0 ) * 32768.0); - thiscore.LastEffect.Right = (s32)(lowpass_right.sample( thiscore.LastEffect.Right / 32768.0 ) * 32768.0); + //thiscore.LastEffect.Left = (s32)(lowpass_left.sample( thiscore.LastEffect.Left / 32768.0 ) * 32768.0); + //thiscore.LastEffect.Right = (s32)(lowpass_right.sample( thiscore.LastEffect.Right / 32768.0 ) * 32768.0); return thiscore.LastEffect; } diff --git a/plugins/spu2-x/src/SaveStateSPU.cpp b/plugins/spu2-x/src/SaveStateSPU.cpp index 25e4b1e023..22b57b5676 100644 --- a/plugins/spu2-x/src/SaveStateSPU.cpp +++ b/plugins/spu2-x/src/SaveStateSPU.cpp @@ -47,7 +47,7 @@ static const u32 SAVE_ID = 0x1227521; // versioning for saves. // Increment this when changes to the savestate system are made. -static const u32 SAVE_VERSION = 0x0002; +static const u32 SAVE_VERSION = 0x0003; static void wipe_the_cache() { @@ -71,7 +71,6 @@ s32 __fastcall FreezeIt( SPU2freezeData& spud ) return 0; } - spud.id = SAVE_ID; spud.version = SAVE_VERSION;