X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=pcsx_rearmed.git;a=blobdiff_plain;f=plugins%2Fdfsound%2Fspu.c;h=6cefd112151e4cebd89bc5b87bbd4e406bf66b5f;hp=1456a21cd92834d7e78ae01bef319223d2c575a9;hb=16187bfb1518db23ade931cd7358ba973a585180;hpb=e34a4bd3b3eec3f95f5ce0cac1c4d47bf03a0409 diff --git a/plugins/dfsound/spu.c b/plugins/dfsound/spu.c index 1456a21c..6cefd112 100644 --- a/plugins/dfsound/spu.c +++ b/plugins/dfsound/spu.c @@ -444,24 +444,30 @@ static int decode_block(int ch) { unsigned char *start; int predict_nr,shift_factor,flags; + int stop = 0; int ret = 0; - start=s_chan[ch].pCurr; // set up the current pos + start = s_chan[ch].pCurr; // set up the current pos + if(start == spuMemC) // ? + stop = 1; if(s_chan[ch].prevflags&1) // 1: stop/loop { if(!(s_chan[ch].prevflags&2)) - { - dwChannelOn&=~(1< turn everything off - s_chan[ch].bStop=1; - s_chan[ch].ADSRX.EnvelopeVol=0; - } + stop = 1; start = s_chan[ch].pLoop; } else ret = check_irq(ch, start); // hack, see check_irq below.. + if(stop) + { + dwChannelOn &= ~(1< turn everything off + s_chan[ch].bStop = 1; + s_chan[ch].ADSRX.EnvelopeVol = 0; + } + predict_nr=(int)start[0]; shift_factor=predict_nr&0xf; predict_nr >>= 4; @@ -665,12 +671,13 @@ static void noinline do_decode_bufs(int which, int start, int count) { const int *src = ChanBuf + start; unsigned short *dst = &spuMem[0x800/2 + which*0x400/2]; - int cursor = decode_pos; + int cursor = decode_pos + start; while (count-- > 0) { + cursor &= 0x1ff; dst[cursor] = *src++; - cursor = (cursor + 1) & 0x1ff; + cursor++; } // decode_pos is updated and irqs are checked later, after voice loop @@ -700,8 +707,6 @@ static int do_samples(int forced_updates) while(!bIRQReturn) { - cycles_since_update = 0; - ns_from=0; ns_to=NSSIZE; ch=0; @@ -770,9 +775,9 @@ static int do_samples(int forced_updates) // no need for bIRQReturn since the channel is silent skip_block(ch); - if(start == s_chan[ch].pCurr) + if(start == s_chan[ch].pCurr || start - spuMemC < 0x1000) { - // looping on self + // looping on self or stopped(?) dwChannelDead |= 1<busy()) break; } + + if(cycles_since_update <= -PSXCLK/60 / 4) + break; } + // this may cause desync, but help audio when the emu can't keep up.. + if(cycles_since_update < 0) + cycles_since_update = 0; + return 0; } @@ -893,7 +907,6 @@ static int do_samples(int forced_updates) void CALLBACK SPUasync(unsigned long cycle) { - static int old_ctrl; int forced_updates = 0; int do_update = 0; @@ -908,16 +921,8 @@ void CALLBACK SPUasync(unsigned long cycle) had_dma = 0; } - if((spuCtrl&CTRL_IRQ) && (((spuCtrl^old_ctrl)&CTRL_IRQ) // irq was enabled - || cycles_since_update > PSXCLK/60 / 4)) { + if(cycles_since_update > PSXCLK/60 * 5/4) do_update = 1; - forced_updates = cycles_since_update / (PSXCLK/44100) / NSSIZE; - } - // with no irqs, once per frame should be fine (using a bit more because of BIAS) - else if(cycles_since_update > PSXCLK/60 * 5/4) - do_update = 1; - - old_ctrl = spuCtrl; if(do_update) do_samples(forced_updates);