+static void do_silent_chans(int ns_to, int silentch)
+{
+ int ch;
+
+ 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].iSBPos << 16;
+ s_chan[ch].iSBPos = 0;
+
+ s_chan[ch].spos += s_chan[ch].sinc * ns_to;
+ 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;
+ }
+ }
+}
+
+static void do_channels(int ns_to)
+{
+ unsigned int mask;
+ int ch, d;
+
+ InitREVERB(ns_to);
+
+ mask = spu.dwChannelOn & 0xffffff;
+ for (ch = 0; mask != 0; ch++, mask >>= 1) // loop em all...
+ {
+ if (!(mask & 1)) continue; // channel not playing? next
+
+ if (s_chan[ch].bNoise)
+ d = do_samples_noise(ch, ns_to);
+ else if (s_chan[ch].bFMod == 2
+ || (s_chan[ch].bFMod == 0 && spu_config.iUseInterpolation == 0))
+ d = do_samples_noint(ch, ns_to);
+ else if (s_chan[ch].bFMod == 0 && spu_config.iUseInterpolation == 1)
+ d = do_samples_simple(ch, ns_to);
+ else
+ d = do_samples_default(ch, ns_to);
+
+ d = MixADSR(ch, d);
+ if (d < ns_to) {
+ spu.dwChannelOn &= ~(1 << ch);
+ s_chan[ch].bStop = 1;
+ s_chan[ch].ADSRX.EnvelopeVol = 0;
+ memset(&ChanBuf[d], 0, (ns_to - d) * sizeof(ChanBuf[0]));
+ }
+
+ if (ch == 1 || ch == 3)
+ {
+ do_decode_bufs(spu.spuMem, ch/2, ns_to, spu.decode_pos);
+ spu.decode_dirty_ch |= 1 << ch;
+ }
+
+ if (s_chan[ch].bFMod == 2) // fmod freq channel
+ memcpy(iFMod, &ChanBuf, ns_to * sizeof(iFMod[0]));
+ if (s_chan[ch].bRVBActive)
+ mix_chan_rvb(0, ns_to, s_chan[ch].iLeftVolume, s_chan[ch].iRightVolume, spu.sRVBStart);
+ else
+ mix_chan(0, ns_to, s_chan[ch].iLeftVolume, s_chan[ch].iRightVolume);
+ }
+}
+