X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=plugins%2Fdfsound%2Fspu.c;h=7f8ab1df97e0b910f1421a21469f8ab71def3f01;hb=88b0dc1df1a0e7b6ec0a505bcb0c19061f8dab6e;hp=fbd555b179877bccbe49b8dce4995a43693ffd61;hpb=5fdcf5cd320abef2c685630e3edf3598645d141e;p=pcsx_rearmed.git diff --git a/plugins/dfsound/spu.c b/plugins/dfsound/spu.c index fbd555b1..7f8ab1df 100644 --- a/plugins/dfsound/spu.c +++ b/plugins/dfsound/spu.c @@ -212,7 +212,7 @@ static void do_irq(void) static int check_irq(int ch, unsigned char *pos) { - if((spu.spuCtrl & CTRL_IRQ) && pos == spu.pSpuIrq) + if((spu.spuCtrl & (CTRL_ON|CTRL_IRQ)) == (CTRL_ON|CTRL_IRQ) && pos == spu.pSpuIrq) { //printf("ch%d irq %04x\n", ch, pos - spu.spuMemC); do_irq(); @@ -221,6 +221,17 @@ static int check_irq(int ch, unsigned char *pos) return 0; } +void check_irq_io(unsigned int addr) +{ + unsigned int irq_addr = regAreaGet(H_SPUirqAddr) << 3; + //addr &= ~7; // ? + if((spu.spuCtrl & (CTRL_ON|CTRL_IRQ)) == (CTRL_ON|CTRL_IRQ) && addr == irq_addr) + { + //printf("io irq %04x\n", irq_addr); + do_irq(); + } +} + //////////////////////////////////////////////////////////////////////// // START SOUND... called by main thread to setup a new sound on a channel //////////////////////////////////////////////////////////////////////// @@ -251,8 +262,7 @@ static void StartSoundMain(int ch) spu.dwNewChannel&=~(1<iRawPitch) - spu.dwChannelsAudible|=1<> 6) & ~3; gpos = SB[28]; - vr=(gauss[vl]*(int)gval0)&~2047; - vr+=(gauss[vl+1]*gval(1))&~2047; - vr+=(gauss[vl+2]*gval(2))&~2047; - vr+=(gauss[vl+3]*gval(3))&~2047; - fa = vr>>11; + vr=(gauss[vl]*(int)gval0) >> 15; + vr+=(gauss[vl+1]*gval(1)) >> 15; + vr+=(gauss[vl+2]*gval(2)) >> 15; + vr+=(gauss[vl+3]*gval(3)) >> 15; + fa = vr; } break; //--------------------------------------------------// case 1: // simple interpolation @@ -426,8 +436,8 @@ static int decode_block(void *unused, int ch, int *SB) start = s_chan->pLoop; } - else - check_irq(ch, start); // hack, see check_irq below.. + + check_irq(ch, start); predict_nr = start[0]; shift_factor = predict_nr & 0xf; @@ -436,19 +446,11 @@ static int decode_block(void *unused, int ch, int *SB) decode_block_data(SB, start + 2, predict_nr, shift_factor); flags = start[1]; - if (flags & 4 && (!s_chan->bIgnoreLoop)) + if (flags & 4 && !s_chan->bIgnoreLoop) s_chan->pLoop = start; // loop adress start += 16; - if (flags & 1) { // 1: stop/loop - start = s_chan->pLoop; - check_irq(ch, start); // hack.. :( - } - - if (start - spu.spuMemC >= 0x80000) - start = spu.spuMemC; - s_chan->pCurr = start; // store values for next cycle s_chan->prevflags = flags; @@ -469,20 +471,15 @@ static int skip_block(int ch) start = s_chan->pLoop; } - else - check_irq(ch, start); + + check_irq(ch, start); flags = start[1]; - if (flags & 4) + if (flags & 4 && !s_chan->bIgnoreLoop) s_chan->pLoop = start; start += 16; - if (flags & 1) { - start = s_chan->pLoop; - check_irq(ch, start); - } - s_chan->pCurr = start; s_chan->prevflags = flags; @@ -511,8 +508,6 @@ static void scan_for_irq(int ch, unsigned int *upd_samples) block += 16; if (flags & 1) { // 1: stop/loop block = s_chan->pLoop; - if (block == spu.pSpuIrq) // hack.. (see decode_block) - break; } pos += 28 << 16; } @@ -965,6 +960,7 @@ static void queue_channel_work(int ns_to, unsigned int silentch) d = SkipADSR(&s_chan->ADSRX, d); if (d < ns_to) { spu.dwChannelsAudible &= ~(1 << ch); + s_chan->ADSRX.State = ADSR_RELEASE; s_chan->ADSRX.EnvelopeVol = 0; } } @@ -1151,6 +1147,7 @@ void do_samples(unsigned int cycles_to, int do_direct) do_irq(); } } + check_irq_io(spu.spuAddr); if (unlikely(spu.rvb->dirty)) REVERBPrep(); @@ -1208,13 +1205,13 @@ static void do_samples_finish(int *SSumLR, int ns_to, for (ns = 0; ns < ns_to * 2; ) { d = SSumLR[ns]; SSumLR[ns] = 0; - d = d * vol_l >> 15; + d = d * vol_l >> 14; ssat32_to_16(d); *spu.pS++ = d; ns++; d = SSumLR[ns]; SSumLR[ns] = 0; - d = d * vol_r >> 15; + d = d * vol_r >> 14; ssat32_to_16(d); *spu.pS++ = d; ns++; @@ -1298,20 +1295,26 @@ void CALLBACK SPUupdate(void) // XA AUDIO -void CALLBACK SPUplayADPCMchannel(xa_decode_t *xap) +void CALLBACK SPUplayADPCMchannel(xa_decode_t *xap, unsigned int cycle, int is_start) { if(!xap) return; - if(!xap->freq) return; // no xa freq ? bye + if(!xap->freq) return; // no xa freq ? bye - FeedXA(xap); // call main XA feeder + if (is_start) + do_samples(cycle, 1); // catch up to prevent source underflows later + + FeedXA(xap); // call main XA feeder } // CDDA AUDIO -int CALLBACK SPUplayCDDAchannel(short *pcm, int nbytes) +int CALLBACK SPUplayCDDAchannel(short *pcm, int nbytes, unsigned int cycle, int is_start) { if (!pcm) return -1; if (nbytes<=0) return -1; + if (is_start) + do_samples(cycle, 1); // catch up to prevent source underflows later + return FeedCDDA((unsigned char *)pcm, nbytes); }