diff --git a/plugins/spu2-x/src/SaveStateSPU.cpp b/plugins/spu2-x/src/SaveStateSPU.cpp index 59445df78f..d8ea6b31a1 100644 --- a/plugins/spu2-x/src/SaveStateSPU.cpp +++ b/plugins/spu2-x/src/SaveStateSPU.cpp @@ -35,6 +35,7 @@ struct SPU2freezeData s16 OutPos; s16 InputPos; u32 Cycles; + u32 lClocks; int PlayMode; // Used as a base pointer to a series PcmCache blocks. @@ -47,7 +48,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 = 0x0004; +static const u32 SAVE_VERSION = 0x0005; static void wipe_the_cache() { @@ -71,6 +72,7 @@ s32 __fastcall FreezeIt( SPU2freezeData& spud ) spud.OutPos = OutPos; spud.InputPos = InputPos; spud.Cycles = Cycles; + spud.lClocks = lClocks; spud.PlayMode = PlayMode; // Save our cache: @@ -115,8 +117,6 @@ s32 __fastcall ThawIt( SPU2freezeData& spud ) printf("\tAudio may not recover correctly. Save your game to memorycard, reset,\n\n"); printf(" and then continue from there.\n\n"); - resetClock = true; - // Do *not* reset the cores. // We'll need some "hints" as to how the cores should be initialized, // and the only way to get that is to use the game's existing core settings @@ -141,6 +141,7 @@ s32 __fastcall ThawIt( SPU2freezeData& spud ) OutPos = spud.OutPos; InputPos = spud.InputPos; Cycles = spud.Cycles; + lClocks = spud.lClocks; PlayMode = spud.PlayMode; // Load the ADPCM cache: @@ -172,6 +173,9 @@ s32 __fastcall ThawIt( SPU2freezeData& spud ) Cores[c].Voices[v].SBuffer = pcm_cache_data[cacheIdx].Sampledata; } } + + SndBuffer::ClearContents(); + } return 0; } diff --git a/plugins/spu2-x/src/SndOut.cpp b/plugins/spu2-x/src/SndOut.cpp index 5d6ebe7b5e..55f035e692 100644 --- a/plugins/spu2-x/src/SndOut.cpp +++ b/plugins/spu2-x/src/SndOut.cpp @@ -303,6 +303,13 @@ int SndBuffer::m_dsp_progress = 0; int SndBuffer::m_dsp_writepos = 0; int SndBuffer::m_timestretch_progress = 0; +int SndBuffer::ssFreeze = 0; + +void SndBuffer::ClearContents() +{ + SndBuffer::soundtouchClearContents(); + SndBuffer::ssFreeze = 30; //Delays sound output for about half a second. +} void SndBuffer::Write( const StereoOut32& Sample ) { @@ -320,7 +327,13 @@ void SndBuffer::Write( const StereoOut32& Sample ) if(sndTempProgress < SndOutPacketSize) return; sndTempProgress = 0; - if( dspPluginEnabled ) + //Don't play anything directly after loading a savestate, avoids static killing your speakers. + if ( ssFreeze > 0 ) + { + ssFreeze--; + return; + } + else if( dspPluginEnabled ) { // Convert in, send to winamp DSP, and convert out. diff --git a/plugins/spu2-x/src/SndOut.h b/plugins/spu2-x/src/SndOut.h index b057f1bc3d..ac9a03d2cb 100644 --- a/plugins/spu2-x/src/SndOut.h +++ b/plugins/spu2-x/src/SndOut.h @@ -251,13 +251,14 @@ private: static float cTempo; static float eTempo; static int freezeTempo; - + static int ssFreeze; static void _InitFail(); static void _WriteSamples(StereoOut32* bData, int nSamples); static bool CheckUnderrunStatus( int& nSamples, int& quietSampleCount ); static void soundtouchInit(); + static void soundtouchClearContents(); static void soundtouchCleanup(); static void timeStretchWrite(); static void timeStretchUnderrun(); @@ -266,13 +267,14 @@ private: static void PredictDataWrite( int samples ); static float GetStatusPct(); static void UpdateTempoChange(); - + public: static void Init(); static void Cleanup(); static void Write( const StereoOut32& Sample ); static s32 Test(); - + static void ClearContents(); + #ifdef _MSC_VER static void Configure(HWND parent, u32 module ); #else diff --git a/plugins/spu2-x/src/Spu2.cpp b/plugins/spu2-x/src/Spu2.cpp index 0deae90f3a..563179752e 100644 --- a/plugins/spu2-x/src/Spu2.cpp +++ b/plugins/spu2-x/src/Spu2.cpp @@ -36,9 +36,6 @@ void InitADSR(); DWORD CALLBACK TimeThread(PVOID /* unused param */); #endif -// [Air]: fixed the hacky part of UpdateTimer with this: -bool resetClock = true; - void (* _irqcallback)(); void (* dma4callback)(); void (* dma7callback)(); diff --git a/plugins/spu2-x/src/Spu2.h b/plugins/spu2-x/src/Spu2.h index b347a28484..374ff59d37 100644 --- a/plugins/spu2-x/src/Spu2.h +++ b/plugins/spu2-x/src/Spu2.h @@ -174,7 +174,6 @@ extern int recording; extern u32 lClocks; extern u32* cPtr; extern bool hasPtr; -extern bool resetClock; extern void SPU2writeLog( const char* action, u32 rmem, u16 value ); diff --git a/plugins/spu2-x/src/Timestretcher.cpp b/plugins/spu2-x/src/Timestretcher.cpp index ff5a097f8e..08ab039337 100644 --- a/plugins/spu2-x/src/Timestretcher.cpp +++ b/plugins/spu2-x/src/Timestretcher.cpp @@ -128,7 +128,7 @@ void SndBuffer::UpdateTempoChange() // "non-emergency" deadzone: In this area stretching will be strongly discouraged. // Note: due tot he nature of timestretch latency, it's always a wee bit harder to - // cope with low fps (underruns) tha it is high fps (overruns). So to help out a + // cope with low fps (underruns) than it is high fps (overruns). So to help out a // little, the low-end portions of this check are less forgiving than the high-sides. if( cTempo < 0.965f || cTempo > 1.060f || @@ -323,7 +323,22 @@ void SndBuffer::soundtouchInit() // just freeze tempo changes for a while at startup. // the driver buffers are bogus anyway. - freezeTempo = 8; + freezeTempo = 16; + m_predictData = 0; +} + +// reset timestretch management vars, and delay updates a bit: +void SndBuffer::soundtouchClearContents() +{ + pSoundTouch->clear(); + pSoundTouch->setTempo(1); + + cTempo = 1.0; + eTempo = 1.0; + lastPct = 0; + lastEmergencyAdj = 0; + + freezeTempo = 16; m_predictData = 0; }