#include "arm_features.h"
#endif
-#ifdef __ARM_ARCH_7A__
+#ifdef HAVE_ARMV7
#define ssat32_to_16(v) \
asm("ssat %0,#16,%1" : "=r" (v) : "r" (v))
#else
s_chan->iSBPos=27;
s_chan->spos=0;
+ s_chan->pCurr = spu.spuMemC+((regAreaGet(ch,6)&~1)<<3);
+
spu.dwNewChannel&=~(1<<ch); // clear new channel bit
- spu.dwChannelOn|=1<<ch;
spu.dwChannelDead&=~(1<<ch);
+ if (s_chan->iRawPitch)
+ spu.dwChannelsAudible|=1<<ch;
}
static void StartSound(int ch)
decode_block_data(SB, start + 2, predict_nr, shift_factor);
flags = start[1];
- if (flags & 4)
+ if (flags & 4 && (!s_chan->bIgnoreLoop))
s_chan->pLoop = start; // loop adress
start += 16;
StartSound(ch);
}
- mask = spu.dwChannelOn & 0xffffff;
+ mask = spu.dwChannelsAudible & 0xffffff;
for (ch = 0; mask != 0; ch++, mask >>= 1) // loop em all...
{
if (!(mask & 1)) continue; // channel not playing? next
d = MixADSR(&s_chan->ADSRX, d);
if (d < ns_to) {
- spu.dwChannelOn &= ~(1 << ch);
+ spu.dwChannelsAudible &= ~(1 << ch);
+ s_chan->ADSRX.State = ADSR_RELEASE;
s_chan->ADSRX.EnvelopeVol = 0;
memset(&ChanBuf[d], 0, (ns_to - d) * sizeof(ChanBuf[0]));
}
unsigned int i_ready;
unsigned int i_reaped;
unsigned int last_boot_cnt; // dsp
+ unsigned int ram_dirty;
};
// aligning for C64X_DSP
unsigned int _pad0[128/4];
StartSoundMain(ch);
}
- mask = work->channels_on = spu.dwChannelOn & 0xffffff;
+ mask = work->channels_on = spu.dwChannelsAudible & 0xffffff;
spu.decode_dirty_ch |= mask & 0x0a;
for (ch = 0; mask != 0; ch++, mask >>= 1)
// note: d is not accurate on skip
d = SkipADSR(&s_chan->ADSRX, d);
if (d < ns_to) {
- spu.dwChannelOn &= ~(1 << ch);
+ spu.dwChannelsAudible &= ~(1 << ch);
s_chan->ADSRX.EnvelopeVol = 0;
}
}
done = thread_get_i_done() - worker->i_reaped;
used_space = worker->i_ready - worker->i_reaped;
+
//printf("done: %d use: %d dsp: %u/%u\n", done, used_space,
// worker->boot_cnt, worker->i_done);
return;
}
- silentch = ~(spu.dwChannelOn | spu.dwNewChannel) & 0xffffff;
+ silentch = ~(spu.dwChannelsAudible | spu.dwNewChannel) & 0xffffff;
do_direct |= (silentch == 0xffffff);
if (worker != NULL)
if ((unsigned long)(spu.pSpuIrq - spu.s_chan[ch].pCurr) > IRQ_NEAR_BLOCKS * 16
&& (unsigned long)(spu.pSpuIrq - spu.s_chan[ch].pLoop) > IRQ_NEAR_BLOCKS * 16)
continue;
+ if (spu.s_chan[ch].sinc == 0)
+ continue;
scan_for_irq(ch, &upd_samples);
}
void CALLBACK SPUasync(unsigned int cycle, unsigned int flags)
{
- do_samples(cycle, 0);
+ do_samples(cycle, spu_config.iUseFixedUpdates);
if (spu.spuCtrl & CTRL_IRQ)
schedule_next_irq();
spu.pSpuBuffer = (unsigned char *)malloc(32768); // alloc mixing buffer
spu.SSumLR = calloc(NSSIZE * 2, sizeof(spu.SSumLR[0]));
- spu.XAStart = // alloc xa buffer
- (uint32_t *)malloc(44100 * sizeof(uint32_t));
+ spu.XAStart = malloc(44100 * sizeof(uint32_t)); // alloc xa buffer
spu.XAEnd = spu.XAStart + 44100;
spu.XAPlay = spu.XAStart;
spu.XAFeed = spu.XAStart;
- spu.CDDAStart = // alloc cdda buffer
- (uint32_t *)malloc(CDDA_BUFFER_SIZE);
+ spu.CDDAStart = malloc(CDDA_BUFFER_SIZE); // alloc cdda buffer
spu.CDDAEnd = spu.CDDAStart + 16384;
spu.CDDAPlay = spu.CDDAStart;
spu.CDDAFeed = spu.CDDAStart;
spu.s_chan[i].ADSRX.SustainIncrease = 1;
spu.s_chan[i].pLoop = spu.spuMemC;
spu.s_chan[i].pCurr = spu.spuMemC;
+ spu.s_chan[i].bIgnoreLoop = 0;
}
spu.bSpuInit=1; // flag: we are inited
spu.irqCallback = callback;
}
-void CALLBACK SPUregisterCDDAVolume(void (CALLBACK *CDDAVcallback)(unsigned short,unsigned short))
+void CALLBACK SPUregisterCDDAVolume(void (CALLBACK *CDDAVcallback)(short, short))
{
spu.cddavCallback = CDDAVcallback;
}
for(;ch<MAXCHAN;ch++)
{
- if (!(spu.dwChannelOn & (1<<ch)))
+ if (!(spu.dwChannelsAudible & (1<<ch)))
continue;
if (spu.s_chan[ch].bFMod == 2)
fmod_chans |= 1 << ch;
irq_chans |= 1 << ch;
}
- *chans_out = spu.dwChannelOn;
- *run_chans = ~spu.dwChannelOn & ~spu.dwChannelDead & irq_chans;
+ *chans_out = spu.dwChannelsAudible;
+ *run_chans = ~spu.dwChannelsAudible & ~spu.dwChannelDead & irq_chans;
*fmod_chans_out = fmod_chans;
*noise_chans_out = noise_chans;
}