extern unsigned short CALLBACK SPUreadDMA(void);
extern void CALLBACK SPUwriteDMAMem(unsigned short *, int, unsigned int);
extern void CALLBACK SPUreadDMAMem(unsigned short *, int, unsigned int);
-extern void CALLBACK SPUplayADPCMchannel(void *);
+extern void CALLBACK SPUplayADPCMchannel(void *, unsigned int, int);
extern void CALLBACK SPUregisterCallback(void (*cb)(void));
extern void CALLBACK SPUregisterScheduleCb(void (*cb)(unsigned int));
extern long CALLBACK SPUconfigure(void);
extern void CALLBACK SPUabout(void);
extern long CALLBACK SPUfreeze(unsigned int, void *, unsigned int);
extern void CALLBACK SPUasync(unsigned int, unsigned int);
-extern int CALLBACK SPUplayCDDAchannel(short *, int);
+extern int CALLBACK SPUplayCDDAchannel(short *, int, unsigned int, int);
/* PAD */
static long CALLBACK PADreadPort1(PadDataS *pad) {
pc_hook_func_ret(unsigned short,SPU_readDMA, (void), (), PCNT_SPU)
pc_hook_func (SPU_writeDMAMem, (unsigned short *a0, int a1, uint32_t a2), (a0, a1, a2), PCNT_SPU)
pc_hook_func (SPU_readDMAMem, (unsigned short *a0, int a1, uint32_t a2), (a0, a1, a2), PCNT_SPU)
-pc_hook_func (SPU_playADPCMchannel, (void *a0), (a0), PCNT_SPU)
+pc_hook_func (SPU_playADPCMchannel, (void *a0, unsigned int a1, int a2), (a0, a1, a2), PCNT_SPU)
pc_hook_func (SPU_async, (uint32_t a0, uint32_t a1), (a0, a1), PCNT_SPU)
-pc_hook_func_ret(int, SPU_playCDDAchannel, (short *a0, int a1), (a0, a1), PCNT_SPU)
+pc_hook_func_ret(int, SPU_playCDDAchannel, (short *a0, int a1, unsigned int a2, int a3), (a0, a1, a2, a3), PCNT_SPU)
#define hook_it(name) { \
o_##name = name; \
if (!cdr.Irq && !cdr.Stat && (cdr.Mode & (MODE_AUTOPAUSE|MODE_REPORT)))
cdrPlayInterrupt_Autopause();
- if (CDR_readCDDA && !cdr.Muted && !Config.Cdda) {
+ if (!cdr.Muted && !Config.Cdda) {
cdrAttenuate(read_buf, CD_FRAMESIZE_RAW / 4, 1);
- if (SPU_playCDDAchannel)
- SPU_playCDDAchannel(read_buf, CD_FRAMESIZE_RAW);
+ SPU_playCDDAchannel(read_buf, CD_FRAMESIZE_RAW, psxRegs.cycle, cdr.FirstSector);
+ cdr.FirstSector = 0;
}
cdr.SetSectorPlay[2]++;
Find_CurTrack(cdr.SetSectorPlay);
ReadTrack(cdr.SetSectorPlay);
cdr.TrackChanged = FALSE;
+ cdr.FirstSector = 1;
if (!Config.Cdda)
CDR_play(cdr.SetSectorPlay);
int ret = xa_decode_sector(&cdr.Xa, cdr.Transfer+4, cdr.FirstSector);
if (!ret) {
cdrAttenuate(cdr.Xa.pcm, cdr.Xa.nsamples, cdr.Xa.stereo);
- SPU_playADPCMchannel(&cdr.Xa);
+ SPU_playADPCMchannel(&cdr.Xa, psxRegs.cycle, cdr.FirstSector);
cdr.FirstSector = 0;
}
else cdr.FirstSector = -1;
typedef unsigned short (CALLBACK* SPUreadDMA)(void);\r
typedef void (CALLBACK* SPUwriteDMAMem)(unsigned short *, int, unsigned int);\r
typedef void (CALLBACK* SPUreadDMAMem)(unsigned short *, int, unsigned int);\r
-typedef void (CALLBACK* SPUplayADPCMchannel)(xa_decode_t *);\r
+typedef void (CALLBACK* SPUplayADPCMchannel)(xa_decode_t *, unsigned int, int);\r
typedef void (CALLBACK* SPUregisterCallback)(void (CALLBACK *callback)(void));\r
typedef void (CALLBACK* SPUregisterScheduleCb)(void (CALLBACK *callback)(unsigned int cycles_after));\r
typedef long (CALLBACK* SPUconfigure)(void);\r
} SPUFreeze_t;\r
typedef long (CALLBACK* SPUfreeze)(uint32_t, SPUFreeze_t *, uint32_t);\r
typedef void (CALLBACK* SPUasync)(uint32_t, uint32_t);\r
-typedef int (CALLBACK* SPUplayCDDAchannel)(short *, int);\r
+typedef int (CALLBACK* SPUplayCDDAchannel)(short *, int, unsigned int, int);\r
\r
// SPU function pointers\r
extern SPUconfigure SPU_configure;\r
spu.bMemDirty = 1;\r
\r
if(pF->xaS.nsamples<=4032) // start xa again\r
- SPUplayADPCMchannel(&pF->xaS);\r
+ SPUplayADPCMchannel(&pF->xaS, spu.cycles_played, 0);\r
\r
spu.xapGlobal=0;\r
\r
// XA AUDIO
-void CALLBACK SPUplayADPCMchannel(xa_decode_t *xap)
+void CALLBACK SPUplayADPCMchannel(xa_decode_t *xap, unsigned int cycle, int is_start)
{
if(!xap) return;
- if(!xap->freq) return; // no xa freq ? bye
+ if(!xap->freq) return; // no xa freq ? bye
- FeedXA(xap); // call main XA feeder
+ if (is_start)
+ do_samples(cycle, 1); // catch up to prevent source underflows later
+
+ FeedXA(xap); // call main XA feeder
}
// CDDA AUDIO
-int CALLBACK SPUplayCDDAchannel(short *pcm, int nbytes)
+int CALLBACK SPUplayCDDAchannel(short *pcm, int nbytes, unsigned int cycle, int is_start)
{
if (!pcm) return -1;
if (nbytes<=0) return -1;
+ if (is_start)
+ do_samples(cycle, 1); // catch up to prevent source underflows later
+
return FeedCDDA((unsigned char *)pcm, nbytes);
}
#define __P_SPU_H__\r
\r
void ClearWorkingState(void);\r
-void CALLBACK SPUplayADPCMchannel(xa_decode_t *xap);\r
-int CALLBACK SPUplayCDDAchannel(short *pcm, int bytes);\r
+void CALLBACK SPUplayADPCMchannel(xa_decode_t *xap, unsigned int cycle, int is_start);\r
+int CALLBACK SPUplayCDDAchannel(short *pcm, int bytes, unsigned int cycle, int is_start);\r
\r
#endif /* __P_SPU_H__ */\r
if(!spu.bSPUIsOpen) return;
spu.xapGlobal = xap; // store info for save states
- spu.XARepeat = 100; // set up repeat
+ spu.XARepeat = 3; // set up repeat
#if 0//def XA_HACK
iSize=((45500*xap->nsamples)/xap->freq); // get size