X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=plugins%2Fdfsound%2Fspu.c;h=ebebd2a2c11cc6789c5c2dac9a6bed87adf40ab9;hb=16809ab9f432e902b4b049b4f1f01a0f42e92914;hp=1127cd7113d0b10a919717e9a2d2d6d7cf5f71ee;hpb=1d5d35bc9d0d3d84873cd1d31870d09248ddc05b;p=pcsx_rearmed.git diff --git a/plugins/dfsound/spu.c b/plugins/dfsound/spu.c index 1127cd71..ebebd2a2 100644 --- a/plugins/dfsound/spu.c +++ b/plugins/dfsound/spu.c @@ -18,8 +18,7 @@ * * ***************************************************************************/ -#if !defined(_WIN32) && !defined(NO_OS) -#include // gettimeofday in xa.c +#if !defined(THREAD_ENABLED) && !defined(_WIN32) && !defined(NO_OS) #define THREAD_ENABLED 1 #endif #include "stdafx.h" @@ -212,7 +211,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 +220,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 //////////////////////////////////////////////////////////////////////// @@ -275,9 +285,8 @@ INLINE int FModChangeFrequency(int *SB, int pitch, int ns) if(NP<0x1) NP=0x1; sinc=NP<<4; // calc frequency - if(spu_config.iUseInterpolation==1) // freq change in simple interpolation mode - SB[32]=1; iFMod[ns]=0; + SB[32]=1; // reset interpolation return sinc; } @@ -769,6 +778,9 @@ static void do_channels(int ns_to) s_chan = &spu.s_chan[ch]; SB = spu.SB + ch * SB_SIZE; sinc = s_chan->sinc; + if (spu.s_chan[ch].bNewPitch) + SB[32] = 1; // reset interpolation + spu.s_chan[ch].bNewPitch = 0; if (s_chan->bNoise) d = do_samples_noise(ch, ns_to); @@ -857,11 +869,14 @@ static struct spu_worker { int sinc; int start; int loop; - int ns_to; short vol_l; short vol_r; + unsigned short ns_to; + unsigned short bNoise:1; + unsigned short bFMod:2; + unsigned short bRVBActive:1; + unsigned short bNewPitch:1; ADSRInfoEx adsr; - // might also want to add fmod flags.. } ch[24]; int SSumLR[NSSIZE * 2]; } i[4]; @@ -939,6 +954,10 @@ static void queue_channel_work(int ns_to, unsigned int silentch) work->ch[ch].vol_r = s_chan->iRightVolume; work->ch[ch].start = s_chan->pCurr - spu.spuMemC; work->ch[ch].loop = s_chan->pLoop - spu.spuMemC; + work->ch[ch].bNoise = s_chan->bNoise; + work->ch[ch].bFMod = s_chan->bFMod; + work->ch[ch].bRVBActive = s_chan->bRVBActive; + work->ch[ch].bNewPitch = s_chan->bNewPitch; if (s_chan->prevflags & 1) work->ch[ch].start = work->ch[ch].loop; @@ -952,6 +971,7 @@ static void queue_channel_work(int ns_to, unsigned int silentch) s_chan->ADSRX.State = ADSR_RELEASE; s_chan->ADSRX.EnvelopeVol = 0; } + s_chan->bNewPitch = 0; } work->rvb_addr = 0; @@ -971,8 +991,6 @@ static void queue_channel_work(int ns_to, unsigned int silentch) static void do_channel_work(struct work_item *work) { unsigned int mask; - unsigned int decode_dirty_ch = 0; - const SPUCHAN *s_chan; int *SB, sinc, spos, sbpos; int d, ch, ns_to; @@ -997,15 +1015,16 @@ static void do_channel_work(struct work_item *work) sbpos = work->ch[ch].sbpos; sinc = work->ch[ch].sinc; - s_chan = &spu.s_chan[ch]; SB = spu.SB + ch * SB_SIZE; + if (work->ch[ch].bNewPitch) + SB[32] = 1; // reset interpolation - if (s_chan->bNoise) + if (work->ch[ch].bNoise) do_lsfr_samples(d, work->ctrl, &spu.dwNoiseCount, &spu.dwNoiseVal); - else if (s_chan->bFMod == 2 - || (s_chan->bFMod == 0 && spu_config.iUseInterpolation == 0)) + else if (work->ch[ch].bFMod == 2 + || (work->ch[ch].bFMod == 0 && spu_config.iUseInterpolation == 0)) do_samples_noint(decode_block_work, work, ch, d, SB, sinc, &spos, &sbpos); - else if (s_chan->bFMod == 0 && spu_config.iUseInterpolation == 1) + else if (work->ch[ch].bFMod == 0 && spu_config.iUseInterpolation == 1) do_samples_simple(decode_block_work, work, ch, d, SB, sinc, &spos, &sbpos); else do_samples_default(decode_block_work, work, ch, d, SB, sinc, &spos, &sbpos); @@ -1017,14 +1036,11 @@ static void do_channel_work(struct work_item *work) } if (ch == 1 || ch == 3) - { - do_decode_bufs(spu.spuMem, ch/2, ns_to, work->decode_pos); - decode_dirty_ch |= 1 << ch; - } + do_decode_bufs(spu.spuMem, ch/2, ns_to, work->decode_pos); - if (s_chan->bFMod == 2) // fmod freq channel + if (work->ch[ch].bFMod == 2) // fmod freq channel memcpy(iFMod, &ChanBuf, ns_to * sizeof(iFMod[0])); - if (s_chan->bRVBActive && work->rvb_addr) + if (work->ch[ch].bRVBActive && work->rvb_addr) mix_chan_rvb(work->SSumLR, ns_to, work->ch[ch].vol_l, work->ch[ch].vol_r, RVB); else @@ -1136,6 +1152,7 @@ void do_samples(unsigned int cycles_to, int do_direct) do_irq(); } } + check_irq_io(spu.spuAddr); if (unlikely(spu.rvb->dirty)) REVERBPrep(); @@ -1146,6 +1163,7 @@ void do_samples(unsigned int cycles_to, int do_direct) } else { queue_channel_work(ns_to, silentch); + //sync_worker_thread(1); // uncomment for debug } // advance "stopped" channels that can cause irqs