-static qboolean SND_PaintChannel (channel_t *ch, portable_sampleframe_t *paint, unsigned int count)
-{
- int snd_vol, vol[SND_LISTENERS];
- const snd_buffer_t *sb;
- unsigned int i, sb_offset;
-
- // If this channel manages its own volume
- if (ch->flags & CHANNELFLAG_FULLVOLUME)
- snd_vol = 256;
- else
- snd_vol = (int)(volume.value * 256);
-
- // calculate mixing volumes based on channel volumes and volume cvar
- // also limit the volumes to values that won't clip
- for (i = 0;i < SND_LISTENERS;i++)
- {
- vol[i] = ch->listener_volume[i] * snd_vol;
- vol[i] = bound(0, vol[i], 65536);
- }
-
- // if volumes are all zero, just return
- for (i = 0;i < SND_LISTENERS;i++)
- if (vol[i])
- break;
- if (i == SND_LISTENERS)
- return false;
-
- sb_offset = ch->pos;
- sb = ch->sfx->fetcher->getsb (ch->sfx->fetcher_data, &ch->fetcher_data, &sb_offset, count);
- if (sb == NULL)
- {
- Con_DPrintf("SND_PaintChannel: ERROR: can't get sound buffer from sfx \"%s\"\n",
- ch->sfx->name); // , count); // or add this? FIXME
- return false;
- }
- else
- {
-#if SND_LISTENERS != 8
-# error the following code only supports up to 8 channels, update it
-#endif
- if (sb->format.width == 1)
- {
- const signed char *samples = (signed char*)sb->samples + (ch->pos - sb_offset) * sb->format.channels;
-
- // Stereo sound support
- if (sb->format.channels == 2)
- {
- if (vol[6] + vol[7] > 0)
- {
- for (i = 0;i < count;i++)
- {
- paint[i].sample[0] += (samples[0] * vol[0]) >> 8;
- paint[i].sample[1] += (samples[1] * vol[1]) >> 8;
- paint[i].sample[2] += (samples[0] * vol[2]) >> 8;
- paint[i].sample[3] += (samples[1] * vol[3]) >> 8;
- paint[i].sample[4] += ((samples[0] + samples[1]) * vol[4]) >> 9;
- paint[i].sample[5] += ((samples[0] + samples[1]) * vol[5]) >> 9;
- paint[i].sample[6] += (samples[0] * vol[6]) >> 8;
- paint[i].sample[7] += (samples[1] * vol[7]) >> 8;
- samples += 2;
- }
- }
- else if (vol[4] + vol[5] > 0)
- {
- for (i = 0;i < count;i++)
- {
- paint[i].sample[0] += (samples[0] * vol[0]) >> 8;
- paint[i].sample[1] += (samples[1] * vol[1]) >> 8;
- paint[i].sample[2] += (samples[0] * vol[2]) >> 8;
- paint[i].sample[3] += (samples[1] * vol[3]) >> 8;
- paint[i].sample[4] += ((samples[0] + samples[1]) * vol[4]) >> 9;
- paint[i].sample[5] += ((samples[0] + samples[1]) * vol[5]) >> 9;
- samples += 2;
- }
- }
- else if (vol[2] + vol[3] > 0)
- {
- for (i = 0;i < count;i++)
- {
- paint[i].sample[0] += (samples[0] * vol[0]) >> 8;
- paint[i].sample[1] += (samples[1] * vol[1]) >> 8;
- paint[i].sample[2] += (samples[0] * vol[2]) >> 8;
- paint[i].sample[3] += (samples[1] * vol[3]) >> 8;
- samples += 2;
- }
- }
- else if (vol[0] + vol[1] > 0)
- {
- for (i = 0;i < count;i++)
- {
- paint[i].sample[0] += (samples[0] * vol[0]) >> 8;
- paint[i].sample[1] += (samples[1] * vol[1]) >> 8;
- samples += 2;
- }
- }
- }
- else if (sb->format.channels == 1)
- {
- if (vol[6] + vol[7] > 0)
- {
- for (i = 0;i < count;i++)
- {
- paint[i].sample[0] += (samples[0] * vol[0]) >> 8;
- paint[i].sample[1] += (samples[0] * vol[1]) >> 8;
- paint[i].sample[2] += (samples[0] * vol[2]) >> 8;
- paint[i].sample[3] += (samples[0] * vol[3]) >> 8;
- paint[i].sample[4] += (samples[0] * vol[4]) >> 8;
- paint[i].sample[5] += (samples[0] * vol[5]) >> 8;
- paint[i].sample[6] += (samples[0] * vol[6]) >> 8;
- paint[i].sample[7] += (samples[0] * vol[7]) >> 8;
- samples += 1;
- }
- }
- else if (vol[4] + vol[5] > 0)
- {
- for (i = 0;i < count;i++)
- {
- paint[i].sample[0] += (samples[0] * vol[0]) >> 8;
- paint[i].sample[1] += (samples[0] * vol[1]) >> 8;
- paint[i].sample[2] += (samples[0] * vol[2]) >> 8;
- paint[i].sample[3] += (samples[0] * vol[3]) >> 8;
- paint[i].sample[4] += (samples[0] * vol[4]) >> 8;
- paint[i].sample[5] += (samples[0] * vol[5]) >> 8;
- samples += 1;
- }
- }
- else if (vol[2] + vol[3] > 0)
- {
- for (i = 0;i < count;i++)
- {
- paint[i].sample[0] += (samples[0] * vol[0]) >> 8;
- paint[i].sample[1] += (samples[0] * vol[1]) >> 8;
- paint[i].sample[2] += (samples[0] * vol[2]) >> 8;
- paint[i].sample[3] += (samples[0] * vol[3]) >> 8;
- samples += 1;
- }
- }
- else if (vol[0] + vol[1] > 0)
- {
- for (i = 0;i < count;i++)
- {
- paint[i].sample[0] += (samples[0] * vol[0]) >> 8;
- paint[i].sample[1] += (samples[0] * vol[1]) >> 8;
- samples += 1;
- }
- }
- }
- else
- return false; // unsupported number of channels in sound
- }
- else if (sb->format.width == 2)
- {
- const signed short *samples = (signed short*)sb->samples + (ch->pos - sb_offset) * sb->format.channels;
-
- // Stereo sound support
- if (sb->format.channels == 2)
- {
- if (vol[6] + vol[7] > 0)
- {
- for (i = 0;i < count;i++)
- {
- paint[i].sample[0] += (samples[0] * vol[0]) >> 16;
- paint[i].sample[1] += (samples[1] * vol[1]) >> 16;
- paint[i].sample[2] += (samples[0] * vol[2]) >> 16;
- paint[i].sample[3] += (samples[1] * vol[3]) >> 16;
- paint[i].sample[4] += ((samples[0] + samples[1]) * vol[4]) >> 17;
- paint[i].sample[5] += ((samples[0] + samples[1]) * vol[5]) >> 17;
- paint[i].sample[6] += (samples[0] * vol[6]) >> 16;
- paint[i].sample[7] += (samples[1] * vol[7]) >> 16;
- samples += 2;
- }
- }
- else if (vol[4] + vol[5] > 0)
- {
- for (i = 0;i < count;i++)
- {
- paint[i].sample[0] += (samples[0] * vol[0]) >> 16;
- paint[i].sample[1] += (samples[1] * vol[1]) >> 16;
- paint[i].sample[2] += (samples[0] * vol[2]) >> 16;
- paint[i].sample[3] += (samples[1] * vol[3]) >> 16;
- paint[i].sample[4] += ((samples[0] + samples[1]) * vol[4]) >> 17;
- paint[i].sample[5] += ((samples[0] + samples[1]) * vol[5]) >> 17;
- samples += 2;
- }
- }
- else if (vol[2] + vol[3] > 0)
- {
- for (i = 0;i < count;i++)
- {
- paint[i].sample[0] += (samples[0] * vol[0]) >> 16;
- paint[i].sample[1] += (samples[1] * vol[1]) >> 16;
- paint[i].sample[2] += (samples[0] * vol[2]) >> 16;
- paint[i].sample[3] += (samples[1] * vol[3]) >> 16;
- samples += 2;
- }
- }
- else if (vol[0] + vol[1] > 0)
- {
- for (i = 0;i < count;i++)
- {
- paint[i].sample[0] += (samples[0] * vol[0]) >> 16;
- paint[i].sample[1] += (samples[1] * vol[1]) >> 16;
- samples += 2;
- }
- }
- }
- else if (sb->format.channels == 1)
- {
- if (vol[6] + vol[7] > 0)
- {
- for (i = 0;i < count;i++)
- {
- paint[i].sample[0] += (samples[0] * vol[0]) >> 16;
- paint[i].sample[1] += (samples[0] * vol[1]) >> 16;
- paint[i].sample[2] += (samples[0] * vol[2]) >> 16;
- paint[i].sample[3] += (samples[0] * vol[3]) >> 16;
- paint[i].sample[4] += (samples[0] * vol[4]) >> 16;
- paint[i].sample[5] += (samples[0] * vol[5]) >> 16;
- paint[i].sample[6] += (samples[0] * vol[6]) >> 16;
- paint[i].sample[7] += (samples[0] * vol[7]) >> 16;
- samples += 1;
- }
- }
- else if (vol[4] + vol[5] > 0)
- {
- for (i = 0;i < count;i++)
- {
- paint[i].sample[0] += (samples[0] * vol[0]) >> 16;
- paint[i].sample[1] += (samples[0] * vol[1]) >> 16;
- paint[i].sample[2] += (samples[0] * vol[2]) >> 16;
- paint[i].sample[3] += (samples[0] * vol[3]) >> 16;
- paint[i].sample[4] += (samples[0] * vol[4]) >> 16;
- paint[i].sample[5] += (samples[0] * vol[5]) >> 16;
- samples += 1;
- }
- }
- else if (vol[2] + vol[3] > 0)
- {
- for (i = 0;i < count;i++)
- {
- paint[i].sample[0] += (samples[0] * vol[0]) >> 16;
- paint[i].sample[1] += (samples[0] * vol[1]) >> 16;
- paint[i].sample[2] += (samples[0] * vol[2]) >> 16;
- paint[i].sample[3] += (samples[0] * vol[3]) >> 16;
- samples += 1;
- }
- }
- else if (vol[0] + vol[1] > 0)
- {
- for (i = 0;i < count;i++)
- {
- paint[i].sample[0] += (samples[0] * vol[0]) >> 16;
- paint[i].sample[1] += (samples[0] * vol[1]) >> 16;
- samples += 1;
- }
- }
- }
- else
- return false; // unsupported number of channels in sound
- }
- }
- return true;
-}
-