diff options
| author | SND\edgbla_cp <SND\edgbla_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97> | 2011-04-17 18:51:03 +0000 |
|---|---|---|
| committer | SND\edgbla_cp <SND\edgbla_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97> | 2011-04-17 18:51:03 +0000 |
| commit | 8e692627c341577078f4b63f78201cf7e1118f93 (patch) | |
| tree | 30639979e339cf772ed6a2604c66fbc0ba65a4cc /plugins | |
| parent | b5707f403cd6cd68ee1e60655f5a9daa26f06f00 (diff) | |
| download | pcsxr-8e692627c341577078f4b63f78201cf7e1118f93.tar.gz | |
Patch 9156 (Shalma).
git-svn-id: https://pcsxr.svn.codeplex.com/svn/pcsxr@65924 e17a0e51-4ae3-4d35-97c3-1a29b211df97
Diffstat (limited to 'plugins')
| -rw-r--r-- | plugins/dfsound/Makefile.am | 2 | ||||
| -rw-r--r-- | plugins/dfsound/dma.c | 44 | ||||
| -rw-r--r-- | plugins/dfsound/externals.c | 26 | ||||
| -rw-r--r-- | plugins/dfsound/externals.h | 10 | ||||
| -rw-r--r-- | plugins/dfsound/freeze.c | 4 | ||||
| -rw-r--r-- | plugins/dfsound/registers.c | 103 | ||||
| -rw-r--r-- | plugins/dfsound/registers.h | 41 | ||||
| -rw-r--r-- | plugins/dfsound/reverb.c | 45 | ||||
| -rw-r--r-- | plugins/dfsound/spu.c | 124 | ||||
| -rw-r--r-- | plugins/dfsound/xa.c | 170 |
10 files changed, 450 insertions, 119 deletions
diff --git a/plugins/dfsound/Makefile.am b/plugins/dfsound/Makefile.am index e5e17917..3b48eefd 100644 --- a/plugins/dfsound/Makefile.am +++ b/plugins/dfsound/Makefile.am @@ -5,7 +5,7 @@ libdir = @libdir@/games/psemu/ lib_LTLIBRARIES = libDFSound.la
-libDFSound_la_SOURCES = spu.c cfg.c dma.c freeze.c registers.c
+libDFSound_la_SOURCES = spu.c cfg.c dma.c freeze.c registers.c externals.c
libDFSound_la_CPPFLAGS = $(AM_CPPFLAGS)
libDFSound_la_LDFLAGS = -module -avoid-version
diff --git a/plugins/dfsound/dma.c b/plugins/dfsound/dma.c index d46afa55..62c2288d 100644 --- a/plugins/dfsound/dma.c +++ b/plugins/dfsound/dma.c @@ -20,6 +20,7 @@ #define _IN_DMA
#include "externals.h"
+#include "registers.h"
////////////////////////////////////////////////////////////////////////
// READ DMA (one value)
@@ -44,25 +45,26 @@ void CALLBACK SPUreadDMAMem(unsigned short * pusPSXMem,int iSize) {
int i;
+ spuStat |= STAT_DATA_BUSY;
+
for(i=0;i<iSize;i++)
{
-#if 0
- if(irqCallback && (spuCtrl&0x40)) // some callback and irq active?
- {
- // SPU2-X
- if(pSpuIrq == spuMemC+spuAddr) {
- irqCallback(); // -> call main emu
- }
- }
-#endif
+ Check_IRQ( spuAddr, 0 );
*pusPSXMem++=spuMem[spuAddr>>1]; // spu addr got by writeregister
spuAddr+=2; // inc spu addr
- if(spuAddr>0x7ffff) spuAddr=0; // wrap
+
+ // guess based on Vib Ribbon (below)
+ if(spuAddr>0x7ffff) break;
}
iSpuAsyncWait=0;
+
+ spuStat &= ~STAT_DATA_BUSY;
+ spuStat &= ~STAT_DMA_NON;
+ spuStat &= ~STAT_DMA_W;
+ spuStat |= STAT_DMA_R;
}
////////////////////////////////////////////////////////////////////////
@@ -95,24 +97,26 @@ void CALLBACK SPUwriteDMAMem(unsigned short * pusPSXMem,int iSize) {
int i;
+ spuStat |= STAT_DATA_BUSY;
+
for(i=0;i<iSize;i++)
{
-#if 0
- if(irqCallback && (spuCtrl&0x40)) // some callback and irq active?
- {
- // SPU2-X
- if(pSpuIrq == spuMemC+spuAddr) {
- irqCallback(); // -> call main emu
- }
- }
-#endif
+ Check_IRQ( spuAddr, 0 );
spuMem[spuAddr>>1] = *pusPSXMem++; // spu addr got by writeregister
spuAddr+=2; // inc spu addr
- if(spuAddr>0x7ffff) spuAddr=0; // wrap
+
+ // Vib Ribbon - stop transfer (reverb playback)
+ if(spuAddr>0x7ffff) break;
}
iSpuAsyncWait=0;
+
+
+ spuStat &= ~STAT_DATA_BUSY;
+ spuStat &= ~STAT_DMA_NON;
+ spuStat &= ~STAT_DMA_R;
+ spuStat |= STAT_DMA_W;
}
////////////////////////////////////////////////////////////////////////
diff --git a/plugins/dfsound/externals.c b/plugins/dfsound/externals.c new file mode 100644 index 00000000..12fde65d --- /dev/null +++ b/plugins/dfsound/externals.c @@ -0,0 +1,26 @@ +/***************************************************************************
+ externals.c - description
+ -------------------
+ begin : Wed May 15 2002
+ copyright : (C) 2002 by Pete Bernert
+ email : BlackDove@addcom.de
+ ***************************************************************************/
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. See also the license.txt file for *
+ * additional informations. *
+ * *
+ ***************************************************************************/
+
+#include <stdint.h>
+
+// 15-bit value + 1-sign
+int CLAMP16(x) {
+ if(x > 32767) x = 32767;
+ else if(x < -32768) x = -32768;
+
+ return x;
+}
diff --git a/plugins/dfsound/externals.h b/plugins/dfsound/externals.h index b8a5c43d..8e570933 100644 --- a/plugins/dfsound/externals.h +++ b/plugins/dfsound/externals.h @@ -31,6 +31,12 @@ #define min(a,b) (((a) < (b)) ? (a) : (b))
#endif
+
+
+// 15-bit value + 1-sign
+extern int CLAMP16(x);
+
+
////////////////////////////////////////////////////////////////////////
// spu defines
////////////////////////////////////////////////////////////////////////
@@ -160,7 +166,7 @@ typedef struct int iUsedFreq; // current pc pitch
int iLeftVolume; // left volume
int iLeftVolRaw; // left psx volume value
- int bIgnoreLoop; // ignore loop bit, if an external loop address is used
+ int bLoopJump; // ignore loop bit, if an external loop address is used
int iMute; // mute mode (debug)
int iSilent; // voice on - sound on/off
int iRightVolume; // right volume
@@ -277,6 +283,7 @@ extern int bEndThread; extern int bThreadEnded;
extern int bSpuInit;
extern uint32_t dwNewChannel;
+extern int bIrqHit;
extern int SSumR[];
extern int SSumL[];
@@ -289,6 +296,7 @@ extern HWND hWDebug; #endif
extern void (CALLBACK *cddavCallback)(unsigned short,unsigned short);
+extern void (CALLBACK *irqCallback)(void); // func of main emu, called on spu irq
#endif
diff --git a/plugins/dfsound/freeze.c b/plugins/dfsound/freeze.c index 156fd693..273f781d 100644 --- a/plugins/dfsound/freeze.c +++ b/plugins/dfsound/freeze.c @@ -43,8 +43,8 @@ typedef struct unsigned short spuIrq;
uint32_t pSpuIrq;
uint32_t spuAddr;
- uint32_t dummy1;
- uint32_t dummy2;
+ uint32_t bIrqHit;
+ uint32_t decoded_ptr;
uint32_t dummy3;
SPUCHAN s_chan[MAXCHAN];
diff --git a/plugins/dfsound/registers.c b/plugins/dfsound/registers.c index 66cff9a2..31c2be0c 100644 --- a/plugins/dfsound/registers.c +++ b/plugins/dfsound/registers.c @@ -42,6 +42,38 @@ #define SUSTAIN_MS 441L
#define RELEASE_MS 437L
+
+
+
+
+
+int Check_IRQ( int addr, int force ) {
+ if(spuCtrl & CTRL_IRQ) // some callback and irq active?
+ {
+ if( ( bIrqHit == 0 ) &&
+ ( force == 1 || pSpuIrq == spuMemC+addr ) )
+ {
+ if(irqCallback)
+ irqCallback(); // -> call main emu
+
+ // one-time
+ bIrqHit = 1;
+ spuStat |= STAT_IRQ;
+
+#if 0
+ MessageBox( NULL, "IRQ", "SPU", MB_OK );
+#endif
+
+ return 1;
+ }
+ }
+
+
+ return 0;
+}
+
+
+
////////////////////////////////////////////////////////////////////////
// WRITE REGISTERS: called by main emu
////////////////////////////////////////////////////////////////////////
@@ -163,8 +195,10 @@ void CALLBACK SPUwriteRegister(unsigned long reg, unsigned short val) //------------------------------------------------//
case 14: // loop?
//WaitForSingleObject(s_chan[ch].hMutex,2000); // -> no multithread fuckups
- s_chan[ch].pLoop=spuMemC+((unsigned long)((val<<3)&~0xf));
- s_chan[ch].bIgnoreLoop=1;
+
+ s_chan[ch].pLoop=spuMemC+((unsigned long)((val<<3)&~0xf));
+
+ //s_chan[ch].bIgnoreLoop=1;
//ReleaseMutex(s_chan[ch].hMutex); // -> oki, on with the thread
break;
//------------------------------------------------//
@@ -181,6 +215,9 @@ void CALLBACK SPUwriteRegister(unsigned long reg, unsigned short val) break;
//-------------------------------------------------//
case H_SPUdata:
+ // BIOS - allow dma 00
+ Check_IRQ( spuAddr, 0 );
+
spuMem[spuAddr>>1] = val;
spuAddr+=2;
if(spuAddr>0x7ffff) spuAddr=0;
@@ -188,7 +225,50 @@ void CALLBACK SPUwriteRegister(unsigned long reg, unsigned short val) //-------------------------------------------------//
case H_SPUctrl:
spuCtrl=val;
- dwNoiseClock = (spuCtrl&0x3f00)>>8;
+
+
+ // flags
+ if( spuCtrl & CTRL_CD_PLAY )
+ spuStat |= CTRL_CD_PLAY;
+ else
+ spuStat &= ~CTRL_CD_PLAY;
+
+ if( spuCtrl & CTRL_CD_REVERB )
+ spuStat |= STAT_CD_REVERB;
+ else
+ spuStat &= ~STAT_CD_REVERB;
+
+
+ if( spuCtrl & CTRL_EXT_PLAY )
+ spuStat |= STAT_EXT_PLAY;
+ else
+ spuStat &= ~STAT_EXT_PLAY;
+
+ if( spuCtrl & CTRL_EXT_REVERB )
+ spuStat |= STAT_EXT_REVERB;
+ else
+ spuStat &= ~STAT_EXT_REVERB;
+
+
+
+ spuStat &= ~(STAT_DMA_NON | STAT_DMA_R | STAT_DMA_W);
+
+ if( spuCtrl & CTRL_DMA_F )
+ spuStat |= STAT_DMA_F;
+
+ if( (spuCtrl & CTRL_DMA_F) == CTRL_DMA_R )
+ spuStat |= STAT_DMA_R;
+
+
+
+ // reset IRQ flag
+ if( (spuCtrl & CTRL_IRQ) == 0 ) {
+ bIrqHit = 0;
+ spuStat &= ~STAT_IRQ;
+ }
+
+
+ dwNoiseClock = (spuCtrl & CTRL_NOISE)>>8;
break;
//-------------------------------------------------//
case H_SPUstat:
@@ -369,13 +449,6 @@ unsigned short CALLBACK SPUreadRegister(unsigned long reg) return 1;
return (unsigned short)(s_chan[ch].ADSRX.EnvelopeVol);
}
-
- case 14: // get loop address
- {
- const int ch=(r>>4)-0xc0;
- if(s_chan[ch].pLoop==NULL) return 0;
- return (unsigned short)((s_chan[ch].pLoop-spuMemC)>>3);
- }
}
}
@@ -386,9 +459,6 @@ unsigned short CALLBACK SPUreadRegister(unsigned long reg) case H_SPUstat:
return spuStat;
-
- case H_SPUaddr:
- return (unsigned short)(spuAddr>>3);
case H_SPUdata:
{
@@ -398,9 +468,6 @@ unsigned short CALLBACK SPUreadRegister(unsigned long reg) return s;
}
- case H_SPUirqAddr:
- return spuIrq;
-
//case H_SPUIsOn1:
// return IsSoundOn(0,16);
@@ -424,11 +491,7 @@ void SoundOn(int start,int end,unsigned short val) // SOUND ON PSX COMAND {
if((val&1) && s_chan[ch].pStart) // mmm... start has to be set before key on !?!
{
-#if 0
s_chan[ch].bLoopJump = 0;
-#else
- s_chan[ch].bIgnoreLoop=0;
-#endif
s_chan[ch].bNew=1;
// do this here, not in StartSound
diff --git a/plugins/dfsound/registers.h b/plugins/dfsound/registers.h index f2a93970..7a10c978 100644 --- a/plugins/dfsound/registers.h +++ b/plugins/dfsound/registers.h @@ -142,3 +142,44 @@ #define H_SPU_ADSRLevel22 0x0d68
#define H_SPU_ADSRLevel23 0x0d78
+
+
+
+#define CTRL_CD_PLAY 0x01
+#define CTRL_CD_REVERB 0x02
+#define CTRL_EXT_PLAY 0x04
+#define CTRL_EXT_REVERB 0x08
+
+#define CTRL_DMA_F 0x30
+#define CTRL_DMA_R 0x30
+#define CTRL_DMA_W 0x20
+#define CTRL_DMA_NON 0x10
+#define CTRL_DMA_OFF 0x00
+
+#define CTRL_IRQ 0x40
+#define CTRL_REVERB 0x80
+#define CTRL_NOISE 0x3f00
+#define CTRL_MUTE 0x4000
+#define CTRL_ON 0x8000
+
+
+
+
+#define STAT_CD_PLAY 0x01
+#define STAT_CD_REVERB 0x02
+#define STAT_EXT_PLAY 0x04
+#define STAT_EXT_REVERB 0x08
+
+#define STAT_DMA_F 0x10
+#define STAT_DMA_OFF 0x00
+#define STAT_DMA_NON 0x10
+#define STAT_DMA_W (0x200 | 0x80 | 0x20)
+#define STAT_DMA_R (0x100 | 0x80 | 0x20 | 0x10)
+
+#define STAT_IRQ 0x40
+#define STAT_DATA_BUSY 0x80
+#define STAT_DECODED 0x800
+
+
+
+extern int Check_IRQ( int addr, int force );
diff --git a/plugins/dfsound/reverb.c b/plugins/dfsound/reverb.c index 92e31fcb..ce119621 100644 --- a/plugins/dfsound/reverb.c +++ b/plugins/dfsound/reverb.c @@ -16,6 +16,7 @@ ***************************************************************************/
#include "stdafx.h"
+#include "registers.h"
#define _IN_REVERB
@@ -93,6 +94,24 @@ INLINE void InitREVERB(void) // STORE REVERB
////////////////////////////////////////////////////////////////////////
+INLINE void StoreREVERB_CD(int left, int right,int ns)
+{
+ if(iUseReverb==0) return;
+ else
+ if(iUseReverb==2) // -------------------------------- // Neil's reverb
+ {
+ const int iRxl=left;
+ const int iRxr=right;
+
+ ns<<=1;
+
+ // -> we mix all active reverb channels into an extra buffer
+ *(sRVBStart+ns) += CLAMP16( *(sRVBStart+ns+0) + ( iRxl ) );
+ *(sRVBStart+ns+1) += CLAMP16( *(sRVBStart+ns+1) + ( iRxr ) );
+ }
+}
+
+
INLINE void StoreREVERB(int ch,int ns)
{
if(iUseReverb==0) return;
@@ -241,9 +260,20 @@ INLINE int MixREVERBLeft(int ns) }
else // -> reverb off
{
- rvb.iLastRVBLeft=rvb.iLastRVBRight=rvb.iRVBLeft=rvb.iRVBRight=0;
+ // Vib Ribbon - grab current reverb sample (cdda data)
+ // - mono data
+
+ rvb.iRVBLeft = (short) spuMem[ rvb.CurrAddr ];
+ rvb.iRVBRight = rvb.iRVBLeft;
+ rvb.iLastRVBLeft = (rvb.iRVBLeft * rvb.VolLeft) / 0x4000;
+ rvb.iLastRVBRight = (rvb.iRVBRight * rvb.VolRight) / 0x4000;
+
+ //rvb.iLastRVBLeft=rvb.iLastRVBRight=rvb.iRVBLeft=rvb.iRVBRight=0;
}
+
+ Check_IRQ( rvb.CurrAddr*2, 0 );
+
rvb.CurrAddr++;
if(rvb.CurrAddr>0x3ffff) rvb.CurrAddr=rvb.StartAddr;
}
@@ -267,9 +297,16 @@ INLINE int MixREVERBRight(void) else
if(iUseReverb==2) // Neill's reverb:
{
- int i=rvb.iLastRVBRight+(rvb.iRVBRight-rvb.iLastRVBRight)/2;
- rvb.iLastRVBRight=rvb.iRVBRight;
- return i; // -> just return the last right reverb val (little bit scaled by the previous right val)
+ // Vib Ribbon - reverb always on (!), reverb write flag
+ if(spuCtrl & CTRL_REVERB) // -> reverb on? oki
+ {
+ int i=rvb.iLastRVBRight+(rvb.iRVBRight-rvb.iLastRVBRight)/2;
+ rvb.iLastRVBRight=rvb.iRVBRight;
+ return i; // -> just return the last right reverb val (little bit scaled by the previous right val)
+ } else {
+ // Vib Ribbon - return reverb buffer (cdda data)
+ return CLAMP16(rvb.iLastRVBRight);
+ }
}
else // easy fake reverb:
{
diff --git a/plugins/dfsound/spu.c b/plugins/dfsound/spu.c index 56fc6ac8..d009692b 100644 --- a/plugins/dfsound/spu.c +++ b/plugins/dfsound/spu.c @@ -91,6 +91,9 @@ unsigned long dwNoiseCount; // global noise generator unsigned long dwNoiseClock; // global noise generator
int iSpuAsyncWait=0;
+int decoded_ptr = 0;
+int bIrqHit = 0;
+
unsigned short spuCtrl=0; // some vars to store psx reg infos
unsigned short spuStat=0;
unsigned short spuIrq=0;
@@ -532,6 +535,7 @@ static void *MAINThread(void *arg) unsigned char * start;unsigned int nSample;
int ch,predict_nr,shift_factor,flags,d,s;
int bIRQReturn=0;
+ int decoded_voice;
// mute output
if( voldiv == 5 ) voldiv = 0x7fffffff;
@@ -587,8 +591,21 @@ static void *MAINThread(void *arg) //--------------------------------------------------//
{
ns=0;
- while(ns<NSSIZE) // loop until 1 ms of data is reached
+ decoded_voice = decoded_ptr;
+
+ while(ns<NSSIZE) // loop until 1 ms of data is reached
{
+ SSumL[ns]=0;
+ SSumR[ns]=0;
+
+
+ // decoded buffer values - dummy
+ spuMem[ (0x000 + decoded_voice) / 2 ] = (short) 0;
+ spuMem[ (0x400 + decoded_voice) / 2 ] = (short) 0;
+ spuMem[ (0x800 + decoded_voice) / 2 ] = (short) 0;
+ spuMem[ (0xc00 + decoded_voice) / 2 ] = (short) 0;
+
+
NoiseClock();
for(ch=0;ch<MAXCHAN;ch++) // loop em all... we will collect 1 ms of sound of each playing channel
@@ -618,13 +635,11 @@ static void *MAINThread(void *arg) {
if(s_chan[ch].iSBPos==28) // 28 reached?
{
-#if 0
// Xenogears - Anima Relic dungeon (exp gain)
if( s_chan[ch].bLoopJump == 1 )
s_chan[ch].pCurr = s_chan[ch].pLoop;
s_chan[ch].bLoopJump = 0;
-#endif
start=s_chan[ch].pCurr; // set up the current pos
@@ -651,6 +666,9 @@ static void *MAINThread(void *arg) predict_nr >>= 4;
flags=(int)*start;start++;
+ // Silhouette Mirage - Serah fight
+ if( predict_nr > 4 ) predict_nr = 0;
+
// -------------------------------------- //
for (nSample=0;nSample<28;start++)
@@ -661,14 +679,23 @@ static void *MAINThread(void *arg) fa=(s >> shift_factor);
fa=fa + ((s_1 * f[predict_nr][0])>>6) + ((s_2 * f[predict_nr][1])>>6);
+
+ // snes brr clamps
+ fa = CLAMP16(fa);
+
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);
+
+ // snes brr clamps
+ fa = CLAMP16(fa);
+
s_2=s_1;s_1=fa;
s_chan[ch].SB[nSample++]=fa;
@@ -676,6 +703,12 @@ static void *MAINThread(void *arg) //////////////////////////////////////////// irq check
+#if 1
+ // ?? (-8)
+ if( Check_IRQ( (start-spuMemC)-8, 0 ) ||
+ Check_IRQ( (start-spuMemC)-0, 0 ) )
+ {
+#else
if(irqCallback && (spuCtrl&0x40)) // some callback and irq active?
{
if((pSpuIrq > start-16 && // irq address reached?
@@ -683,6 +716,7 @@ static void *MAINThread(void *arg) ((flags&1) && // special: irq on looping addr, when stop/loop flag is set
(pSpuIrq > s_chan[ch].pLoop-16 &&
pSpuIrq <= s_chan[ch].pLoop)))
+#endif
{
s_chan[ch].iIrqDone=1; // -> debug flag
irqCallback(); // -> call main emu
@@ -706,15 +740,9 @@ static void *MAINThread(void *arg) silence means no volume (ADSR keeps playing!!)
*/
-#if 0
if(flags&4)
s_chan[ch].pLoop=start-16;
-#else
- // Jungle Book - Rhythm 'n Groove - use external loop address
- // - fixes music player (+IRQ generate)
- if((flags&4) && (s_chan[ch].bIgnoreLoop == 0))
- s_chan[ch].pLoop=start-16;
-#endif
+
// Jungle Book - Rhythm 'n Groove - don't reset ignore status
// - fixes gameplay speed (IRQ hits)
@@ -727,12 +755,9 @@ static void *MAINThread(void *arg) //s_chan[ch].bIgnoreLoop = 0;
// Xenogears - 7 = play missing sounds
-#if 0
// set jump flag
- pChannel->bLoopJump = 1;
-#else
- start = s_chan[ch].pLoop;
-#endif
+ s_chan[ch].bLoopJump = 1;
+
// silence = keep playing..?
if( (flags&2) == 0 ) {
@@ -753,6 +778,18 @@ static void *MAINThread(void *arg) start = spuMemC - 0x80000;
#endif
+
+ // Silhouette Mirage - ending mini-game
+
+ // ??
+ if( start - spuMemC >= 0x80000 ) {
+ start -= 16;
+
+ s_chan[ch].iSilent = 1;
+ s_chan[ch].bStop = 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;
@@ -800,14 +837,12 @@ GOON: ; else fa=iGetInterpolationVal(ch); // get sample val
-#if 0
// Voice 1/3 decoded buffer
if( ch == 0 ) {
- spuMem[ (0x800 + voice_dbuf_ptr) / 2 ] = (short) fa;
+ spuMem[ (0x800 + decoded_voice) / 2 ] = (short) fa;
} else if( ch == 2 ) {
- spuMem[ (0xc00 + voice_dbuf_ptr) / 2 ] = (short) fa;
+ spuMem[ (0xc00 + decoded_voice) / 2 ] = (short) fa;
}
-#endif
s_chan[ch].sval = (MixADSR(ch) * fa) / 1023; // mix adsr
@@ -837,13 +872,56 @@ GOON: ; s_chan[ch].spos += s_chan[ch].sinc;
}
+
////////////////////////////////////////////////
// ok, go on until 1 ms data of this channel is collected
+ // decoded buffer - voice
+ decoded_voice += 2;
+ if( decoded_voice >= 0x400 ) {
+ decoded_voice = 0;
+ }
+
+
+ // status flag
+ if( decoded_voice >= 0x200 ) {
+ spuStat |= STAT_DECODED;
+ } else {
+ spuStat &= ~STAT_DECODED;
+ }
+
+
+ // IRQ work
+ {
+ unsigned char *old_irq;
+ int old_ptr;
+
+ old_irq = pSpuIrq;
+ old_ptr = decoded_voice;
+
+
+#if 0
+ // align to boundaries ($0, $200, $400, $600)
+ pSpuIrq = ((pSpuIrq - spuMemC) & (~0x1ff)) + spuMemC;
+ decoded_voice = decoded_voice & (~0x1ff);
+#endif
+
+ // check all decoded buffer IRQs - timing issue
+ Check_IRQ( decoded_voice + 0x000, 0 );
+ Check_IRQ( decoded_voice + 0x400, 0 );
+ Check_IRQ( decoded_voice + 0x800, 0 );
+ Check_IRQ( decoded_voice + 0xc00, 0 );
+
+ pSpuIrq = old_irq;
+ decoded_voice = old_ptr;
+ }
+
+
ns++;
} // end ns
}
+
//---------------------------------------------------//
//- here we have another 1 ms of sound data
//---------------------------------------------------//
@@ -851,6 +929,12 @@ GOON: ; MixXA();
+
+ // now safe to update deocded buffer ptr
+ decoded_ptr += ns * 2;
+ if( decoded_ptr >= 0x400 ) decoded_ptr -= 0x400;
+
+
///////////////////////////////////////////////////////
// mix all channels (including reverb) into one buffer
@@ -948,6 +1032,7 @@ GOON: ; // an IRQ. Only problem: the "wait for cpu" option is kinda hard to do here
// in some of Peops timer modes. So: we ignore this option here (for now).
+#if 0
if(pMixIrq && irqCallback)
{
for(ns=0;ns<NSSIZE;ns++)
@@ -963,6 +1048,7 @@ GOON: ; pMixIrq+=2;if(pMixIrq>spuMemC+0x3ff) pMixIrq=spuMemC;
}
}
+#endif
InitREVERB();
diff --git a/plugins/dfsound/xa.c b/plugins/dfsound/xa.c index bec405bd..4d46be66 100644 --- a/plugins/dfsound/xa.c +++ b/plugins/dfsound/xa.c @@ -67,6 +67,8 @@ INLINE void MixXA(void) int ns;
int lc,rc;
unsigned long cdda_l;
+ int decoded_xa;
+ int decoded_cdda;
lc = 0;
rc = 0;
@@ -79,13 +81,6 @@ INLINE void MixXA(void) lc = (short)(XALastVal&0xffff);
rc = (short)((XALastVal>>16) & 0xffff);
- 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;
// improve crackle - buffer under
// - not update fast enough
@@ -93,34 +88,74 @@ INLINE void MixXA(void) lastxa_rc = rc;
-#if 0
- if( cdxa_dbuf_ptr >= 0x400 )
- cdxa_dbuf_ptr = 0;
- spuMem[ (cdxa_dbuf_ptr + 0)/2 ] = lc;
- spuMem[ (cdxa_dbuf_ptr + 0x400)/2 ] = rc;
- cdxa_dbuf_ptr += 2;
-#endif
- }
+ // Tales of Phantasia - voice meter
+ spuMem[ (decoded_xa + 0x000)/2 ] = (short) lc;
+ spuMem[ (decoded_xa + 0x400)/2 ] = (short) rc;
+
+ decoded_xa += 2;
+ if( decoded_xa >= 0x400 )
+ decoded_xa = 0;
+
+
+ lc = CLAMP16( (lc * iLeftXAVol) / 0x8000 );
+ rc = CLAMP16( (rc * iRightXAVol) / 0x8000 );
+
+
+ // reverb write flag
+ if( spuCtrl & CTRL_CD_REVERB ) {
+ StoreREVERB_CD( lc, rc, ns );
+ }
+
+
+ // play flag
+ if( spuCtrl & CTRL_CD_PLAY ) {
+ SSumL[ns]+=lc;
+ SSumR[ns]+=rc;
+ }
+ }
if(XAPlay==XAFeed && XARepeat)
{
//XARepeat--;
for(;ns<NSSIZE;ns++)
{
- SSumL[ns]+=lastxa_rc;
- SSumR[ns]+=lastxa_rc;
+ // improve crackle - buffer under
+ // - not update fast enough
+ lc = lastxa_lc;
+ rc = lastxa_rc;
+
-#if 0
// Tales of Phantasia - voice meter
- if( cdxa_dbuf_ptr >= 0x400 )
- cdxa_dbuf_ptr = 0;
- spuMem[ (cdxa_dbuf_ptr + 0)/2 ] = lastxa_rc;
- spuMem[ (cdxa_dbuf_ptr + 0x400)/2 ] = lastxa_rc;
- cdxa_dbuf_ptr += 2;
-#endif
+ spuMem[ (decoded_xa + 0x000)/2 ] = (short) lc;
+ spuMem[ (decoded_xa + 0x400)/2 ] = (short) rc;
+
+ decoded_xa += 2;
+ if( decoded_xa >= 0x400 )
+ decoded_xa = 0;
+
+
+ lc = CLAMP16( (lc * iLeftXAVol) / 0x8000 );
+ rc = CLAMP16( (rc * iRightXAVol) / 0x8000 );
+
+
+ // reverb write flags
+ if( spuCtrl & CTRL_CD_REVERB ) {
+ StoreREVERB_CD( lc, rc, ns );
+ }
+
+
+ // play flag
+ if( spuCtrl & CTRL_CD_PLAY ) {
+ SSumL[ns]+=lc;
+ SSumR[ns]+=rc;
+ }
}
}
+
+
+ decoded_cdda = decoded_ptr;
+
for(ns=0;ns<NSSIZE && CDDAPlay!=CDDAFeed && (CDDAPlay!=CDDAEnd-1||CDDAFeed!=CDDAStart);ns++)
{
cdda_l=*CDDAPlay++;
@@ -129,27 +164,38 @@ INLINE void MixXA(void) lc = (short)(cdda_l&0xffff);
rc = (short)((cdda_l>>16) & 0xffff);
- 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;
-
-#if 0
- // Vib Ribbon - playback
- if( cdxa_dbuf_ptr >= 0x400 )
- cdxa_dbuf_ptr = 0;
- spuMem[ (cdxa_dbuf_ptr + 0)/2 ] = lc;
- spuMem[ (cdxa_dbuf_ptr + 0x400)/2 ] = rc;
- cdxa_dbuf_ptr += 2;
-#endif
// improve crackle - buffer under
// - not update fast enough
lastcd_lc = lc;
lastcd_rc = rc;
+
+
+ // Vib Ribbon - playback
+ spuMem[ (decoded_cdda + 0x000)/2 ] = (short) lc;
+ spuMem[ (decoded_cdda + 0x400)/2 ] = (short) rc;
+
+ decoded_cdda += 2;
+ if( decoded_cdda >= 0x400 )
+ decoded_cdda = 0;
+
+
+ // Rayman - stage end fadeout
+ lc = CLAMP16( (lc * iLeftXAVol) / 0x8000 );
+ rc = CLAMP16( (rc * iRightXAVol) / 0x8000 );
+
+
+ // reverb write flag
+ if( spuCtrl & CTRL_CD_REVERB ) {
+ StoreREVERB_CD( lc, rc, ns );
+ }
+
+
+ // play flag
+ if( spuCtrl & CTRL_CD_PLAY ) {
+ SSumL[ns]+=lc;
+ SSumR[ns]+=rc;
+ }
}
@@ -158,18 +204,38 @@ INLINE void MixXA(void) //XARepeat--;
for(;ns<NSSIZE;ns++)
{
-#if 0
- // Vib Ribbon - playback
- if( cdxa_dbuf_ptr >= 0x400 )
- cdxa_dbuf_ptr = 0;
- spuMem[ (cdxa_dbuf_ptr + 0)/2 ] = lastcd_lc;
- spuMem[ (cdxa_dbuf_ptr + 0x400)/2 ] = lastcd_rc;
- cdxa_dbuf_ptr += 2;
-#endif
+ // improve crackle - buffer under
+ // - not update fast enough
+ lc = lastcd_lc;
+ rc = lastcd_rc;
- SSumL[ns]+=lastcd_lc;
- SSumR[ns]+=lastcd_rc;
- }
+
+ // Vib Ribbon - playback
+ spuMem[ (decoded_cdda + 0x000)/2 ] = (short) lc;
+ spuMem[ (decoded_cdda + 0x400)/2 ] = (short) rc;
+
+ decoded_cdda += 2;
+ if( decoded_cdda >= 0x400 )
+ decoded_cdda = 0;
+
+
+ // Rayman - stage end fadeout
+ lc = CLAMP16( (lc * iLeftXAVol) / 0x8000 );
+ rc = CLAMP16( (rc * iRightXAVol) / 0x8000 );
+
+
+ // reverb write flag
+ if( spuCtrl & CTRL_CD_REVERB ) {
+ StoreREVERB_CD( lc, rc, ns );
+ }
+
+
+ // play flag
+ if( spuCtrl & CTRL_CD_PLAY ) {
+ SSumL[ns]+=lc;
+ SSumR[ns]+=rc;
+ }
+ }
}
}
@@ -194,7 +260,7 @@ unsigned long timeGetTime_spu() INLINE void FeedXA(xa_decode_t *xap)
{
- int sinc,spos,i,iSize,iPlace,vl,vr;
+ int sinc,spos,i,iSize,iPlace;
if(!bSPUIsOpen) return;
|
