From a4eaf7dc19a2a848be36055de473dda932889db7 Mon Sep 17 00:00:00 2001 From: StapleButter Date: Fri, 14 Dec 2018 00:14:06 +0100 Subject: [PATCH] SPU: * support channel repeat mode 3, behaves same as mode 1 (loops) * always clear channel buffers, so if channels 0-7 use format 3, they don't output old data over and over again (fixes #281) --- src/SPU.cpp | 47 ++++++++++++++++++++--------------------------- src/SPU.h | 3 +++ 2 files changed, 23 insertions(+), 27 deletions(-) diff --git a/src/SPU.cpp b/src/SPU.cpp index 034e1aa3..19eb98ea 100644 --- a/src/SPU.cpp +++ b/src/SPU.cpp @@ -204,8 +204,8 @@ void Channel::FIFO_BufferData() if (FIFOReadOffset >= totallen) { u32 repeatmode = (Cnt >> 27) & 0x3; - if (repeatmode == 2) return; // one-shot sound, we're done - if (repeatmode == 1) FIFOReadOffset = LoopPos; + if (repeatmode & 1) FIFOReadOffset = LoopPos; + else if (repeatmode & 2) return; // one-shot sound, we're done } u32 burstlen = 16; @@ -255,11 +255,10 @@ void Channel::Start() FIFOReadOffset = 0; FIFOLevel = 0; - // when starting a channel, two 4-word chunks are buffered + // when starting a channel, buffer data if (((Cnt >> 29) & 0x3) != 3) { FIFO_BufferData(); - FIFO_BufferData(); } } @@ -269,18 +268,17 @@ void Channel::NextSample_PCM8() if (Pos < 0) return; if (Pos >= (LoopPos + Length)) { - // TODO: what happens when mode 3 is used? u32 repeat = (Cnt >> 27) & 0x3; - if (repeat == 2) + if (repeat & 1) + { + Pos = LoopPos; + } + else if (repeat & 2) { CurSample = 0; Cnt &= ~(1<<31); return; } - else if (repeat == 1) - { - Pos = LoopPos; - } } s8 val = FIFO_ReadData(); @@ -293,18 +291,17 @@ void Channel::NextSample_PCM16() if (Pos < 0) return; if ((Pos<<1) >= (LoopPos + Length)) { - // TODO: what happens when mode 3 is used? u32 repeat = (Cnt >> 27) & 0x3; - if (repeat == 2) + if (repeat & 1) + { + Pos = LoopPos>>1; + } + else if (repeat & 2) { CurSample = 0; Cnt &= ~(1<<31); return; } - else if (repeat == 1) - { - Pos = LoopPos>>1; - } } s16 val = FIFO_ReadData(); @@ -333,21 +330,20 @@ void Channel::NextSample_ADPCM() if ((Pos>>1) >= (LoopPos + Length)) { - // TODO: what happens when mode 3 is used? u32 repeat = (Cnt >> 27) & 0x3; - if (repeat == 2) - { - CurSample = 0; - Cnt &= ~(1<<31); - return; - } - else if (repeat == 1) + if (repeat & 1) { Pos = LoopPos<<1; ADPCMVal = ADPCMValLoop; ADPCMIndex = ADPCMIndexLoop; ADPCMCurByte = FIFO_ReadData(); } + else if (repeat & 2) + { + CurSample = 0; + Cnt &= ~(1<<31); + return; + } } else { @@ -410,9 +406,6 @@ void Channel::NextSample_Noise() template void Channel::Run(s32* buf, u32 samples) { - for (u32 s = 0; s < samples; s++) - buf[s] = 0; - if (!(Cnt & (1<<31))) return; for (u32 s = 0; s < samples; s++) diff --git a/src/SPU.h b/src/SPU.h index d340a724..a7afbf7f 100644 --- a/src/SPU.h +++ b/src/SPU.h @@ -121,6 +121,9 @@ public: void DoRun(s32* buf, u32 samples) { + for (u32 s = 0; s < samples; s++) + buf[s] = 0; + switch ((Cnt >> 29) & 0x3) { case 0: Run<0>(buf, samples); break;