mirror of https://github.com/PCSX2/pcsx2.git
SPU: Wait 2T when keying on a voice
Just like Delay cycles used to do, but done better and tested on a PS2 to get the correct timings
This commit is contained in:
parent
2415fd3415
commit
97ed78109c
|
@ -193,7 +193,7 @@ struct V_Voice
|
|||
s32 SCurrent;
|
||||
|
||||
// it takes a few ticks for voices to start on the real SPU2?
|
||||
bool Start();
|
||||
void Start();
|
||||
void Stop();
|
||||
};
|
||||
|
||||
|
|
|
@ -336,32 +336,11 @@ void V_Core::UpdateEffectsBufferSize()
|
|||
RevBuffers.APF2_R_SRC = EffectsBufferIndexer(Revb.APF2_R_DST - Revb.APF2_SIZE);
|
||||
}
|
||||
|
||||
bool V_Voice::Start()
|
||||
void V_Voice::Start()
|
||||
{
|
||||
if (StartA & 7)
|
||||
{
|
||||
fprintf(stderr, " *** Misaligned StartA %05x!\n", StartA);
|
||||
StartA = (StartA + 0xFFFF8) + 0x8;
|
||||
}
|
||||
|
||||
ADSR.Releasing = false;
|
||||
ADSR.Value = 1;
|
||||
ADSR.Phase = 1;
|
||||
SCurrent = 28;
|
||||
LoopMode = 0;
|
||||
SP = 0;
|
||||
LoopFlags = 0;
|
||||
NextA = StartA | 1;
|
||||
Prev1 = 0;
|
||||
Prev2 = 0;
|
||||
PendingLoopStart = false;
|
||||
|
||||
PV1 = PV2 = 0;
|
||||
PV3 = PV4 = 0;
|
||||
NextCrest = -0x8000;
|
||||
PlayCycle = Cycles;
|
||||
LoopCycle = Cycles - 1; // Get it out of the start range as to not confuse it
|
||||
return true;
|
||||
PendingLoopStart = false;
|
||||
}
|
||||
|
||||
void V_Voice::Stop()
|
||||
|
@ -374,6 +353,37 @@ uint TickInterval = 768;
|
|||
static const int SanityInterval = 4800;
|
||||
extern void UpdateDebugDialog();
|
||||
|
||||
__forceinline bool StartQueuedVoice(uint coreidx, uint voiceidx)
|
||||
{
|
||||
V_Voice& vc(Cores[coreidx].Voices[voiceidx]);
|
||||
|
||||
if ((Cycles - vc.PlayCycle) < 2)
|
||||
return false;
|
||||
|
||||
if (vc.StartA & 7)
|
||||
{
|
||||
fprintf(stderr, " *** Misaligned StartA %05x!\n", vc.StartA);
|
||||
vc.StartA = (vc.StartA + 0xFFFF8) + 0x8;
|
||||
}
|
||||
|
||||
vc.ADSR.Releasing = false;
|
||||
vc.ADSR.Value = 1;
|
||||
vc.ADSR.Phase = 1;
|
||||
vc.SCurrent = 28;
|
||||
vc.LoopMode = 0;
|
||||
vc.SP = 0;
|
||||
vc.LoopFlags = 0;
|
||||
vc.NextA = vc.StartA | 1;
|
||||
vc.Prev1 = 0;
|
||||
vc.Prev2 = 0;
|
||||
|
||||
vc.PV1 = vc.PV2 = 0;
|
||||
vc.PV3 = vc.PV4 = 0;
|
||||
vc.NextCrest = -0x8000;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
__forceinline void TimeUpdate(u32 cClocks)
|
||||
{
|
||||
u32 dClocks = cClocks - lClocks;
|
||||
|
@ -429,6 +439,12 @@ __forceinline void TimeUpdate(u32 cClocks)
|
|||
lClocks += TickInterval;
|
||||
Cycles++;
|
||||
|
||||
// Start Queued Voices, they start after 2T (Tested on real HW)
|
||||
for(int c = 0; c < 2; c++)
|
||||
for (int v = 0; v < 24; v++)
|
||||
if(Cores[c].KeyOn & (1 << v))
|
||||
if(StartQueuedVoice(c, v))
|
||||
Cores[c].KeyOn &= ~(1 << v);
|
||||
// Note: IOP does not use MMX regs, so no need to save them.
|
||||
//SaveMMXRegs();
|
||||
Mix();
|
||||
|
@ -1970,8 +1986,7 @@ void StartVoices(int core, u32 value)
|
|||
if (!((value >> vc) & 1))
|
||||
continue;
|
||||
|
||||
if (Cores[core].Voices[vc].Start())
|
||||
Cores[core].KeyOn &= ~(1 << vc);
|
||||
Cores[core].Voices[vc].Start();
|
||||
|
||||
if (IsDevBuild)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue