} while (0)
#endif
+#define PSXCLK 33868800 /* 33.8688 MHz */
+
/*
#if defined (USEMACOSX)
static char * libraryName = N_("Mac OS X Sound");
int iVolume=768; // 1024 is 1.0
int iXAPitch=1;
-int iSPUIRQWait=1;
-int iDebugMode=0;
-int iRecordMode=0;
int iUseReverb=2;
int iUseInterpolation=2;
unsigned int dwNoiseVal; // global noise generator
unsigned int dwNoiseCount;
-int iSpuAsyncWait=0;
unsigned short spuCtrl=0; // some vars to store psx reg infos
unsigned short spuStat=0;
int iCycle = 0;
short * pS;
+int had_dma;
int lastch=-1; // last channel processed on spu irq in timer mode
static int lastns=0; // last ns pos
-static int iSecureStart=0; // secure start counter
+static int cycles_since_update;
#define CDDA_BUFFER_SIZE (16384 * sizeof(uint32_t)) // must be power of 2
{ \
sbpos = 0; \
d = decode_block(ch); \
- if(d && iSPUIRQWait) \
+ if(d) \
{ \
ret = ns; \
goto out; \
// basically the whole sound processing is done in this fat func!
////////////////////////////////////////////////////////////////////////
-static int do_samples(void)
+static int do_samples(int forced_updates)
{
int volmult = iVolume;
int ns,ns_from,ns_to;
// until enuff free place is available/a new channel gets
// started
- if(dwNewChannel) // new channel should start immedately?
- { // (at least one bit 0 ... MAXCHANNEL is set?)
- iSecureStart++; // -> set iSecure
- if(iSecureStart>5) iSecureStart=0; // (if it is set 5 times - that means on 5 tries a new samples has been started - in a row, we will reset it, to give the sound update a chance)
- }
- else iSecureStart=0; // 0: no new channel should start
-
- if(!iSecureStart && // no new start?
- (SoundGetBytesBuffered()>TESTSIZE)) // and still enuff data in sound buffer?
+ if(!forced_updates && SoundGetBytesBuffered()) // still enuff data in sound buffer?
{
return 0;
}
+ cycles_since_update = 0;
+ if(forced_updates > 0)
+ forced_updates--;
+
//--------------------------------------------------// continue from irq handling in timer mode?
ns_from=0;
// advance "stopped" channels that can cause irqs
// (all chans are always playing on the real thing..)
- if(!bIRQReturn && (spuCtrl&CTRL_IRQ))
+ if(spuCtrl&CTRL_IRQ)
for(ch=0;ch<MAXCHAN;ch++)
{
if(!(silentch&(1<<ch))) continue; // already handled
if(s_chan[ch].pCurr > pSpuIrq && s_chan[ch].pLoop > pSpuIrq)
continue;
- s_chan[ch].spos += s_chan[ch].sinc * NSSIZE;
+ s_chan[ch].spos += s_chan[ch].sinc * (ns_to - ns_from);
while(s_chan[ch].spos >= 28 * 0x10000)
{
unsigned char *start = s_chan[ch].pCurr;
// no need for bIRQReturn since the channel is silent
- iSpuAsyncWait |= skip_block(ch);
+ skip_block(ch);
if(start == s_chan[ch].pCurr)
{
// looping on self
}
}
- if(bIRQReturn && iSPUIRQWait) // special return for "spu irq - wait for cpu action"
- {
- iSpuAsyncWait=1;
- bIRQReturn=0;
+ if(bIRQReturn) // special return for "spu irq - wait for cpu action"
return 0;
- }
//---------------------------------------------------//
void CALLBACK SPUasync(unsigned long cycle)
{
- if(iSpuAsyncWait)
- {
- iSpuAsyncWait++;
- if(iSpuAsyncWait<=16/FRAG_MSECS) return;
- iSpuAsyncWait=0;
- }
+ int forced_updates = 0;
+ int do_update = 0;
if(!bSpuInit) return; // -> no init, no call
- do_samples();
+ cycles_since_update += cycle;
+
+ if(dwNewChannel || had_dma)
+ {
+ forced_updates = 1;
+ do_update = 1;
+ had_dma = 0;
+ }
+
+ // once per frame should be fine (using a bit more because of BIAS)
+ if(cycles_since_update > PSXCLK/60 * 5/4)
+ do_update = 1;
- // abuse iSpuAsyncWait mechanism to reduce calls to above function
- // to make it do larger chunks
- // note: doing it less often than once per frame causes skips
- iSpuAsyncWait=1;
+ if(do_update)
+ do_samples(forced_updates);
}
// SPU UPDATE... new epsxe func
pMixIrq = 0;
memset((void *)s_chan, 0, (MAXCHAN + 1) * sizeof(SPUCHAN));
pSpuIrq = 0;
- //iSPUIRQWait = 0;
lastch = -1;
SetupStreams(); // prepare streaming