X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=pcsx_rearmed.git;a=blobdiff_plain;f=plugins%2Fdfsound%2Fspu.c;h=df95f35db8578e70ae16912c6f3b292c8029bc9a;hp=791b27eb7bff176189f176124b34c31841708160;hb=554a2220f2413cc29d7912ad3f7d91c9e64284cf;hpb=b1094d0ef5dce90b6c344e7616ca0acd10050c7e diff --git a/plugins/dfsound/spu.c b/plugins/dfsound/spu.c index 791b27eb..df95f35d 100644 --- a/plugins/dfsound/spu.c +++ b/plugins/dfsound/spu.c @@ -26,7 +26,6 @@ #include "registers.h" #include "cfg.h" #include "dsoundoss.h" -#include "regs.h" #ifdef ENABLE_NLS #include @@ -38,7 +37,7 @@ #define N_(x) (x) #endif -#ifdef __arm__ +#ifdef __ARM_ARCH_7A__ #define ssat32_to_16(v) \ asm("ssat %0,#16,%1" : "=r" (v) : "r" (v)) #else @@ -108,9 +107,10 @@ int bSPUIsOpen=0; static pthread_t thread = (pthread_t)-1; // thread id (linux) -unsigned long dwNewChannel=0; // flags for faster testing, if new channel starts -unsigned long dwChannelOn=0; -unsigned long dwPendingChanOff=0; +unsigned int dwNewChannel=0; // flags for faster testing, if new channel starts +unsigned int dwChannelOn=0; // not silent channels +unsigned int dwPendingChanOff=0; +unsigned int dwChannelDead=0; // silent+not useful channels void (CALLBACK *irqCallback)(void)=0; // func of main emu, called on spu irq void (CALLBACK *cddavCallback)(unsigned short,unsigned short)=0; @@ -122,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; @@ -132,6 +132,8 @@ int lastch=-1; // last channel processed on spu irq in timer mode static int lastns=0; // last ns pos static int iSecureStart=0; // secure start counter +#define CDDA_BUFFER_SIZE (16384 * sizeof(uint32_t)) // must be power of 2 + //////////////////////////////////////////////////////////////////////// // CODE AREA //////////////////////////////////////////////////////////////////////// @@ -220,9 +222,10 @@ INLINE void InterpolateUp(int ch) s_chan[ch].SB[32]=0; s_chan[ch].SB[28]=(s_chan[ch].SB[28]*s_chan[ch].sinc)/0x20000L; - if(s_chan[ch].sinc<=0x8000) - s_chan[ch].SB[29]=s_chan[ch].SB[30]-(s_chan[ch].SB[28]*((0x10000/s_chan[ch].sinc)-1)); - else s_chan[ch].SB[29]+=s_chan[ch].SB[28]; + //if(s_chan[ch].sinc<=0x8000) + // s_chan[ch].SB[29]=s_chan[ch].SB[30]-(s_chan[ch].SB[28]*((0x10000/s_chan[ch].sinc)-1)); + //else + s_chan[ch].SB[29]+=s_chan[ch].SB[28]; } else // no flags? add bigger val (if possible), calc smaller step, set flag1 s_chan[ch].SB[29]+=s_chan[ch].SB[28]; @@ -286,19 +289,9 @@ INLINE void StartSound(int ch) // ALL KIND OF HELPERS //////////////////////////////////////////////////////////////////////// -INLINE void VoiceChangeFrequency(int ch) -{ - s_chan[ch].iUsedFreq=s_chan[ch].iActFreq; // -> take it and calc steps - s_chan[ch].sinc=s_chan[ch].iRawPitch<<4; - if(!s_chan[ch].sinc) s_chan[ch].sinc=1; - if(iUseInterpolation==1) s_chan[ch].SB[32]=1; // -> freq change in simle imterpolation mode: set flag -} - -//////////////////////////////////////////////////////////////////////// - INLINE int FModChangeFrequency(int ch,int ns) { - int NP=s_chan[ch].iRawPitch; + unsigned int NP=s_chan[ch].iRawPitch; int sinc; NP=((32768L+iFMod[ns])*NP)/32768L; @@ -306,12 +299,7 @@ INLINE int FModChangeFrequency(int ch,int ns) if(NP>0x3fff) NP=0x3fff; if(NP<0x1) NP=0x1; - NP=(44100L*NP)/(4096L); // calc frequency - - s_chan[ch].iActFreq=NP; - s_chan[ch].iUsedFreq=NP; - sinc=(((NP/10)<<16)/4410); - if(!sinc) sinc=1; + sinc=NP<<4; // calc frequency if(iUseInterpolation==1) // freq change in simple interpolation mode s_chan[ch].SB[32]=1; iFMod[ns]=0; @@ -453,14 +441,12 @@ static int decode_block(int ch) int ret = 0; start=s_chan[ch].pCurr; // set up the current pos - if(start == (unsigned char*)-1 || // special "stop" sign - (dwPendingChanOff&(1< turn everything off dwPendingChanOff&=~(1< and done for this channel } //////////////////////////////////////////// irq check @@ -495,10 +481,14 @@ static int decode_block(int ch) start = s_chan[ch].pLoop; } - if (start - spuMemC >= 0x80000) - start = (unsigned char*)-1; + if (start - spuMemC >= 0x80000) { + // most likely wrong + start = spuMemC; + printf("ch%d oflow\n", ch); + } s_chan[ch].pCurr = start; // store values for next cycle + s_chan[ch].bJump = flags & 1; return ret; } @@ -510,9 +500,6 @@ static int skip_block(int ch) int flags = start[1]; int ret = 0; - // Tron Bonne hack, probably wrong (could be wrong memory contents..) - if(flags & ~7) flags = 0; - if(start == pSpuIrq) { do_irq(); @@ -520,13 +507,14 @@ static int skip_block(int ch) } if(flags & 4) - s_chan[ch].pLoop=start; + s_chan[ch].pLoop = start; s_chan[ch].pCurr += 16; if(flags & 1) s_chan[ch].pCurr = s_chan[ch].pLoop; + s_chan[ch].bJump = flags & 1; return ret; } @@ -635,6 +623,49 @@ static int do_samples_noise(int ch, int ns, int ns_to) return -1; } +#ifdef __ARM_ARCH_7A__ +// 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 @@ -654,7 +685,7 @@ static void *MAINThread(void *arg) { int volmult = iVolume; int ns,ns_from,ns_to; - int ch,d; + int ch,d,silentch; int bIRQReturn=0; while(!bEndThread) // until we are shutting down @@ -694,6 +725,8 @@ static void *MAINThread(void *arg) ch=lastch; ns_from=lastns; lastch=-1; // -> setup all kind of vars to continue } + silentch=~(dwChannelOn|dwNewChannel); + //--------------------------------------------------// //- main channel loop -// //--------------------------------------------------// @@ -703,9 +736,6 @@ static void *MAINThread(void *arg) if(dwNewChannel&(1<>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); } } @@ -757,25 +769,23 @@ static void *MAINThread(void *arg) if(!bIRQReturn && (spuCtrl&CTRL_IRQ)) for(ch=0;ch pSpuIrq && s_chan[ch].pLoop > pSpuIrq) continue; - if(s_chan[ch].iActFreq!=s_chan[ch].iUsedFreq) // new psx frequency? - VoiceChangeFrequency(ch); - s_chan[ch].spos += s_chan[ch].sinc * NSSIZE; while(s_chan[ch].spos >= 28 * 0x10000) { - unsigned char *start=s_chan[ch].pCurr; + 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 - s_chan[ch].pCurr=(unsigned char *)-1; + dwChannelDead |= 1< init sustain s_chan[i].pLoop=spuMemC; - s_chan[i].pStart=spuMemC; s_chan[i].pCurr=spuMemC; } @@ -1161,9 +1172,9 @@ char * SPUgetLibInfos(void) */ // debug -void spu_get_debug_info(int *chans_out, int *fmod_chans_out, int *noise_chans_out) +void spu_get_debug_info(int *chans_out, int *run_chans, int *fmod_chans_out, int *noise_chans_out) { - int ch = 0, fmod_chans = 0, noise_chans = 0; + int ch = 0, fmod_chans = 0, noise_chans = 0, irq_chans = 0; for(;ch