mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-30 08:00:51 +00:00
[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:
parent
94db9c8ab1
commit
da90d93135
3 changed files with 50 additions and 36 deletions
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue