From 2062913f19d4d8a47daab7e762bb79203fff5c22 Mon Sep 17 00:00:00 2001 From: "SND\\shalma_cp" Date: Mon, 27 Dec 2010 18:37:10 +0000 Subject: hopkat-dfsound-port dsound r12 git-svn-id: https://pcsxr.svn.codeplex.com/svn/pcsxr@61528 e17a0e51-4ae3-4d35-97c3-1a29b211df97 --- plugins/dfsound/cfg.c | 1 + plugins/dfsound/externals.h | 1 + plugins/dfsound/registers.c | 10 +-- plugins/dfsound/spu.c | 214 +++++++++++++++++++++++++------------------- plugins/dfsound/xa.c | 123 +++++++++++++++++-------- 5 files changed, 213 insertions(+), 136 deletions(-) (limited to 'plugins') diff --git a/plugins/dfsound/cfg.c b/plugins/dfsound/cfg.c index 2acb9c37..70e06685 100644 --- a/plugins/dfsound/cfg.c +++ b/plugins/dfsound/cfg.c @@ -162,6 +162,7 @@ void ReadConfig(void) iUseReverb=2; iUseInterpolation=2; iDisStereo=0; + iFreqResponse=0; ReadConfigFile(); } diff --git a/plugins/dfsound/externals.h b/plugins/dfsound/externals.h index 6a971aab..e0dedd30 100644 --- a/plugins/dfsound/externals.h +++ b/plugins/dfsound/externals.h @@ -244,6 +244,7 @@ extern int iRecordMode; extern int iUseReverb; extern int iUseInterpolation; extern int iDisStereo; +extern int iFreqResponse; // MISC extern int iSpuAsyncWait; diff --git a/plugins/dfsound/registers.c b/plugins/dfsound/registers.c index 1115685c..bd0de567 100644 --- a/plugins/dfsound/registers.c +++ b/plugins/dfsound/registers.c @@ -267,15 +267,13 @@ void CALLBACK SPUwriteRegister(unsigned long reg, unsigned short val) break; //-------------------------------------------------// case H_CDLeft: - // Fake attenuation hack: [$00-ff left][$00-ff right] - // - TODO: fixme later - iLeftXAVol = val > 0x7fff ? 0x7fff : val; + // Attenuation: [$00-ff left][$00-ff right] + iLeftXAVol = val; if(cddavCallback) cddavCallback(0,val); break; case H_CDRight: - // Fake attenuation hack: [$00-ff right][$00-ff left] - // - TODO: fixme later - iRightXAVol = val > 0x7fff ? 0x7fff : val; + // Attenuation: [$00-ff right][$00-ff left] + iRightXAVol = val; if(cddavCallback) cddavCallback(1,val); break; //-------------------------------------------------// diff --git a/plugins/dfsound/spu.c b/plugins/dfsound/spu.c index 14aa01b3..44b7763b 100644 --- a/plugins/dfsound/spu.c +++ b/plugins/dfsound/spu.c @@ -79,6 +79,7 @@ int iRecordMode=0; int iUseReverb=2; int iUseInterpolation=2; int iDisStereo=0; +int iFreqResponse=0; // MAIN infos struct for each channel @@ -318,94 +319,71 @@ INLINE void 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 - -int INLINE GetNoiseValue() -{ -#if 1 - // Not great - works okay - return (-32767/4 + (rand() % 32767)); -#elif 0 - // SPU2-X - doesn't seem to work here..? - static int Seed = 0x41595321; - int retval = 0x8000; - - if( Seed&0x100 ) - retval = (Seed&0xff) << 8; - else if( Seed&0xffff ) - retval = 0x7fff; - - __asm { - MOV eax,Seed - ROR eax,5 - XOR eax,0x9a - MOV ebx,eax - ROL eax,2 - ADD eax,ebx - XOR eax,ebx - ROR eax,3 - MOV Seed,eax - } +/* +Noise Algorithm +- Dr.Hell (Xebra PS1 emu) +- 100% accurate (waveform + frequency) +- http://drhell.web.fc2.com - return retval; -#endif -} +Level change cycle +Freq = 0x8000 >> (NoiseClock >> 2); -/* -Eternal: -- pitch somewhat comparable -- texture less grainy -- more loud and rich - -10 = similar -12 = similar -14 = similar -16 = similar -18 = similar -20 = about right -22 = about right -24 = about right -26 = about right -28 = about right -30 = about right (+) -32 = about right -34 = similar -36 = about right (+) -38 = about right -40 = about right -44 = similar -46 = about right -52 = similar -56 = about right -60 = about right - -very sensitive to change, might need fractions +Frequency of half cycle +Half = ((NoiseClock & 3) * 2) / (4 + (NoiseClock & 3)); +- 0 = (0*2)/(4+0) = 0/4 +- 1 = (1*2)/(4+1) = 2/5 +- 2 = (2*2)/(4+2) = 4/6 +- 3 = (3*2)/(4+3) = 6/7 + +------------------------------- + +5*6*7 = 210 +4 - 0*0 = 0 +5 - 42*2 = 84 +6 - 35*4 = 140 +7 - 30*6 = 180 */ -unsigned int NoiseClockFreq[64] = { --1,33400,16800,16800,16800,16800,8300,8300, // 0-7 -8300,8300,4200,4200,4200,4200,2100,2100, // 8-15 -2100,2100,1040,1040,1040,1040,510,510, // 16-23 -510,510,253,253,252,252,128,128, // 24-31 -127,127,65,65,64,64,32,32, // 32-39 -32,32,20,20,16,16,12,12, // 40-47 -10,10,6,6,4,4,3,3, // 48-55 -2,2,2,2,1,1,1,1, // 56-63 + +// Noise Waveform - Dr. Hell (Xebra) +char NoiseWaveAdd [64] = { + 1, 0, 0, 1, 0, 1, 1, 0, + 1, 0, 0, 1, 0, 1, 1, 0, + 1, 0, 0, 1, 0, 1, 1, 0, + 1, 0, 0, 1, 0, 1, 1, 0, + 0, 1, 1, 0, 1, 0, 0, 1, + 0, 1, 1, 0, 1, 0, 0, 1, + 0, 1, 1, 0, 1, 0, 0, 1, + 0, 1, 1, 0, 1, 0, 0, 1 +}; + +unsigned short NoiseFreqAdd[5] = { + 0, 84, 140, 180, 210 }; INLINE void NoiseClock() { - dwNoiseCount += 1; - if( dwNoiseCount >= NoiseClockFreq[ dwNoiseClock ] ) + unsigned int level; + + level = 0x8000 >> (dwNoiseClock >> 2); + level <<= 16; + + dwNoiseCount += 0x10000; + + // Dr. Hell - fraction + dwNoiseCount += NoiseFreqAdd[ dwNoiseClock & 3 ]; + if( (dwNoiseCount&0xffff) >= NoiseFreqAdd[4] ) { + dwNoiseCount += 0x10000; + dwNoiseCount -= NoiseFreqAdd[ dwNoiseClock & 3 ]; + } + + if( dwNoiseCount >= level ) { - dwNoiseCount = 0; + while( dwNoiseCount >= level ) + dwNoiseCount -= level; - if( dwNoiseVal >= 0 ) - dwNoiseVal = -GetNoiseValue(); - else - dwNoiseVal = +GetNoiseValue(); + // Dr. Hell - form + dwNoiseVal = (dwNoiseVal<<1) | NoiseWaveAdd[ (dwNoiseVal>>10) & 63 ]; } } @@ -413,10 +391,9 @@ INLINE int iGetNoiseVal(int ch) { int fa; - if( dwNoiseClock == 0 ) return 0; - - fa = (int) dwNoiseVal; + fa = (short) dwNoiseVal; + // no clip need //if(fa>32767L) fa=32767L; //if(fa<-32767L) fa=-32767L; @@ -424,8 +401,9 @@ INLINE int iGetNoiseVal(int ch) //if(iUseInterpolation<2) // no gauss/cubic interpolation? //pChannel->SB[29] = fa; // -> store noise val in "current sample" slot - // boost volume - return fa * 3 / 2; + // boost volume - no more! + //return fa * 3 / 2; + return fa; } //////////////////////////////////////////////////////////////////////// @@ -558,6 +536,11 @@ static void *MAINThread(void *arg) int ch,predict_nr,shift_factor,flags,d,s; int bIRQReturn=0; + + // mute output + if( voldiv == 5 ) voldiv = 0x7fffffff; + + while(!bEndThread) // until we are shutting down { // ok, at the beginning we are looking if there is @@ -854,17 +837,60 @@ GOON: ; else // stereo: for (ns = 0; ns < NSSIZE; ns++) { - SSumL[ns] += MixREVERBLeft(ns); - - d = SSumL[ns] / voldiv; SSumL[ns] = 0; - if (d < -32767) d = -32767; if (d > 32767) d = 32767; - *pS++ = d; - - SSumR[ns] += MixREVERBRight(); - - d = SSumR[ns] / voldiv; SSumR[ns] = 0; - if(d < -32767) d = -32767; if(d > 32767) d = 32767; - *pS++ = d; + static double _interpolation_coefficient = 3.759285613; + + if(iFreqResponse) { + int sl,sr; + double ldiff, rdiff, avg, tmp; + + SSumL[ns]+=MixREVERBLeft(ns); + SSumR[ns]+=MixREVERBRight(); + + sl = SSumL[ns]; SSumL[ns]=0; + sr = SSumR[ns]; SSumR[ns]=0; + + + /* + Frequency Response + - William Pitcock (nenolod) (UPSE PSF player) + - accurate (!) + - http://nenolod.net + */ + + avg = ((sl + sr) / 2); + ldiff = sl - avg; + rdiff = sr - avg; + + tmp = avg + ldiff * _interpolation_coefficient; + if (tmp < -32768) + tmp = -32768; + if (tmp > 32767) + tmp = 32767; + sl = tmp; + + tmp = avg + rdiff * _interpolation_coefficient; + if (tmp < -32768) + tmp = -32768; + if (tmp > 32767) + tmp = 32767; + sr = tmp; + + + *pS++=sl/voldiv; + *pS++=sr/voldiv; + } else { + SSumL[ns]+=MixREVERBLeft(ns); + + d=SSumL[ns]/voldiv;SSumL[ns]=0; + if(d<-32767) d=-32767;if(d>32767) d=32767; + *pS++=d; + + SSumR[ns]+=MixREVERBRight(); + + d=SSumR[ns]/voldiv;SSumR[ns]=0; + if(d<-32767) d=-32767;if(d>32767) d=32767; + *pS++=d; + } } ////////////////////////////////////////////////////// diff --git a/plugins/dfsound/xa.c b/plugins/dfsound/xa.c index 0f523934..79a59122 100644 --- a/plugins/dfsound/xa.c +++ b/plugins/dfsound/xa.c @@ -42,8 +42,8 @@ uint32_t * CDDAPlay = NULL; uint32_t * CDDAStart = NULL; uint32_t * CDDAEnd = NULL; -int iLeftXAVol = 32767; -int iRightXAVol = 32767; +int iLeftXAVol = 0x8000; +int iRightXAVol = 0x8000; static int gauss_ptr = 0; static int gauss_window[8] = {0, 0, 0, 0, 0, 0, 0, 0}; @@ -52,50 +52,101 @@ static int gauss_window[8] = {0, 0, 0, 0, 0, 0, 0, 0}; #define gvall(x) gauss_window[(gauss_ptr+x)&3] #define gvalr0 gauss_window[4+gauss_ptr] #define gvalr(x) gauss_window[4+((gauss_ptr+x)&3)] + +long cdxa_dbuf_ptr; //////////////////////////////////////////////////////////////////////// // MIX XA & CDDA //////////////////////////////////////////////////////////////////////// +/* +Attenuation +- Blade_Arma (edgbla) (PCSX-reloaded) +- accurate (!) + + +s32 lc = (spsound[i ] * attenuators.val0 + spsound[i+1] * attenuators.val3]) / 128; +s32 rc = (spsound[i+1] * attenuators.val2 + spsound[i ] * attenuators.val1]) / 128; +*/ + INLINE void MixXA(void) { - int ns; - uint32_t l; - - for(ns=0;ns>16)&0xffff)) * iRightXAVol)/32768; -#else - SSumL[ns]+=(((short)(XALastVal&0xffff)) * iLeftXAVol)/32767; - SSumR[ns]+=(((short)((XALastVal>>16)&0xffff)) * iRightXAVol)/32767; -#endif - } - - if(XAPlay==XAFeed && XARepeat) - { - XARepeat--; - for(;ns>16)&0xffff)) * iRightXAVol)/32768; -#else - SSumL[ns]+=(((short)(XALastVal&0xffff)) * iLeftXAVol)/32767; - SSumR[ns]+=(((short)((XALastVal>>16)&0xffff)) * iRightXAVol)/32767; -#endif - } - } + int ns; + unsigned char val0,val1,val2,val3; + short l,r; + int lc,rc; + unsigned long cdda_l; + + val0 = (iLeftXAVol>>8)&0xff; + val1 = iLeftXAVol&0xff; + val2 = (iRightXAVol>>8)&0xff; + val3 = iRightXAVol&0xff; + + lc = 0; + rc = 0; + + for(ns=0;ns>16) & 0xffff; + + lc=(l * val0 + r * val3) / 128; + rc=(r * val2 + l * val1) / 128; + + if( lc < -32768 ) lc = -32768; + if( rc < -32768 ) rc = -32768; + if( lc > 32767 ) lc = 32767; + if( rc > 32767 ) rc = 32767; + + SSumL[ns]+=lc; + SSumR[ns]+=rc; + + + // Tales of Phantasia - voice meter + if( cdxa_dbuf_ptr >= 0x800 ) + cdxa_dbuf_ptr = 0; + spuMem[ cdxa_dbuf_ptr++ ] = lc; + spuMem[ cdxa_dbuf_ptr++ ] = rc; + } + + if(XAPlay==XAFeed && XARepeat) + { + XARepeat--; + for(;ns= 0x800 ) + cdxa_dbuf_ptr = 0; + spuMem[ cdxa_dbuf_ptr++ ] = lc; + spuMem[ cdxa_dbuf_ptr++ ] = rc; + } + } for(ns=0;ns>16)&0xffff)) * iRightXAVol)/32767; + cdda_l=*CDDAPlay++; + if(CDDAPlay==CDDAEnd) CDDAPlay=CDDAStart; + + l = cdda_l&0xffff; + r = (cdda_l>>16) & 0xffff; + + lc=(l * val0 + r * val3) / 128; + rc=(r * val2 + l * val1) / 128; + + if( lc < -32768 ) lc = -32768; + if( rc < -32768 ) rc = -32768; + if( lc > 32767 ) lc = 32767; + if( rc > 32767 ) rc = 32767; + + SSumL[ns]+=lc; + SSumR[ns]+=rc; } } -- cgit v1.2.3