backport the snd_* setup cvars

This commit is contained in:
Bill Currie 2001-03-10 06:00:19 +00:00
parent 73bc23e117
commit 048a9253ea
3 changed files with 521 additions and 502 deletions

View file

@ -174,6 +174,10 @@ extern cvar_t *loadas8bit;
extern cvar_t *bgmvolume;
extern cvar_t *volume;
extern cvar_t *snd_device;
extern cvar_t *snd_rate;
extern cvar_t *snd_bits;
extern cvar_t *snd_stereo;
extern cvar_t *snd_interp;
extern cvar_t *snd_stereo_phase_separation;

View file

@ -47,179 +47,183 @@ static const snd_pcm_channel_area_t *mmap_areas;
static char *pcmname = NULL;
size_t buffer_size;
qboolean SNDDMA_Init(void)
qboolean
SNDDMA_Init (void)
{
int err,i;
int rate=-1,bps=-1,stereo=-1,frag_size;
int err;
int rate = -1, bps = -1, stereo = -1, frag_size;
snd_pcm_hw_params_t *hw;
snd_pcm_sw_params_t *sw;
snd_pcm_hw_params_alloca(&hw);
snd_pcm_sw_params_alloca(&sw);
if ((i=COM_CheckParm("-sndpcm"))!=0) {
pcmname=com_argv[i+1];
}
if ((i=COM_CheckParm("-sndbits")) != 0) {
bps = atoi(com_argv[i+1]);
snd_pcm_hw_params_alloca (&hw);
snd_pcm_sw_params_alloca (&sw);
if (snd_device->string[0])
pcmname = snd_device->string;
if (snd_bits->int_val) {
bps = snd_bits->int_val;
if (bps != 16 && bps != 8) {
Con_Printf("Error: invalid sample bits: %d\n", i);
Con_Printf ("Error: invalid sample bits: %d\n", bps);
return 0;
}
}
if ((i=COM_CheckParm("-sndspeed")) != 0) {
rate = atoi(com_argv[i+1]);
if (rate!=44100 && rate!=22050 && rate!=11025) {
Con_Printf("Error: invalid sample rate: %d\n", rate);
if (snd_rate->int_val) {
rate = snd_rate->int_val;
if (rate != 44100 && rate != 22050 && rate != 11025) {
Con_Printf ("Error: invalid sample rate: %d\n", rate);
return 0;
}
}
if ((i=COM_CheckParm("-sndmono")) != 0) {
stereo=0;
}
if ((i=COM_CheckParm("-sndstereo")) != 0) {
stereo=1;
}
stereo = snd_stereo->int_val;
if (!pcmname)
pcmname = "plug:0,0";
if ((err=snd_pcm_open(&pcm, pcmname,
SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK))<0) {
Con_Printf("Error: audio open error: %s\n", snd_strerror(err));
if ((err = snd_pcm_open (&pcm, pcmname,
SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK)) < 0) {
Con_Printf ("Error: audio open error: %s\n", snd_strerror (err));
return 0;
}
Con_Printf("Using PCM %s.\n", pcmname);
snd_pcm_hw_params_any(pcm, hw);
Con_Printf ("Using PCM %s.\n", pcmname);
snd_pcm_hw_params_any (pcm, hw);
switch (rate) {
case -1:
if (snd_pcm_hw_params_set_rate_near(pcm, hw, 44100, 0) >= 0) {
if (snd_pcm_hw_params_set_rate_near (pcm, hw, 44100, 0) >= 0) {
frag_size = 256; /* assuming stereo 8 bit */
rate = 44100;
} else if (snd_pcm_hw_params_set_rate_near(pcm, hw, 22050, 0) >= 0) {
} else if (snd_pcm_hw_params_set_rate_near (pcm, hw, 22050, 0) >= 0) {
frag_size = 128; /* assuming stereo 8 bit */
rate = 22050;
} else if (snd_pcm_hw_params_set_rate_near(pcm, hw, 11025, 0) >= 0) {
} else if (snd_pcm_hw_params_set_rate_near (pcm, hw, 11025, 0) >= 0) {
frag_size = 64; /* assuming stereo 8 bit */
rate = 11025;
} else {
Con_Printf("ALSA: no useable rates\n");
Con_Printf ("ALSA: no useable rates\n");
goto error;
}
break;
case 11025:
case 22050:
case 44100:
if (snd_pcm_hw_params_set_rate_near(pcm, hw, rate, 0) >= 0) {
if (snd_pcm_hw_params_set_rate_near (pcm, hw, rate, 0) >= 0) {
frag_size = 64 * rate / 11025; /* assuming stereo 8 bit */
break;
}
/* Fall through */
default:
Con_Printf("ALSA: desired rate not supported\n");
Con_Printf ("ALSA: desired rate not supported\n");
goto error;
}
switch (bps) {
case -1:
if (snd_pcm_hw_params_set_format(pcm, hw, SND_PCM_FORMAT_S16_LE) >= 0) {
if (snd_pcm_hw_params_set_format (pcm, hw, SND_PCM_FORMAT_S16_LE) >= 0) {
bps = 16;
} else if (snd_pcm_hw_params_set_format(pcm, hw, SND_PCM_FORMAT_U8) >= 0) {
} else if (snd_pcm_hw_params_set_format (pcm, hw, SND_PCM_FORMAT_U8) >=
0) {
bps = 8;
} else {
Con_Printf("ALSA: no useable formats\n");
Con_Printf ("ALSA: no useable formats\n");
goto error;
}
break;
case 8:
case 16:
if (snd_pcm_hw_params_set_format(pcm, hw,
if (snd_pcm_hw_params_set_format (pcm, hw,
bps == 8 ? SND_PCM_FORMAT_U8 :
SND_PCM_FORMAT_S16) >= 0) {
break;
}
/* Fall through */
default:
Con_Printf("ALSA: desired format not supported\n");
Con_Printf ("ALSA: desired format not supported\n");
goto error;
}
if (snd_pcm_hw_params_set_access(pcm, hw,
if (snd_pcm_hw_params_set_access (pcm, hw,
SND_PCM_ACCESS_MMAP_INTERLEAVED) < 0) {
Con_Printf("ALSA: interleaved is not supported\n");
Con_Printf ("ALSA: interleaved is not supported\n");
goto error;
}
switch (stereo) {
case -1:
if (snd_pcm_hw_params_set_channels(pcm, hw, 2) >= 0) {
if (snd_pcm_hw_params_set_channels (pcm, hw, 2) >= 0) {
stereo = 1;
} else if (snd_pcm_hw_params_set_channels(pcm, hw, 1) >= 0) {
} else if (snd_pcm_hw_params_set_channels (pcm, hw, 1) >= 0) {
stereo = 0;
} else {
Con_Printf("ALSA: no useable channels\n");
Con_Printf ("ALSA: no useable channels\n");
goto error;
}
break;
case 0:
case 1:
if (snd_pcm_hw_params_set_channels(pcm, hw, stereo ? 2 : 1) >= 0)
if (snd_pcm_hw_params_set_channels (pcm, hw, stereo ? 2 : 1) >= 0)
break;
/* Fall through */
default:
Con_Printf("ALSA: desired channels not supported\n");
Con_Printf ("ALSA: desired channels not supported\n");
goto error;
}
snd_pcm_hw_params_set_period_size_near(pcm, hw, frag_size, 0);
snd_pcm_hw_params_set_period_size_near (pcm, hw, frag_size, 0);
err = snd_pcm_hw_params(pcm, hw);
err = snd_pcm_hw_params (pcm, hw);
if (err < 0) {
Con_Printf("ALSA: unable to install hw params\n");
Con_Printf ("ALSA: unable to install hw params\n");
goto error;
}
snd_pcm_sw_params_current(pcm, sw);
snd_pcm_sw_params_set_start_mode(pcm, sw, SND_PCM_START_EXPLICIT);
snd_pcm_sw_params_set_xrun_mode(pcm, sw, SND_PCM_XRUN_NONE);
snd_pcm_sw_params_current (pcm, sw);
snd_pcm_sw_params_set_start_mode (pcm, sw, SND_PCM_START_EXPLICIT);
snd_pcm_sw_params_set_xrun_mode (pcm, sw, SND_PCM_XRUN_NONE);
err = snd_pcm_sw_params(pcm, sw);
err = snd_pcm_sw_params (pcm, sw);
if (err < 0) {
Con_Printf("ALSA: unable to install sw params\n");
Con_Printf ("ALSA: unable to install sw params\n");
goto error;
}
mmap_areas = snd_pcm_mmap_running_areas(pcm);
mmap_areas = snd_pcm_mmap_running_areas (pcm);
shm=&sn;
memset((dma_t*)shm,0,sizeof(*shm));
shm = &sn;
memset ((dma_t *) shm, 0, sizeof (*shm));
shm->splitbuffer = 0;
shm->channels=stereo+1;
shm->submission_chunk=snd_pcm_hw_params_get_period_size(hw, 0); // don't mix less than this #
shm->samplepos=0; // in mono samples
shm->samplebits=bps;
buffer_size = snd_pcm_hw_params_get_buffer_size(hw);
shm->samples=buffer_size*shm->channels; // mono samples in buffer
shm->speed=rate;
shm->buffer=(unsigned char*)mmap_areas->addr;
Con_Printf("%5d stereo\n", shm->channels - 1);
Con_Printf("%5d samples\n", shm->samples);
Con_Printf("%5d samplepos\n", shm->samplepos);
Con_Printf("%5d samplebits\n", shm->samplebits);
Con_Printf("%5d submission_chunk\n", shm->submission_chunk);
Con_Printf("%5d speed\n", shm->speed);
Con_Printf("0x%x dma buffer\n", (int)shm->buffer);
Con_Printf("%5d total_channels\n", total_channels);
shm->channels = stereo + 1;
shm->submission_chunk = snd_pcm_hw_params_get_period_size (hw, 0); // don't
//
//
// mix
// less
// than
// this
// #
shm->samplepos = 0; // in mono samples
shm->samplebits = bps;
buffer_size = snd_pcm_hw_params_get_buffer_size (hw);
shm->samples = buffer_size * shm->channels; // mono samples in buffer
shm->speed = rate;
shm->buffer = (unsigned char *) mmap_areas->addr;
Con_Printf ("%5d stereo\n", shm->channels - 1);
Con_Printf ("%5d samples\n", shm->samples);
Con_Printf ("%5d samplepos\n", shm->samplepos);
Con_Printf ("%5d samplebits\n", shm->samplebits);
Con_Printf ("%5d submission_chunk\n", shm->submission_chunk);
Con_Printf ("%5d speed\n", shm->speed);
Con_Printf ("0x%x dma buffer\n", (int) shm->buffer);
Con_Printf ("%5d total_channels\n", total_channels);
snd_inited=1;
snd_inited = 1;
return 1;
error:
snd_pcm_close(pcm);
snd_pcm_close (pcm);
return 0;
}
static inline int
get_hw_ptr()
get_hw_ptr ()
{
size_t app_ptr;
snd_pcm_sframes_t delay;
@ -235,23 +239,25 @@ get_hw_ptr()
return hw_ptr;
}
int SNDDMA_GetDMAPos(void)
int
SNDDMA_GetDMAPos (void)
{
int hw_ptr;
if (!snd_inited) return 0;
if (!snd_inited)
return 0;
hw_ptr = get_hw_ptr();
hw_ptr = get_hw_ptr ();
hw_ptr *= shm->channels;
shm->samplepos = hw_ptr;
return shm->samplepos;
}
void SNDDMA_Shutdown(void)
void
SNDDMA_Shutdown (void)
{
if (snd_inited)
{
snd_pcm_close(pcm);
if (snd_inited) {
snd_pcm_close (pcm);
snd_inited = 0;
}
}
@ -263,7 +269,8 @@ SNDDMA_Submit
Send sound to device if buffer isn't really the dma buffer
===============
*/
void SNDDMA_Submit(void)
void
SNDDMA_Submit (void)
{
int count = paintedtime - soundtime;
int avail;
@ -280,7 +287,7 @@ void SNDDMA_Submit(void)
snd_pcm_start (pcm);
break;
case SND_PCM_STATE_RUNNING:
hw_ptr = get_hw_ptr();
hw_ptr = get_hw_ptr ();
missed = hw_ptr - shm->samplepos / shm->channels;
if (missed < 0)
missed += buffer_size;
@ -293,7 +300,7 @@ void SNDDMA_Submit(void)
if (count < 0) {
snd_pcm_rewind (pcm, -count);
} else {
avail = snd_pcm_avail_update(pcm);
avail = snd_pcm_avail_update (pcm);
if (avail < 0)
avail = buffer_size;
if (count > avail)
@ -305,4 +312,3 @@ void SNDDMA_Submit(void)
break;
}
}

View file

@ -45,12 +45,12 @@
#include "winquake.h"
#endif
void S_Play(void);
void S_PlayVol(void);
void S_SoundList(void);
void S_Update_();
void S_StopAllSounds(qboolean clear);
void S_StopAllSoundsC(void);
void S_Play (void);
void S_PlayVol (void);
void S_SoundList (void);
void S_Update_ ();
void S_StopAllSounds (qboolean clear);
void S_StopAllSoundsC (void);
// =======================================================================
// Internal sound data & structures
@ -71,7 +71,7 @@ vec3_t listener_origin;
vec3_t listener_forward;
vec3_t listener_right;
vec3_t listener_up;
vec_t sound_nominal_clip_dist=1000.0;
vec_t sound_nominal_clip_dist = 1000.0;
int soundtime; // sample PAIRS
int paintedtime; // sample PAIRS
@ -86,11 +86,15 @@ sfx_t *ambient_sfx[NUM_AMBIENTS];
int desired_speed = 11025;
int desired_bits = 16;
int sound_started=0;
int sound_started = 0;
cvar_t *bgmvolume;
cvar_t *volume;
cvar_t *snd_device;
cvar_t *snd_rate;
cvar_t *snd_bits;
cvar_t *snd_stereo;
cvar_t *nosound;
cvar_t *precache;
cvar_t *loadas8bit;
@ -120,34 +124,36 @@ qboolean fakedma = false;
int fakedma_updates = 15;
void S_AmbientOff (void)
void
S_AmbientOff (void)
{
snd_ambient = false;
}
void S_AmbientOn (void)
void
S_AmbientOn (void)
{
snd_ambient = true;
}
void S_SoundInfo_f(void)
void
S_SoundInfo_f (void)
{
if (!sound_started || !shm)
{
if (!sound_started || !shm) {
Con_Printf ("sound system not started\n");
return;
}
Con_Printf("%5d stereo\n", shm->channels - 1);
Con_Printf("%5d samples\n", shm->samples);
Con_Printf("%5d samplepos\n", shm->samplepos);
Con_Printf("%5d samplebits\n", shm->samplebits);
Con_Printf("%5d submission_chunk\n", shm->submission_chunk);
Con_Printf("%5d speed\n", shm->speed);
Con_Printf("0x%x dma buffer\n", shm->buffer);
Con_Printf("%5d total_channels\n", total_channels);
Con_Printf ("%5d stereo\n", shm->channels - 1);
Con_Printf ("%5d samples\n", shm->samples);
Con_Printf ("%5d samplepos\n", shm->samplepos);
Con_Printf ("%5d samplebits\n", shm->samplebits);
Con_Printf ("%5d submission_chunk\n", shm->submission_chunk);
Con_Printf ("%5d speed\n", shm->speed);
Con_Printf ("0x%x dma buffer\n", (int) shm->buffer);
Con_Printf ("%5d total_channels\n", total_channels);
}
@ -157,21 +163,20 @@ S_Startup
================
*/
void S_Startup (void)
void
S_Startup (void)
{
int rc;
if (!snd_initialized)
return;
if (!fakedma)
{
rc = SNDDMA_Init();
if (!fakedma) {
rc = SNDDMA_Init ();
if (!rc)
{
if (!rc) {
#ifndef _WIN32
Con_Printf("S_Startup: SNDDMA_Init failed.\n");
Con_Printf ("S_Startup: SNDDMA_Init failed.\n");
#endif
sound_started = 0;
return;
@ -187,41 +192,55 @@ void S_Startup (void)
S_Init
================
*/
void S_Init (void)
void
S_Init (void)
{
Con_Printf("\nSound Initialization\n");
Con_Printf ("\nSound Initialization\n");
Cmd_AddCommand("play", S_Play);
Cmd_AddCommand("playvol", S_PlayVol);
Cmd_AddCommand("stopsound", S_StopAllSoundsC);
Cmd_AddCommand("soundlist", S_SoundList);
Cmd_AddCommand("soundinfo", S_SoundInfo_f);
Cmd_AddCommand ("play", S_Play);
Cmd_AddCommand ("playvol", S_PlayVol);
Cmd_AddCommand ("stopsound", S_StopAllSoundsC);
Cmd_AddCommand ("soundlist", S_SoundList);
Cmd_AddCommand ("soundinfo", S_SoundInfo_f);
nosound = Cvar_Get("nosound", "0", CVAR_NONE, "None");
volume = Cvar_Get("volume", "0.7", CVAR_ARCHIVE, "None");
precache = Cvar_Get("precache", "1", CVAR_NONE, "None");
loadas8bit = Cvar_Get("loadas8bit", "0", CVAR_NONE, "None");
bgmvolume = Cvar_Get("bgmvolume", "1", CVAR_ARCHIVE, "None");
bgmbuffer = Cvar_Get("bgmbuffer", "4096", CVAR_NONE, "None");
ambient_level = Cvar_Get("ambient_level", "0.3", CVAR_NONE, "None");
ambient_fade = Cvar_Get("ambient_fade", "100", CVAR_NONE, "None");
snd_noextraupdate = Cvar_Get("snd_noextraupdate", "0", CVAR_NONE, "None");
snd_show = Cvar_Get("snd_show", "0", CVAR_NONE, "None");
snd_interp = Cvar_Get("snd_interp", "1", CVAR_ARCHIVE, "control sample interpolation");
snd_phasesep = Cvar_Get("snd_phasesep", "0.0", CVAR_ARCHIVE, "max stereo phase separation in ms. 0.6 is for 20cm head");
snd_volumesep = Cvar_Get("snd_volumesep", "1.0", CVAR_ARCHIVE, "max stereo volume separation in ms. 1.0 is max");
_snd_mixahead = Cvar_Get("_snd_mixahead", "0.1", CVAR_ARCHIVE, "None");
snd_device = Cvar_Get ("snd_device", "", CVAR_ROM,
"sound device. \"\" is system default");
snd_rate = Cvar_Get ("snd_rate", "0", CVAR_ROM,
"sound playback rate. 0 is system default");
snd_bits = Cvar_Get ("snd_bits", "0", CVAR_ROM,
"sound sample depth. 0 is system default");
snd_stereo = Cvar_Get ("snd_stereo", "1", CVAR_ROM,
"sound stereo output");
nosound = Cvar_Get ("nosound", "0", CVAR_NONE, "None");
volume = Cvar_Get ("volume", "0.7", CVAR_ARCHIVE, "None");
precache = Cvar_Get ("precache", "1", CVAR_NONE, "None");
loadas8bit = Cvar_Get ("loadas8bit", "0", CVAR_NONE, "None");
bgmvolume = Cvar_Get ("bgmvolume", "1", CVAR_ARCHIVE, "None");
bgmbuffer = Cvar_Get ("bgmbuffer", "4096", CVAR_NONE, "None");
ambient_level = Cvar_Get ("ambient_level", "0.3", CVAR_NONE, "None");
ambient_fade = Cvar_Get ("ambient_fade", "100", CVAR_NONE, "None");
snd_noextraupdate = Cvar_Get ("snd_noextraupdate", "0", CVAR_NONE, "None");
snd_show = Cvar_Get ("snd_show", "0", CVAR_NONE, "None");
snd_interp =
Cvar_Get ("snd_interp", "1", CVAR_ARCHIVE,
"control sample interpolation");
snd_phasesep =
Cvar_Get ("snd_phasesep", "0.0", CVAR_ARCHIVE,
"max stereo phase separation in ms. 0.6 is for 20cm head");
snd_volumesep =
Cvar_Get ("snd_volumesep", "1.0", CVAR_ARCHIVE,
"max stereo volume separation in ms. 1.0 is max");
_snd_mixahead = Cvar_Get ("_snd_mixahead", "0.1", CVAR_ARCHIVE, "None");
if (COM_CheckParm("-nosound"))
if (COM_CheckParm ("-nosound"))
return;
if (COM_CheckParm("-simsound"))
if (COM_CheckParm ("-simsound"))
fakedma = true;
if (host_parms.memsize < 0x800000)
{
Cvar_Set(loadas8bit, "1");
if (host_parms.memsize < 0x800000) {
Cvar_Set (loadas8bit, "1");
Con_Printf ("loading all sounds as 8bit\n");
}
@ -236,14 +255,14 @@ void S_Init (void)
SND_InitScaletable ();
known_sfx = Hunk_AllocName (MAX_SFX*sizeof(sfx_t), "sfx_t");
known_sfx = Hunk_AllocName (MAX_SFX * sizeof (sfx_t), "sfx_t");
num_sfx = 0;
// create a piece of DMA memory
if (fakedma)
{
shm = (void *) Hunk_AllocName(sizeof(*shm), "shm");
if (fakedma) {
shm = (void *) Hunk_AllocName (sizeof (*shm), "shm");
shm->splitbuffer = 0;
shm->samplebits = 16;
shm->speed = 22050;
@ -253,7 +272,7 @@ void S_Init (void)
shm->soundalive = true;
shm->gamealive = true;
shm->submission_chunk = 1;
shm->buffer = Hunk_AllocName(1<<16, "shmbuf");
shm->buffer = Hunk_AllocName (1 << 16, "shmbuf");
}
Con_Printf ("Sound sampling rate: %i\n", shm->speed);
@ -274,7 +293,8 @@ void S_Init (void)
// Shutdown sound engine
// =======================================================================
void S_Shutdown(void)
void
S_Shutdown (void)
{
if (!sound_started)
@ -286,9 +306,8 @@ void S_Shutdown(void)
shm = 0;
sound_started = 0;
if (!fakedma)
{
SNDDMA_Shutdown();
if (!fakedma) {
SNDDMA_Shutdown ();
}
}
@ -303,7 +322,8 @@ S_FindName
==================
*/
sfx_t *S_FindName (char *name)
sfx_t *
S_FindName (char *name)
{
int i;
sfx_t *sfx;
@ -311,13 +331,12 @@ sfx_t *S_FindName (char *name)
if (!name)
Sys_Error ("S_FindName: NULL\n");
if (strlen(name) >= MAX_QPATH)
if (strlen (name) >= MAX_QPATH)
Sys_Error ("Sound name too long: %s", name);
// see if already loaded
for (i=0 ; i < num_sfx ; i++)
if (!strcmp(known_sfx[i].name, name))
{
for (i = 0; i < num_sfx; i++)
if (!strcmp (known_sfx[i].name, name)) {
return &known_sfx[i];
}
@ -339,7 +358,8 @@ S_TouchSound
==================
*/
void S_TouchSound (char *name)
void
S_TouchSound (char *name)
{
sfx_t *sfx;
@ -356,7 +376,8 @@ S_PrecacheSound
==================
*/
sfx_t *S_PrecacheSound (char *name)
sfx_t *
S_PrecacheSound (char *name)
{
sfx_t *sfx;
@ -380,7 +401,8 @@ sfx_t *S_PrecacheSound (char *name)
SND_PickChannel
=================
*/
channel_t *SND_PickChannel(int entnum, int entchannel)
channel_t *
SND_PickChannel (int entnum, int entchannel)
{
int ch_idx;
int first_to_die;
@ -389,22 +411,27 @@ channel_t *SND_PickChannel(int entnum, int entchannel)
// Check for replacement sound, or find the best one to replace
first_to_die = -1;
life_left = 0x7fffffff;
for (ch_idx=NUM_AMBIENTS ; ch_idx < NUM_AMBIENTS + MAX_DYNAMIC_CHANNELS ; ch_idx++)
{
for (ch_idx = NUM_AMBIENTS; ch_idx < NUM_AMBIENTS + MAX_DYNAMIC_CHANNELS;
ch_idx++) {
if (entchannel != 0 // channel 0 never overrides
&& channels[ch_idx].entnum == entnum
&& (channels[ch_idx].entchannel == entchannel || entchannel == -1) )
{ // allways override sound from same entity
&& (channels[ch_idx].entchannel == entchannel || entchannel == -1)) { // always
//
//
// override
// sound
// from
// same
// entity
first_to_die = ch_idx;
break;
}
// don't let monster sounds override player sounds
if (channels[ch_idx].entnum == cl.viewentity && entnum != cl.viewentity && channels[ch_idx].sfx)
if (channels[ch_idx].entnum == cl.viewentity && entnum != cl.viewentity
&& channels[ch_idx].sfx)
continue;
if (channels[ch_idx].end - paintedtime < life_left)
{
if (channels[ch_idx].end - paintedtime < life_left) {
life_left = channels[ch_idx].end - paintedtime;
first_to_die = ch_idx;
}
@ -424,7 +451,8 @@ channel_t *SND_PickChannel(int entnum, int entchannel)
SND_Spatialize
=================
*/
void SND_Spatialize(channel_t *ch)
void
SND_Spatialize (channel_t *ch)
{
vec_t dot;
vec_t dist;
@ -433,32 +461,27 @@ void SND_Spatialize(channel_t *ch)
vec3_t source_vec;
sfx_t *snd;
// anything coming from the view entity will allways be full volume
if (ch->entnum == cl.viewentity)
{
// anything coming from the view entity will always be full volume
if (ch->entnum == cl.viewentity) {
ch->leftvol = ch->master_vol;
ch->rightvol = ch->master_vol;
ch->phase = 0;
return;
}
// calculate stereo seperation and distance attenuation
snd = ch->sfx;
VectorSubtract(ch->origin, listener_origin, source_vec);
VectorSubtract (ch->origin, listener_origin, source_vec);
dist = VectorNormalize(source_vec) * ch->dist_mult;
dist = VectorNormalize (source_vec) * ch->dist_mult;
dot = DotProduct(listener_right, source_vec);
dot = DotProduct (listener_right, source_vec);
if (shm->channels == 1)
{
if (shm->channels == 1) {
rscale = 1.0;
lscale = 1.0;
phase = 0;
}
else
{
} else {
rscale = 1.0 + dot * snd_volumesep->value;
lscale = 1.0 - dot * snd_volumesep->value;
phase = snd_phasesep->value * 0.001 * shm->speed * dot;
@ -483,7 +506,9 @@ void SND_Spatialize(channel_t *ch)
// Start a sound effect
// =======================================================================
void S_StartSound(int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float fvol, float attenuation)
void
S_StartSound (int entnum, int entchannel, sfx_t *sfx, vec3_t origin,
float fvol, float attenuation)
{
channel_t *target_chan, *check;
sfxcache_t *sc;
@ -500,21 +525,21 @@ void S_StartSound(int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float f
if (nosound->int_val)
return;
vol = fvol*255;
vol = fvol * 255;
// pick a channel to play on
target_chan = SND_PickChannel(entnum, entchannel);
target_chan = SND_PickChannel (entnum, entchannel);
if (!target_chan)
return;
// spatialize
memset (target_chan, 0, sizeof(*target_chan));
VectorCopy(origin, target_chan->origin);
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;
SND_Spatialize(target_chan);
SND_Spatialize (target_chan);
target_chan->oldphase = target_chan->phase;
if (!target_chan->leftvol && !target_chan->rightvol)
@ -522,8 +547,7 @@ void S_StartSound(int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float f
// new channel
sc = S_LoadSound (sfx);
if (!sc)
{
if (!sc) {
target_chan->sfx = NULL;
return; // couldn't load the sound's data
}
@ -535,13 +559,12 @@ void S_StartSound(int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float f
// 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
check = &channels[NUM_AMBIENTS];
for (ch_idx=NUM_AMBIENTS ; ch_idx < NUM_AMBIENTS + MAX_DYNAMIC_CHANNELS ; ch_idx++, check++)
{
for (ch_idx = NUM_AMBIENTS; ch_idx < NUM_AMBIENTS + MAX_DYNAMIC_CHANNELS;
ch_idx++, check++) {
if (check == target_chan)
continue;
if (check->sfx == sfx && !check->pos)
{
skip = rand () % (int)(0.1*shm->speed);
if (check->sfx == sfx && !check->pos) {
skip = rand () % (int) (0.1 * shm->speed);
if (skip >= target_chan->end)
skip = target_chan->end - 1;
target_chan->pos += skip;
@ -552,15 +575,14 @@ void S_StartSound(int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float f
}
}
void S_StopSound(int entnum, int entchannel)
void
S_StopSound (int entnum, int entchannel)
{
int i;
for (i=0 ; i<MAX_DYNAMIC_CHANNELS ; i++)
{
for (i = 0; i < MAX_DYNAMIC_CHANNELS; i++) {
if (channels[i].entnum == entnum
&& channels[i].entchannel == entchannel)
{
&& channels[i].entchannel == entchannel) {
channels[i].end = 0;
channels[i].sfx = NULL;
return;
@ -568,7 +590,8 @@ void S_StopSound(int entnum, int entchannel)
}
}
void S_StopAllSounds(qboolean clear)
void
S_StopAllSounds (qboolean clear)
{
int i;
@ -577,22 +600,24 @@ void S_StopAllSounds(qboolean clear)
total_channels = MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS; // no statics
for (i=0 ; i<MAX_CHANNELS ; i++)
for (i = 0; i < MAX_CHANNELS; i++)
if (channels[i].sfx)
channels[i].sfx = NULL;
memset(channels, 0, MAX_CHANNELS * sizeof(channel_t));
memset (channels, 0, MAX_CHANNELS * sizeof (channel_t));
if (clear)
S_ClearBuffer ();
}
void S_StopAllSoundsC (void)
void
S_StopAllSoundsC (void)
{
S_StopAllSounds (true);
}
void S_ClearBuffer (void)
void
S_ClearBuffer (void)
{
int clear;
@ -609,8 +634,7 @@ void S_ClearBuffer (void)
clear = 0;
#ifdef _WIN32
if (pDSBuf)
{
if (pDSBuf) {
DWORD dwSize;
DWORD *pData;
int reps;
@ -618,32 +642,31 @@ void S_ClearBuffer (void)
reps = 0;
while ((hresult = pDSBuf->lpVtbl->Lock(pDSBuf, 0, gSndBufSize, &pData, &dwSize, NULL, NULL, 0)) != DS_OK)
{
if (hresult != DSERR_BUFFERLOST)
{
while (
(hresult =
pDSBuf->lpVtbl->Lock (pDSBuf, 0, gSndBufSize, &pData, &dwSize,
NULL, NULL, 0)) != DS_OK) {
if (hresult != DSERR_BUFFERLOST) {
Con_Printf ("S_ClearBuffer: DS::Lock Sound Buffer Failed\n");
S_Shutdown ();
return;
}
if (++reps > 10000)
{
if (++reps > 10000) {
Con_Printf ("S_ClearBuffer: DS: couldn't restore buffer\n");
S_Shutdown ();
return;
}
}
memset(pData, clear, shm->samples * shm->samplebits/8);
memset (pData, clear, shm->samples * shm->samplebits / 8);
pDSBuf->lpVtbl->Unlock(pDSBuf, pData, dwSize, NULL, 0);
pDSBuf->lpVtbl->Unlock (pDSBuf, pData, dwSize, NULL, 0);
}
else
} else
#endif
{
memset(shm->buffer, clear, shm->samples * shm->samplebits/8);
memset (shm->buffer, clear, shm->samples * shm->samplebits / 8);
}
}
@ -653,7 +676,8 @@ void S_ClearBuffer (void)
S_StaticSound
=================
*/
void S_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation)
void
S_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation)
{
channel_t *ss;
sfxcache_t *sc;
@ -661,8 +685,7 @@ void S_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation)
if (!sfx)
return;
if (total_channels == MAX_CHANNELS)
{
if (total_channels == MAX_CHANNELS) {
Con_Printf ("total_channels == MAX_CHANNELS\n");
return;
}
@ -674,8 +697,7 @@ void S_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation)
if (!sc)
return;
if (sc->loopstart == -1)
{
if (sc->loopstart == -1) {
Con_Printf ("Sound %s not looped\n", sfx->name);
return;
}
@ -683,7 +705,7 @@ void S_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation)
ss->sfx = sfx;
VectorCopy (origin, ss->origin);
ss->master_vol = vol;
ss->dist_mult = (attenuation/64) / sound_nominal_clip_dist;
ss->dist_mult = (attenuation / 64) / sound_nominal_clip_dist;
ss->end = paintedtime + sc->length;
SND_Spatialize (ss);
@ -698,7 +720,8 @@ void S_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation)
S_UpdateAmbientSounds
===================
*/
void S_UpdateAmbientSounds (void)
void
S_UpdateAmbientSounds (void)
{
mleaf_t *l;
float vol;
@ -713,15 +736,14 @@ void S_UpdateAmbientSounds (void)
return;
l = Mod_PointInLeaf (listener_origin, cl.worldmodel);
if (!l || !ambient_level->value)
{
for (ambient_channel = 0 ; ambient_channel< NUM_AMBIENTS ; ambient_channel++)
if (!l || !ambient_level->value) {
for (ambient_channel = 0; ambient_channel < NUM_AMBIENTS;
ambient_channel++)
channels[ambient_channel].sfx = NULL;
return;
}
for (ambient_channel = 0 ; ambient_channel< NUM_AMBIENTS ; ambient_channel++)
{
for (ambient_channel = 0; ambient_channel < NUM_AMBIENTS; ambient_channel++) {
chan = &channels[ambient_channel];
chan->sfx = ambient_sfx[ambient_channel];
@ -730,14 +752,11 @@ void S_UpdateAmbientSounds (void)
vol = 0;
// don't adjust volume too fast
if (chan->master_vol < vol)
{
if (chan->master_vol < vol) {
chan->master_vol += host_frametime * ambient_fade->value;
if (chan->master_vol > vol)
chan->master_vol = vol;
}
else if (chan->master_vol > vol)
{
} else if (chan->master_vol > vol) {
chan->master_vol -= host_frametime * ambient_fade->value;
if (chan->master_vol < vol)
chan->master_vol = vol;
@ -755,7 +774,8 @@ S_Update
Called once each time through the main loop
============
*/
void S_Update(vec3_t origin, vec3_t forward, vec3_t right, vec3_t up)
void
S_Update (vec3_t origin, vec3_t forward, vec3_t right, vec3_t up)
{
int i, j;
int total;
@ -765,10 +785,10 @@ void S_Update(vec3_t origin, vec3_t forward, vec3_t right, vec3_t up)
if (!sound_started || (snd_blocked > 0))
return;
VectorCopy(origin, listener_origin);
VectorCopy(forward, listener_forward);
VectorCopy(right, listener_right);
VectorCopy(up, listener_up);
VectorCopy (origin, listener_origin);
VectorCopy (forward, listener_forward);
VectorCopy (right, listener_right);
VectorCopy (up, listener_up);
// update general area ambient sound sources
S_UpdateAmbientSounds ();
@ -776,43 +796,37 @@ void S_Update(vec3_t origin, vec3_t forward, vec3_t right, vec3_t up)
combine = NULL;
// update spatialization for static and dynamic sounds
ch = channels+NUM_AMBIENTS;
for (i=NUM_AMBIENTS ; i<total_channels; i++, ch++)
{
ch = channels + NUM_AMBIENTS;
for (i = NUM_AMBIENTS; i < total_channels; i++, ch++) {
if (!ch->sfx)
continue;
ch->oldphase = ch->phase; // prepare to lerp from prev to next phase
SND_Spatialize(ch); // respatialize channel
ch->oldphase = ch->phase; // prepare to lerp from prev to next
// phase
SND_Spatialize (ch); // respatialize channel
if (!ch->leftvol && !ch->rightvol)
continue;
// try to combine static sounds with a previous channel of the same
// sound effect so we don't mix five torches every frame
if (i >= MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS)
{
if (i >= MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS) {
// 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
combine = channels+MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS;
for (j=MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS ; j<i; j++, combine++)
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)
{
if (j == total_channels) {
combine = NULL;
}
else
{
if (combine != ch)
{
} else {
if (combine != ch) {
combine->leftvol += ch->leftvol;
combine->rightvol += ch->rightvol;
ch->leftvol = ch->rightvol = 0;
@ -827,25 +841,24 @@ void S_Update(vec3_t origin, vec3_t forward, vec3_t right, vec3_t up)
//
// debugging output
//
if (snd_show->int_val)
{
if (snd_show->int_val) {
total = 0;
ch = channels;
for (i=0 ; i<total_channels; i++, ch++)
if (ch->sfx && (ch->leftvol || ch->rightvol) )
{
//Con_Printf ("%3i %3i %s\n", ch->leftvol, ch->rightvol, ch->sfx->name);
for (i = 0; i < total_channels; i++, ch++)
if (ch->sfx && (ch->leftvol || ch->rightvol)) {
// Con_Printf ("%3i %3i %s\n", ch->leftvol, ch->rightvol,
// ch->sfx->name);
total++;
}
Con_Printf ("----(%i)----\n", total);
}
// mix some sound
S_Update_();
S_Update_ ();
}
void GetSoundtime(void)
void
GetSoundtime (void)
{
int samplepos;
static int buffers;
@ -857,17 +870,16 @@ void GetSoundtime(void)
// it is possible to miscount buffers if it has wrapped twice between
// calls to S_Update. Oh well.
#ifdef __sun__
soundtime = SNDDMA_GetSamples();
soundtime = SNDDMA_GetSamples ();
#else
samplepos = SNDDMA_GetDMAPos();
samplepos = SNDDMA_GetDMAPos ();
if (samplepos < oldsamplepos)
{
if (samplepos < oldsamplepos) {
buffers++; // buffer wrapped
if (paintedtime > 0x40000000)
{ // time to chop things off to avoid 32 bit limits
if (paintedtime > 0x40000000) { // time to chop things off to avoid
// 32 bit limits
buffers = 0;
paintedtime = fullsamples;
S_StopAllSounds (true);
@ -875,11 +887,12 @@ void GetSoundtime(void)
}
oldsamplepos = samplepos;
soundtime = buffers*fullsamples + samplepos/shm->channels;
soundtime = buffers * fullsamples + samplepos / shm->channels;
#endif
}
void S_ExtraUpdate (void)
void
S_ExtraUpdate (void)
{
#ifdef _WIN32
@ -888,10 +901,11 @@ void S_ExtraUpdate (void)
if (snd_noextraupdate->int_val)
return; // don't pollute timings
S_Update_();
S_Update_ ();
}
void S_Update_(void)
void
S_Update_ (void)
{
unsigned endtime;
int samps;
@ -900,18 +914,16 @@ void S_Update_(void)
return;
// Updates DMA time
GetSoundtime();
GetSoundtime ();
// check to make sure that we haven't overshot
if (paintedtime < soundtime)
{
//Con_Printf ("S_Update_ : overflow\n");
if (paintedtime < soundtime) {
// Con_Printf ("S_Update_ : overflow\n");
paintedtime = soundtime;
}
// mix ahead of current position
endtime = soundtime + _snd_mixahead->value * shm->speed;
samps = shm->samples >> (shm->channels-1);
samps = shm->samples >> (shm->channels - 1);
if (endtime - soundtime > samps)
endtime = soundtime + samps;
@ -920,8 +932,7 @@ void S_Update_(void)
{
DWORD dwStatus;
if (pDSBuf)
{
if (pDSBuf) {
if (pDSBuf->lpVtbl->GetStatus (pDSBuf, &dwStatus) != DD_OK)
Con_Printf ("Couldn't get sound buffer status\n");
@ -929,7 +940,7 @@ void S_Update_(void)
pDSBuf->lpVtbl->Restore (pDSBuf);
if (!(dwStatus & DSBSTATUS_PLAYING))
pDSBuf->lpVtbl->Play(pDSBuf, 0, 0, DSBPLAY_LOOPING);
pDSBuf->lpVtbl->Play (pDSBuf, 0, 0, DSBPLAY_LOOPING);
}
}
#endif
@ -947,55 +958,52 @@ console functions
===============================================================================
*/
void S_Play(void)
void
S_Play (void)
{
static int hash=345;
static int hash = 345;
int i;
char name[256];
sfx_t *sfx;
i = 1;
while (i<Cmd_Argc())
{
if (!strrchr(Cmd_Argv(i), '.'))
{
strcpy(name, Cmd_Argv(i));
strcat(name, ".wav");
}
else
strcpy(name, Cmd_Argv(i));
sfx = S_PrecacheSound(name);
S_StartSound(hash++, 0, sfx, listener_origin, 1.0, 1.0);
while (i < Cmd_Argc ()) {
if (!strrchr (Cmd_Argv (i), '.')) {
strcpy (name, Cmd_Argv (i));
strcat (name, ".wav");
} else
strcpy (name, Cmd_Argv (i));
sfx = S_PrecacheSound (name);
S_StartSound (hash++, 0, sfx, listener_origin, 1.0, 1.0);
i++;
}
}
void S_PlayVol(void)
void
S_PlayVol (void)
{
static int hash=543;
static int hash = 543;
int i;
float vol;
char name[256];
sfx_t *sfx;
i = 1;
while (i<Cmd_Argc())
{
if (!strrchr(Cmd_Argv(i), '.'))
{
strcpy(name, Cmd_Argv(i));
strcat(name, ".wav");
}
else
strcpy(name, Cmd_Argv(i));
sfx = S_PrecacheSound(name);
vol = atof(Cmd_Argv(i+1));
S_StartSound(hash++, 0, sfx, listener_origin, vol, 1.0);
i+=2;
while (i < Cmd_Argc ()) {
if (!strrchr (Cmd_Argv (i), '.')) {
strcpy (name, Cmd_Argv (i));
strcat (name, ".wav");
} else
strcpy (name, Cmd_Argv (i));
sfx = S_PrecacheSound (name);
vol = atof (Cmd_Argv (i + 1));
S_StartSound (hash++, 0, sfx, listener_origin, vol, 1.0);
i += 2;
}
}
void S_SoundList(void)
void
S_SoundList (void)
{
int i;
sfx_t *sfx;
@ -1003,24 +1011,24 @@ void S_SoundList(void)
int size, total;
total = 0;
for (sfx=known_sfx, i=0 ; i<num_sfx ; i++, sfx++)
{
for (sfx = known_sfx, i = 0; i < num_sfx; i++, sfx++) {
sc = Cache_Check (&sfx->cache);
if (!sc)
continue;
size = sc->length*sc->width*(sc->stereo+1);
size = sc->length * sc->width * (sc->stereo + 1);
total += size;
if (sc->loopstart >= 0)
Con_Printf ("L");
else
Con_Printf (" ");
Con_Printf("(%2db) %6i : %s\n",sc->width*8, size, sfx->name);
Con_Printf ("(%2db) %6i : %s\n", sc->width * 8, size, sfx->name);
}
Con_Printf ("Total resident: %i\n", total);
}
void S_LocalSound (char *sound)
void
S_LocalSound (char *sound)
{
sfx_t *sfx;
@ -1030,8 +1038,7 @@ void S_LocalSound (char *sound)
return;
sfx = S_PrecacheSound (sound);
if (!sfx)
{
if (!sfx) {
Con_Printf ("S_LocalSound: can't cache %s\n", sound);
return;
}
@ -1039,17 +1046,19 @@ void S_LocalSound (char *sound)
}
void S_ClearPrecache (void)
void
S_ClearPrecache (void)
{
}
void S_BeginPrecaching (void)
void
S_BeginPrecaching (void)
{
}
void S_EndPrecaching (void)
void
S_EndPrecaching (void)
{
}