mastervol = ch->master_vol;
+ // always apply "master"
+ mastervol *= mastervolume.value;
+
+ // If this channel does not manage its own volume (like CD tracks)
+ if (!(ch->flags & CHANNELFLAG_FULLVOLUME))
+ mastervol *= volume.value;
+
// Adjust volume of static sounds
if (isstatic)
mastervol *= snd_staticvolume.value;
}
}
+ // clamp HERE to keep relative volumes of the channels correct
+ mastervol = bound(0, mastervol, 65536);
+
// anything coming from the view entity will always be full volume
// LordHavoc: make sounds with ATTN_NONE have no spatialization
if (ch->entnum == cl.viewentity || ch->dist_mult == 0)
ch->prologic_invert = 1;
if (snd_spatialization_prologic.integer != 0)
{
- for (i = 0;i < 2;i++)
- {
- vol = mastervol * snd_speakerlayout.listeners[i].ambientvolume * sqrt(0.5);
- ch->listener_volume[i] = (int)bound(0, vol, 255);
- }
+ vol = mastervol * snd_speakerlayout.listeners[0].ambientvolume * sqrt(0.5);
+ ch->listener_volume[0] = (int)bound(0, vol, 65536);
+ vol = mastervol * snd_speakerlayout.listeners[1].ambientvolume * sqrt(0.5);
+ ch->listener_volume[1] = (int)bound(0, vol, 65536);
for (i = 2;i < SND_LISTENERS;i++)
ch->listener_volume[i] = 0;
}
for (i = 0;i < SND_LISTENERS;i++)
{
vol = mastervol * snd_speakerlayout.listeners[i].ambientvolume;
- ch->listener_volume[i] = (int)bound(0, vol, 255);
+ ch->listener_volume[i] = (int)bound(0, vol, 65536);
}
}
}
}
vol = intensity * sqrt(angle_factor);
- ch->listener_volume[0] = (int)bound(0, vol, 255);
+ ch->listener_volume[0] = (int)bound(0, vol, 65536);
vol = intensity * sqrt(1 - angle_factor);
- ch->listener_volume[1] = (int)bound(0, vol, 255);
+ ch->listener_volume[1] = (int)bound(0, vol, 65536);
for (i = 2;i < SND_LISTENERS;i++)
ch->listener_volume[i] = 0;
}
vol = intensity * max(0, source_vec[0] * snd_speakerlayout.listeners[i].dotscale + snd_speakerlayout.listeners[i].dotbias);
- ch->listener_volume[i] = (int)bound(0, vol, 255);
+ ch->listener_volume[i] = (int)bound(0, vol, 65536);
}
}
}
fvol = 1 / sfx->volume_peak;
// Con_DPrintf("%f\n", fvol);
}
- channels[ch_ind].master_vol = (int)(fvol * 255.0f);
+ channels[ch_ind].master_vol = (int)(fvol * 65536.0f);
}
void S_SetChannelVolume(unsigned int ch_ind, float fvol)
vol = (int)ambientlevels[ambient_channel];
if (vol < 8)
vol = 0;
+ vol *= 256;
// Don't adjust volume too fast
// FIXME: this rounds off to an int each frame, meaning there is little to no fade at extremely high framerates!
{
if (chan->master_vol < vol)
{
- chan->master_vol += (int)((cl.time - cl.oldtime) * ambient_fade.value);
+ chan->master_vol += (int)((cl.time - cl.oldtime) * 256.0 * ambient_fade.value);
if (chan->master_vol > vol)
chan->master_vol = vol;
}
else if (chan->master_vol > vol)
{
- chan->master_vol -= (int)((cl.time - cl.oldtime) * ambient_fade.value);
+ chan->master_vol -= (int)((cl.time - cl.oldtime) * 256.0 * ambient_fade.value);
if (chan->master_vol < vol)
chan->master_vol = vol;
}
if (snd_spatialization_prologic.integer != 0)
{
- chan->listener_volume[0] = chan->listener_volume[1] = (int)(chan->master_vol * ambient_level.value * snd_speakerlayout.listeners[i].ambientvolume * sqrt(0.5));
+ chan->listener_volume[0] = chan->listener_volume[1] = (int)bound(0, chan->master_vol * ambient_level.value * snd_speakerlayout.listeners[i].ambientvolume * sqrt(0.5), 65536);
for (i = 2;i < SND_LISTENERS;i++)
chan->listener_volume[i] = 0;
}
else
{
for (i = 0;i < SND_LISTENERS;i++)
- chan->listener_volume[i] = (int)(chan->master_vol * ambient_level.value * snd_speakerlayout.listeners[i].ambientvolume);
+ chan->listener_volume[i] = (int)bound(0, chan->master_vol * ambient_level.value * snd_speakerlayout.listeners[i].ambientvolume, 65536);
}
}
}
{
for (j = 0;j < SND_LISTENERS;j++)
{
- combine->listener_volume[j] += ch->listener_volume[j];
+ combine->listener_volume[j] = bound(0, combine->listener_volume[j] + ch->listener_volume[j], 65536);
ch->listener_volume[j] = 0;
}
}
static qboolean SND_PaintChannel (channel_t *ch, portable_sampleframe_t *paint, unsigned int count)
{
- int snd_vol, vol[SND_LISTENERS];
+ int 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 = (int)(mastervolume.value * 256);
- else
- snd_vol = (int)(mastervolume.value * volume.value * 256);
-
- // calculate mixing volumes based on channel volumes and volume cvar
- // also limit the volumes to values that won't clip
+ // move to the stack (do we need to?)
for (i = 0;i < SND_LISTENERS;i++)
- {
- vol[i] = ch->listener_volume[i] * snd_vol;
- vol[i] = bound(0, vol[i], 65536);
- }
+ vol[i] = ch->listener_volume[i];
// if volumes are all zero, just return
for (i = 0;i < SND_LISTENERS;i++)