mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-13 00:24:12 +00:00
extend the sound api slightly to ease things like cd_file and make cd_file
work as intended :)
This commit is contained in:
parent
19ef80c555
commit
d5a33c9545
7 changed files with 203 additions and 119 deletions
|
@ -55,6 +55,8 @@ typedef void (*P_S_ExtraUpdate) (void);
|
||||||
typedef void (*P_S_LocalSound) (const char *s);
|
typedef void (*P_S_LocalSound) (const char *s);
|
||||||
typedef void (*P_S_BlockSound) (void);
|
typedef void (*P_S_BlockSound) (void);
|
||||||
typedef void (*P_S_UnblockSound) (void);
|
typedef void (*P_S_UnblockSound) (void);
|
||||||
|
typedef struct sfx_s *(*P_S_LoadSound) (const char *name);
|
||||||
|
typedef struct channel_s *(*P_S_AllocChannel) (void);
|
||||||
|
|
||||||
typedef struct snd_render_funcs_s {
|
typedef struct snd_render_funcs_s {
|
||||||
P_S_AmbientOff pS_AmbientOff;
|
P_S_AmbientOff pS_AmbientOff;
|
||||||
|
@ -73,6 +75,8 @@ typedef struct snd_render_funcs_s {
|
||||||
P_S_LocalSound pS_LocalSound;
|
P_S_LocalSound pS_LocalSound;
|
||||||
P_S_BlockSound pS_BlockSound;
|
P_S_BlockSound pS_BlockSound;
|
||||||
P_S_UnblockSound pS_UnblockSound;
|
P_S_UnblockSound pS_UnblockSound;
|
||||||
|
P_S_LoadSound pS_LoadSound;
|
||||||
|
P_S_AllocChannel pS_AllocChannel;
|
||||||
} snd_render_funcs_t;
|
} snd_render_funcs_t;
|
||||||
|
|
||||||
typedef struct snd_render_data_s {
|
typedef struct snd_render_data_s {
|
||||||
|
|
|
@ -96,6 +96,8 @@ void S_ClearPrecache (void);
|
||||||
void S_BeginPrecaching (void);
|
void S_BeginPrecaching (void);
|
||||||
void S_EndPrecaching (void);
|
void S_EndPrecaching (void);
|
||||||
|
|
||||||
|
sfx_t *S_LoadSound (const char *name);
|
||||||
|
struct channel_s *S_AllocChannel (void);
|
||||||
|
|
||||||
// ====================================================================
|
// ====================================================================
|
||||||
// User-setable variables
|
// User-setable variables
|
||||||
|
|
|
@ -36,28 +36,28 @@
|
||||||
|
|
||||||
// !!! if this is changed, it must be changed in asm_i386.h too !!!
|
// !!! if this is changed, it must be changed in asm_i386.h too !!!
|
||||||
typedef struct portable_samplepair_s {
|
typedef struct portable_samplepair_s {
|
||||||
int left;
|
int left;
|
||||||
int right;
|
int right;
|
||||||
} portable_samplepair_t;
|
} portable_samplepair_t;
|
||||||
|
|
||||||
typedef struct wavinfo_s {
|
typedef struct wavinfo_s {
|
||||||
unsigned int rate;
|
unsigned rate;
|
||||||
unsigned int width;
|
unsigned width;
|
||||||
unsigned int channels;
|
unsigned channels;
|
||||||
unsigned int loopstart;
|
unsigned loopstart;
|
||||||
unsigned int samples;
|
unsigned samples;
|
||||||
unsigned int dataofs; // chunk starts this many bytes from file start
|
unsigned dataofs; // chunk starts this many bytes from file start
|
||||||
unsigned int datalen; // chunk bytes
|
unsigned datalen; // chunk bytes
|
||||||
} wavinfo_t;
|
} wavinfo_t;
|
||||||
|
|
||||||
typedef struct channel_s channel_t;
|
typedef struct channel_s channel_t;
|
||||||
typedef struct sfxbuffer_s sfxbuffer_t;
|
typedef struct sfxbuffer_s sfxbuffer_t;
|
||||||
struct sfxbuffer_s {
|
struct sfxbuffer_s {
|
||||||
unsigned int head; // ring buffer head position in sampels
|
unsigned head; // ring buffer head position in sampels
|
||||||
unsigned int tail; // ring buffer tail position in sampels
|
unsigned tail; // ring buffer tail position in sampels
|
||||||
unsigned int length; // length of buffer in samples
|
unsigned length; // length of buffer in samples
|
||||||
unsigned int pos; // position of tail within full stream
|
unsigned pos; // position of tail within full stream
|
||||||
unsigned int bps; // bytes per sample: 1 2 4 usually
|
unsigned bps; // bytes per sample: 1 2 4 usually
|
||||||
void (*paint) (channel_t *ch, sfxbuffer_t *buffer, int count);
|
void (*paint) (channel_t *ch, sfxbuffer_t *buffer, int count);
|
||||||
void (*advance) (sfxbuffer_t *buffer, unsigned int count);
|
void (*advance) (sfxbuffer_t *buffer, unsigned int count);
|
||||||
void (*setpos) (sfxbuffer_t *buffer, unsigned int pos);
|
void (*setpos) (sfxbuffer_t *buffer, unsigned int pos);
|
||||||
|
@ -70,9 +70,9 @@ typedef struct sfxstream_s {
|
||||||
void *file;
|
void *file;
|
||||||
wavinfo_t wavinfo;
|
wavinfo_t wavinfo;
|
||||||
int pos;
|
int pos;
|
||||||
void (*resample)(sfxbuffer_t *, byte *, int, void *);
|
void (*resample)(sfxbuffer_t *, byte *, int, void *);
|
||||||
int (*read)(void *file, byte *data, int bytes, wavinfo_t *info);
|
int (*read)(void *file, byte *data, int bytes, wavinfo_t *info);
|
||||||
int (*seek)(void *file, int pos, wavinfo_t *info);
|
int (*seek)(void *file, int pos, wavinfo_t *info);
|
||||||
sfxbuffer_t buffer;
|
sfxbuffer_t buffer;
|
||||||
} sfxstream_t;
|
} sfxstream_t;
|
||||||
|
|
||||||
|
@ -85,19 +85,19 @@ typedef struct sfxblock_s {
|
||||||
|
|
||||||
// !!! if this is changed, it much be changed in asm_i386.h too !!!
|
// !!! if this is changed, it much be changed in asm_i386.h too !!!
|
||||||
struct channel_s {
|
struct channel_s {
|
||||||
sfx_t *sfx; // sfx number
|
sfx_t *sfx; // sfx number
|
||||||
int leftvol; // 0-255 volume
|
int leftvol; // 0-255 volume
|
||||||
int rightvol; // 0-255 volume
|
int rightvol; // 0-255 volume
|
||||||
unsigned int end; // end time in global paintsamples
|
unsigned end; // end time in global paintsamples
|
||||||
unsigned int pos; // sample position in sfx
|
unsigned pos; // sample position in sfx
|
||||||
unsigned int looping; // where to loop, -1 = no looping
|
unsigned looping; // where to loop, -1 = no looping
|
||||||
int entnum; // to allow overriding a specific sound
|
int entnum; // to allow overriding a specific sound
|
||||||
int entchannel; //
|
int entchannel; //
|
||||||
vec3_t origin; // origin of sound effect
|
vec3_t origin; // origin of sound effect
|
||||||
vec_t dist_mult; // distance multiplier (attenuation/clipK)
|
vec_t dist_mult; // distance multiplier (attenuation/clipK)
|
||||||
int master_vol; // 0-255 master volume
|
int master_vol; // 0-255 master 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
|
||||||
};
|
};
|
||||||
|
|
||||||
void SND_PaintChannels(unsigned int endtime);
|
void SND_PaintChannels(unsigned int endtime);
|
||||||
|
|
|
@ -75,6 +75,8 @@ static qboolean mus_enabled = false;
|
||||||
|
|
||||||
static cvar_t *bgmvolume;
|
static cvar_t *bgmvolume;
|
||||||
|
|
||||||
|
static channel_t *cd_channel;
|
||||||
|
static sfx_t cd_sfx;
|
||||||
|
|
||||||
/* added by Andrew, for cd_ogg */
|
/* added by Andrew, for cd_ogg */
|
||||||
static cvar_t *mus_ogglist; // contain the filename of the ogglist.
|
static cvar_t *mus_ogglist; // contain the filename of the ogglist.
|
||||||
|
@ -174,6 +176,7 @@ I_OGGMus_Play (int track, qboolean looping)
|
||||||
{
|
{
|
||||||
plitem_t *trackmap = NULL;
|
plitem_t *trackmap = NULL;
|
||||||
dstring_t *trackstring = dstring_new ();
|
dstring_t *trackstring = dstring_new ();
|
||||||
|
wavinfo_t *info;
|
||||||
|
|
||||||
Sys_Printf ("Entering I_OGGMus_Play\n");
|
Sys_Printf ("Entering I_OGGMus_Play\n");
|
||||||
/* alrighty. grab the list, map track to filename. grab filename from data
|
/* alrighty. grab the list, map track to filename. grab filename from data
|
||||||
|
@ -192,7 +195,27 @@ I_OGGMus_Play (int track, qboolean looping)
|
||||||
}
|
}
|
||||||
|
|
||||||
Sys_Printf ("Playing: %s.\n", (char *) trackmap->data);
|
Sys_Printf ("Playing: %s.\n", (char *) trackmap->data);
|
||||||
S_LocalSound ((char *) trackmap->data);
|
if (cd_channel->sfx) {
|
||||||
|
cd_channel->sfx->close (cd_channel->sfx);
|
||||||
|
memset (cd_channel, 0, sizeof (*cd_channel));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cd_sfx.name)
|
||||||
|
free ((char *) cd_sfx.name);
|
||||||
|
cd_sfx.name = strdup ((char *) trackmap->data);
|
||||||
|
SND_Load (&cd_sfx);
|
||||||
|
if (cd_sfx.wavinfo)
|
||||||
|
info = cd_sfx.wavinfo (&cd_sfx);
|
||||||
|
if (info)
|
||||||
|
info->loopstart = 0;
|
||||||
|
cd_channel->sfx = cd_sfx.open (&cd_sfx);
|
||||||
|
if (cd_channel->sfx) {
|
||||||
|
int vol = bgmvolume->value * 255;
|
||||||
|
|
||||||
|
cd_channel->master_vol = vol;
|
||||||
|
cd_channel->leftvol = cd_channel->rightvol = cd_channel->master_vol;
|
||||||
|
}
|
||||||
|
|
||||||
free (trackstring);
|
free (trackstring);
|
||||||
playing = true;
|
playing = true;
|
||||||
}
|
}
|
||||||
|
@ -411,12 +434,21 @@ static void
|
||||||
Mus_VolChange (cvar_t *bgmvolume)
|
Mus_VolChange (cvar_t *bgmvolume)
|
||||||
{
|
{
|
||||||
Sys_Printf ("Entering Mus_VolChange\n");
|
Sys_Printf ("Entering Mus_VolChange\n");
|
||||||
|
if (cd_channel->sfx) {
|
||||||
|
int vol = bgmvolume->value * 255;
|
||||||
|
|
||||||
|
cd_channel->master_vol = vol;
|
||||||
|
cd_channel->leftvol = cd_channel->rightvol = cd_channel->master_vol;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
I_OGGMus_Init (void)
|
I_OGGMus_Init (void)
|
||||||
{
|
{
|
||||||
Sys_Printf ("Entering I_OGGMus_Init\n");
|
Sys_Printf ("Entering I_OGGMus_Init\n");
|
||||||
|
|
||||||
|
cd_channel = S_AllocChannel ();
|
||||||
|
|
||||||
/* check list file cvar, open list file, create map, close file. */
|
/* check list file cvar, open list file, create map, close file. */
|
||||||
|
|
||||||
mus_ogglist = Cvar_Get ("mus_ogglist", "tracklist.cfg", CVAR_NONE,
|
mus_ogglist = Cvar_Get ("mus_ogglist", "tracklist.cfg", CVAR_NONE,
|
||||||
|
|
|
@ -50,6 +50,7 @@ static __attribute__ ((unused)) const char rcsid[] =
|
||||||
#include "QF/sys.h"
|
#include "QF/sys.h"
|
||||||
#include "QF/sound.h"
|
#include "QF/sound.h"
|
||||||
#include "QF/plugin.h"
|
#include "QF/plugin.h"
|
||||||
|
#include "QF/va.h"
|
||||||
|
|
||||||
#include "snd_render.h"
|
#include "snd_render.h"
|
||||||
|
|
||||||
|
@ -65,6 +66,11 @@ cvar_t *snd_interp;
|
||||||
channel_t channels[MAX_CHANNELS];
|
channel_t channels[MAX_CHANNELS];
|
||||||
int total_channels;
|
int total_channels;
|
||||||
|
|
||||||
|
static channel_t *ambient_channels[NUM_AMBIENTS];
|
||||||
|
static channel_t *dynamic_channels[MAX_DYNAMIC_CHANNELS];
|
||||||
|
static channel_t *static_channels[MAX_CHANNELS];
|
||||||
|
static int num_statics;
|
||||||
|
|
||||||
static qboolean snd_initialized = false;
|
static qboolean snd_initialized = false;
|
||||||
static int snd_blocked = 0;
|
static int snd_blocked = 0;
|
||||||
static qboolean snd_ambient = 1;
|
static qboolean snd_ambient = 1;
|
||||||
|
@ -170,17 +176,11 @@ s_startup (void)
|
||||||
|
|
||||||
// Load a sound ===============================================================
|
// Load a sound ===============================================================
|
||||||
static sfx_t *
|
static sfx_t *
|
||||||
s_findname (const char *name)
|
s_load_sound (const char *name)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
sfx_t *sfx;
|
sfx_t *sfx;
|
||||||
|
|
||||||
if (!name)
|
|
||||||
Sys_Error ("S_FindName: NULL");
|
|
||||||
|
|
||||||
if (strlen (name) >= MAX_QPATH)
|
|
||||||
Sys_Error ("Sound name too long: %s", name);
|
|
||||||
|
|
||||||
// see if already loaded
|
// see if already loaded
|
||||||
for (i = 0; i < num_sfx; i++)
|
for (i = 0; i < num_sfx; i++)
|
||||||
if (known_sfx[i].name && !strcmp (known_sfx[i].name, name)) {
|
if (known_sfx[i].name && !strcmp (known_sfx[i].name, name)) {
|
||||||
|
@ -209,7 +209,11 @@ s_touch_sound (const char *name)
|
||||||
if (!sound_started)
|
if (!sound_started)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
sfx = s_findname (name);
|
if (!name)
|
||||||
|
Sys_Error ("s_touch_sound: NULL");
|
||||||
|
|
||||||
|
name = va ("sound/%s", name);
|
||||||
|
sfx = s_load_sound (name);
|
||||||
sfx->touch (sfx);
|
sfx->touch (sfx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,7 +225,11 @@ s_precache_sound (const char *name)
|
||||||
if (!sound_started || nosound->int_val)
|
if (!sound_started || nosound->int_val)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
sfx = s_findname (name);
|
if (!name)
|
||||||
|
Sys_Error ("s_precache_sound: NULL");
|
||||||
|
|
||||||
|
name = va ("sound/%s", name);
|
||||||
|
sfx = s_load_sound (name);
|
||||||
|
|
||||||
// cache it in
|
// cache it in
|
||||||
if (precache->int_val) {
|
if (precache->int_val) {
|
||||||
|
@ -233,46 +241,54 @@ s_precache_sound (const char *name)
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
|
static channel_t *
|
||||||
|
s_alloc_channel (void)
|
||||||
|
{
|
||||||
|
if (total_channels < MAX_CHANNELS)
|
||||||
|
return &channels[total_channels++];
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static channel_t *
|
static channel_t *
|
||||||
s_pick_channel (int entnum, int entchannel)
|
s_pick_channel (int entnum, int entchannel)
|
||||||
{
|
{
|
||||||
int ch_idx, first_to_die;
|
int ch_idx;
|
||||||
unsigned life_left;
|
unsigned life_left;
|
||||||
|
channel_t *ch, *first_to_die;
|
||||||
|
|
||||||
// Check for replacement sound, or find the best one to replace
|
// Check for replacement sound, or find the best one to replace
|
||||||
first_to_die = -1;
|
first_to_die = 0;
|
||||||
life_left = 0x7fffffff;
|
life_left = 0x7fffffff;
|
||||||
for (ch_idx = NUM_AMBIENTS; ch_idx < NUM_AMBIENTS + MAX_DYNAMIC_CHANNELS;
|
for (ch_idx = 0; ch_idx < MAX_DYNAMIC_CHANNELS; ch_idx++) {
|
||||||
ch_idx++) {
|
ch = dynamic_channels[ch_idx];
|
||||||
if (entchannel != 0 // channel 0 never overrides
|
if (entchannel != 0 // channel 0 never overrides
|
||||||
&& channels[ch_idx].entnum == entnum
|
&& ch->entnum == entnum
|
||||||
&& (channels[ch_idx].entchannel == entchannel ||
|
&& (ch->entchannel == entchannel || entchannel == -1)) {
|
||||||
entchannel == -1)) {
|
|
||||||
// always override sound from same entity
|
// always override sound from same entity
|
||||||
first_to_die = ch_idx;
|
first_to_die = ch;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// don't let monster sounds override player sounds
|
// don't let monster sounds override player sounds
|
||||||
if (channels[ch_idx].entnum == *render_data.viewentity
|
if (ch->entnum == *render_data.viewentity
|
||||||
&& entnum != *render_data.viewentity
|
&& entnum != *render_data.viewentity
|
||||||
&& channels[ch_idx].sfx)
|
&& ch->sfx)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (paintedtime + life_left > channels[ch_idx].end) {
|
if (paintedtime + life_left > ch->end) {
|
||||||
life_left = channels[ch_idx].end - paintedtime;
|
life_left = ch->end - paintedtime;
|
||||||
first_to_die = ch_idx;
|
first_to_die = ch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (first_to_die == -1)
|
if (!first_to_die)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (channels[first_to_die].sfx) {
|
if (first_to_die->sfx) {
|
||||||
channels[first_to_die].sfx->close (channels[first_to_die].sfx);
|
first_to_die->sfx->close (first_to_die->sfx);
|
||||||
channels[first_to_die].sfx = NULL;
|
first_to_die->sfx = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return &channels[first_to_die];
|
return first_to_die;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -376,9 +392,8 @@ s_start_sound (int entnum, int entchannel, sfx_t *sfx, const vec3_t origin,
|
||||||
|
|
||||||
// if an identical sound has also been started this frame, offset the pos
|
// if an identical sound has also been started this frame, offset the pos
|
||||||
// a bit to keep it from just making the first one louder
|
// a bit to keep it from just making the first one louder
|
||||||
check = &channels[NUM_AMBIENTS];
|
for (ch_idx = 0; ch_idx < MAX_DYNAMIC_CHANNELS; ch_idx++) {
|
||||||
for (ch_idx = NUM_AMBIENTS; ch_idx < NUM_AMBIENTS + MAX_DYNAMIC_CHANNELS;
|
check = dynamic_channels[ch_idx];
|
||||||
ch_idx++, check++) {
|
|
||||||
if (check == target_chan)
|
if (check == target_chan)
|
||||||
continue;
|
continue;
|
||||||
if (check->sfx == sfx && !check->pos) {
|
if (check->sfx == sfx && !check->pos) {
|
||||||
|
@ -396,17 +411,18 @@ static void
|
||||||
s_stop_sound (int entnum, int entchannel)
|
s_stop_sound (int entnum, int entchannel)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
channel_t *ch;
|
||||||
|
|
||||||
if (!sound_started)
|
if (!sound_started)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (i = 0; i < MAX_DYNAMIC_CHANNELS; i++) {
|
for (i = 0; i < MAX_DYNAMIC_CHANNELS; i++) {
|
||||||
if (channels[i].entnum == entnum
|
ch = dynamic_channels[i];
|
||||||
&& channels[i].entchannel == entchannel) {
|
if (ch->entnum == entnum && ch->entchannel == entchannel) {
|
||||||
channels[i].end = 0;
|
ch->end = 0;
|
||||||
if (channels[i].sfx)
|
if (ch->sfx)
|
||||||
channels[i].sfx->close (channels[i].sfx);
|
ch->sfx->close (ch->sfx);
|
||||||
channels[i].sfx = NULL;
|
ch->sfx = NULL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -439,7 +455,7 @@ s_stop_all_sounds (qboolean clear)
|
||||||
if (!sound_started)
|
if (!sound_started)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
total_channels = MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS; // no statics
|
num_statics = 0;
|
||||||
|
|
||||||
for (i = 0; i < MAX_CHANNELS; i++)
|
for (i = 0; i < MAX_CHANNELS; i++)
|
||||||
if (channels[i].sfx) {
|
if (channels[i].sfx) {
|
||||||
|
@ -468,13 +484,14 @@ s_static_sound (sfx_t *sfx, const vec3_t origin, float vol,
|
||||||
if (!sound_started || !sfx)
|
if (!sound_started || !sfx)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (total_channels == MAX_CHANNELS) {
|
if (!static_channels[num_statics]) {
|
||||||
Sys_Printf ("total_channels == MAX_CHANNELS\n");
|
if (!(static_channels[num_statics] = s_alloc_channel ())) {
|
||||||
return;
|
Sys_Printf ("ran out of channels\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ss = &channels[total_channels];
|
ss = static_channels[num_statics];
|
||||||
total_channels++;
|
|
||||||
|
|
||||||
if (!sfx->retain (sfx))
|
if (!sfx->retain (sfx))
|
||||||
return;
|
return;
|
||||||
|
@ -497,6 +514,7 @@ s_static_sound (sfx_t *sfx, const vec3_t origin, float vol,
|
||||||
|
|
||||||
s_spatialize (ss);
|
s_spatialize (ss);
|
||||||
ss->oldphase = ss->phase;
|
ss->oldphase = ss->phase;
|
||||||
|
num_statics++;
|
||||||
}
|
}
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
@ -520,16 +538,17 @@ s_updateAmbientSounds (void)
|
||||||
if (!l || !ambient_level->value) {
|
if (!l || !ambient_level->value) {
|
||||||
for (ambient_channel = 0; ambient_channel < NUM_AMBIENTS;
|
for (ambient_channel = 0; ambient_channel < NUM_AMBIENTS;
|
||||||
ambient_channel++) {
|
ambient_channel++) {
|
||||||
if (channels[ambient_channel].sfx)
|
chan = ambient_channels[ambient_channel];
|
||||||
channels[ambient_channel].sfx->close (channels[ambient_channel].sfx);
|
if (chan->sfx)
|
||||||
channels[ambient_channel].sfx = NULL;
|
chan->sfx->close (chan->sfx);
|
||||||
|
chan->sfx = NULL;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ambient_channel = 0; ambient_channel < NUM_AMBIENTS;
|
for (ambient_channel = 0; ambient_channel < NUM_AMBIENTS;
|
||||||
ambient_channel++) {
|
ambient_channel++) {
|
||||||
chan = &channels[ambient_channel];
|
chan = ambient_channels[ambient_channel];
|
||||||
if (!ambient_sfx[ambient_channel]) {
|
if (!ambient_sfx[ambient_channel]) {
|
||||||
chan->sfx = 0;
|
chan->sfx = 0;
|
||||||
continue;
|
continue;
|
||||||
|
@ -611,6 +630,18 @@ s_update_ (void)
|
||||||
snd_output_funcs->pS_O_Submit ();
|
snd_output_funcs->pS_O_Submit ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
s_update_channel (channel_t *ch)
|
||||||
|
{
|
||||||
|
if (!ch->sfx)
|
||||||
|
return 0;
|
||||||
|
ch->oldphase = ch->phase; // prepare to lerp from prev to next phase
|
||||||
|
s_spatialize (ch); // respatialize channel
|
||||||
|
if (!ch->leftvol && !ch->rightvol)
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
s_update
|
s_update
|
||||||
|
|
||||||
|
@ -637,43 +668,39 @@ s_update (const vec3_t origin, const vec3_t forward, const vec3_t right,
|
||||||
combine = NULL;
|
combine = NULL;
|
||||||
|
|
||||||
// update spatialization for static and dynamic sounds
|
// update spatialization for static and dynamic sounds
|
||||||
ch = channels + NUM_AMBIENTS;
|
for (i = 0; i < MAX_DYNAMIC_CHANNELS; i++)
|
||||||
for (i = NUM_AMBIENTS; i < total_channels; i++, ch++) {
|
s_update_channel (dynamic_channels[i]);
|
||||||
if (!ch->sfx)
|
|
||||||
continue;
|
for (i = 0; i < num_statics; i++) {
|
||||||
ch->oldphase = ch->phase; // prepare to lerp from prev to next
|
ch = static_channels[i];
|
||||||
// phase
|
if (!s_update_channel (ch))
|
||||||
s_spatialize (ch); // respatialize channel
|
|
||||||
if (!ch->leftvol && !ch->rightvol)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// try to combine static sounds with a previous channel of the same
|
// try to combine static sounds with a previous channel of the same
|
||||||
// sound effect so we don't mix five torches every frame
|
// sound effect so we don't mix five torches every frame
|
||||||
if (i >= MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS) {
|
// see if it can just use the last one
|
||||||
// see if it can just use the last one
|
if (combine && combine->sfx == ch->sfx) {
|
||||||
if (combine && combine->sfx == ch->sfx) {
|
combine->leftvol += ch->leftvol;
|
||||||
|
combine->rightvol += ch->rightvol;
|
||||||
|
ch->leftvol = ch->rightvol = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// search for one
|
||||||
|
for (j = 0; j < i; j++) {
|
||||||
|
combine = static_channels[j];
|
||||||
|
if (combine->sfx == ch->sfx)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (j == i) {
|
||||||
|
combine = NULL;
|
||||||
|
} else {
|
||||||
|
if (combine != ch) {
|
||||||
combine->leftvol += ch->leftvol;
|
combine->leftvol += ch->leftvol;
|
||||||
combine->rightvol += ch->rightvol;
|
combine->rightvol += ch->rightvol;
|
||||||
ch->leftvol = ch->rightvol = 0;
|
ch->leftvol = ch->rightvol = 0;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// search for one
|
|
||||||
combine = channels + MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS;
|
|
||||||
for (j = MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS; j < i; j++,
|
|
||||||
combine++)
|
|
||||||
if (combine->sfx == ch->sfx)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (j == total_channels) {
|
|
||||||
combine = NULL;
|
|
||||||
} else {
|
|
||||||
if (combine != ch) {
|
|
||||||
combine->leftvol += ch->leftvol;
|
|
||||||
combine->rightvol += ch->rightvol;
|
|
||||||
ch->leftvol = ch->rightvol = 0;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -857,6 +884,13 @@ s_unblock_sound (void)
|
||||||
static void
|
static void
|
||||||
s_init (void)
|
s_init (void)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < NUM_AMBIENTS; i++)
|
||||||
|
ambient_channels[i] = s_alloc_channel ();
|
||||||
|
for (i = 0; i < MAX_DYNAMIC_CHANNELS; i++)
|
||||||
|
dynamic_channels[i] = s_alloc_channel ();
|
||||||
|
|
||||||
snd_output_funcs = render_data.output->functions->snd_output;
|
snd_output_funcs = render_data.output->functions->snd_output;
|
||||||
Sys_Printf ("\nSound Initialization\n");
|
Sys_Printf ("\nSound Initialization\n");
|
||||||
|
|
||||||
|
@ -997,6 +1031,8 @@ static snd_render_funcs_t plugin_info_render_funcs = {
|
||||||
s_local_sound,
|
s_local_sound,
|
||||||
s_block_sound,
|
s_block_sound,
|
||||||
s_unblock_sound,
|
s_unblock_sound,
|
||||||
|
s_load_sound,
|
||||||
|
s_alloc_channel,
|
||||||
};
|
};
|
||||||
|
|
||||||
static plugin_funcs_t plugin_info_funcs = {
|
static plugin_funcs_t plugin_info_funcs = {
|
||||||
|
|
|
@ -291,7 +291,6 @@ SND_StreamAdvance (sfxbuffer_t *buffer, unsigned int count)
|
||||||
void
|
void
|
||||||
SND_Load (sfx_t *sfx)
|
SND_Load (sfx_t *sfx)
|
||||||
{
|
{
|
||||||
dstring_t *name = dstring_new ();
|
|
||||||
dstring_t *foundname = dstring_new ();
|
dstring_t *foundname = dstring_new ();
|
||||||
char *realname;
|
char *realname;
|
||||||
char buf[4];
|
char buf[4];
|
||||||
|
@ -302,22 +301,17 @@ SND_Load (sfx_t *sfx)
|
||||||
sfx->close = snd_noop;
|
sfx->close = snd_noop;
|
||||||
sfx->open = snd_open;
|
sfx->open = snd_open;
|
||||||
|
|
||||||
dsprintf (name, "sound/%s", sfx->name);
|
_QFS_FOpenFile (sfx->name, &file, foundname, 1);
|
||||||
_QFS_FOpenFile (name->str, &file, foundname, 1);
|
|
||||||
if (!file) {
|
if (!file) {
|
||||||
Sys_Printf ("Couldn't load %s\n", name->str);
|
Sys_Printf ("Couldn't load %s\n", sfx->name);
|
||||||
dstring_delete (name);
|
|
||||||
dstring_delete (foundname);
|
dstring_delete (foundname);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!strequal (foundname->str, name->str)) {
|
if (!strequal (foundname->str, sfx->name)) {
|
||||||
realname = foundname->str;
|
realname = foundname->str;
|
||||||
dstring_delete (name);
|
|
||||||
free (foundname);
|
free (foundname);
|
||||||
} else {
|
} else {
|
||||||
realname = name->str;
|
realname = (char *) sfx->name; // won't free if realname == sfx->name
|
||||||
free (name);
|
|
||||||
dstring_delete (foundname);
|
|
||||||
}
|
}
|
||||||
Qread (file, buf, 4);
|
Qread (file, buf, 4);
|
||||||
Qseek (file, 0, SEEK_SET);
|
Qseek (file, 0, SEEK_SET);
|
||||||
|
@ -341,7 +335,8 @@ SND_Load (sfx_t *sfx)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Qclose (file);
|
Qclose (file);
|
||||||
free (realname);
|
if (realname != sfx->name)
|
||||||
|
free (realname);
|
||||||
}
|
}
|
||||||
|
|
||||||
sfxbuffer_t *
|
sfxbuffer_t *
|
||||||
|
|
|
@ -179,8 +179,7 @@ S_PrecacheSound (const char *sample)
|
||||||
{
|
{
|
||||||
if (snd_render_funcs)
|
if (snd_render_funcs)
|
||||||
return snd_render_funcs->pS_PrecacheSound (sample);
|
return snd_render_funcs->pS_PrecacheSound (sample);
|
||||||
else
|
return NULL;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -246,3 +245,19 @@ S_UnblockSound (void)
|
||||||
if (snd_render_funcs)
|
if (snd_render_funcs)
|
||||||
snd_render_funcs->pS_UnblockSound ();
|
snd_render_funcs->pS_UnblockSound ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sfx_t *
|
||||||
|
S_LoadSound (const char *name)
|
||||||
|
{
|
||||||
|
if (snd_render_funcs)
|
||||||
|
return snd_render_funcs->pS_LoadSound (name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct channel_s *
|
||||||
|
S_AllocChannel (void)
|
||||||
|
{
|
||||||
|
if (snd_render_funcs)
|
||||||
|
return snd_render_funcs->pS_AllocChannel ();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue