- fixed a bug in SPU when total length of the samples is less than 16 bytes (fixed issue [#1357])
This commit is contained in:
mtabachenko 2013-11-30 12:48:25 +00:00
parent dba7e21423
commit 0191b680c4
2 changed files with 18 additions and 5 deletions

View File

@ -750,6 +750,8 @@ void SPU_struct::WriteByte(u32 addr, u8 val)
u8 chan_num = (addr >> 4) & 0xF; u8 chan_num = (addr >> 4) & 0xF;
channel_struct &thischan=channels[chan_num]; channel_struct &thischan=channels[chan_num];
//printf("SPU write08 channel%d, reg %04X, val %02X\n", chan_num, addr, val);
switch (addr & 0x000F) switch (addr & 0x000F)
{ {
case 0x0: thischan.vol = (val & 0x7F); break; case 0x0: thischan.vol = (val & 0x7F); break;
@ -844,6 +846,8 @@ void SPU_struct::WriteWord(u32 addr, u16 val)
u32 chan_num = (addr >> 4) & 0xF; u32 chan_num = (addr >> 4) & 0xF;
channel_struct &thischan=channels[chan_num]; channel_struct &thischan=channels[chan_num];
//printf("SPU write16 channel%d, reg %04X, val %04X\n", chan_num, addr, val);
switch (addr & 0xF) switch (addr & 0xF)
{ {
case 0x0: case 0x0:
@ -929,6 +933,8 @@ void SPU_struct::WriteLong(u32 addr, u32 val)
u32 chan_num = (addr >> 4) & 0xF; u32 chan_num = (addr >> 4) & 0xF;
channel_struct &thischan=channels[chan_num]; channel_struct &thischan=channels[chan_num];
//printf("SPU write32 channel%d, reg %04X, val %08X\n", chan_num, addr, val);
switch (addr & 0xF) switch (addr & 0xF)
{ {
case 0x0: case 0x0:
@ -1211,6 +1217,12 @@ template<int FORMAT> static FORCEINLINE void TestForLoop(SPU_struct *SPU, channe
static FORCEINLINE void TestForLoop2(SPU_struct *SPU, channel_struct *chan) static FORCEINLINE void TestForLoop2(SPU_struct *SPU, channel_struct *chan)
{ {
// Minimum length (the sum of PNT+LEN) is 4 words (16 bytes),
// smaller values (0..3 words) are causing hang-ups
// (busy bit remains set infinite, but no sound output occurs).
// fix: 7th Dragon (JP) - http://sourceforge.net/p/desmume/bugs/1357/
if (chan->totlength < 4) return;
chan->sampcnt += chan->sampinc; chan->sampcnt += chan->sampinc;
if (chan->sampcnt > chan->double_totlength_shifted) if (chan->sampcnt > chan->double_totlength_shifted)
@ -1218,8 +1230,9 @@ static FORCEINLINE void TestForLoop2(SPU_struct *SPU, channel_struct *chan)
// Do we loop? Or are we done? // Do we loop? Or are we done?
if (chan->repeat == 1) if (chan->repeat == 1)
{ {
while (chan->sampcnt > chan->double_totlength_shifted) double step = (chan->double_totlength_shifted - (double)(chan->loopstart << 3));
chan->sampcnt -= chan->double_totlength_shifted - (double)(chan->loopstart << 3);
while (chan->sampcnt > chan->double_totlength_shifted) chan->sampcnt -= step;
if(chan->loop_index == K_ADPCM_LOOPING_RECOVERY_INDEX) if(chan->loop_index == K_ADPCM_LOOPING_RECOVERY_INDEX)
{ {

View File

@ -87,9 +87,9 @@ struct channel_struct
loopstart(0), loopstart(0),
length(0), length(0),
totlength(0), totlength(0),
double_totlength_shifted(0.f), double_totlength_shifted(0.0),
sampcnt(0.f), sampcnt(0.0),
sampinc(0.f), sampinc(0.0),
lastsampcnt(0), lastsampcnt(0),
pcm16b(0), pcm16b(0),
pcm16b_last(0), pcm16b_last(0),