From f1cffa6f7fd8e85a2d2df35b7c18ca2e4d3606ab Mon Sep 17 00:00:00 2001 From: "sudonim1@gmail.com" Date: Fri, 21 Sep 2012 15:17:16 +0000 Subject: [PATCH] SPU2-X: Delay starting voices for 4 SPU2 cycles after key on. No idea if this is right, but there must be a reason some register writes aren't effective for a few cycles after key on, and this seems likely. Fixes DQ5 adventure log music and Le Mans 24 Hours everything. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@5418 96395faa-99c1-11dd-bbfe-3dabce05a288 --- plugins/spu2-x/src/defs.h | 6 +++++- plugins/spu2-x/src/spu2freeze.cpp | 2 +- plugins/spu2-x/src/spu2sys.cpp | 28 ++++++++++++++++++++++------ 3 files changed, 28 insertions(+), 8 deletions(-) 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 ) {