+ // set up our fixedpoint resampling variables (float to int conversions are expensive so do not do one per sampleframe)
+ fetchsampleframe = fetchsampleframes;
+ indexfrac = (int)floor((posd - floor(posd)) * 65536.0);
+ indexfracstep = (int)floor(speedd * 65536.0);
+ if (!silent)
+ {
+ if (sfx->format.channels == 2)
+ {
+ // music is stereo
+#if SND_LISTENERS != 8
+#error the following code only supports up to 8 channels, update it
+#endif
+ if (snd_speakerlayout.channels > 2)
+ {
+ // surround mixing
+ for (i = 0;i < count;i++, paint++)
+ {
+ lerp[1] = indexfrac * (1.0f / 65536.0f);
+ lerp[0] = 1.0f - lerp[1];
+ sample[0] = fetchsampleframe[0] * lerp[0] + fetchsampleframe[2] * lerp[1];
+ sample[1] = fetchsampleframe[1] * lerp[0] + fetchsampleframe[3] * lerp[1];
+ sample[2] = (sample[0] + sample[1]) * 0.5f;
+ paint->sample[0] += sample[0] * vol[0];
+ paint->sample[1] += sample[1] * vol[1];
+ paint->sample[2] += sample[0] * vol[2];
+ paint->sample[3] += sample[1] * vol[3];
+ paint->sample[4] += sample[2] * vol[4];
+ paint->sample[5] += sample[2] * vol[5];
+ paint->sample[6] += sample[0] * vol[6];
+ paint->sample[7] += sample[1] * vol[7];
+ indexfrac += indexfracstep;
+ fetchsampleframe += 2 * (indexfrac >> 16);
+ indexfrac &= 0xFFFF;
+ }
+ }
+ else
+ {
+ // stereo mixing
+ for (i = 0;i < count;i++, paint++)
+ {
+ lerp[1] = indexfrac * (1.0f / 65536.0f);
+ lerp[0] = 1.0f - lerp[1];
+ sample[0] = fetchsampleframe[0] * lerp[0] + fetchsampleframe[2] * lerp[1];
+ sample[1] = fetchsampleframe[1] * lerp[0] + fetchsampleframe[3] * lerp[1];
+ paint->sample[0] += sample[0] * vol[0];
+ paint->sample[1] += sample[1] * vol[1];
+ indexfrac += indexfracstep;
+ fetchsampleframe += 2 * (indexfrac >> 16);
+ indexfrac &= 0xFFFF;
+ }
+ }
+ }
+ else if (sfx->format.channels == 1)
+ {
+ // most sounds are mono
+#if SND_LISTENERS != 8
+#error the following code only supports up to 8 channels, update it
+#endif
+ if (snd_speakerlayout.channels > 2)
+ {
+ // surround mixing
+ for (i = 0;i < count;i++, paint++)
+ {
+ lerp[1] = indexfrac * (1.0f / 65536.0f);
+ lerp[0] = 1.0f - lerp[1];
+ sample[0] = fetchsampleframe[0] * lerp[0] + fetchsampleframe[1] * lerp[1];
+ paint->sample[0] += sample[0] * vol[0];
+ paint->sample[1] += sample[0] * vol[1];
+ paint->sample[2] += sample[0] * vol[2];
+ paint->sample[3] += sample[0] * vol[3];
+ paint->sample[4] += sample[0] * vol[4];
+ paint->sample[5] += sample[0] * vol[5];
+ paint->sample[6] += sample[0] * vol[6];
+ paint->sample[7] += sample[0] * vol[7];
+ indexfrac += indexfracstep;
+ fetchsampleframe += (indexfrac >> 16);
+ indexfrac &= 0xFFFF;
+ }
+ }
+ else
+ {
+ // stereo mixing
+ for (i = 0;i < count;i++, paint++)
+ {
+ lerp[1] = indexfrac * (1.0f / 65536.0f);
+ lerp[0] = 1.0f - lerp[1];
+ sample[0] = fetchsampleframe[0] * lerp[0] + fetchsampleframe[1] * lerp[1];
+ paint->sample[0] += sample[0] * vol[0];
+ paint->sample[1] += sample[0] * vol[1];
+ indexfrac += indexfracstep;
+ fetchsampleframe += (indexfrac >> 16);
+ indexfrac &= 0xFFFF;
+ }
+ }
+ }
+ }
+ }
+ ch->position = posd;
+ if (!looping && istartframe == totallength)
+ S_StopChannel(ch - channels, false, false);