diff --git a/configure.ac b/configure.ac index 83916981a..fb32029fe 100644 --- a/configure.ac +++ b/configure.ac @@ -1032,6 +1032,30 @@ fi AC_SUBST(ALSA_LIBS) AC_SUBST(HAVE_ALSA) +AC_ARG_ENABLE(jack, +[ --disable-jack disable jack support], +) +HAVE_JACK=no +JACK_LIBS="" +if test "x$enable_jack" != "xno"; then + if test "x$PKG_CONFIG" != "x"; then + PKG_CHECK_MODULES([JACK], [jack], HAVE_JACK=yes, HAVE_JACK=no) + SOUND_TYPES="$SOUND_TYPES JACK" + else + AC_CHECK_LIB(jack, jack_client_open, HAVE_JACK=yes, HAVE_JACK=no, + [$LIBS]) + if test "x$HAVE_JACK" = "xyes"; then + AC_CHECK_HEADER(jack/jack.h, HAVE_JACK=yes, HAVE_JACK=no) + if test "x$HAVE_JACK" = "xyes"; then + JACK_LIBS="-ljack" + AC_DEFINE(HAVE_JACK, 1, [Define if you have libjack]) + SOUND_TYPES="$SOUND_TYPES JACK" + fi + fi + fi +fi +AC_SUBST(JACK_LIBS) + SOUND_TYPES="$SOUND_TYPES DISK" dnl MME @@ -2015,6 +2039,9 @@ if test -n "$CL_TARGETS"; then fi if test "$SOUND_TYPES"; then SND_REND_TARGETS="$SND_REND_TARGETS snd_render_default.la" + if test "`echo $SOUND_TYPES | grep JACK`"; then + SND_REND_TARGETS="$SND_REND_TARGETS snd_render_jack.la" + fi fi # priority sorted list for default sound driver in order of increasing diff --git a/include/QF/plugin/cd.h b/include/QF/plugin/cd.h index 255e7b6fc..cee9d0886 100644 --- a/include/QF/plugin/cd.h +++ b/include/QF/plugin/cd.h @@ -29,7 +29,6 @@ #define __QF_plugin_cd_h_ #include -#include /* All CDAudio plugins must export these functions diff --git a/include/QF/plugin/console.h b/include/QF/plugin/console.h index adb260e24..c6b243475 100644 --- a/include/QF/plugin/console.h +++ b/include/QF/plugin/console.h @@ -33,7 +33,6 @@ #include #include -#include typedef void (*P_C_Print) (const char *fmt, va_list args); typedef void (*P_C_ProcessInput) (void); diff --git a/include/QF/plugin/general.h b/include/QF/plugin/general.h index 9b2c46505..d0b70129e 100644 --- a/include/QF/plugin/general.h +++ b/include/QF/plugin/general.h @@ -30,7 +30,6 @@ #define __QF_plugin_general_h_ #include -#include /* All plugins, of all types, must export these functions diff --git a/include/QF/plugin/input.h b/include/QF/plugin/input.h index 0b6e9c3bf..0073a106d 100644 --- a/include/QF/plugin/input.h +++ b/include/QF/plugin/input.h @@ -30,7 +30,6 @@ #define __QF_plugin_input_h_ #include -#include /* All input plugins must export these functions diff --git a/include/QF/plugin/snd_output.h b/include/QF/plugin/snd_output.h index eca8bc4f1..55fe8dfe0 100644 --- a/include/QF/plugin/snd_output.h +++ b/include/QF/plugin/snd_output.h @@ -29,7 +29,6 @@ #define __QF_plugin_snd_output_h_ #include -#include /* All sound plugins must export these functions diff --git a/include/QF/plugin/snd_render.h b/include/QF/plugin/snd_render.h index 26b818615..f776ce480 100644 --- a/include/QF/plugin/snd_render.h +++ b/include/QF/plugin/snd_render.h @@ -29,7 +29,6 @@ #define __QF_plugin_snd_render_h_ #include -#include /* All sound plugins must export these functions @@ -47,7 +46,7 @@ typedef void (*P_S_StaticSound) (struct sfx_s *sfx, const vec3_t origin, float v typedef void (*P_S_StopSound) (int entnum, int entchannel); typedef struct sfx_s * (*P_S_PrecacheSound) (const char *sample); typedef void (*P_S_Update) (const vec3_t origin, const vec3_t v_forward, const vec3_t v_right, const vec3_t v_up); -typedef void (*P_S_StopAllSounds) (qboolean clear); +typedef void (*P_S_StopAllSounds) (void); typedef void (*P_S_ExtraUpdate) (void); typedef void (*P_S_LocalSound) (const char *s); typedef void (*P_S_BlockSound) (void); diff --git a/include/QF/sound.h b/include/QF/sound.h index 6ef85d01e..934c58ccc 100644 --- a/include/QF/sound.h +++ b/include/QF/sound.h @@ -119,10 +119,8 @@ void S_StaticSound (sfx_t *sfx, const vec3_t origin, float vol, void S_StopSound (int entnum, int entchannel); /** Stop all sounds from playing. - \param clear if true, the buffer is cleared so sound stops immediately - rather than trailing off */ -void S_StopAllSounds(qboolean clear); +void S_StopAllSounds(void); /** Update the sound engine with the client's position and orientation and render some sound. diff --git a/include/snd_render.h b/include/snd_render.h index 6bbcf25f2..2bda8c49f 100644 --- a/include/snd_render.h +++ b/include/snd_render.h @@ -38,6 +38,8 @@ */ //@{ +#include "QF/plugin/snd_render.h" +#include "QF/quakeio.h" #include "QF/sound.h" #include "QF/zone.h" @@ -176,14 +178,42 @@ struct channel_s { int oldphase; //!< phase shift between l-r in samples }; -extern struct cvar_s *snd_loadas8bit; -extern struct cvar_s *snd_volume; +extern struct cvar_s *snd_loadas8bit; +extern struct cvar_s *snd_volume; -extern struct cvar_s *snd_interp; -extern struct cvar_s *snd_stereo_phase_separation; +extern struct cvar_s *snd_interp; +extern struct cvar_s *snd_stereo_phase_separation; extern volatile dma_t *snd_shm; +extern snd_render_data_t snd_render_data; + +//@} + +/** \defgroup sound_render_sfx Sound sfx + \ingroup sound_render_mix +*/ +//@{ +/** Pre-load a sound into the cache. + \param sample name of sound to precache +*/ +sfx_t *SND_PrecacheSound (const char *sample); + +/** Tag a cached sound to prevent it being flushed unnecessarily. + \param sample name of sound touch + \todo check that Cache_TryGet() does the right thing +*/ +void SND_TouchSound (const char *sample); + +/** Pre-load a sound. + \param name name of sound to load +*/ +sfx_t *SND_LoadSound (const char *name); + +/** Initialize the sfx sub-subsystem +*/ +void SND_SFX_Init (void); + //@} /** \defgroup sound_render_mix_channels Sound channels @@ -202,6 +232,78 @@ extern volatile dma_t *snd_shm; #define MAX_DYNAMIC_CHANNELS 8 //!< number of dynamic channels extern channel_t snd_channels[MAX_CHANNELS]; //!< pool of available channels extern int snd_total_channels; //!< number of active channels + +/** Allocate a sound channel that can be used for playing sounds. +*/ +struct channel_s *SND_AllocChannel (void); + +/** Stop a channel from playing. + \param chan the channel to stop +*/ +void SND_ChannelStop (channel_t *chan); + +/** Disable ambient sounds. + \todo not used, remove? +*/ +void SND_AmbientOff (void); + +/** Enable ambient sounds. + \todo not used, remove? +*/ +void SND_AmbientOn (void); + +/** Update the sound engine with the client's position and orientation and + render some sound. + \param origin 3d coords of the client + \param v_forward 3d vector of the client's facing direction + \param v_right 3d vector of the client's rightward direction + \param v_up 3d vector of the client's upward direction +*/ +void SND_SetListener (const vec3_t origin, const vec3_t v_forward, + const vec3_t v_right, const vec3_t v_up); + +/** Stop all sounds from playing. +*/ +void SND_StopAllSounds(void); + +/** Initialize the channels sub-subsystem +*/ +void SND_Channels_Init (void); + +/** Start a sound playing. + \param entnum index of entity the sound is associated with. + \param entchannel 0-7 + - 0 auto (never willingly overrides) + - 1 weapon + - 2 voice + - 3 item + - 4 body + \param sfx sound to play + \param origin 3d coords of where the sound originates + \param fvol absolute volume of the sound + \param attenuation rate of volume dropoff vs distance +*/ +void SND_StartSound (int entnum, int entchannel, sfx_t *sfx, const vec3_t origin, + float fvol, float attenuation); + +/** Create a sound generated by the world. + \param sfx sound to play + \param origin 3d coords of where the sound originates + \param vol absolute volume of the sound + \param attenuation rate of volume dropoff vs distance +*/ +void SND_StaticSound (sfx_t *sfx, const vec3_t origin, float vol, + float attenuation); +/** Stop an entity's sound. + \param entnum index of entity the sound is associated with. + \param entchannel channel to silence +*/ +void SND_StopSound (int entnum, int entchannel); + +/** Start a sound local to the client view. + \param s name of sound to play +*/ +void SND_LocalSound (const char *s); //@} diff --git a/libs/audio/renderer/Makefile.am b/libs/audio/renderer/Makefile.am index 7490fc368..36be1ab24 100644 --- a/libs/audio/renderer/Makefile.am +++ b/libs/audio/renderer/Makefile.am @@ -8,12 +8,18 @@ plugin_libadd= @plugin_libadd@ EXEEXT= plugin_LTLIBRARIES= @SND_REND_TARGETS@ -EXTRA_LTLIBRARIES= snd_render_default.la +EXTRA_LTLIBRARIES= snd_render_default.la snd_render_jack.la noinst_LTLIBRARIES= @SND_REND_STATIC@ snd_render_default_la_LDFLAGS= $(plugin_ldflags) -snd_render_default_la_SOURCES= snd_dma.c snd_mem.c snd_mix.c snd_resample.c \ +snd_render_default_la_SOURCES= \ + snd_channels.c snd_dma.c snd_mem.c snd_mix.c snd_resample.c snd_sfx.c \ flac.c vorbis.c wav.c midi.c snd_render_default_la_LIBADD= $(VORBISFILE_LIBS) $(VORBIS_LIBS) $(LIBFLAC_LIBS) $(OGG_LIBS) $(WM_LIBS) snd_render_default_la_DEPENDENCIES= + +snd_render_jack_la_LDFLAGS= $(plugin_ldflags) +snd_render_jack_la_SOURCES= snd_channels.c snd_jack.c snd_sfx.c +snd_render_jack_la_LIBADD= $(VORBISFILE_LIBS) $(VORBIS_LIBS) $(LIBFLAC_LIBS) $(OGG_LIBS) $(WM_LIBS) +snd_render_jack_la_DEPENDENCIES= diff --git a/libs/audio/renderer/snd_dma.c b/libs/audio/renderer/snd_dma.c index 210c5d865..67f29228e 100644 --- a/libs/audio/renderer/snd_dma.c +++ b/libs/audio/renderer/snd_dma.c @@ -62,47 +62,21 @@ cvar_t *snd_loadas8bit; cvar_t *snd_volume; cvar_t *snd_interp; -channel_t snd_channels[MAX_CHANNELS]; -int snd_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 int snd_blocked = 0; -static qboolean snd_ambient = 1; - -static vec3_t listener_origin; -static vec3_t listener_forward; -static vec3_t listener_right; -static vec3_t listener_up; -static vec_t sound_nominal_clip_dist = 1000.0; static unsigned soundtime; // sample PAIRS -#define MAX_SFX 512 -static sfx_t *known_sfx; // hunk allocated [MAX_SFX] -static int num_sfx; - -static sfx_t *ambient_sfx[NUM_AMBIENTS]; - static int sound_started = 0; -static cvar_t *ambient_fade; -static cvar_t *ambient_level; static cvar_t *nosound; -static cvar_t *precache; static cvar_t *snd_mixahead; static cvar_t *snd_noextraupdate; -static cvar_t *snd_phasesep; static cvar_t *snd_show; -static cvar_t *snd_volumesep; static general_data_t plugin_info_general_data; -static snd_render_data_t render_data = { +snd_render_data_t snd_render_data = { 0, 0, 0, @@ -114,273 +88,9 @@ static snd_render_data_t render_data = { static snd_output_funcs_t *snd_output_funcs; -// User-setable variables ===================================================== - -static void -s_ambient_off (void) -{ - snd_ambient = false; -} - -static void -s_ambient_on (void) -{ - snd_ambient = true; -} - -// Load a sound =============================================================== -static sfx_t * -s_load_sound (const char *name) -{ - int i; - sfx_t *sfx; - - if (!known_sfx) - return 0; - - // see if already loaded - for (i = 0; i < num_sfx; i++) - if (known_sfx[i].name && !strcmp (known_sfx[i].name, name)) { - return &known_sfx[i]; - } - - if (num_sfx == MAX_SFX) - Sys_Error ("S_FindName: out of sfx_t"); - - sfx = &known_sfx[i]; - if (sfx->name) - free ((char *) sfx->name); - sfx->name = strdup (name); - SND_Load (sfx); - - num_sfx++; - - return sfx; -} - -static void -s_touch_sound (const char *name) -{ - sfx_t *sfx; - - if (!sound_started) - return; - - if (!name) - Sys_Error ("s_touch_sound: NULL"); - - name = va ("sound/%s", name); - sfx = s_load_sound (name); - sfx->touch (sfx); -} - -static sfx_t * -s_precache_sound (const char *name) -{ - sfx_t *sfx; - - if (!sound_started || nosound->int_val) - return NULL; - - if (!name) - Sys_Error ("s_precache_sound: NULL"); - - name = va ("sound/%s", name); - sfx = s_load_sound (name); - - // cache it in - if (precache->int_val) { - if (sfx->retain (sfx)) - sfx->release (sfx); - } - return sfx; -} - //============================================================================= -static channel_t * -s_alloc_channel (void) -{ - if (snd_total_channels < MAX_CHANNELS) - return &snd_channels[snd_total_channels++]; - return 0; -} - -static channel_t * -s_pick_channel (int entnum, int entchannel) -{ - int ch_idx; - unsigned life_left; - channel_t *ch, *first_to_die; - - // Check for replacement sound, or find the best one to replace - first_to_die = 0; - life_left = 0x7fffffff; - for (ch_idx = 0; ch_idx < MAX_DYNAMIC_CHANNELS; ch_idx++) { - ch = dynamic_channels[ch_idx]; - if (entchannel != 0 // channel 0 never overrides - && ch->entnum == entnum - && (ch->entchannel == entchannel || entchannel == -1)) { - // always override sound from same entity - first_to_die = ch; - break; - } - // don't let monster sounds override player sounds - if (ch->entnum == *render_data.viewentity - && entnum != *render_data.viewentity - && ch->sfx) - continue; - - if (snd_paintedtime + life_left > ch->end) { - life_left = ch->end - snd_paintedtime; - first_to_die = ch; - } - } - - if (!first_to_die) - return NULL; - - if (first_to_die->sfx) { - first_to_die->sfx->close (first_to_die->sfx); - first_to_die->sfx = NULL; - } - - return first_to_die; -} - -static void -s_spatialize (channel_t *ch) -{ - int phase; // in samples - vec_t dist, dot, lscale, rscale, scale; - vec3_t source_vec; - - // anything coming from the view entity will always be full volume - if (ch->entnum == *render_data.viewentity) { - ch->leftvol = ch->master_vol; - ch->rightvol = ch->master_vol; - ch->phase = 0; - return; - } - // calculate stereo seperation and distance attenuation - - VectorSubtract (ch->origin, listener_origin, source_vec); - - dist = VectorNormalize (source_vec) * ch->dist_mult; - - dot = DotProduct (listener_right, source_vec); - - if (snd_shm->channels == 1) { - rscale = 1.0; - lscale = 1.0; - phase = 0; - } else { - rscale = 1.0 + dot * snd_volumesep->value; - lscale = 1.0 - dot * snd_volumesep->value; - phase = snd_phasesep->value * 0.001 * snd_shm->speed * dot; - } - - // add in distance effect - scale = (1.0 - dist) * rscale; - ch->rightvol = (int) (ch->master_vol * scale); - if (ch->rightvol < 0) - ch->rightvol = 0; - - scale = (1.0 - dist) * lscale; - ch->leftvol = (int) (ch->master_vol * scale); - if (ch->leftvol < 0) - ch->leftvol = 0; - - ch->phase = phase; -} - // Start a sound effect ======================================================= -static void -s_start_sound (int entnum, int entchannel, sfx_t *sfx, const vec3_t origin, - float fvol, float attenuation) -{ - int ch_idx, vol; - unsigned int skip; - channel_t *target_chan, *check; - - if (!sound_started) - return; - if (!sfx) - return; - if (nosound->int_val) - return; - // pick a channel to play on - target_chan = s_pick_channel (entnum, entchannel); - if (!target_chan) - return; - - vol = fvol * 255; - - // spatialize - memset (target_chan, 0, sizeof (*target_chan)); - VectorCopy (origin, target_chan->origin); - target_chan->dist_mult = attenuation / sound_nominal_clip_dist; - target_chan->master_vol = vol; - target_chan->entnum = entnum; - target_chan->entchannel = entchannel; - s_spatialize (target_chan); - - if (!target_chan->leftvol && !target_chan->rightvol) - return; // not audible at all - - // new channel - if (!sfx->retain (sfx)) { - if (target_chan->sfx) - target_chan->sfx->close (target_chan->sfx); - target_chan->sfx = NULL; - return; // couldn't load the sound's data - } - - if (!(target_chan->sfx = sfx->open (sfx))) { - sfx->release (sfx); - return; - } - target_chan->pos = 0.0; - target_chan->end = snd_paintedtime + target_chan->sfx->length; - sfx->release (sfx); - - // 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 - for (ch_idx = 0; ch_idx < MAX_DYNAMIC_CHANNELS; ch_idx++) { - check = dynamic_channels[ch_idx]; - if (check == target_chan) - continue; - if (check->sfx == sfx && !check->pos) { - skip = rand () % (int) (0.1 * snd_shm->speed); - if (skip >= target_chan->end) - skip = target_chan->end - 1; - target_chan->pos += skip; - target_chan->end -= skip; - break; - } - } -} - -static void -s_stop_sound (int entnum, int entchannel) -{ - int i; - channel_t *ch; - - if (!sound_started) - return; - - for (i = 0; i < MAX_DYNAMIC_CHANNELS; i++) { - ch = dynamic_channels[i]; - if (ch->entnum == entnum && ch->entchannel == entchannel) { - ch->end = 0; - if (ch->sfx) - ch->sfx->close (ch->sfx); - ch->sfx = NULL; - return; - } - } -} static void s_clear_buffer (void) @@ -396,131 +106,18 @@ s_clear_buffer (void) clear = 0; for (i = 0; i < snd_shm->samples * snd_shm->samplebits / 8; i++) - snd_shm->buffer[i] = 0; + snd_shm->buffer[i] = clear; } static void -s_stop_all_sounds (qboolean clear) +s_stop_all_sounds (void) { - int i; - - if (!sound_started) - return; - - num_statics = 0; - - for (i = 0; i < MAX_CHANNELS; i++) - if (snd_channels[i].sfx) { - snd_channels[i].sfx->close (snd_channels[i].sfx); - snd_channels[i].sfx = NULL; - } - - memset (snd_channels, 0, MAX_CHANNELS * sizeof (channel_t)); - - if (clear) - s_clear_buffer (); -} - -static void -s_static_sound (sfx_t *sfx, const vec3_t origin, float vol, - float attenuation) -{ - channel_t *ss; - - if (!sound_started || !sfx) - return; - - if (!static_channels[num_statics]) { - if (!(static_channels[num_statics] = s_alloc_channel ())) { - Sys_Printf ("ran out of channels\n"); - return; - } - } - - ss = static_channels[num_statics]; - - if (!sfx->retain (sfx)) - return; - - if (sfx->loopstart == (unsigned int) -1) { - Sys_Printf ("Sound %s not looped\n", sfx->name); - sfx->release (sfx); - return; - } - - if (!(ss->sfx = sfx->open (sfx))) { - sfx->release (sfx); - return; - } - VectorCopy (origin, ss->origin); - ss->master_vol = vol; - ss->dist_mult = (attenuation / 64) / sound_nominal_clip_dist; - ss->end = snd_paintedtime + sfx->length; - sfx->release (sfx); - - s_spatialize (ss); - ss->oldphase = ss->phase; - num_statics++; + SND_StopAllSounds (); + s_clear_buffer (); } //============================================================================= -static void -s_updateAmbientSounds (void) -{ - float vol; - int ambient_channel; - channel_t *chan; - mleaf_t *l; - - if (!snd_ambient) - return; - // calc ambient sound levels - if (!*render_data.worldmodel) - return; - - l = Mod_PointInLeaf (listener_origin, *render_data.worldmodel); - if (!l || !ambient_level->value) { - for (ambient_channel = 0; ambient_channel < NUM_AMBIENTS; - ambient_channel++) { - chan = ambient_channels[ambient_channel]; - if (chan->sfx) - chan->sfx->close (chan->sfx); - chan->sfx = NULL; - } - return; - } - - for (ambient_channel = 0; ambient_channel < NUM_AMBIENTS; - ambient_channel++) { - chan = ambient_channels[ambient_channel]; - if (!ambient_sfx[ambient_channel]) { - chan->sfx = 0; - continue; - } else if (!chan->sfx) - chan->sfx = ambient_sfx[ambient_channel]->open (ambient_sfx[ambient_channel]); - - vol = ambient_level->value * l->ambient_sound_level[ambient_channel]; - if (vol < 8) - vol = 0; - - // don't adjust volume too fast - if (chan->master_vol < vol) { - chan->master_vol += *render_data.host_frametime - * ambient_fade->value; - if (chan->master_vol > vol) - chan->master_vol = vol; - } else if (chan->master_vol > vol) { - chan->master_vol -= *render_data.host_frametime - * ambient_fade->value; - if (chan->master_vol < vol) - chan->master_vol = vol; - } - - chan->leftvol = chan->rightvol = chan->master_vol; - } -} - static void s_get_soundtime (void) { @@ -541,7 +138,7 @@ s_get_soundtime (void) // 32 bit limits buffers = 0; snd_paintedtime = fullsamples; - s_stop_all_sounds (true); + s_stop_all_sounds (); } } oldsamplepos = samplepos; @@ -575,18 +172,6 @@ s_update_ (void) 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 @@ -596,72 +181,10 @@ static void s_update (const vec3_t origin, const vec3_t forward, const vec3_t right, const vec3_t up) { - int total, i, j; - channel_t *ch, *combine; - if (!sound_started || (snd_blocked > 0)) return; - VectorCopy (origin, listener_origin); - VectorCopy (forward, listener_forward); - VectorCopy (right, listener_right); - VectorCopy (up, listener_up); - - // update general area ambient sound sources - s_updateAmbientSounds (); - - combine = NULL; - - // update spatialization for static and dynamic sounds - for (i = 0; i < MAX_DYNAMIC_CHANNELS; i++) - s_update_channel (dynamic_channels[i]); - - for (i = 0; i < num_statics; i++) { - ch = static_channels[i]; - if (!s_update_channel (ch)) - continue; - - // try to combine static sounds with a previous channel of the same - // sound effect so we don't mix five torches every frame - // see if it can just use the last one - 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->rightvol += ch->rightvol; - ch->leftvol = ch->rightvol = 0; - } - continue; - } - } - - // debugging output - if (snd_show->int_val) { - total = 0; - ch = snd_channels; - for (i = 0; i < snd_total_channels; i++, ch++) - if (ch->sfx && (ch->leftvol || ch->rightvol)) { - // Sys_Printf ("%3i %3i %s\n", ch->leftvol, ch->rightvol, - // ch->sfx->name); - total++; - } - - Sys_Printf ("----(%i)----\n", total); - } + SND_SetListener (origin, forward, right, up); // mix some sound s_update_ (); @@ -675,24 +198,6 @@ s_extra_update (void) s_update_ (); } -static void -s_local_sound (const char *sound) -{ - sfx_t *sfx; - - if (!sound_started) - return; - if (nosound->int_val) - return; - - sfx = s_precache_sound (sound); - if (!sfx) { - Sys_Printf ("S_LocalSound: can't cache %s\n", sound); - return; - } - s_start_sound (*render_data.viewentity, -1, sfx, vec3_origin, 1, 1); -} - static void s_block_sound (void) { @@ -714,12 +219,6 @@ s_unblock_sound (void) } } -static void -s_gamedir (void) -{ - num_sfx = 0; -} - /* console functions */ static void @@ -740,106 +239,10 @@ s_soundinfo_f (void) Sys_Printf ("%5d total_channels\n", snd_total_channels); } -static void -s_play_f (void) -{ - dstring_t *name = dstring_new (); - int i; - static int hash = 345; - sfx_t *sfx; - - i = 1; - while (i < Cmd_Argc ()) { - if (!strrchr (Cmd_Argv (i), '.')) { - dsprintf (name, "%s.wav", Cmd_Argv (i)); - } else { - dsprintf (name, "%s", Cmd_Argv (i)); - } - sfx = s_precache_sound (name->str); - s_start_sound (hash++, 0, sfx, listener_origin, 1.0, 1.0); - i++; - } - dstring_delete (name); -} - -static void -s_playcenter_f (void) -{ - dstring_t *name = dstring_new (); - int i; - sfx_t *sfx; - - i = 1; - while (i < Cmd_Argc ()) { - if (!strrchr (Cmd_Argv (i), '.')) { - dsprintf (name, "%s.wav", Cmd_Argv (i)); - } else { - dsprintf (name, "%s", Cmd_Argv (i)); - } - sfx = s_precache_sound (name->str); - s_start_sound (*render_data.viewentity, 0, sfx, listener_origin, 1.0, 1.0); - i++; - } - dstring_delete (name); -} - -static void -s_playvol_f (void) -{ - dstring_t *name = dstring_new (); - float vol; - int i; - static int hash = 543; - sfx_t *sfx; - - i = 1; - while (i < Cmd_Argc ()) { - if (!strrchr (Cmd_Argv (i), '.')) { - dsprintf (name, "%s.wav", Cmd_Argv (i)); - } else { - dsprintf (name, "%s", Cmd_Argv (i)); - } - sfx = s_precache_sound (name->str); - vol = atof (Cmd_Argv (i + 1)); - s_start_sound (hash++, 0, sfx, listener_origin, vol, 1.0); - i += 2; - } - dstring_delete (name); -} - -static void -s_soundlist_f (void) -{ - int load, total, i; - sfx_t *sfx; - - if (Cmd_Argc() >= 2 && Cmd_Argv (1)[0]) - load = 1; - else - load = 0; - - total = 0; - for (sfx = known_sfx, i = 0; i < num_sfx; i++, sfx++) { - if (load) { - if (!sfx->retain (sfx)) - continue; - } else { - if (!sfx->touch (sfx)) - continue; - } - total += sfx->length; - Sys_Printf ("%6d %6d %s\n", sfx->loopstart, sfx->length, sfx->name); - - if (load) - sfx->release (sfx); - } - Sys_Printf ("Total resident: %i\n", total); -} - static void s_stop_all_sounds_f (void) { - s_stop_all_sounds (true); + s_stop_all_sounds (); } static void @@ -862,39 +265,18 @@ s_startup (void) static 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 = snd_render_data.output->functions->snd_output; Sys_Printf ("\nSound Initialization\n"); - Cmd_AddCommand ("play", s_play_f, - "Play selected sound effect (play pathto/sound.wav)"); - Cmd_AddCommand ("playcenter", s_playcenter_f, - "Play selected sound effect without 3D spatialization."); - Cmd_AddCommand ("playvol", s_playvol_f, "Play selected sound effect at " - "selected volume (playvol pathto/sound.wav num"); Cmd_AddCommand ("stopsound", s_stop_all_sounds_f, "Stops all sounds currently being played"); - Cmd_AddCommand ("soundlist", s_soundlist_f, - "Reports a list of sounds in the cache"); Cmd_AddCommand ("soundinfo", s_soundinfo_f, "Report information on the sound system"); snd_interp = Cvar_Get ("snd_interp", "1", CVAR_ARCHIVE, NULL, "control sample interpolation"); - ambient_fade = Cvar_Get ("ambient_fade", "100", CVAR_NONE, NULL, - "How quickly ambient sounds fade in or out"); - ambient_level = Cvar_Get ("ambient_level", "0.3", CVAR_NONE, NULL, - "Ambient sounds' volume"); nosound = Cvar_Get ("nosound", "0", CVAR_NONE, NULL, "Set to turn sound off"); - precache = Cvar_Get ("precache", "1", CVAR_NONE, NULL, - "Toggle the use of a precache"); snd_volume = Cvar_Get ("volume", "0.7", CVAR_ARCHIVE, NULL, "Set the volume for sound playback"); snd_interp = Cvar_Get ("snd_interp", "1", CVAR_ARCHIVE, NULL, @@ -907,13 +289,8 @@ s_init (void) "Toggles the correct value display in " "host_speeds. Usually messes up sound " "playback when in effect"); - snd_phasesep = Cvar_Get ("snd_phasesep", "0.0", CVAR_ARCHIVE, NULL, - "max stereo phase separation in ms. 0.6 is for " - "20cm head"); snd_show = Cvar_Get ("snd_show", "0", CVAR_NONE, NULL, "Toggles display of sounds currently being played"); - snd_volumesep = Cvar_Get ("snd_volumesep", "1.0", CVAR_ARCHIVE, NULL, - "max stereo volume separation. 1.0 is max"); // FIXME // if (host_parms.memsize < 0x800000) { // Cvar_Set (snd_loadas8bit, "1"); @@ -927,18 +304,12 @@ s_init (void) if (sound_started == 0) // sound startup failed? Bail out. return; + SND_SFX_Init (); + SND_Channels_Init (); + SND_InitScaletable (); - known_sfx = Hunk_AllocName (MAX_SFX * sizeof (sfx_t), "sfx_t"); - - num_sfx = 0; - - ambient_sfx[AMBIENT_WATER] = s_precache_sound ("ambience/water1.wav"); - ambient_sfx[AMBIENT_SKY] = s_precache_sound ("ambience/wind2.wav"); - - s_stop_all_sounds (true); - - QFS_GamedirCallback (s_gamedir); + s_stop_all_sounds (); } static void @@ -960,21 +331,21 @@ static general_funcs_t plugin_info_general_funcs = { }; static snd_render_funcs_t plugin_info_render_funcs = { - s_ambient_off, - s_ambient_on, - s_touch_sound, - s_static_sound, - s_start_sound, - s_stop_sound, - s_precache_sound, + SND_AmbientOff, + SND_AmbientOn, + SND_TouchSound, + SND_StaticSound, + SND_StartSound, + SND_StopSound, + SND_PrecacheSound, s_update, s_stop_all_sounds, s_extra_update, - s_local_sound, + SND_LocalSound, s_block_sound, s_unblock_sound, - s_load_sound, - s_alloc_channel, + SND_LoadSound, + SND_AllocChannel, }; static plugin_funcs_t plugin_info_funcs = { @@ -992,7 +363,7 @@ static plugin_data_t plugin_info_data = { 0, 0, 0, - &render_data, + &snd_render_data, }; static plugin_t plugin_info = { diff --git a/libs/audio/renderer/snd_mix.c b/libs/audio/renderer/snd_mix.c index 3c46a52fb..2f162811f 100644 --- a/libs/audio/renderer/snd_mix.c +++ b/libs/audio/renderer/snd_mix.c @@ -219,8 +219,7 @@ SND_PaintChannels (unsigned int endtime) ch->end = ltime + ch->sfx->length - ch->pos; } else { // channel just stopped ch->sfx->release (ch->sfx); - ch->sfx->close (ch->sfx); - ch->sfx = NULL; + SND_ChannelStop (ch); break; } } diff --git a/libs/audio/snd.c b/libs/audio/snd.c index eff07a638..d4d6ae5b2 100644 --- a/libs/audio/snd.c +++ b/libs/audio/snd.c @@ -185,10 +185,10 @@ S_Update (const vec3_t origin, const vec3_t v_forward, const vec3_t v_right, } VISIBLE void -S_StopAllSounds (qboolean clear) +S_StopAllSounds (void) { if (snd_render_funcs) - snd_render_funcs->pS_StopAllSounds (clear); + snd_render_funcs->pS_StopAllSounds (); } VISIBLE void diff --git a/nq/source/cl_main.c b/nq/source/cl_main.c index 0e4bb7f19..8f7377117 100644 --- a/nq/source/cl_main.c +++ b/nq/source/cl_main.c @@ -202,7 +202,7 @@ void CL_Disconnect (void) { // stop sounds (especially looping!) - S_StopAllSounds (true); + S_StopAllSounds (); // Clean the Cshifts CL_StopCshifts (); diff --git a/nq/source/cl_parse.c b/nq/source/cl_parse.c index 3e39aa2af..79e6e6b5f 100644 --- a/nq/source/cl_parse.c +++ b/nq/source/cl_parse.c @@ -268,7 +268,7 @@ CL_ParseServerInfo (void) Con_DPrintf ("Serverinfo packet received.\n"); S_BlockSound (); - S_StopAllSounds (true); + S_StopAllSounds (); // wipe the client_state_t struct CL_ClearState (); diff --git a/qw/source/cl_main.c b/qw/source/cl_main.c index db7f40d3b..a5f68cdc3 100644 --- a/qw/source/cl_main.c +++ b/qw/source/cl_main.c @@ -393,7 +393,7 @@ CL_ClearState (void) { int i; - S_StopAllSounds (true); + S_StopAllSounds (); // wipe the entire cl structure Info_Destroy (cl.serverinfo); @@ -472,7 +472,7 @@ CL_Disconnect (void) VID_SetCaption ("Disconnected"); // stop sounds (especially looping!) - S_StopAllSounds (true); + S_StopAllSounds (); // Clean the Cshifts CL_StopCshifts (); @@ -794,7 +794,7 @@ CL_Changing_f (void) if (cls.download) // don't change when downloading return; - S_StopAllSounds (true); + S_StopAllSounds (); cl.intermission = 0; r_force_fullscreen = 0; CL_SetState (ca_connected); // not active anymore, but not @@ -815,7 +815,7 @@ CL_Reconnect_f (void) if (cls.demoplayback) return; - S_StopAllSounds (true); + S_StopAllSounds (); if (cls.state == ca_connected) { Con_Printf ("reconnecting...\n");