diff options
Diffstat (limited to 'plugins/dfsound')
-rw-r--r-- | plugins/dfsound/externals.h | 12 | ||||
-rw-r--r-- | plugins/dfsound/freeze.c | 18 | ||||
-rw-r--r-- | plugins/dfsound/spu.c | 98 | ||||
-rw-r--r-- | plugins/dfsound/xa.c | 13 |
4 files changed, 60 insertions, 81 deletions
diff --git a/plugins/dfsound/externals.h b/plugins/dfsound/externals.h index 73134d0..c69af81 100644 --- a/plugins/dfsound/externals.h +++ b/plugins/dfsound/externals.h @@ -46,7 +46,8 @@ // ~ 1 ms of data
// note: must be even due to the way reverb works now
-#define NSSIZE 46
+#define FRAG_MSECS 2
+#define NSSIZE ((44100 * FRAG_MSECS / 1000 + 1) & ~1)
///////////////////////////////////////////////////////////
// struct defines
@@ -121,17 +122,10 @@ typedef struct int iUsedFreq; // current pc pitch
int iLeftVolume; // left volume
int iRightVolume; // right volume
- int s_1; // last decoding infos
- int s_2;
ADSRInfoEx ADSRX;
int iRawPitch; // raw pitch (0...3fff)
- int iRVBOffset; // reverb offset
- int iRVBRepeat; // reverb repeat
- int iRVBNum; // another reverb helper
- int iOldNoise; // old noise val for this channel
-
- int SB[32+32];
+ int SB[32+4];
} SPUCHAN;
///////////////////////////////////////////////////////////
diff --git a/plugins/dfsound/freeze.c b/plugins/dfsound/freeze.c index 3969469..41c6f16 100644 --- a/plugins/dfsound/freeze.c +++ b/plugins/dfsound/freeze.c @@ -121,7 +121,7 @@ extern int lastch; // we want to retain compatibility between versions,
// so use original channel struct
-static void save_channel(SPUCHAN_orig *d, SPUCHAN *s, int ch)
+static void save_channel(SPUCHAN_orig *d, const SPUCHAN *s, int ch)
{
memset(d, 0, sizeof(*d));
d->bNew = !!(dwNewChannel & (1<<ch));
@@ -141,15 +141,11 @@ static void save_channel(SPUCHAN_orig *d, SPUCHAN *s, int ch) d->bIgnoreLoop = s->bIgnoreLoop;
d->iRightVolume = s->iRightVolume;
d->iRawPitch = s->iRawPitch;
- d->s_1 = s->s_1;
- d->s_2 = s->s_2;
+ d->s_1 = s->SB[27]; // yes it's reversed
+ d->s_2 = s->SB[26];
d->bRVBActive = s->bRVBActive;
- d->iRVBOffset = s->iRVBOffset;
- d->iRVBRepeat = s->iRVBRepeat;
d->bNoise = s->bNoise;
d->bFMod = s->bFMod;
- d->iRVBNum = s->iRVBNum;
- d->iOldNoise = s->iOldNoise;
d->ADSRX.State = s->ADSRX.State;
d->ADSRX.AttackModeExp = s->ADSRX.AttackModeExp;
d->ADSRX.AttackRate = s->ADSRX.AttackRate;
@@ -164,7 +160,7 @@ static void save_channel(SPUCHAN_orig *d, SPUCHAN *s, int ch) d->ADSRX.lVolume = d->bOn; // hmh
}
-static void load_channel(SPUCHAN *d, SPUCHAN_orig *s, int ch)
+static void load_channel(SPUCHAN *d, const SPUCHAN_orig *s, int ch)
{
memset(d, 0, sizeof(*d));
if (s->bNew) dwNewChannel |= 1<<ch;
@@ -184,15 +180,9 @@ static void load_channel(SPUCHAN *d, SPUCHAN_orig *s, int ch) d->bIgnoreLoop = s->bIgnoreLoop;
d->iRightVolume = s->iRightVolume;
d->iRawPitch = s->iRawPitch;
- d->s_1 = s->s_1;
- d->s_2 = s->s_2;
d->bRVBActive = s->bRVBActive;
- d->iRVBOffset = s->iRVBOffset;
- d->iRVBRepeat = s->iRVBRepeat;
d->bNoise = s->bNoise;
d->bFMod = s->bFMod;
- d->iRVBNum = s->iRVBNum;
- d->iOldNoise = s->iOldNoise;
d->ADSRX.State = s->ADSRX.State;
d->ADSRX.AttackModeExp = s->ADSRX.AttackModeExp;
d->ADSRX.AttackRate = s->ADSRX.AttackRate;
diff --git a/plugins/dfsound/spu.c b/plugins/dfsound/spu.c index d6cd952..7b435ac 100644 --- a/plugins/dfsound/spu.c +++ b/plugins/dfsound/spu.c @@ -267,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 @@ -355,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 { @@ -451,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<<ch))) @@ -483,42 +502,19 @@ static int decode_block(int ch) } } - s_1=s_chan[ch].s_1; - s_2=s_chan[ch].s_2; - - predict_nr=(int)*start;start++; + predict_nr=(int)start[0]; shift_factor=predict_nr&0xf; predict_nr >>= 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)) @@ -530,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; } @@ -553,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; @@ -569,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; \ @@ -579,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) \ { \ @@ -589,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; \ } \ @@ -601,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; \ @@ -888,7 +886,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)); @@ -912,7 +910,7 @@ void CALLBACK SPUasync(unsigned long cycle) if(iSpuAsyncWait) { iSpuAsyncWait++; - if(iSpuAsyncWait<=16) return; + if(iSpuAsyncWait<=16/FRAG_MSECS) return; iSpuAsyncWait=0; } diff --git a/plugins/dfsound/xa.c b/plugins/dfsound/xa.c index bdea89a..b45aef2 100644 --- a/plugins/dfsound/xa.c +++ b/plugins/dfsound/xa.c @@ -95,8 +95,8 @@ INLINE void MixXA(void) { l=*CDDAPlay++; if(CDDAPlay==CDDAEnd) CDDAPlay=CDDAStart; - SSumLR[ns++]+=(((short)(l&0xffff)) * iLeftXAVol)/32767; - SSumLR[ns++]+=(((short)((l>>16)&0xffff)) * iRightXAVol)/32767; + SSumLR[ns++]+=(((short)(l&0xffff)) * iLeftXAVol) >> 15; + SSumLR[ns++]+=(((short)((l>>16)&0xffff)) * iRightXAVol) >> 15; } } @@ -222,13 +222,11 @@ INLINE void FeedXA(xa_decode_t *xap) s=(short)LOWORD(l); l1=s; l1=(l1*iPlace)/iSize; - if(l1<-32767) l1=-32767; - if(l1> 32767) l1=32767; + ssat32_to_16(l1); s=(short)HIWORD(l); l2=s; l2=(l2*iPlace)/iSize; - if(l2<-32767) l2=-32767; - if(l2> 32767) l2=32767; + ssat32_to_16(l2); l=(l1&0xffff)|(l2<<16); *XAFeed++=l; @@ -328,8 +326,7 @@ INLINE void FeedXA(xa_decode_t *xap) } l1=(l1*iPlace)/iSize; - if(l1<-32767) l1=-32767; - if(l1> 32767) l1=32767; + ssat32_to_16(l1); l=(l1&0xffff)|(l1<<16); *XAFeed++=l; |