[sound] Move most spacialization fields out of channel_t

More shrinkage. It turned out the mixer uses the phase fields, so they
couldn't be removed, but even at 192kHz, +/- 127 samples produces
sufficient phase separation for a 21cm head (which is, actually, pretty
big: mine is about 15cm across), but that change can come later.

The ambient sound loading has been removed from snd_channels because 1)
it doesn't work for nq, 2) it should never have been there in the first
place (it belongs in the client, but that needs some more API).
This commit is contained in:
Bill Currie 2022-06-04 16:17:43 +09:00
parent 94db9c8ab1
commit da90d93135
3 changed files with 50 additions and 36 deletions

View file

@ -229,10 +229,7 @@ struct channel_s {
unsigned end; //!< end time in global paintsamples unsigned end; //!< end time in global paintsamples
unsigned pos; //!< sample position in sfx unsigned pos; //!< sample position in sfx
unsigned looping; //!< where to loop, -1 = no looping unsigned looping; //!< where to loop, -1 = no looping
vec3_t origin; //!< origin of sound effect
vec_t dist_mult; //!< distance multiplier (attenuation/clip)
int pause; //!< don't update the channel at all int pause; //!< don't update the channel at all
float volume; //!< 0-1 overall channel volume
int phase; //!< phase shift between l-r in samples int phase; //!< phase shift between l-r in samples
int oldphase; //!< phase shift between l-r in samples int oldphase; //!< phase shift between l-r in samples
/** signal between main program and mixer thread that the channel is to be /** signal between main program and mixer thread that the channel is to be
@ -340,6 +337,8 @@ extern int snd_total_channels; //!< number of active channels
*/ */
channel_t *SND_AllocChannel (snd_t *snd); channel_t *SND_AllocChannel (snd_t *snd);
void SND_ChannelSetVolume (channel_t *chan, float volume);
/** Stop a channel from playing. /** Stop a channel from playing.
\param snd sound system state \param snd sound system state
\param chan the channel to stop \param chan the channel to stop

View file

@ -60,9 +60,16 @@ typedef struct entchan_s {
int channel; // per-entity sound channel int channel; // per-entity sound channel
} entchan_t; } entchan_t;
typedef struct spacial_s {
vec3_t origin; //!< origin of sound effect
vec_t dist_mult; //!< distance multiplier (attenuation/clip)
float volume; //!< 0-1 overall channel volume
} spacial_t;
int snd_total_channels; int snd_total_channels;
channel_t snd_channels[MAX_CHANNELS]; channel_t snd_channels[MAX_CHANNELS];
static entchan_t snd_entity_channels[MAX_CHANNELS]; static entchan_t snd_entity_channels[MAX_CHANNELS];
static spacial_t snd_spacialization[MAX_CHANNELS];
static int snd_free_channels[MAX_CHANNELS]; static int snd_free_channels[MAX_CHANNELS];
static int snd_num_free_channels; static int snd_num_free_channels;
/* Dynamic channels are (usually) short sound bytes, never looped. They do not /* Dynamic channels are (usually) short sound bytes, never looped. They do not
@ -347,14 +354,6 @@ s_playvol_f (void *_snd)
static void static void
s_channels_gamedir (int phase, void *_snd) s_channels_gamedir (int phase, void *_snd)
{ {
//FIXME for some reason, a gamedir change causes semi-random
//"already released" cache errors. fortunatly, servers don't change
//gamedir often, so I'll put this in the too-hard basket for now.
//XXX FIXME set ambient sounds
//if (phase) {
// ambient_sfx[AMBIENT_WATER] = SND_PrecacheSound (snd, "ambience/water1.wav");
// ambient_sfx[AMBIENT_SKY] = SND_PrecacheSound (snd, "ambience/wind2.wav");
//}
} }
void void
@ -442,8 +441,10 @@ s_updateAmbientSounds (snd_t *snd, const byte *ambient_sound_level)
ambient_channel++) { ambient_channel++) {
chan = ambient_channels[ambient_channel]; chan = ambient_channels[ambient_channel];
if (chan) { if (chan) {
chan->volume = 0; int chan_ind = chan - snd_channels;
chan->leftvol = chan->rightvol = chan->volume; spacial_t *spacial = &snd_spacialization[chan_ind];
spacial->volume = 0;
chan->leftvol = chan->rightvol = spacial->volume;
} }
} }
return; return;
@ -474,23 +475,26 @@ s_updateAmbientSounds (snd_t *snd, const byte *ambient_sound_level)
// sfx will be written to chan->sfx later to ensure mixer doesn't use // sfx will be written to chan->sfx later to ensure mixer doesn't use
// channel prematurely. // channel prematurely.
int chan_ind = chan - snd_channels;
spacial_t *spacial = &snd_spacialization[chan_ind];
vol = ambient_level * ambient_sound_level[ambient_channel] * (1/255.0); vol = ambient_level * ambient_sound_level[ambient_channel] * (1/255.0);
if (vol < 8/255.0) if (vol < 8/255.0)
vol = 0; vol = 0;
// don't adjust volume too fast // don't adjust volume too fast
float fade = ambient_fade * (1/255.0); float fade = ambient_fade * (1/255.0);
if (chan->volume < vol) { if (spacial->volume < vol) {
chan->volume += *snd_render_data.host_frametime * fade; spacial->volume += *snd_render_data.host_frametime * fade;
if (chan->volume > vol) if (spacial->volume > vol)
chan->volume = vol; spacial->volume = vol;
} else if (chan->volume > vol) { } else if (spacial->volume > vol) {
chan->volume -= *snd_render_data.host_frametime * fade; spacial->volume -= *snd_render_data.host_frametime * fade;
if (chan->volume < vol) if (spacial->volume < vol)
chan->volume = vol; spacial->volume = vol;
} }
chan->leftvol = chan->rightvol = chan->volume; chan->leftvol = chan->rightvol = spacial->volume;
chan->sfx = sfx; chan->sfx = sfx;
} }
} }
@ -506,19 +510,21 @@ s_spatialize (snd_t *snd, channel_t *ch)
// prepare to lerp from prev to next phase // prepare to lerp from prev to next phase
ch->oldphase = ch->phase; ch->oldphase = ch->phase;
spacial_t *spacial = &snd_spacialization[chan_ind];
// anything coming from the view entity will always be full volume // anything coming from the view entity will always be full volume
if (!snd_render_data.viewentity if (!snd_render_data.viewentity
|| snd_entity_channels[chan_ind].id == *snd_render_data.viewentity) { || snd_entity_channels[chan_ind].id == *snd_render_data.viewentity) {
ch->leftvol = ch->volume; ch->leftvol = spacial->volume;
ch->rightvol = ch->volume; ch->rightvol = spacial->volume;
ch->phase = 0; ch->phase = 0;
return; return;
} }
// calculate stereo seperation and distance attenuation // calculate stereo seperation and distance attenuation
VectorSubtract (ch->origin, listener_origin, source_vec); VectorSubtract (spacial->origin, listener_origin, source_vec);
dist = VectorNormalize (source_vec) * ch->dist_mult; dist = VectorNormalize (source_vec) * spacial->dist_mult;
dot = DotProduct (listener_right, source_vec); dot = DotProduct (listener_right, source_vec);
if (snd_swapchannelside) if (snd_swapchannelside)
@ -536,12 +542,12 @@ s_spatialize (snd_t *snd, channel_t *ch)
// add in distance effect // add in distance effect
scale = (1.0 - dist) * rscale; scale = (1.0 - dist) * rscale;
ch->rightvol = ch->volume * scale; ch->rightvol = spacial->volume * scale;
if (ch->rightvol < 0) if (ch->rightvol < 0)
ch->rightvol = 0; ch->rightvol = 0;
scale = (1.0 - dist) * lscale; scale = (1.0 - dist) * lscale;
ch->leftvol = ch->volume * scale; ch->leftvol = spacial->volume * scale;
if (ch->leftvol < 0) if (ch->leftvol < 0)
ch->leftvol = 0; ch->leftvol = 0;
@ -656,9 +662,10 @@ SND_StartSound (snd_t *snd, int entnum, int entchannel, sfx_t *sfx,
int chan_ind = target_chan - snd_channels; int chan_ind = target_chan - snd_channels;
// spatialize // spatialize
VectorCopy (origin, target_chan->origin); spacial_t *spacial = &snd_spacialization[chan_ind];
target_chan->dist_mult = attenuation / sound_nominal_clip_dist; VectorCopy (origin, spacial->origin);
target_chan->volume = vol; spacial->dist_mult = attenuation / sound_nominal_clip_dist;
spacial->volume = vol;
snd_entity_channels[chan_ind] = (entchan_t) { snd_entity_channels[chan_ind] = (entchan_t) {
.id = entnum, .id = entnum,
.channel = entchannel, .channel = entchannel,
@ -737,9 +744,10 @@ SND_StaticSound (snd_t *snd, sfx_t *sfx, vec4f_t origin, float vol,
if (!(osfx = sfx->open (sfx))) if (!(osfx = sfx->open (sfx)))
return; return;
VectorCopy (origin, ss->origin); spacial_t *spacial = &snd_spacialization[ss_ind];
ss->volume = vol; VectorCopy (origin, spacial->origin);
ss->dist_mult = attenuation / sound_nominal_clip_dist; spacial->volume = vol;
spacial->dist_mult = attenuation / sound_nominal_clip_dist;
ss->end = 0; ss->end = 0;
s_spatialize (snd, ss); s_spatialize (snd, ss);
@ -771,3 +779,11 @@ SND_LocalSound (snd_t *snd, const char *sound)
viewent = *snd_render_data.viewentity; viewent = *snd_render_data.viewentity;
SND_StartSound (snd, viewent, -1, sfx, (vec4f_t) {0, 0, 0, 1}, 1, 1); SND_StartSound (snd, viewent, -1, sfx, (vec4f_t) {0, 0, 0, 1}, 1, 1);
} }
void
SND_ChannelSetVolume (channel_t *chan, float volume)
{
int chan_ind = chan - snd_channels;
snd_spacialization[chan_ind].volume = volume;
chan->leftvol = chan->rightvol = volume;
}

View file

@ -522,8 +522,7 @@ s_channel_get_state (channel_t *chan)
static void static void
s_channel_set_volume (channel_t *chan, float volume) s_channel_set_volume (channel_t *chan, float volume)
{ {
chan->volume = volume; SND_ChannelSetVolume (chan, volume);
chan->leftvol = chan->rightvol = chan->volume;
} }
static void static void