+ //--------------------------------------------------//
+ //- main channel loop -//
+ //--------------------------------------------------//
+ {
+ for(ch=0;ch<MAXCHAN;ch++) // loop em all...
+ {
+ if(spu.dwNewChannel&(1<<ch)) StartSound(ch); // start new sound
+ if(!(spu.dwChannelOn&(1<<ch))) continue; // channel not playing? next
+
+ if(s_chan[ch].bNoise)
+ do_samples_noise(ch, ns_from, ns_to);
+ else if(s_chan[ch].bFMod==2 || (s_chan[ch].bFMod==0 && spu_config.iUseInterpolation==0))
+ do_samples_noint(ch, ns_from, ns_to);
+ else if(s_chan[ch].bFMod==0 && spu_config.iUseInterpolation==1)
+ do_samples_simple(ch, ns_from, ns_to);
+ else
+ do_samples_default(ch, ns_from, ns_to);
+
+ ns_len = ns_to - ns_from;
+
+ MixADSR(ch, ns_from, ns_to);
+
+ if(ch==1 || ch==3)
+ {
+ do_decode_bufs(ch/2, ns_from, ns_len);
+ spu.decode_dirty_ch |= 1<<ch;
+ }
+
+ if(s_chan[ch].bFMod==2) // fmod freq channel
+ memcpy(&iFMod[ns_from], &ChanBuf[ns_from], ns_len * sizeof(iFMod[0]));
+ if(s_chan[ch].bRVBActive)
+ mix_chan_rvb(ns_from, ns_len, s_chan[ch].iLeftVolume, s_chan[ch].iRightVolume, spu.sRVBStart);
+ else
+ mix_chan(ns_from, ns_len, s_chan[ch].iLeftVolume, s_chan[ch].iRightVolume);
+ }
+ }
+
+ // advance "stopped" channels that can cause irqs
+ // (all chans are always playing on the real thing..)
+ if(spu.spuCtrl&CTRL_IRQ)
+ for(ch=0;ch<MAXCHAN;ch++)
+ {
+ if(!(silentch&(1<<ch))) continue; // already handled
+ if(spu.dwChannelDead&(1<<ch)) continue;
+ if(s_chan[ch].pCurr > spu.pSpuIrq && s_chan[ch].pLoop > spu.pSpuIrq)
+ continue;
+
+ 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;
+
+ skip_block(ch);
+ if(start == s_chan[ch].pCurr || start - spu.spuMemC < 0x1000)
+ {
+ // looping on self or stopped(?)
+ spu.dwChannelDead |= 1<<ch;
+ s_chan[ch].spos = 0;
+ break;
+ }
+
+ s_chan[ch].spos -= 28 * 0x10000;
+ }
+ }
+
+ if(unlikely(silentch & spu.decode_dirty_ch & (1<<1))) // must clear silent channel decode buffers
+ {
+ memset(&spu.spuMem[0x800/2], 0, 0x400);
+ spu.decode_dirty_ch &= ~(1<<1);
+ }
+ if(unlikely(silentch & spu.decode_dirty_ch & (1<<3)))