mirror of https://github.com/PCSX2/pcsx2.git
SPU2-X:
Worked on savestate support a bit. It now remembers an update timing variable more (could fix a few crashes). This increases the savestate version though, so make sure you have a memory card save ready before upgrading! Also implemented a way of delaying audio output after loading states. This masks the ugly noise that some games produce directly after loading, keeping your valuable speakers intact :p git-svn-id: http://pcsx2.googlecode.com/svn/trunk@963 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
6830f07f27
commit
ad6dce5e9c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
@ -272,6 +273,7 @@ public:
|
|||
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 );
|
||||
|
|
|
@ -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)();
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue