* 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)
This commit is contained in:
StapleButter 2018-12-14 00:14:06 +01:00
parent 68d5e3c782
commit a4eaf7dc19
2 changed files with 23 additions and 27 deletions

View File

@ -204,8 +204,8 @@ void Channel::FIFO_BufferData()
if (FIFOReadOffset >= totallen) if (FIFOReadOffset >= totallen)
{ {
u32 repeatmode = (Cnt >> 27) & 0x3; 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; u32 burstlen = 16;
@ -255,11 +255,10 @@ void Channel::Start()
FIFOReadOffset = 0; FIFOReadOffset = 0;
FIFOLevel = 0; FIFOLevel = 0;
// when starting a channel, two 4-word chunks are buffered // when starting a channel, buffer data
if (((Cnt >> 29) & 0x3) != 3) if (((Cnt >> 29) & 0x3) != 3)
{ {
FIFO_BufferData(); FIFO_BufferData();
FIFO_BufferData();
} }
} }
@ -269,18 +268,17 @@ void Channel::NextSample_PCM8()
if (Pos < 0) return; if (Pos < 0) return;
if (Pos >= (LoopPos + Length)) if (Pos >= (LoopPos + Length))
{ {
// TODO: what happens when mode 3 is used?
u32 repeat = (Cnt >> 27) & 0x3; u32 repeat = (Cnt >> 27) & 0x3;
if (repeat == 2) if (repeat & 1)
{
Pos = LoopPos;
}
else if (repeat & 2)
{ {
CurSample = 0; CurSample = 0;
Cnt &= ~(1<<31); Cnt &= ~(1<<31);
return; return;
} }
else if (repeat == 1)
{
Pos = LoopPos;
}
} }
s8 val = FIFO_ReadData<s8>(); s8 val = FIFO_ReadData<s8>();
@ -293,18 +291,17 @@ void Channel::NextSample_PCM16()
if (Pos < 0) return; if (Pos < 0) return;
if ((Pos<<1) >= (LoopPos + Length)) if ((Pos<<1) >= (LoopPos + Length))
{ {
// TODO: what happens when mode 3 is used?
u32 repeat = (Cnt >> 27) & 0x3; u32 repeat = (Cnt >> 27) & 0x3;
if (repeat == 2) if (repeat & 1)
{
Pos = LoopPos>>1;
}
else if (repeat & 2)
{ {
CurSample = 0; CurSample = 0;
Cnt &= ~(1<<31); Cnt &= ~(1<<31);
return; return;
} }
else if (repeat == 1)
{
Pos = LoopPos>>1;
}
} }
s16 val = FIFO_ReadData<s16>(); s16 val = FIFO_ReadData<s16>();
@ -333,21 +330,20 @@ void Channel::NextSample_ADPCM()
if ((Pos>>1) >= (LoopPos + Length)) if ((Pos>>1) >= (LoopPos + Length))
{ {
// TODO: what happens when mode 3 is used?
u32 repeat = (Cnt >> 27) & 0x3; u32 repeat = (Cnt >> 27) & 0x3;
if (repeat == 2) if (repeat & 1)
{
CurSample = 0;
Cnt &= ~(1<<31);
return;
}
else if (repeat == 1)
{ {
Pos = LoopPos<<1; Pos = LoopPos<<1;
ADPCMVal = ADPCMValLoop; ADPCMVal = ADPCMValLoop;
ADPCMIndex = ADPCMIndexLoop; ADPCMIndex = ADPCMIndexLoop;
ADPCMCurByte = FIFO_ReadData<u8>(); ADPCMCurByte = FIFO_ReadData<u8>();
} }
else if (repeat & 2)
{
CurSample = 0;
Cnt &= ~(1<<31);
return;
}
} }
else else
{ {
@ -410,9 +406,6 @@ void Channel::NextSample_Noise()
template<u32 type> template<u32 type>
void Channel::Run(s32* buf, u32 samples) void Channel::Run(s32* buf, u32 samples)
{ {
for (u32 s = 0; s < samples; s++)
buf[s] = 0;
if (!(Cnt & (1<<31))) return; if (!(Cnt & (1<<31))) return;
for (u32 s = 0; s < samples; s++) for (u32 s = 0; s < samples; s++)

View File

@ -121,6 +121,9 @@ public:
void DoRun(s32* buf, u32 samples) void DoRun(s32* buf, u32 samples)
{ {
for (u32 s = 0; s < samples; s++)
buf[s] = 0;
switch ((Cnt >> 29) & 0x3) switch ((Cnt >> 29) & 0x3)
{ {
case 0: Run<0>(buf, samples); break; case 0: Run<0>(buf, samples); break;