- // transfer out according to DMA format
- //S_CaptureAVISound(paintbuffer, end - paintedtime);
- S_TransferPaintBuffer(end);
- paintedtime = end;
- }
-}
-
-void SND_InitScaletable (void)
-{
- int i, j;
-
- for (i=0 ; i<32 ; i++)
- for (j=0 ; j<256 ; j++)
- snd_scaletable[i][j] = ((signed char)j) * i * 8;
-}
-
-
-void SND_PaintChannelFrom8 (channel_t *ch, sfxcache_t *sc, int count)
-{
-// int data;
- int *lscale, *rscale;
- unsigned char *sfx;
- int i;
-
- if (ch->leftvol > 255)
- ch->leftvol = 255;
- if (ch->rightvol > 255)
- ch->rightvol = 255;
-
- lscale = snd_scaletable[ch->leftvol >> 3];
- rscale = snd_scaletable[ch->rightvol >> 3];
- if (sc->stereo)
- {
- // LordHavoc: stereo sound support, and optimizations
- sfx = (unsigned char *)sc->data + ch->pos * 2;
-
- for (i=0 ; i<count ; i++)
- {
- paintbuffer[i].left += lscale[*sfx++];
- paintbuffer[i].right += rscale[*sfx++];
- }
-
- }
- else
- {
- sfx = (unsigned char *)sc->data + ch->pos;
-
- for (i=0 ; i<count ; i++)
- {
- paintbuffer[i].left += lscale[*sfx];
- paintbuffer[i].right += rscale[*sfx++];
+ // 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);