From 1e4fe28814b6fcdaf1c8c35a805fb221dd860ec4 Mon Sep 17 00:00:00 2001 From: divverent Date: Thu, 23 Sep 2010 05:17:05 +0000 Subject: [PATCH] expand volume accuracy from 8bit to 16bit; allow channel volume values to be > 1, and clamp the resulting volume git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@10482 d7cf8633-e32d-0410-b094-e92efae38249 --- snd_main.c | 40 +++++++++++++++++++++++++--------------- snd_main.h | 4 ++-- snd_mix.c | 16 +++------------- 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/snd_main.c b/snd_main.c index 98fa0d15..f00f75dc 100644 --- a/snd_main.c +++ b/snd_main.c @@ -1297,6 +1297,13 @@ void SND_Spatialize(channel_t *ch, qboolean isstatic) 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; @@ -1364,6 +1371,9 @@ void SND_Spatialize(channel_t *ch, qboolean isstatic) } } + // 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) @@ -1371,11 +1381,10 @@ void SND_Spatialize(channel_t *ch, qboolean isstatic) 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; } @@ -1384,7 +1393,7 @@ void SND_Spatialize(channel_t *ch, qboolean isstatic) 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); } } } @@ -1469,9 +1478,9 @@ void SND_Spatialize(channel_t *ch, qboolean isstatic) } 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; } @@ -1507,7 +1516,7 @@ void SND_Spatialize(channel_t *ch, qboolean isstatic) 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); } } } @@ -1762,7 +1771,7 @@ static void S_SetChannelVolume_WithSfx (unsigned int ch_ind, float fvol, sfx_t * 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) @@ -1858,6 +1867,7 @@ void S_UpdateAmbientSounds (void) 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! @@ -1865,13 +1875,13 @@ void S_UpdateAmbientSounds (void) { 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; } @@ -1879,14 +1889,14 @@ void S_UpdateAmbientSounds (void) 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); } } } @@ -2183,7 +2193,7 @@ void S_Update(const matrix4x4_t *listenermatrix) { 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; } } diff --git a/snd_main.h b/snd_main.h index dfe72f25..c7c631f8 100644 --- a/snd_main.h +++ b/snd_main.h @@ -84,8 +84,8 @@ struct sfx_s typedef struct channel_s { - short listener_volume [SND_LISTENERS]; // 0-255 volume per speaker - int master_vol; // 0-255 master volume + int listener_volume [SND_LISTENERS]; // 0-65536 volume per speaker + int master_vol; // 0-65536 master volume sfx_t *sfx; // sfx number unsigned int flags; // cf CHANNELFLAG_* defines int pos; // sample position in sfx, negative values delay the start of the sound playback diff --git a/snd_mix.c b/snd_mix.c index 8b77d96d..74a13671 100644 --- a/snd_mix.c +++ b/snd_mix.c @@ -183,23 +183,13 @@ CHANNEL MIXING 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++) -- 2.39.2