summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorSND\shalma_cp <SND\shalma_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97>2010-12-27 18:37:10 +0000
committerSND\shalma_cp <SND\shalma_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97>2010-12-27 18:37:10 +0000
commit2062913f19d4d8a47daab7e762bb79203fff5c22 (patch)
tree117e340708dccce95d18cadaa1dcac529cb87d4c /plugins
parentb9b56cc0db2e0ac2d3366fc1b1095c0cd3798cb2 (diff)
downloadpcsxr-2062913f19d4d8a47daab7e762bb79203fff5c22.tar.gz
hopkat-dfsound-port dsound r12
git-svn-id: https://pcsxr.svn.codeplex.com/svn/pcsxr@61528 e17a0e51-4ae3-4d35-97c3-1a29b211df97
Diffstat (limited to 'plugins')
-rw-r--r--plugins/dfsound/cfg.c1
-rw-r--r--plugins/dfsound/externals.h1
-rw-r--r--plugins/dfsound/registers.c10
-rw-r--r--plugins/dfsound/spu.c214
-rw-r--r--plugins/dfsound/xa.c123
5 files changed, 213 insertions, 136 deletions
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<NSSIZE && XAPlay!=XAFeed;ns++)
- {
- XALastVal=*XAPlay++;
- if(XAPlay==XAEnd) XAPlay=XAStart;
-#ifdef XA_HACK
- SSumL[ns]+=(((short)(XALastVal&0xffff)) * iLeftXAVol)/32768;
- SSumR[ns]+=(((short)((XALastVal>>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<NSSIZE;ns++)
- {
-#ifdef XA_HACK
- SSumL[ns]+=(((short)(XALastVal&0xffff)) * iLeftXAVol)/32768;
- SSumR[ns]+=(((short)((XALastVal>>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<NSSIZE && XAPlay!=XAFeed;ns++)
+ {
+ XALastVal=*XAPlay++;
+ if(XAPlay==XAEnd) XAPlay=XAStart;
+
+ l = XALastVal&0xffff;
+ r = (XALastVal>>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<NSSIZE;ns++)
+ {
+ 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;
+ }
+ }
for(ns=0;ns<NSSIZE && CDDAPlay!=CDDAFeed && (CDDAPlay!=CDDAEnd-1||CDDAFeed!=CDDAStart);ns++)
{
- l=*CDDAPlay++;
- if(CDDAPlay==CDDAEnd) CDDAPlay=CDDAStart;
- SSumL[ns]+=(((short)(l&0xffff)) * iLeftXAVol)/32767;
- SSumR[ns]+=(((short)((l>>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;
}
}