+make_do_samples(do_samples_gauss, , ,
+ StoreInterpolationGaussCubic(sb, fa),
+ dst[ns] = GetInterpolationGauss(sb, *spos), )
+make_do_samples(do_samples_cubic, , ,
+ StoreInterpolationGaussCubic(sb, fa),
+ dst[ns] = GetInterpolationCubic(sb, *spos), )
+make_do_samples(do_samples_fmod,
+ sinc = FModChangeFrequency(spu.s_chan[ch].iRawPitch, ns, iFMod), ,
+ StoreInterpolationGaussCubic(sb, fa),
+ dst[ns] = GetInterpolationGauss(sb, *spos), )
+
+INLINE int do_samples_adpcm(int *dst,
+ int (*decode_f)(void *context, int ch, int *SB), void *ctx,
+ int ch, int ns_to, int fmod, sample_buf *sb, int sinc, int *spos, int *sbpos)
+{
+ int interp = spu.interpolation;
+ if (fmod == 1)
+ return do_samples_fmod(dst, decode_f, ctx, ch, ns_to, sb, sinc, spos, sbpos);
+ if (fmod)
+ interp = 2;
+ switch (interp) {
+ case 0:
+ return do_samples_nointerp(dst, decode_f, ctx, ch, ns_to, sb, sinc, spos, sbpos);
+ case 1:
+ return do_samples_simple (dst, decode_f, ctx, ch, ns_to, sb, sinc, spos, sbpos);
+ default:
+ return do_samples_gauss (dst, decode_f, ctx, ch, ns_to, sb, sinc, spos, sbpos);
+ case 3:
+ return do_samples_cubic (dst, decode_f, ctx, ch, ns_to, sb, sinc, spos, sbpos);
+ }
+}
+
+static int do_samples_skip(int ch, int ns_to)
+{
+ SPUCHAN *s_chan = &spu.s_chan[ch];
+ int spos = s_chan->spos;
+ int sinc = s_chan->sinc;
+ int ret = ns_to, ns, d;
+
+ spos += s_chan->iSBPos << 16;
+
+ for (ns = 0; ns < ns_to; ns++)
+ {
+ spos += sinc;
+ while (spos >= 28*0x10000)
+ {
+ d = skip_block(ch);
+ if (d && ns < ret)
+ ret = ns;
+ spos -= 28*0x10000;
+ }
+ }
+
+ s_chan->iSBPos = spos >> 16;
+ s_chan->spos = spos & 0xffff;
+
+ return ret;
+}