diff --git a/plugins/spu2-x/src/defs.h b/plugins/spu2-x/src/defs.h index 24b0f664eb..575a20e875 100644 --- a/plugins/spu2-x/src/defs.h +++ b/plugins/spu2-x/src/defs.h @@ -189,7 +189,9 @@ struct V_Voice // sample position within the current decoded packet. s32 SCurrent; - void Start(); + // it takes a few ticks for voices to start on the real SPU2? + void QueueStart(); + bool Start(); void Stop(); }; @@ -436,6 +438,8 @@ struct V_Core u32 MADR; u32 TADR; + u32 KeyOn; // not the KON register (though maybe it is) + StereoOut32 downbuf[8]; StereoOut32 upbuf[8]; int dbpos, ubpos; diff --git a/plugins/spu2-x/src/spu2freeze.cpp b/plugins/spu2-x/src/spu2freeze.cpp index f18e0fbe12..572ba07a0e 100644 --- a/plugins/spu2-x/src/spu2freeze.cpp +++ b/plugins/spu2-x/src/spu2freeze.cpp @@ -25,7 +25,7 @@ namespace Savestate // versioning for saves. // Increment this when changes to the savestate system are made. - static const u32 SAVE_VERSION = 0x000b; + static const u32 SAVE_VERSION = 0x000c; static void wipe_the_cache() { diff --git a/plugins/spu2-x/src/spu2sys.cpp b/plugins/spu2-x/src/spu2sys.cpp index 2ca84a12d4..3557693fe3 100644 --- a/plugins/spu2-x/src/spu2sys.cpp +++ b/plugins/spu2-x/src/spu2sys.cpp @@ -303,7 +303,16 @@ void V_Core::UpdateEffectsBufferSize() RevBuffers.MIX_DEST_B1 = EffectsBufferIndexer( Revb.MIX_DEST_B1 ); } -void V_Voice::Start() +void V_Voice::QueueStart() +{ + if (Cycles - PlayCycle < 4) + { + printf(" *** KeyOn after less than 4 T disregarded.\n"); + } + PlayCycle = Cycles; +} + +bool V_Voice::Start() { if((Cycles-PlayCycle)>=4) { @@ -316,7 +325,6 @@ void V_Voice::Start() ADSR.Releasing = false; ADSR.Value = 1; ADSR.Phase = 1; - PlayCycle = Cycles; SCurrent = 28; LoopMode = 0; LoopFlags = 0; @@ -327,11 +335,10 @@ void V_Voice::Start() PV1 = PV2 = 0; PV3 = PV4 = 0; NextCrest = -0x8000; + return true; } else - { - printf(" *** KeyOn after less than 4 T disregarded.\n"); - } + return false; } void V_Voice::Stop() @@ -421,6 +428,13 @@ __forceinline void TimeUpdate(u32 cClocks) lClocks += TickInterval; Cycles++; + for (int i = 0; i < 2; i++) + if (Cores[i].KeyOn) + for (int j = 0; j < 24; j++) + if (Cores[i].KeyOn >> j & 1) + if (Cores[i].Voices[j].Start()) + Cores[i].KeyOn &= ~(1 << j); + // Note: IOP does not use MMX regs, so no need to save them. //SaveMMXRegs(); Mix(); @@ -1528,11 +1542,13 @@ void StartVoices(int core, u32 value) Cores[core].Regs.ENDX &= ~value; + Cores[core].KeyOn |= value; + for( u8 vc=0; vc>vc) & 1) ) continue; - Cores[core].Voices[vc].Start(); + Cores[core].Voices[vc].QueueStart(); if( IsDevBuild ) {