#include "externals.h"
#include "registers.h"
-#include "dsoundoss.h"
+#include "out.h"
+#include "arm_features.h"
#ifdef ENABLE_NLS
#include <libintl.h>
// helpers for gauss interpolation
#define gval0 (((short*)(&s_chan[ch].SB[29]))[gpos])
-#define gval(x) (((short*)(&s_chan[ch].SB[29]))[(gpos+x)&3])
+#define gval(x) ((int)((short*)(&s_chan[ch].SB[29]))[(gpos+x)&3])
#include "gauss_i.h"
int vl, vr;int gpos;
vl = (spos >> 6) & ~3;
gpos = s_chan[ch].SB[28];
- vr=(gauss[vl]*gval0)&~2047;
+ vr=(gauss[vl]*(int)gval0)&~2047;
vr+=(gauss[vl+1]*gval(1))&~2047;
vr+=(gauss[vl+2]*gval(2))&~2047;
vr+=(gauss[vl+3]*gval(3))&~2047;
{
unsigned char *start;
int predict_nr,shift_factor,flags;
+ int stop = 0;
int ret = 0;
- start=s_chan[ch].pCurr; // set up the current pos
+ start = s_chan[ch].pCurr; // set up the current pos
+ if(start == spuMemC) // ?
+ stop = 1;
if(s_chan[ch].prevflags&1) // 1: stop/loop
{
if(!(s_chan[ch].prevflags&2))
- {
- dwChannelOn&=~(1<<ch); // -> turn everything off
- s_chan[ch].bStop=1;
- s_chan[ch].ADSRX.EnvelopeVol=0;
- }
+ stop = 1;
start = s_chan[ch].pLoop;
}
else
ret = check_irq(ch, start); // hack, see check_irq below..
+ if(stop)
+ {
+ dwChannelOn &= ~(1<<ch); // -> turn everything off
+ s_chan[ch].bStop = 1;
+ s_chan[ch].ADSRX.EnvelopeVol = 0;
+ }
+
predict_nr=(int)start[0];
shift_factor=predict_nr&0xf;
predict_nr >>= 4;
return ret;
}
-#ifdef __arm__
+#ifdef HAVE_ARMV5
// asm code; lv and rv must be 0-3fff
extern void mix_chan(int start, int count, int lv, int rv);
extern void mix_chan_rvb(int start, int count, int lv, int rv);
{
const int *src = ChanBuf + start;
unsigned short *dst = &spuMem[0x800/2 + which*0x400/2];
- int cursor = decode_pos;
+ int cursor = decode_pos + start;
while (count-- > 0)
{
+ cursor &= 0x1ff;
dst[cursor] = *src++;
- cursor = (cursor + 1) & 0x1ff;
+ cursor++;
}
// decode_pos is updated and irqs are checked later, after voice loop
int ch,d,silentch;
int bIRQReturn=0;
- while(1)
- {
- // ok, at the beginning we are looking if there is
- // enuff free place in the dsound/oss buffer to
- // fill in new data, or if there is a new channel to start.
- // if not, we wait (thread) or return (timer/spuasync)
- // until enuff free place is available/a new channel gets
- // started
-
- if(!forced_updates && SoundGetBytesBuffered()) // still enuff data in sound buffer?
- {
- return 0;
- }
+ // ok, at the beginning we are looking if there is
+ // enuff free place in the dsound/oss buffer to
+ // fill in new data, or if there is a new channel to start.
+ // if not, we return until enuff free place is available
+ // /a new channel gets started
- cycles_since_update = 0;
- if(forced_updates > 0)
- forced_updates--;
+ if(!forced_updates && out_current->busy()) // still enuff data in sound buffer?
+ return 0;
- //--------------------------------------------------// continue from irq handling in timer mode?
+ while(!bIRQReturn)
+ {
+ cycles_since_update = 0;
ns_from=0;
ns_to=NSSIZE;
// no need for bIRQReturn since the channel is silent
skip_block(ch);
- if(start == s_chan[ch].pCurr)
+ if(start == s_chan[ch].pCurr || start - spuMemC < 0x1000)
{
- // looping on self
+ // looping on self or stopped(?)
dwChannelDead |= 1<<ch;
s_chan[ch].spos = 0;
break;
{
//printf("decoder irq %x\n", decode_pos);
do_irq();
+ bIRQReturn = 1;
}
}
decode_pos = (decode_pos + NSSIZE) & 0x1ff;
// feed the sound
// wanna have around 1/60 sec (16.666 ms) updates
- if (iCycle++ > 16/FRAG_MSECS)
+ if (iCycle++ >= 16/FRAG_MSECS)
{
- SoundFeedStreamData((unsigned char *)pSpuBuffer,
- ((unsigned char *)pS) - ((unsigned char *)pSpuBuffer));
+ out_current->feed(pSpuBuffer, (unsigned char *)pS - pSpuBuffer);
pS = (short *)pSpuBuffer;
iCycle = 0;
+
+ if(!forced_updates && out_current->busy())
+ break;
+ }
+
+ if(forced_updates > 0)
+ {
+ forced_updates--;
+ if(forced_updates == 0 && out_current->busy())
+ break;
}
}
bSPUIsOpen = 0; // no more open
- RemoveSound(); // no more sound handling
+ out_current->finish(); // no more sound handling
return 0;
}