all -snd* params and environment checking have been removed from the sound

subsystem in favor of Cvars*. These new cvars are:
 o  snd_device  defaults to "" which selects the default device of the system
    (eg, plug:0,0 for ALSA 0.9 or /dev/dsp for OSS)
 o  snd_rate    defaults to 0 which selects the system default rate.
 o  snd_bits    defaults to 0 which selects the system default bit depth.
 o  snd_stereo  defaults to 1 (0 is mono)

* actually, not that thorough: alsa and oss only. The rest have just ws :/
This commit is contained in:
Bill Currie 2001-02-26 17:39:32 +00:00
parent 95e5b5e4cf
commit f6d047712d
10 changed files with 366 additions and 322 deletions

View file

@ -172,6 +172,10 @@ extern cvar_t *loadas8bit;
extern cvar_t *bgmvolume; extern cvar_t *bgmvolume;
extern cvar_t *volume; 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_interp;
extern cvar_t *snd_stereo_phase_separation; extern cvar_t *snd_stereo_phase_separation;

View file

@ -123,14 +123,11 @@ SNDDMA_Init (void)
Con_Printf ("No sound cards detected\n"); Con_Printf ("No sound cards detected\n");
return 0; return 0;
} }
if ((i = COM_CheckParm ("-sndcard")) != 0) { if (snd_device->string[0]) {
card = atoi (com_argv[i + 1]); sscanf (snd_device->string, "%d,%d", &card, &dev);
} }
if ((i = COM_CheckParm ("-snddev")) != 0) { if (snd_bits->int_val) {
dev = atoi (com_argv[i + 1]); i = snd_bits->int_val;
}
if ((i = COM_CheckParm ("-sndbits")) != 0) {
i = atoi (com_argv[i + 1]);
if (i == 16) { if (i == 16) {
format = SND_PCM_SFMT_S16_LE; format = SND_PCM_SFMT_S16_LE;
} else if (i == 8) { } else if (i == 8) {
@ -140,16 +137,14 @@ SNDDMA_Init (void)
return 0; return 0;
} }
} }
if ((i = COM_CheckParm ("-sndspeed")) != 0) { if (snd_rate->int_val) {
rate = atoi (com_argv[i + 1]); rate = snd_rate->int_val;
if (rate != 44100 && rate != 22050 && rate != 11025) { if (rate != 44100 && rate != 22050 && rate != 11025) {
Con_Printf ("Error: invalid sample rate: %d\n", rate); Con_Printf ("Error: invalid sample rate: %d\n", rate);
return 0; return 0;
} }
} }
if ((i = COM_CheckParm ("-sndmono")) != 0) { stereo = snd_stereo->int_val;
stereo = 0;
}
if (card == -1) { if (card == -1) {
for (card = 0; card < SND_CARDS; card++) { for (card = 0; card < SND_CARDS; card++) {
if (!(mask & (1 << card))) if (!(mask & (1 << card)))
@ -273,6 +268,7 @@ SNDDMA_Init (void)
shm->samplebits = setup.format.format == SND_PCM_SFMT_S16_LE ? 16 : 8; shm->samplebits = setup.format.format == SND_PCM_SFMT_S16_LE ? 16 : 8;
shm->samples = shm->samples =
setup.buf.block.frags * setup.buf.block.frag_size / (shm->samplebits / 8); // mono setup.buf.block.frags * setup.buf.block.frag_size / (shm->samplebits / 8); // mono
//
// samples // samples
// in // in
// buffer // buffer

View file

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

View file

@ -101,6 +101,10 @@ int sound_started = 0;
cvar_t *bgmvolume; cvar_t *bgmvolume;
cvar_t *volume; cvar_t *volume;
cvar_t *snd_device;
cvar_t *snd_rate;
cvar_t *snd_bits;
cvar_t *snd_stereo;
cvar_t *nosound; cvar_t *nosound;
cvar_t *precache; cvar_t *precache;
cvar_t *loadas8bit; cvar_t *loadas8bit;
@ -197,13 +201,18 @@ void
S_Init (void) S_Init (void)
{ {
Con_Printf("\nSound Initialization\n"); Con_Printf ("\nSound Initialization\n");
Cmd_AddCommand ("play", S_Play, "Play selected sound effect (play pathto/sound.wav)"); Cmd_AddCommand ("play", S_Play,
Cmd_AddCommand ("playvol", S_PlayVol, "Play selected sound effect at selected volume (playvol pathto/sound.wav num"); "Play selected sound effect (play pathto/sound.wav)");
Cmd_AddCommand ("stopsound", S_StopAllSoundsC, "Stops all sounds currently being played"); Cmd_AddCommand ("playvol", S_PlayVol,
Cmd_AddCommand ("soundlist", S_SoundList, "Reports a list of sounds in the cache"); "Play selected sound effect at selected volume (playvol pathto/sound.wav num");
Cmd_AddCommand ("soundinfo", S_SoundInfo_f, "Report information on the sound system"); Cmd_AddCommand ("stopsound", S_StopAllSoundsC,
"Stops all sounds currently being played");
Cmd_AddCommand ("soundlist", S_SoundList,
"Reports a list of sounds in the cache");
Cmd_AddCommand ("soundinfo", S_SoundInfo_f,
"Report information on the sound system");
if (COM_CheckParm ("-nosound")) if (COM_CheckParm ("-nosound"))
return; return;
@ -261,22 +270,47 @@ S_Init (void)
void void
S_Init_Cvars (void) S_Init_Cvars (void)
{ {
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, "Set to turn sound off"); nosound = Cvar_Get ("nosound", "0", CVAR_NONE, "Set to turn sound off");
volume = Cvar_Get ("volume", "0.7", CVAR_ARCHIVE, "Set the volume for sound playback"); volume =
precache = Cvar_Get ("precache", "1", CVAR_NONE, "Toggle the use of a precache"); Cvar_Get ("volume", "0.7", CVAR_ARCHIVE,
loadas8bit = Cvar_Get ("loadas8bit", "0", CVAR_NONE, "Toggles if sounds are loaded as 8-bit samples"); "Set the volume for sound playback");
precache =
Cvar_Get ("precache", "1", CVAR_NONE, "Toggle the use of a precache");
loadas8bit =
Cvar_Get ("loadas8bit", "0", CVAR_NONE,
"Toggles if sounds are loaded as 8-bit samples");
bgmvolume = Cvar_Get ("bgmvolume", "1", CVAR_ARCHIVE, "Volume of CD music"); bgmvolume = Cvar_Get ("bgmvolume", "1", CVAR_ARCHIVE, "Volume of CD music");
ambient_level = Cvar_Get ("ambient_level", "0.3", CVAR_NONE, "Ambient sounds' volume"); ambient_level =
ambient_fade = Cvar_Get ("ambient_fade", "100", CVAR_NONE, "How quickly ambient sounds fade in or out"); Cvar_Get ("ambient_level", "0.3", CVAR_NONE, "Ambient sounds' volume");
snd_noextraupdate = Cvar_Get ("snd_noextraupdate", "0", CVAR_NONE, ambient_fade =
Cvar_Get ("ambient_fade", "100", CVAR_NONE,
"How quickly ambient sounds fade in or out");
snd_noextraupdate =
Cvar_Get ("snd_noextraupdate", "0", CVAR_NONE,
"Toggles the correct value display in host_speeds. Usually messes up sound playback when in effect"); "Toggles the correct value display in host_speeds. Usually messes up sound playback when in effect");
snd_show = Cvar_Get ("snd_show", "0", CVAR_NONE, "Toggles the display of sounds currently being played"); snd_show =
Cvar_Get ("snd_show", "0", CVAR_NONE,
"Toggles the display of sounds currently being played");
snd_interp = snd_interp =
Cvar_Get ("snd_interp", "1", CVAR_ARCHIVE, Cvar_Get ("snd_interp", "1", CVAR_ARCHIVE,
"control sample interpolation"); "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_phasesep =
snd_volumesep = Cvar_Get("snd_volumesep", "1.0", CVAR_ARCHIVE, "max stereo volume separation in ms. 1.0 is max"); Cvar_Get ("snd_phasesep", "0.0", CVAR_ARCHIVE,
_snd_mixahead = Cvar_Get ("_snd_mixahead", "0.1", CVAR_ARCHIVE, "Delay time for sounds"); "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,
"Delay time for sounds");
} }
@ -605,7 +639,8 @@ S_ClearBuffer (void)
clear = 0; clear = 0;
#ifdef _WIN32 #ifdef _WIN32
if (pDSBuf) DSOUND_ClearBuffer(clear); if (pDSBuf)
DSOUND_ClearBuffer (clear);
else else
#endif #endif
{ {
@ -737,7 +772,8 @@ S_Update (vec3_t origin, vec3_t forward, vec3_t right, vec3_t up)
for (i = NUM_AMBIENTS; i < total_channels; i++, ch++) { for (i = NUM_AMBIENTS; i < total_channels; i++, ch++) {
if (!ch->sfx) if (!ch->sfx)
continue; continue;
ch->oldphase = ch->phase; // prepare to lerp from prev to next phase ch->oldphase = ch->phase; // prepare to lerp from prev to next
// phase
SND_Spatialize (ch); // respatialize channel SND_Spatialize (ch); // respatialize channel
if (!ch->leftvol && !ch->rightvol) if (!ch->leftvol && !ch->rightvol)
continue; continue;
@ -861,7 +897,8 @@ S_Update_ (void)
endtime = soundtime + samps; endtime = soundtime + samps;
#ifdef _WIN32 #ifdef _WIN32
if(pDSBuf) DSOUND_Restore(); if (pDSBuf)
DSOUND_Restore ();
#endif #endif
S_PaintChannels (endtime); S_PaintChannels (endtime);

View file

@ -71,6 +71,7 @@ ResampleSfx (sfx_t *sfx, int inrate, int inwidth, byte * data)
ob = sc->data; ob = sc->data;
stepscale = (float) inrate / shm->speed; // this is usually 0.5, 1, or stepscale = (float) inrate / shm->speed; // this is usually 0.5, 1, or
//
// 2 // 2
outcount = sc->length / stepscale; outcount = sc->length / stepscale;

View file

@ -47,7 +47,9 @@
#define PAINTBUFFER_SIZE 512 #define PAINTBUFFER_SIZE 512
portable_samplepair_t paintbuffer[PAINTBUFFER_SIZE * 2]; portable_samplepair_t paintbuffer[PAINTBUFFER_SIZE * 2];
int max_overpaint; // number of extra samples painted due to phase shift int max_overpaint; // number of extra samples painted
// due to phase shift
int snd_scaletable[32][256]; int snd_scaletable[32][256];
int *snd_p, snd_linear_count, snd_vol; int *snd_p, snd_linear_count, snd_vol;
short *snd_out; short *snd_out;
@ -95,13 +97,12 @@ S_TransferStereo16 (int endtime)
#ifdef _WIN32 #ifdef _WIN32
if (pDSBuf) { if (pDSBuf) {
pbuf=DSOUND_LockBuffer(true); pbuf = DSOUND_LockBuffer (true);
if(!pbuf) { if (!pbuf) {
Con_Printf("DSOUND_LockBuffer fails!\n"); Con_Printf ("DSOUND_LockBuffer fails!\n");
return; return;
} }
} } else
else
#endif #endif
{ {
pbuf = (DWORD *) shm->buffer; pbuf = (DWORD *) shm->buffer;
@ -127,7 +128,8 @@ S_TransferStereo16 (int endtime)
} }
#ifdef _WIN32 #ifdef _WIN32
if (pDSBuf) DSOUND_LockBuffer(false); if (pDSBuf)
DSOUND_LockBuffer (false);
#endif #endif
} }
@ -157,13 +159,12 @@ S_TransferPaintBuffer (int endtime)
#ifdef _WIN32 #ifdef _WIN32
if (pDSBuf) { if (pDSBuf) {
pbuf=DSOUND_LockBuffer(true); pbuf = DSOUND_LockBuffer (true);
if(!pbuf) { if (!pbuf) {
Con_Printf("DSOUND_LockBuffer fails!\n"); Con_Printf ("DSOUND_LockBuffer fails!\n");
return; return;
} }
} } else
else
#endif #endif
{ {
pbuf = (DWORD *) shm->buffer; pbuf = (DWORD *) shm->buffer;
@ -197,7 +198,8 @@ S_TransferPaintBuffer (int endtime)
} }
} }
#ifdef _WIN32 #ifdef _WIN32
if (pDSBuf) DSOUND_LockBuffer(false); if (pDSBuf)
DSOUND_LockBuffer (false);
#endif #endif
} }

View file

@ -57,7 +57,8 @@ void
S_Init_Cvars (void) S_Init_Cvars (void)
{ {
volume = Cvar_Get ("volume", "0.7", CVAR_ARCHIVE, "Volume level of sounds"); volume = Cvar_Get ("volume", "0.7", CVAR_ARCHIVE, "Volume level of sounds");
loadas8bit = Cvar_Get ("loadas8bit", "0", CVAR_NONE, "Load samples as 8-bit"); loadas8bit =
Cvar_Get ("loadas8bit", "0", CVAR_NONE, "Load samples as 8-bit");
bgmvolume = Cvar_Get ("bgmvolume", "1", CVAR_ARCHIVE, "CD music volume"); bgmvolume = Cvar_Get ("bgmvolume", "1", CVAR_ARCHIVE, "CD music volume");
} }

View file

@ -64,8 +64,9 @@
# define MAP_FAILED ((void *) -1) # define MAP_FAILED ((void *) -1)
#endif #endif
int audio_fd; static int audio_fd;
int snd_inited; static int snd_inited;
static char *snd_dev;
static int tryrates[] = { 11025, 22050, 22051, 44100, 8000 }; static int tryrates[] = { 11025, 22050, 22051, 44100, 8000 };
@ -76,38 +77,40 @@ SNDDMA_Init (void)
int fmt; int fmt;
int tmp; int tmp;
int i; int i;
char *s;
struct audio_buf_info info; struct audio_buf_info info;
int caps; int caps;
int retries = 3; int retries = 3;
snd_inited = 0; snd_inited = 0;
// open /dev/dsp, confirm capability to mmap, and get size of dma buffer // open snd_dev, confirm capability to mmap, and get size of dma buffer
audio_fd = open ("/dev/dsp", O_RDWR); if (snd_device->string[0])
snd_dev = snd_device->string;
audio_fd = open (snd_dev, O_RDWR);
if (audio_fd < 0) { // Failed open, retry up to 3 times if (audio_fd < 0) { // Failed open, retry up to 3 times
// if it's busy // if it's busy
while ((audio_fd < 0) && retries-- && while ((audio_fd < 0) && retries-- &&
((errno == EAGAIN) || (errno == EBUSY))) { ((errno == EAGAIN) || (errno == EBUSY))) {
sleep (1); sleep (1);
audio_fd = open ("/dev/dsp", O_RDWR); audio_fd = open (snd_dev, O_RDWR);
} }
if (audio_fd < 0) { if (audio_fd < 0) {
perror ("/dev/dsp"); perror (snd_dev);
Con_Printf ("Could not open /dev/dsp\n"); Con_Printf ("Could not open %s\n", snd_dev);
return 0; return 0;
} }
} }
if ((rc = ioctl (audio_fd, SNDCTL_DSP_RESET, 0)) < 0) { if ((rc = ioctl (audio_fd, SNDCTL_DSP_RESET, 0)) < 0) {
perror ("/dev/dsp"); perror (snd_dev);
Con_Printf ("Could not reset /dev/dsp\n"); Con_Printf ("Could not reset %s\n", snd_dev);
close (audio_fd); close (audio_fd);
return 0; return 0;
} }
if (ioctl (audio_fd, SNDCTL_DSP_GETCAPS, &caps) == -1) { if (ioctl (audio_fd, SNDCTL_DSP_GETCAPS, &caps) == -1) {
perror ("/dev/dsp"); perror (snd_dev);
Con_Printf ("Sound driver too old\n"); Con_Printf ("Sound driver too old\n");
close (audio_fd); close (audio_fd);
return 0; return 0;
@ -130,13 +133,7 @@ SNDDMA_Init (void)
shm->splitbuffer = 0; shm->splitbuffer = 0;
// set sample bits & speed // set sample bits & speed
if ((i = COM_CheckParm ("-sndbits"))) { shm->samplebits = snd_bits->int_val;
shm->samplebits = atoi (com_argv[i + 1]);
} else {
if ((s = getenv ("QF_SND_BITS"))) {
shm->samplebits = atoi (s);
}
}
if (shm->samplebits != 16 && shm->samplebits != 8) { if (shm->samplebits != 16 && shm->samplebits != 8) {
ioctl (audio_fd, SNDCTL_DSP_GETFMTS, &fmt); ioctl (audio_fd, SNDCTL_DSP_GETFMTS, &fmt);
@ -150,10 +147,8 @@ SNDDMA_Init (void)
} }
} }
if ((i = COM_CheckParm ("-sndspeed"))) { if (snd_rate->int_val) {
shm->speed = atoi (com_argv[i + 1]); shm->speed = snd_rate->int_val;
} else if ((s = getenv ("QF_SND_SPEED"))) {
shm->speed = atoi (s);
} else { } else {
for (i = 0; i < (sizeof (tryrates) / 4); i++) for (i = 0; i < (sizeof (tryrates) / 4); i++)
if (!ioctl (audio_fd, SNDCTL_DSP_SPEED, &tryrates[i])) if (!ioctl (audio_fd, SNDCTL_DSP_SPEED, &tryrates[i]))
@ -161,12 +156,8 @@ SNDDMA_Init (void)
shm->speed = tryrates[i]; shm->speed = tryrates[i];
} }
if ((i = COM_CheckParm ("-sndmono"))) { if (!snd_stereo->int_val) {
shm->channels = 1; shm->channels = 1;
} else if ((i = COM_CheckParm ("-sndstereo"))) {
shm->channels = 2;
} else if ((s = getenv ("QF_SND_CHANNELS"))) {
shm->channels = atoi (s);
} else { } else {
shm->channels = 2; shm->channels = 2;
} }
@ -181,8 +172,8 @@ SNDDMA_Init (void)
MAP_FILE | MAP_SHARED, audio_fd, 0); MAP_FILE | MAP_SHARED, audio_fd, 0);
if (shm->buffer == MAP_FAILED) { if (shm->buffer == MAP_FAILED) {
perror ("/dev/dsp"); perror (snd_dev);
Con_Printf ("Could not mmap /dev/dsp\n"); Con_Printf ("Could not mmap %s\n", snd_dev);
close (audio_fd); close (audio_fd);
return 0; return 0;
} }
@ -192,8 +183,8 @@ SNDDMA_Init (void)
tmp = 1; tmp = 1;
rc = ioctl (audio_fd, SNDCTL_DSP_STEREO, &tmp); rc = ioctl (audio_fd, SNDCTL_DSP_STEREO, &tmp);
if (rc < 0) { if (rc < 0) {
perror ("/dev/dsp"); perror (snd_dev);
Con_Printf ("Could not set /dev/dsp to stereo=%d", shm->channels); Con_Printf ("Could not set %s to stereo=%d", snd_dev, shm->channels);
close (audio_fd); close (audio_fd);
return 0; return 0;
} }
@ -205,8 +196,8 @@ SNDDMA_Init (void)
rc = ioctl (audio_fd, SNDCTL_DSP_SPEED, &shm->speed); rc = ioctl (audio_fd, SNDCTL_DSP_SPEED, &shm->speed);
if (rc < 0) { if (rc < 0) {
perror ("/dev/dsp"); perror (snd_dev);
Con_Printf ("Could not set /dev/dsp speed to %d", shm->speed); Con_Printf ("Could not set %s speed to %d", snd_dev, shm->speed);
close (audio_fd); close (audio_fd);
return 0; return 0;
} }
@ -215,7 +206,7 @@ SNDDMA_Init (void)
rc = AFMT_S16_LE; rc = AFMT_S16_LE;
rc = ioctl (audio_fd, SNDCTL_DSP_SETFMT, &rc); rc = ioctl (audio_fd, SNDCTL_DSP_SETFMT, &rc);
if (rc < 0) { if (rc < 0) {
perror ("/dev/dsp"); perror (snd_dev);
Con_Printf ("Could not support 16-bit data. Try 8-bit.\n"); Con_Printf ("Could not support 16-bit data. Try 8-bit.\n");
close (audio_fd); close (audio_fd);
return 0; return 0;
@ -224,13 +215,13 @@ SNDDMA_Init (void)
rc = AFMT_U8; rc = AFMT_U8;
rc = ioctl (audio_fd, SNDCTL_DSP_SETFMT, &rc); rc = ioctl (audio_fd, SNDCTL_DSP_SETFMT, &rc);
if (rc < 0) { if (rc < 0) {
perror ("/dev/dsp"); perror (snd_dev);
Con_Printf ("Could not support 8-bit data.\n"); Con_Printf ("Could not support 8-bit data.\n");
close (audio_fd); close (audio_fd);
return 0; return 0;
} }
} else { } else {
perror ("/dev/dsp"); perror (snd_dev);
Con_Printf ("%d-bit sound not supported.", shm->samplebits); Con_Printf ("%d-bit sound not supported.", shm->samplebits);
close (audio_fd); close (audio_fd);
return 0; return 0;
@ -241,7 +232,7 @@ SNDDMA_Init (void)
tmp = 0; tmp = 0;
rc = ioctl (audio_fd, SNDCTL_DSP_SETTRIGGER, &tmp); rc = ioctl (audio_fd, SNDCTL_DSP_SETTRIGGER, &tmp);
if (rc < 0) { if (rc < 0) {
perror ("/dev/dsp"); perror (snd_dev);
Con_Printf ("Could not toggle.\n"); Con_Printf ("Could not toggle.\n");
close (audio_fd); close (audio_fd);
return 0; return 0;
@ -249,7 +240,7 @@ SNDDMA_Init (void)
tmp = PCM_ENABLE_OUTPUT; tmp = PCM_ENABLE_OUTPUT;
rc = ioctl (audio_fd, SNDCTL_DSP_SETTRIGGER, &tmp); rc = ioctl (audio_fd, SNDCTL_DSP_SETTRIGGER, &tmp);
if (rc < 0) { if (rc < 0) {
perror ("/dev/dsp"); perror (snd_dev);
Con_Printf ("Could not toggle.\n"); Con_Printf ("Could not toggle.\n");
close (audio_fd); close (audio_fd);
return 0; return 0;
@ -272,7 +263,7 @@ SNDDMA_GetDMAPos (void)
return 0; return 0;
if (ioctl (audio_fd, SNDCTL_DSP_GETOPTR, &count) == -1) { if (ioctl (audio_fd, SNDCTL_DSP_GETOPTR, &count) == -1) {
perror ("/dev/dsp"); perror (snd_dev);
Con_Printf ("Uh, sound dead.\n"); Con_Printf ("Uh, sound dead.\n");
close (audio_fd); close (audio_fd);
snd_inited = 0; snd_inited = 0;

View file

@ -40,7 +40,8 @@
#define iDirectSoundCreate(a,b,c) pDirectSoundCreate(a,b,c) #define iDirectSoundCreate(a,b,c) pDirectSoundCreate(a,b,c)
HRESULT (WINAPI * pDirectSoundCreate) (GUID FAR * lpGUID, HRESULT (WINAPI * pDirectSoundCreate) (GUID FAR * lpGUID,
LPDIRECTSOUND FAR * lplpDS,IUnknown FAR * pUnkOuter); LPDIRECTSOUND FAR * lplpDS,
IUnknown FAR * pUnkOuter);
// 64K is > 1 second at 16-bit, 22050 Hz // 64K is > 1 second at 16-bit, 22050 Hz
#define WAV_BUFFERS 64 #define WAV_BUFFERS 64
@ -181,8 +182,7 @@ FreeSound (void)
Direct-Sound support Direct-Sound support
*/ */
sndinitstat sndinitstat SNDDMA_InitDirect (void)
SNDDMA_InitDirect (void)
{ {
DSBUFFERDESC dsbuf; DSBUFFERDESC dsbuf;
DSBCAPS dsbcaps; DSBCAPS dsbcaps;
@ -271,7 +271,8 @@ SNDDMA_InitDirect (void)
pformat = format; pformat = format;
if (DS_OK != IDirectSoundBuffer_SetFormat (pDSPBuf, &pformat)) { if (DS_OK != IDirectSoundBuffer_SetFormat (pDSPBuf, &pformat)) {
} else primary_format_set = true; } else
primary_format_set = true;
} }
} }
@ -328,7 +329,8 @@ SNDDMA_InitDirect (void)
reps = 0; reps = 0;
while ((hresult = IDirectSoundBuffer_Lock (pDSBuf, 0, gSndBufSize, while ((hresult = IDirectSoundBuffer_Lock (pDSBuf, 0, gSndBufSize,
(LPVOID *) & lpData, &dwSize, NULL,NULL, 0)) != DS_OK) { (LPVOID *) & lpData, &dwSize,
NULL, NULL, 0)) != DS_OK) {
if (hresult != DSERR_BUFFERLOST) { if (hresult != DSERR_BUFFERLOST) {
Con_Printf ("SNDDMA_InitDirect: DS::Lock Sound Buffer Failed\n"); Con_Printf ("SNDDMA_InitDirect: DS::Lock Sound Buffer Failed\n");
FreeSound (); FreeSound ();
@ -403,7 +405,8 @@ SNDDMA_InitWav (void)
/* Open a waveform device for output using window callback. */ /* Open a waveform device for output using window callback. */
while ((hr = waveOutOpen ((LPHWAVEOUT) & hWaveOut, WAVE_MAPPER, while ((hr = waveOutOpen ((LPHWAVEOUT) & hWaveOut, WAVE_MAPPER,
&format,0, 0L, CALLBACK_NULL)) != MMSYSERR_NOERROR) { &format, 0, 0L,
CALLBACK_NULL)) != MMSYSERR_NOERROR) {
if (hr != MMSYSERR_ALLOCATED) { if (hr != MMSYSERR_ALLOCATED) {
Con_Printf ("waveOutOpen failed\n"); Con_Printf ("waveOutOpen failed\n");
return false; return false;
@ -565,7 +568,8 @@ SNDDMA_GetDMAPos (void)
if (dsound_init) { if (dsound_init) {
mmtime.wType = TIME_SAMPLES; mmtime.wType = TIME_SAMPLES;
IDirectSoundBuffer_GetCurrentPosition (pDSBuf, &mmtime.u.sample, &dwWrite); IDirectSoundBuffer_GetCurrentPosition (pDSBuf, &mmtime.u.sample,
&dwWrite);
s = mmtime.u.sample - mmstarttime.u.sample; s = mmtime.u.sample - mmstarttime.u.sample;
} else if (wav_init) { } else if (wav_init) {
s = snd_sent * WAV_BUFFER_SIZE; s = snd_sent * WAV_BUFFER_SIZE;
@ -643,7 +647,7 @@ SNDDMA_Shutdown (void)
} }
DWORD * DWORD *
DSOUND_LockBuffer(qboolean lockit) DSOUND_LockBuffer (qboolean lockit)
{ {
int reps; int reps;
@ -660,7 +664,8 @@ DSOUND_LockBuffer(qboolean lockit)
reps = 0; reps = 0;
while ((hresult = IDirectSoundBuffer_Lock (pDSBuf, 0, gSndBufSize, while ((hresult = IDirectSoundBuffer_Lock (pDSBuf, 0, gSndBufSize,
(LPVOID *) & pbuf1, &dwSize, (LPVOID *) & pbuf1, &dwSize,
(LPVOID *) & pbuf2, &dwSize2,0)) != DS_OK) { (LPVOID *) & pbuf2, &dwSize2,
0)) != DS_OK) {
if (hresult != DSERR_BUFFERLOST) { if (hresult != DSERR_BUFFERLOST) {
Con_Printf Con_Printf
("S_TransferStereo16: DS::Lock Sound Buffer Failed\n"); ("S_TransferStereo16: DS::Lock Sound Buffer Failed\n");
@ -679,30 +684,33 @@ DSOUND_LockBuffer(qboolean lockit)
} }
} else { } else {
IDirectSoundBuffer_Unlock (pDSBuf, pbuf1, dwSize, NULL, 0); IDirectSoundBuffer_Unlock (pDSBuf, pbuf1, dwSize, NULL, 0);
pbuf1=NULL; pbuf1 = NULL;
pbuf2=NULL; pbuf2 = NULL;
dwSize=0; dwSize = 0;
dwSize2=0; dwSize2 = 0;
} }
return(pbuf1); return (pbuf1);
} }
void DSOUND_ClearBuffer(int clear) void
DSOUND_ClearBuffer (int clear)
{ {
DWORD *pData; DWORD *pData;
// FIXME: this should be called with 2nd pbuf2 = NULL, dwsize =0 // FIXME: this should be called with 2nd pbuf2 = NULL, dwsize =0
pData=DSOUND_LockBuffer(true); pData = DSOUND_LockBuffer (true);
memset (pData, clear, shm->samples * shm->samplebits / 8); memset (pData, clear, shm->samples * shm->samplebits / 8);
DSOUND_LockBuffer(false); DSOUND_LockBuffer (false);
} }
void DSOUND_Restore(void) void
DSOUND_Restore (void)
{ {
// if the buffer was lost or stopped, restore it and/or restart it // if the buffer was lost or stopped, restore it and/or restart it
DWORD dwStatus; DWORD dwStatus;
if (!pDSBuf) return; if (!pDSBuf)
return;
if (IDirectSoundBuffer_GetStatus (pDSBuf, &dwStatus) != DD_OK) if (IDirectSoundBuffer_GetStatus (pDSBuf, &dwStatus) != DD_OK)
Con_Printf ("Couldn't get sound buffer status\n"); Con_Printf ("Couldn't get sound buffer status\n");
@ -715,4 +723,3 @@ void DSOUND_Restore(void)
return; return;
} }