#include "registers.h"
#include "out.h"
#include "spu_config.h"
+#include "spu.h"
#ifdef __arm__
#include "arm_features.h"
mix_chan(spu.SSumLR, ns_to, s_chan->iLeftVolume, s_chan->iRightVolume);
}
- MixXA(spu.SSumLR, RVB, ns_to, spu.decode_pos);
+ MixCD(spu.SSumLR, RVB, ns_to, spu.decode_pos);
if (spu.rvb->StartAddr) {
if (do_rvb)
work = &worker->i[worker->i_reaped & WORK_I_MASK];
thread_work_wait_sync(work, force);
- MixXA(work->SSumLR, RVB, work->ns_to, work->decode_pos);
+ MixCD(work->SSumLR, RVB, work->ns_to, work->decode_pos);
do_samples_finish(work->SSumLR, work->ns_to,
work->channels_silent, work->decode_pos);
// XA AUDIO
-void CALLBACK SPUplayADPCMchannel(xa_decode_t *xap, unsigned int cycle, int unused)
+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 (is_start)
+ spu.XAPlay = spu.XAFeed = spu.XAStart;
if (spu.XAPlay == spu.XAFeed)
do_samples(cycle, 1); // catch up to prevent source underflows later
return 0;
}
+void CALLBACK SPUsetCDvol(unsigned char ll, unsigned char lr,
+ unsigned char rl, unsigned char rr, unsigned int cycle)
+{
+ if (spu.XAPlay != spu.XAFeed || spu.CDDAPlay != spu.CDDAFeed)
+ do_samples(cycle, 1);
+ spu.cdv.ll = ll;
+ spu.cdv.lr = lr;
+ spu.cdv.rl = rl;
+ spu.cdv.rr = rr;
+}
+
// to be called after state load
void ClearWorkingState(void)
{
int i;
memset(&spu, 0, sizeof(spu));
- spu.spuMemC = calloc(1, 512 * 1024);
+ spu.spuMemC = calloc(1, 512 * 1024 + 16);
+ // a guard for runaway channels - End+Mute
+ spu.spuMemC[512 * 1024 + 1] = 1;
+
InitADSR();
spu.s_chan = calloc(MAXCHAN+1, sizeof(spu.s_chan[0])); // channel + 1 infos (1 is security for fmod handling)