X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=pcsx_rearmed.git;a=blobdiff_plain;f=plugins%2Fdfsound%2Fspu.c;h=bea8414e80e8e11f7c4bb023c5bd31d53af082e4;hp=b94fe90a1f4a395b275c82746fec2f1dea0be055;hb=587fa7de9b496a0b7fa1d52d393733886602ca83;hpb=9e7a735287d03149ccf7d0db6c0193cc565c3fff diff --git a/plugins/dfsound/spu.c b/plugins/dfsound/spu.c index b94fe90a..bea8414e 100644 --- a/plugins/dfsound/spu.c +++ b/plugins/dfsound/spu.c @@ -93,7 +93,8 @@ int iUseInterpolation=2; SPUCHAN s_chan[MAXCHAN+1]; // channel + 1 infos (1 is security for fmod handling) REVERBInfo rvb; -unsigned long dwNoiseVal=1; // global noise generator +unsigned int dwNoiseVal; // global noise generator +unsigned int dwNoiseCount; int iSpuAsyncWait=0; unsigned short spuCtrl=0; // some vars to store psx reg infos @@ -121,8 +122,8 @@ static const int f[8][2] = { { 0, 0 }, { 115, -52 }, { 98, -55 }, { 122, -60 } }; -int ChanBuf[NSSIZE]; -int SSumLR[NSSIZE*2]; +int ChanBuf[NSSIZE+3]; +int SSumLR[(NSSIZE+3)*2]; int iFMod[NSSIZE]; int iCycle = 0; short * pS; @@ -320,35 +321,6 @@ INLINE int FModChangeFrequency(int ch,int ns) //////////////////////////////////////////////////////////////////////// -// noise handler... just produces some noise data -// surely wrong... and no noise frequency (spuCtrl&0x3f00) will be used... -// and sometimes the noise will be used as fmod modulation... pfff - -INLINE int iGetNoiseVal(int ch) -{ - int fa; - - if((dwNoiseVal<<=1)&0x80000000L) - { - dwNoiseVal^=0x0040001L; - fa=((dwNoiseVal>>2)&0x7fff); - fa=-fa; - } - else fa=(dwNoiseVal>>2)&0x7fff; - - // mmm... depending on the noise freq we allow bigger/smaller changes to the previous val - fa=s_chan[ch].iOldNoise+((fa-s_chan[ch].iOldNoise)/((0x001f-((spuCtrl&0x3f00)>>9))+1)); - if(fa>32767L) fa=32767L; - if(fa<-32767L) fa=-32767L; - s_chan[ch].iOldNoise=fa; - - if(iUseInterpolation<2) // no gauss/cubic interpolation? - s_chan[ch].SB[29] = fa; // -> store noise val in "current sample" slot - return fa; -} - -//////////////////////////////////////////////////////////////////////// - INLINE void StoreInterpolationVal(int ch,int fa) { if(s_chan[ch].bFMod==2) // fmod freq channel @@ -631,6 +603,8 @@ make_do_samples(simple, , , static int do_samples_noise(int ch, int ns, int ns_to) { + int level, shift, bit; + s_chan[ch].spos += s_chan[ch].sinc * (ns_to - ns); while (s_chan[ch].spos >= 28*0x10000) { @@ -638,12 +612,72 @@ static int do_samples_noise(int ch, int ns, int ns_to) s_chan[ch].spos -= 28*0x10000; } + // modified from DrHell/shalma, no fraction + level = (spuCtrl >> 10) & 0x0f; + level = 0x8000 >> level; + for (; ns < ns_to; ns++) - ChanBuf[ns] = iGetNoiseVal(ch); + { + dwNoiseCount += 2; + if (dwNoiseCount >= level) + { + dwNoiseCount -= level; + shift = (dwNoiseVal >> 10) & 0x1f; + bit = (0x69696969 >> shift) & 1; + if (dwNoiseVal & 0x8000) + bit ^= 1; + dwNoiseVal = (dwNoiseVal << 1) | bit; + } + + ChanBuf[ns] = (signed short)dwNoiseVal; + } return -1; } +#ifdef __arm__ +// asm code +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); +#else +static void mix_chan(int start, int count, int lv, int rv) +{ + int *dst = SSumLR + start * 2; + const int *src = ChanBuf + start; + int l, r; + + while (count--) + { + int sval = *src++; + + l = (sval * lv) >> 14; + r = (sval * rv) >> 14; + *dst++ += l; + *dst++ += r; + } +} + +static void mix_chan_rvb(int start, int count, int lv, int rv) +{ + int *dst = SSumLR + start * 2; + int *drvb = sRVBStart + start * 2; + const int *src = ChanBuf + start; + int l, r; + + while (count--) + { + int sval = *src++; + + l = (sval * lv) >> 14; + r = (sval * rv) >> 14; + *dst++ += l; + *dst++ += r; + *drvb++ += l; + *drvb++ += r; + } +} +#endif + //////////////////////////////////////////////////////////////////////// // MAIN SPU FUNCTION // here is the main job handler... thread, timer or direct func call @@ -728,36 +762,18 @@ static void *MAINThread(void *arg) bIRQReturn=1; lastch=ch; lastns=ns_to=d; + if(d==0) + break; } MixADSR(ch, ns_from, ns_to); if(s_chan[ch].bFMod==2) // fmod freq channel memcpy(iFMod, ChanBuf, sizeof(iFMod)); + else if(s_chan[ch].bRVBActive) + mix_chan_rvb(ns_from,ns_to-ns_from,s_chan[ch].iLeftVolume,s_chan[ch].iRightVolume); else - { - int lv=s_chan[ch].iLeftVolume; - int rv=s_chan[ch].iRightVolume; - - for(ns=ns_from;ns>14; - r=(sval*rv)>>14; - SSumLR[ns*2] +=l; - SSumLR[ns*2+1]+=r; - - ////////////////////////////////////////////// - // now let us store sound data for reverb - - if(s_chan[ch].bRVBActive) StoreREVERB(ch,ns,l,r); - } - } + mix_chan(ns_from,ns_to-ns_from,s_chan[ch].iLeftVolume,s_chan[ch].iRightVolume); } } @@ -780,7 +796,8 @@ static void *MAINThread(void *arg) { unsigned char *start=s_chan[ch].pCurr; - bIRQReturn |= skip_block(ch); + // no need for bIRQReturn since the channel is silent + iSpuAsyncWait |= skip_block(ch); if(start == s_chan[ch].pCurr) { // looping on self