X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=pcsx_rearmed.git;a=blobdiff_plain;f=plugins%2Fdfsound%2Fspu.c;h=7d3f1a0efc2a479d48a41fafb0ae76424ada29eb;hp=bbbe1e372739a02c1067b04715ca6e56a3c41d68;hb=2b30c1291db9d9801d51cf85f71f40fe54958898;hpb=f05d6ca255c80170e4e5fc61cc48d87e013b8807 diff --git a/plugins/dfsound/spu.c b/plugins/dfsound/spu.c index bbbe1e37..7d3f1a0e 100644 --- a/plugins/dfsound/spu.c +++ b/plugins/dfsound/spu.c @@ -24,7 +24,8 @@ #include "externals.h" #include "registers.h" -#include "dsoundoss.h" +#include "out.h" +#include "arm_features.h" #ifdef ENABLE_NLS #include @@ -443,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; @@ -615,7 +622,7 @@ static int do_samples_noise(int ch, int ns, int ns_to) return ret; } -#ifdef __arm__ +#ifdef HAVE_ARMV5 // asm code; lv and rv must be 0-3fff extern void mix_chan(int start, int count, int lv, int rv); extern void mix_chan_rvb(int start, int count, int lv, int rv); @@ -664,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 @@ -684,30 +692,21 @@ static void noinline do_decode_bufs(int which, int start, int count) static int do_samples(int forced_updates) { int volmult = iVolume; - int ns,ns_from,ns_to; + int ns,ns_from,ns_to,ns_len; int ch,d,silentch; int bIRQReturn=0; - while(1) - { - // ok, at the beginning we are looking if there is - // enuff free place in the dsound/oss buffer to - // fill in new data, or if there is a new channel to start. - // if not, we wait (thread) or return (timer/spuasync) - // until enuff free place is available/a new channel gets - // started - - if(!forced_updates && SoundGetBytesBuffered()) // still enuff data in sound buffer? - { - return 0; - } - - cycles_since_update = 0; - if(forced_updates > 0) - forced_updates--; + // ok, at the beginning we are looking if there is + // enuff free place in the dsound/oss buffer to + // fill in new data, or if there is a new channel to start. + // if not, we return until enuff free place is available + // /a new channel gets started - //--------------------------------------------------// continue from irq handling in timer mode? + if(!forced_updates && out_current->busy()) // still enuff data in sound buffer? + return 0; + while(!bIRQReturn) + { ns_from=0; ns_to=NSSIZE; ch=0; @@ -741,21 +740,22 @@ static int do_samples(int forced_updates) lastch=ch; lastns=ns_to=d; } + ns_len = ns_to - ns_from; MixADSR(ch, ns_from, ns_to); if(ch==1 || ch==3) { - do_decode_bufs(ch/2, ns_from, ns_to-ns_from); + do_decode_bufs(ch/2, ns_from, ns_len); decode_dirty_ch |= 1< 16/FRAG_MSECS) + if (iCycle++ >= 16/FRAG_MSECS) { - SoundFeedStreamData((unsigned char *)pSpuBuffer, - ((unsigned char *)pS) - ((unsigned char *)pSpuBuffer)); + out_current->feed(pSpuBuffer, (unsigned char *)pS - pSpuBuffer); pS = (short *)pSpuBuffer; iCycle = 0; + + if(!forced_updates && out_current->busy()) + break; } + + if(forced_updates > 0) + { + forced_updates--; + if(forced_updates == 0 && out_current->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; } @@ -889,7 +908,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; @@ -904,16 +922,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); @@ -1056,7 +1066,7 @@ long CALLBACK SPUclose(void) bSPUIsOpen = 0; // no more open - RemoveSound(); // no more sound handling + out_current->finish(); // no more sound handling return 0; } @@ -1111,6 +1121,10 @@ void CALLBACK SPUregisterCDDAVolume(void (CALLBACK *CDDAVcallback)(unsigned shor cddavCallback = CDDAVcallback; } +void CALLBACK SPUregisterScheduleCb(void (CALLBACK *callback)(unsigned int)) +{ +} + // COMMON PLUGIN INFO FUNCS /* char * CALLBACK PSEgetLibName(void)