X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=pcsx_rearmed.git;a=blobdiff_plain;f=plugins%2Fdfsound%2Fspu.c;h=b94fe90a1f4a395b275c82746fec2f1dea0be055;hp=e6c5449d3cf8f0c657f75d54d5539284a6c8fa4a;hb=9e7a735287d03149ccf7d0db6c0193cc565c3fff;hpb=07a6dd2ce2c0c8ea2de11c30c134c877e7c7b0fb diff --git a/plugins/dfsound/spu.c b/plugins/dfsound/spu.c index e6c5449d..b94fe90a 100644 --- a/plugins/dfsound/spu.c +++ b/plugins/dfsound/spu.c @@ -38,6 +38,16 @@ #define N_(x) (x) #endif +#ifdef __arm__ + #define ssat32_to_16(v) \ + asm("ssat %0,#16,%1" : "=r" (v) : "r" (v)) +#else + #define ssat32_to_16(v) do { \ + if (v < -32768) v = -32768; \ + else if (v > 32767) v = 32767; \ + } while (0) +#endif + /* #if defined (USEMACOSX) static char * libraryName = N_("Mac OS X Sound"); @@ -69,7 +79,7 @@ unsigned char * pMixIrq=0; // user settings -int iVolume=3; +int iVolume=768; // 1024 is 1.0 int iXAPitch=1; int iUseTimer=2; int iSPUIRQWait=1; @@ -257,8 +267,8 @@ INLINE void StartSound(int ch) //s_chan[ch].bStop=0; //s_chan[ch].bOn=1; - s_chan[ch].s_1=0; // init mixing vars - s_chan[ch].s_2=0; + s_chan[ch].SB[26]=0; // init mixing vars + s_chan[ch].SB[27]=0; s_chan[ch].iSBPos=28; s_chan[ch].SB[29]=0; // init our interpolation helpers @@ -345,12 +355,7 @@ INLINE void StoreInterpolationVal(int ch,int fa) s_chan[ch].SB[29]=fa; else { - if((spuCtrl&0x4000)==0) fa=0; // muted? - else // else adjust - { - if(fa>32767L) fa=32767L; - if(fa<-32767L) fa=-32767L; - } + ssat32_to_16(fa); if(iUseInterpolation>=2) // gauss/cubic interpolation { @@ -441,16 +446,40 @@ static void do_irq(void) } } +static void decode_block_data(int *dest, const unsigned char *src, int predict_nr, int shift_factor) +{ + int nSample; + int fa, s_1, s_2, d, s; + + s_1 = dest[27]; + s_2 = dest[26]; + + for (nSample = 0; nSample < 28; src++) + { + d = (int)*src; + s = (int)(signed short)((d & 0x0f) << 12); + + fa = s >> shift_factor; + fa += ((s_1 * f[predict_nr][0])>>6) + ((s_2 * f[predict_nr][1])>>6); + s_2=s_1;s_1=fa; + + dest[nSample++] = fa; + + s = (int)(signed short)((d & 0xf0) << 8); + fa = s >> shift_factor; + fa += ((s_1 * f[predict_nr][0])>>6) + ((s_2 * f[predict_nr][1])>>6); + s_2=s_1;s_1=fa; + + dest[nSample++] = fa; + } +} + static int decode_block(int ch) { unsigned char *start; - unsigned int nSample; - int predict_nr,shift_factor,flags,d,s; - int fa,s_1,s_2; + int predict_nr,shift_factor,flags; int ret = 0; - s_chan[ch].iSBPos=0; - start=s_chan[ch].pCurr; // set up the current pos if(start == (unsigned char*)-1 || // special "stop" sign (dwPendingChanOff&(1<>= 4; - flags=(int)*start;start++; - - // -------------------------------------- // - - for (nSample=0;nSample<28;start++) - { - d=(int)*start; - s=((d&0xf)<<12); - if(s&0x8000) s|=0xffff0000; - - fa=(s >> shift_factor); - fa=fa + ((s_1 * f[predict_nr][0])>>6) + ((s_2 * f[predict_nr][1])>>6); - s_2=s_1;s_1=fa; - s=((d & 0xf0) << 8); - - s_chan[ch].SB[nSample++]=fa; - if(s&0x8000) s|=0xffff0000; - fa=(s>>shift_factor); - fa=fa + ((s_1 * f[predict_nr][0])>>6) + ((s_2 * f[predict_nr][1])>>6); - s_2=s_1;s_1=fa; - - s_chan[ch].SB[nSample++]=fa; - } + decode_block_data(s_chan[ch].SB, start + 2, predict_nr, shift_factor); //////////////////////////////////////////// flag handler - if((flags&4) && (!s_chan[ch].bIgnoreLoop)) - s_chan[ch].pLoop=start-16; // loop adress + flags=(int)start[1]; + if(flags&4) + s_chan[ch].pLoop=start; // loop adress + start+=16; if(flags&1) // 1: stop/loop { if(!(flags&2)) @@ -520,9 +526,7 @@ static int decode_block(int ch) if (start - spuMemC >= 0x80000) start = (unsigned char*)-1; - s_chan[ch].pCurr=start; // store values for next cycle - s_chan[ch].s_1=s_1; - s_chan[ch].s_2=s_2; + s_chan[ch].pCurr = start; // store values for next cycle return ret; } @@ -543,7 +547,7 @@ static int skip_block(int ch) ret = 1; } - if((flags & 4) && !s_chan[ch].bIgnoreLoop) + if(flags & 4) s_chan[ch].pLoop=start; s_chan[ch].pCurr += 16; @@ -559,6 +563,8 @@ static int do_samples_##name(int ch, int ns, int ns_to) \ { \ int sinc = s_chan[ch].sinc; \ int spos = s_chan[ch].spos; \ + int sbpos = s_chan[ch].iSBPos; \ + int *SB = s_chan[ch].SB; \ int ret = -1; \ int d, fa; \ interp_start; \ @@ -569,8 +575,9 @@ static int do_samples_##name(int ch, int ns, int ns_to) \ \ while (spos >= 0x10000) \ { \ - if(s_chan[ch].iSBPos == 28) \ + if(sbpos == 28) \ { \ + sbpos = 0; \ d = decode_block(ch); \ if(d && iSPUIRQWait) \ { \ @@ -579,7 +586,7 @@ static int do_samples_##name(int ch, int ns, int ns_to) \ } \ } \ \ - fa = s_chan[ch].SB[s_chan[ch].iSBPos++]; \ + fa = SB[sbpos++]; \ interp1_code; \ spos -= 0x10000; \ } \ @@ -591,6 +598,7 @@ static int do_samples_##name(int ch, int ns, int ns_to) \ out: \ s_chan[ch].sinc = sinc; \ s_chan[ch].spos = spos; \ + s_chan[ch].iSBPos = sbpos; \ interp_end; \ \ return ret; \ @@ -653,12 +661,8 @@ static int do_samples_noise(int ch, int ns, int ns_to) static void *MAINThread(void *arg) { + int volmult = iVolume; int ns,ns_from,ns_to; -#if !defined(_MACOSX) && !defined(__arm__) - int voldiv = iVolume; -#else - const int voldiv = 2; -#endif int ch,d; int bIRQReturn=0; @@ -730,21 +734,28 @@ static void *MAINThread(void *arg) if(s_chan[ch].bFMod==2) // fmod freq channel memcpy(iFMod, ChanBuf, sizeof(iFMod)); - else 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,sval); + if(s_chan[ch].bRVBActive) StoreREVERB(ch,ns,l,r); } } } @@ -811,19 +822,26 @@ static void *MAINThread(void *arg) /////////////////////////////////////////////////////// // mix all channels (including reverb) into one buffer + if(iUseReverb) + REVERBDo(); + + if((spuCtrl&0x4000)==0) // muted? (rare, don't optimize for this) + { + memset(pS, 0, NSSIZE * 2 * sizeof(pS[0])); + pS += NSSIZE*2; + } + else for (ns = 0; ns < NSSIZE*2; ) { - SSumLR[ns] += MixREVERBLeft(ns/2); - - d = SSumLR[ns] / voldiv; SSumLR[ns] = 0; - if (d < -32767) d = -32767; if (d > 32767) d = 32767; + d = SSumLR[ns]; SSumLR[ns] = 0; + d = d * volmult >> 10; + ssat32_to_16(d); *pS++ = d; ns++; - SSumLR[ns] += MixREVERBRight(); - - d = SSumLR[ns] / voldiv; SSumLR[ns] = 0; - if(d < -32767) d = -32767; if(d > 32767) d = 32767; + d = SSumLR[ns]; SSumLR[ns] = 0; + d = d * volmult >> 10; + ssat32_to_16(d); *pS++ = d; ns++; } @@ -866,7 +884,7 @@ static void *MAINThread(void *arg) // feed the sound // wanna have around 1/60 sec (16.666 ms) updates - if (iCycle++ > 16) + if (iCycle++ > 16/FRAG_MSECS) { SoundFeedStreamData((unsigned char *)pSpuBuffer, ((unsigned char *)pS) - ((unsigned char *)pSpuBuffer)); @@ -890,7 +908,7 @@ void CALLBACK SPUasync(unsigned long cycle) if(iSpuAsyncWait) { iSpuAsyncWait++; - if(iSpuAsyncWait<=16) return; + if(iSpuAsyncWait<=16/FRAG_MSECS) return; iSpuAsyncWait=0; } @@ -1036,8 +1054,6 @@ long CALLBACK SPUinit(void) memset((void *)&rvb, 0, sizeof(REVERBInfo)); InitADSR(); - iVolume = 3; - iReverbOff = -1; spuIrq = 0; spuAddr = 0xffffffff; bEndThread = 0;