* OpenAL support, from BlackAura aka Stuart Dalton <badcdev@gmail.com>

+ An abstract codec system, simplifying support for new formats
  + Changes versus BlackAura's patch:
    o Consolidated the OpenAL parts into one file
    o Changed the function naming scheme to more closely resemble Q3
    o Changed the interface to fall back on the "base" sound system
      if loading OpenAL fails
  + This is enabled on Linux and MinGW for now, but should work on the
    other *nixs with appropriate additions to the Makefile
  + NOT enabled on OS X or MSVC Windows builds
  + Probably breaks the Windows build again
* Retabulated sdl_snd.c and made the messages less verbose since
  there do not seem to be many having problems with SDL sound now
This commit is contained in:
Tim Angus 2005-11-13 18:58:14 +00:00
parent 79ceef93cc
commit 84c4f21082
14 changed files with 3813 additions and 703 deletions

View file

@ -30,6 +30,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*****************************************************************************/
#include "snd_local.h"
#include "snd_codec.h"
#include "client.h"
void S_Play_f(void);
@ -37,13 +38,11 @@ void S_SoundList_f(void);
void S_Music_f(void);
void S_Update_( void );
void S_StopAllSounds(void);
void S_UpdateBackgroundTrack( void );
void S_Base_StopAllSounds(void);
void S_Base_StopBackgroundTrack( void );
static fileHandle_t s_backgroundFile;
static wavinfo_t s_backgroundInfo;
//int s_nextWavChunk;
static int s_backgroundSamples;
snd_stream_t *s_backgroundStream = NULL;
static char s_backgroundLoop[MAX_QPATH];
//static char s_backgroundMusic[MAX_QPATH]; //TTimo: unused
@ -82,15 +81,11 @@ int s_numSfx = 0;
#define LOOP_HASH 128
static sfx_t *sfxHash[LOOP_HASH];
cvar_t *s_volume;
cvar_t *s_testsound;
cvar_t *s_khz;
cvar_t *s_show;
cvar_t *s_mixahead;
cvar_t *s_mixPreStep;
cvar_t *s_musicVolume;
cvar_t *s_separation;
cvar_t *s_doppler;
static loopSound_t loopSounds[MAX_GENTITIES];
static channel_t *freelist = NULL;
@ -104,7 +99,7 @@ portable_samplepair_t s_rawsamples[MAX_RAW_SAMPLES];
// ====================================================================
void S_SoundInfo_f(void) {
void S_Base_SoundInfo(void) {
Com_Printf("----- Sound Info -----\n" );
if (!s_soundStarted) {
Com_Printf ("sound system not started\n");
@ -115,7 +110,7 @@ void S_SoundInfo_f(void) {
Com_Printf("%5d submission_chunk\n", dma.submission_chunk);
Com_Printf("%5d speed\n", dma.speed);
Com_Printf("0x%x dma buffer\n", dma.buffer);
if ( s_backgroundFile ) {
if ( s_backgroundStream ) {
Com_Printf("Background file: %s\n", s_backgroundLoop );
} else {
Com_Printf("No background file.\n" );
@ -125,64 +120,37 @@ void S_SoundInfo_f(void) {
Com_Printf("----------------------\n" );
}
/*
================
S_Init
================
=================
S_Base_SoundList
=================
*/
void S_Init( void ) {
cvar_t *cv;
qboolean r;
void S_Base_SoundList( void ) {
int i;
sfx_t *sfx;
int size, total;
char type[4][16];
char mem[2][16];
Com_Printf("\n------- sound initialization -------\n");
s_volume = Cvar_Get ("s_volume", "0.8", CVAR_ARCHIVE);
s_musicVolume = Cvar_Get ("s_musicvolume", "0.25", CVAR_ARCHIVE);
s_separation = Cvar_Get ("s_separation", "0.5", CVAR_ARCHIVE);
s_doppler = Cvar_Get ("s_doppler", "1", CVAR_ARCHIVE);
s_khz = Cvar_Get ("s_khz", "22", CVAR_ARCHIVE);
s_mixahead = Cvar_Get ("s_mixahead", "0.2", CVAR_ARCHIVE);
s_mixPreStep = Cvar_Get ("s_mixPreStep", "0.05", CVAR_ARCHIVE);
s_show = Cvar_Get ("s_show", "0", CVAR_CHEAT);
s_testsound = Cvar_Get ("s_testsound", "0", CVAR_CHEAT);
cv = Cvar_Get ("s_initsound", "1", 0);
if ( !cv->integer ) {
Com_Printf ("not initializing.\n");
Com_Printf("------------------------------------\n");
return;
strcpy(type[0], "16bit");
strcpy(type[1], "adpcm");
strcpy(type[2], "daub4");
strcpy(type[3], "mulaw");
strcpy(mem[0], "paged out");
strcpy(mem[1], "resident ");
total = 0;
for (sfx=s_knownSfx, i=0 ; i<s_numSfx ; i++, sfx++) {
size = sfx->soundLength;
total += size;
Com_Printf("%6i[%s] : %s[%s]\n", size, type[sfx->soundCompressionMethod],
sfx->soundName, mem[sfx->inMemory] );
}
Cmd_AddCommand("play", S_Play_f);
Cmd_AddCommand("music", S_Music_f);
Cmd_AddCommand("s_list", S_SoundList_f);
Cmd_AddCommand("s_info", S_SoundInfo_f);
Cmd_AddCommand("s_stop", S_StopAllSounds);
r = SNDDMA_Init();
Com_Printf("------------------------------------\n");
if ( r ) {
s_soundStarted = 1;
s_soundMuted = 1;
// s_numSfx = 0;
Com_Memset(sfxHash, 0, sizeof(sfx_t *)*LOOP_HASH);
s_soundtime = 0;
s_paintedtime = 0;
S_StopAllSounds ();
S_SoundInfo_f();
}
Com_Printf ("Total resident: %i\n", total);
S_DisplayFreeMemory();
}
void S_ChannelFree(channel_t *v) {
v->thesfx = NULL;
*(channel_t **)v = freelist;
@ -217,25 +185,6 @@ void S_ChannelSetup( void ) {
Com_DPrintf("Channel memory manager started\n");
}
// =======================================================================
// Shutdown sound engine
// =======================================================================
void S_Shutdown( void ) {
if ( !s_soundStarted ) {
return;
}
SNDDMA_Shutdown();
s_soundStarted = 0;
Cmd_RemoveCommand("play");
Cmd_RemoveCommand("music");
Cmd_RemoveCommand("stopsound");
Cmd_RemoveCommand("soundlist");
Cmd_RemoveCommand("soundinfo");
}
// =======================================================================
@ -352,32 +301,11 @@ This is called when the hunk is cleared and the sounds
are no longer valid.
===================
*/
void S_DisableSounds( void ) {
S_StopAllSounds();
void S_Base_DisableSounds( void ) {
S_Base_StopAllSounds();
s_soundMuted = qtrue;
}
/*
=====================
S_BeginRegistration
=====================
*/
void S_BeginRegistration( void ) {
s_soundMuted = qfalse; // we can play again
if (s_numSfx == 0) {
SND_setup();
s_numSfx = 0;
Com_Memset( s_knownSfx, 0, sizeof( s_knownSfx ) );
Com_Memset(sfxHash, 0, sizeof(sfx_t *)*LOOP_HASH);
S_RegisterSound("sound/feedback/hit.wav", qfalse); // changed to a sound in baseq3
}
}
/*
==================
S_RegisterSound
@ -385,7 +313,7 @@ S_RegisterSound
Creates a default buzz sound if the file can't be loaded
==================
*/
sfxHandle_t S_RegisterSound( const char *name, qboolean compressed ) {
sfxHandle_t S_Base_RegisterSound( const char *name, qboolean compressed ) {
sfx_t *sfx;
compressed = qfalse;
@ -420,6 +348,26 @@ sfxHandle_t S_RegisterSound( const char *name, qboolean compressed ) {
return sfx - s_knownSfx;
}
/*
=====================
S_BeginRegistration
=====================
*/
void S_Base_BeginRegistration( void ) {
s_soundMuted = qfalse; // we can play again
if (s_numSfx == 0) {
SND_setup();
s_numSfx = 0;
Com_Memset( s_knownSfx, 0, sizeof( s_knownSfx ) );
Com_Memset(sfxHash, 0, sizeof(sfx_t *)*LOOP_HASH);
S_Base_RegisterSound("sound/feedback/hit.wav", qfalse); // changed to a sound in baseq3
}
}
void S_memoryLoad(sfx_t *sfx) {
// load the sound file
if ( !S_LoadSound ( sfx ) ) {
@ -470,8 +418,6 @@ void S_SpatializeOrigin (vec3_t origin, int master_vol, int *left_vol, int *righ
{
rscale = 0.5 * (1.0 + dot);
lscale = 0.5 * (1.0 - dot);
//rscale = s_separation->value + ( 1.0 - s_separation->value ) * dot;
//lscale = s_separation->value - ( 1.0 - s_separation->value ) * dot;
if ( rscale < 0 ) {
rscale = 0;
}
@ -505,7 +451,7 @@ if pos is NULL, the sound will be dynamically sourced from the entity
Entchannel 0 will never override a playing sound
====================
*/
void S_StartSound(vec3_t origin, int entityNum, int entchannel, sfxHandle_t sfxHandle ) {
void S_Base_StartSound(vec3_t origin, int entityNum, int entchannel, sfxHandle_t sfxHandle ) {
channel_t *ch;
sfx_t *sfx;
int i, oldest, chosen, time;
@ -626,7 +572,7 @@ void S_StartSound(vec3_t origin, int entityNum, int entchannel, sfxHandle_t sfxH
S_StartLocalSound
==================
*/
void S_StartLocalSound( sfxHandle_t sfxHandle, int channelNum ) {
void S_Base_StartLocalSound( sfxHandle_t sfxHandle, int channelNum ) {
if ( !s_soundStarted || s_soundMuted ) {
return;
}
@ -636,7 +582,7 @@ void S_StartLocalSound( sfxHandle_t sfxHandle, int channelNum ) {
return;
}
S_StartSound (NULL, listener_number, channelNum, sfxHandle );
S_Base_StartSound (NULL, listener_number, channelNum, sfxHandle );
}
@ -648,7 +594,7 @@ If we are about to perform file access, clear the buffer
so sound doesn't stutter.
==================
*/
void S_ClearSoundBuffer( void ) {
void S_Base_ClearSoundBuffer( void ) {
int clear;
if (!s_soundStarted)
@ -683,15 +629,15 @@ void S_ClearSoundBuffer( void ) {
S_StopAllSounds
==================
*/
void S_StopAllSounds(void) {
void S_Base_StopAllSounds(void) {
if ( !s_soundStarted ) {
return;
}
// stop the background music
S_StopBackgroundTrack();
S_Base_StopBackgroundTrack();
S_ClearSoundBuffer ();
S_Base_ClearSoundBuffer ();
}
/*
@ -702,7 +648,7 @@ continuous looping sounds are added each frame
==============================================================
*/
void S_StopLoopingSound(int entityNum) {
void S_Base_StopLoopingSound(int entityNum) {
loopSounds[entityNum].active = qfalse;
// loopSounds[entityNum].sfx = 0;
loopSounds[entityNum].kill = qfalse;
@ -714,12 +660,12 @@ S_ClearLoopingSounds
==================
*/
void S_ClearLoopingSounds( qboolean killall ) {
void S_Base_ClearLoopingSounds( qboolean killall ) {
int i;
for ( i = 0 ; i < MAX_GENTITIES ; i++) {
if (killall || loopSounds[i].kill == qtrue || (loopSounds[i].sfx && loopSounds[i].sfx->soundLength == 0)) {
loopSounds[i].kill = qfalse;
S_StopLoopingSound(i);
S_Base_StopLoopingSound(i);
}
}
numLoopChannels = 0;
@ -733,7 +679,7 @@ Called during entity generation for a frame
Include velocity in case I get around to doing doppler...
==================
*/
void S_AddLoopingSound( int entityNum, const vec3_t origin, const vec3_t velocity, sfxHandle_t sfxHandle ) {
void S_Base_AddLoopingSound( int entityNum, const vec3_t origin, const vec3_t velocity, sfxHandle_t sfxHandle ) {
sfx_t *sfx;
if ( !s_soundStarted || s_soundMuted ) {
@ -796,7 +742,7 @@ Called during entity generation for a frame
Include velocity in case I get around to doing doppler...
==================
*/
void S_AddRealLoopingSound( int entityNum, const vec3_t origin, const vec3_t velocity, sfxHandle_t sfxHandle ) {
void S_Base_AddRealLoopingSound( int entityNum, const vec3_t origin, const vec3_t velocity, sfxHandle_t sfxHandle ) {
sfx_t *sfx;
if ( !s_soundStarted || s_soundMuted ) {
@ -947,7 +893,7 @@ S_RawSamples
Music streaming
============
*/
void S_RawSamples( int samples, int rate, int width, int s_channels, const byte *data, float volume ) {
void S_Base_RawSamples( int samples, int rate, int width, int s_channels, const byte *data, float volume ) {
int i;
int src, dst;
float scale;
@ -1051,7 +997,7 @@ S_UpdateEntityPosition
let the sound system know where an entity currently is
======================
*/
void S_UpdateEntityPosition( int entityNum, const vec3_t origin ) {
void S_Base_UpdateEntityPosition( int entityNum, const vec3_t origin ) {
if ( entityNum < 0 || entityNum > MAX_GENTITIES ) {
Com_Error( ERR_DROP, "S_UpdateEntityPosition: bad entitynum %i", entityNum );
}
@ -1066,7 +1012,7 @@ S_Respatialize
Change the volumes of all the playing sounds for changes in their positions
============
*/
void S_Respatialize( int entityNum, const vec3_t head, vec3_t axis[3], int inwater ) {
void S_Base_Respatialize( int entityNum, const vec3_t head, vec3_t axis[3], int inwater ) {
int i;
channel_t *ch;
vec3_t origin;
@ -1151,7 +1097,7 @@ S_Update
Called once each time through the main loop
============
*/
void S_Update( void ) {
void S_Base_Update( void ) {
int i;
int total;
channel_t *ch;
@ -1204,7 +1150,7 @@ void S_GetSoundtime(void)
{ // time to chop things off to avoid 32 bit limits
buffers = 0;
s_paintedtime = fullsamples;
S_StopAllSounds ();
S_Base_StopAllSounds ();
}
}
oldsamplepos = samplepos;
@ -1289,73 +1235,6 @@ void S_Update_(void) {
lastTime = thisTime;
}
/*
===============================================================================
console functions
===============================================================================
*/
void S_Play_f( void ) {
int i;
sfxHandle_t h;
char name[256];
i = 1;
while ( i<Cmd_Argc() ) {
if ( !Q_strrchr(Cmd_Argv(i), '.') ) {
Com_sprintf( name, sizeof(name), "%s.wav", Cmd_Argv(1) );
} else {
Q_strncpyz( name, Cmd_Argv(i), sizeof(name) );
}
h = S_RegisterSound( name, qfalse );
if( h ) {
S_StartLocalSound( h, CHAN_LOCAL_SOUND );
}
i++;
}
}
void S_Music_f( void ) {
int c;
c = Cmd_Argc();
if ( c == 2 ) {
S_StartBackgroundTrack( Cmd_Argv(1), Cmd_Argv(1) );
s_backgroundLoop[0] = 0;
} else if ( c == 3 ) {
S_StartBackgroundTrack( Cmd_Argv(1), Cmd_Argv(2) );
} else {
Com_Printf ("music <musicfile> [loopfile]\n");
return;
}
}
void S_SoundList_f( void ) {
int i;
sfx_t *sfx;
int size, total;
char type[4][16];
char mem[2][16];
strcpy(type[0], "16bit");
strcpy(type[1], "adpcm");
strcpy(type[2], "daub4");
strcpy(type[3], "mulaw");
strcpy(mem[0], "paged out");
strcpy(mem[1], "resident ");
total = 0;
for (sfx=s_knownSfx, i=0 ; i<s_numSfx ; i++, sfx++) {
size = sfx->soundLength;
total += size;
Com_Printf("%6i[%s] : %s[%s]\n", size, type[sfx->soundCompressionMethod], sfx->soundName, mem[sfx->inMemory] );
}
Com_Printf ("Total resident: %i\n", total);
S_DisplayFreeMemory();
}
/*
@ -1366,61 +1245,16 @@ background music functions
===============================================================================
*/
int FGetLittleLong( fileHandle_t f ) {
int v;
FS_Read( &v, sizeof(v), f );
return LittleLong( v);
}
int FGetLittleShort( fileHandle_t f ) {
short v;
FS_Read( &v, sizeof(v), f );
return LittleShort( v);
}
// returns the length of the data in the chunk, or 0 if not found
int S_FindWavChunk( fileHandle_t f, char *chunk ) {
char name[5];
int len;
int r;
name[4] = 0;
len = 0;
r = FS_Read( name, 4, f );
if ( r != 4 ) {
return 0;
}
len = FGetLittleLong( f );
if ( len < 0 || len > 0xfffffff ) {
len = 0;
return 0;
}
len = (len + 1 ) & ~1; // pad to word boundary
// s_nextWavChunk += len + 8;
if ( strcmp( name, chunk ) ) {
return 0;
}
return len;
}
/*
======================
S_StopBackgroundTrack
======================
*/
void S_StopBackgroundTrack( void ) {
if ( !s_backgroundFile ) {
void S_Base_StopBackgroundTrack( void ) {
if(!s_backgroundStream)
return;
}
Sys_EndStreamedFile( s_backgroundFile );
FS_FCloseFile( s_backgroundFile );
s_backgroundFile = 0;
S_CodecCloseStream(s_backgroundStream);
s_backgroundStream = NULL;
s_rawend = 0;
}
@ -1429,11 +1263,7 @@ void S_StopBackgroundTrack( void ) {
S_StartBackgroundTrack
======================
*/
void S_StartBackgroundTrack( const char *intro, const char *loop ){
int len;
char dump[16];
char name[MAX_QPATH];
void S_Base_StartBackgroundTrack( const char *intro, const char *loop ){
if ( !intro ) {
intro = "";
}
@ -1442,77 +1272,34 @@ void S_StartBackgroundTrack( const char *intro, const char *loop ){
}
Com_DPrintf( "S_StartBackgroundTrack( %s, %s )\n", intro, loop );
Q_strncpyz( name, intro, sizeof( name ) - 4 );
COM_DefaultExtension( name, sizeof( name ), ".wav" );
if ( !intro[0] ) {
return;
}
Q_strncpyz( s_backgroundLoop, loop, sizeof( s_backgroundLoop ) );
if( !loop ) {
s_backgroundLoop[0] = 0;
} else {
Q_strncpyz( s_backgroundLoop, loop, sizeof( s_backgroundLoop ) );
}
// close the background track, but DON'T reset s_rawend
// if restarting the same back ground track
if ( s_backgroundFile ) {
Sys_EndStreamedFile( s_backgroundFile );
FS_FCloseFile( s_backgroundFile );
s_backgroundFile = 0;
if(s_backgroundStream)
{
S_CodecCloseStream(s_backgroundStream);
s_backgroundStream = NULL;
}
//
// open up a wav file and get all the info
//
FS_FOpenFileRead( name, &s_backgroundFile, qtrue );
if ( !s_backgroundFile ) {
Com_Printf( S_COLOR_YELLOW "WARNING: couldn't open music file %s\n", name );
// Open stream
s_backgroundStream = S_CodecOpenStream(intro);
if(!s_backgroundStream) {
Com_Printf( S_COLOR_YELLOW "WARNING: couldn't open music file %s\n", intro );
return;
}
// skip the riff wav header
FS_Read(dump, 12, s_backgroundFile);
if ( !S_FindWavChunk( s_backgroundFile, "fmt " ) ) {
Com_Printf( "No fmt chunk in %s\n", name );
FS_FCloseFile( s_backgroundFile );
s_backgroundFile = 0;
return;
if(s_backgroundStream->info.channels != 2 || s_backgroundStream->info.rate != 22050) {
Com_Printf(S_COLOR_YELLOW "WARNING: music file %s is not 22k stereo\n", intro );
}
// save name for soundinfo
s_backgroundInfo.format = FGetLittleShort( s_backgroundFile );
s_backgroundInfo.channels = FGetLittleShort( s_backgroundFile );
s_backgroundInfo.rate = FGetLittleLong( s_backgroundFile );
FGetLittleLong( s_backgroundFile );
FGetLittleShort( s_backgroundFile );
s_backgroundInfo.width = FGetLittleShort( s_backgroundFile ) / 8;
if ( s_backgroundInfo.format != WAV_FORMAT_PCM ) {
FS_FCloseFile( s_backgroundFile );
s_backgroundFile = 0;
Com_Printf("Not a microsoft PCM format wav: %s\n", name);
return;
}
if ( s_backgroundInfo.channels != 2 || s_backgroundInfo.rate != 22050 ) {
Com_Printf(S_COLOR_YELLOW "WARNING: music file %s is not 22k stereo\n", name );
}
if ( ( len = S_FindWavChunk( s_backgroundFile, "data" ) ) == 0 ) {
FS_FCloseFile( s_backgroundFile );
s_backgroundFile = 0;
Com_Printf("No data chunk in %s\n", name);
return;
}
s_backgroundInfo.samples = len / (s_backgroundInfo.width * s_backgroundInfo.channels);
s_backgroundSamples = s_backgroundInfo.samples;
//
// start the background streaming
//
Sys_BeginStreamedFile( s_backgroundFile, 0x10000 );
}
/*
@ -1528,7 +1315,7 @@ void S_UpdateBackgroundTrack( void ) {
int r;
static float musicVolume = 0.5f;
if ( !s_backgroundFile ) {
if(!s_backgroundStream) {
return;
}
@ -1549,50 +1336,47 @@ void S_UpdateBackgroundTrack( void ) {
bufferSamples = MAX_RAW_SAMPLES - (s_rawend - s_soundtime);
// decide how much data needs to be read from the file
fileSamples = bufferSamples * s_backgroundInfo.rate / dma.speed;
// don't try and read past the end of the file
if ( fileSamples > s_backgroundSamples ) {
fileSamples = s_backgroundSamples;
}
fileSamples = bufferSamples * s_backgroundStream->info.rate / dma.speed;
// our max buffer size
fileBytes = fileSamples * (s_backgroundInfo.width * s_backgroundInfo.channels);
fileBytes = fileSamples * (s_backgroundStream->info.width * s_backgroundStream->info.channels);
if ( fileBytes > sizeof(raw) ) {
fileBytes = sizeof(raw);
fileSamples = fileBytes / (s_backgroundInfo.width * s_backgroundInfo.channels);
fileSamples = fileBytes / (s_backgroundStream->info.width * s_backgroundStream->info.channels);
}
r = Sys_StreamedRead( raw, 1, fileBytes, s_backgroundFile );
if ( r != fileBytes ) {
Com_Printf("StreamedRead failure on music track\n");
S_StopBackgroundTrack();
return;
// Read
r = S_CodecReadStream(s_backgroundStream, fileBytes, raw);
if(r < fileBytes)
{
fileBytes = r;
fileSamples = r / (s_backgroundStream->info.width * s_backgroundStream->info.channels);
}
// byte swap if needed
S_ByteSwapRawSamples( fileSamples, s_backgroundInfo.width, s_backgroundInfo.channels, raw );
// add to raw buffer
S_RawSamples( fileSamples, s_backgroundInfo.rate,
s_backgroundInfo.width, s_backgroundInfo.channels, raw, musicVolume );
s_backgroundSamples -= fileSamples;
if ( !s_backgroundSamples ) {
if(r > 0)
{
// add to raw buffer
S_Base_RawSamples( fileSamples, s_backgroundStream->info.rate,
s_backgroundStream->info.width, s_backgroundStream->info.channels, raw, musicVolume );
}
else
{
// loop
if (s_backgroundLoop[0]) {
Sys_EndStreamedFile( s_backgroundFile );
FS_FCloseFile( s_backgroundFile );
s_backgroundFile = 0;
S_StartBackgroundTrack( s_backgroundLoop, s_backgroundLoop );
if ( !s_backgroundFile ) {
return; // loop failed to restart
}
} else {
s_backgroundFile = 0;
if(s_backgroundLoop[0])
{
S_CodecCloseStream(s_backgroundStream);
s_backgroundStream = NULL;
S_Base_StartBackgroundTrack( s_backgroundLoop, s_backgroundLoop );
if(!s_backgroundStream)
return;
}
else
{
S_Base_StopBackgroundTrack();
return;
}
}
}
}
@ -1632,3 +1416,78 @@ void S_FreeOldestSound( void ) {
sfx->inMemory = qfalse;
sfx->soundData = NULL;
}
// =======================================================================
// Shutdown sound engine
// =======================================================================
void S_Base_Shutdown( void ) {
if ( !s_soundStarted ) {
return;
}
SNDDMA_Shutdown();
s_soundStarted = 0;
Cmd_RemoveCommand("s_info");
}
/*
================
S_Init
================
*/
qboolean S_Base_Init( soundInterface_t *si ) {
qboolean r;
if( !si ) {
return qfalse;
}
s_khz = Cvar_Get ("s_khz", "22", CVAR_ARCHIVE);
s_mixahead = Cvar_Get ("s_mixahead", "0.2", CVAR_ARCHIVE);
s_mixPreStep = Cvar_Get ("s_mixPreStep", "0.05", CVAR_ARCHIVE);
s_show = Cvar_Get ("s_show", "0", CVAR_CHEAT);
s_testsound = Cvar_Get ("s_testsound", "0", CVAR_CHEAT);
r = SNDDMA_Init();
if ( r ) {
s_soundStarted = 1;
s_soundMuted = 1;
// s_numSfx = 0;
Com_Memset(sfxHash, 0, sizeof(sfx_t *)*LOOP_HASH);
s_soundtime = 0;
s_paintedtime = 0;
S_Base_StopAllSounds( );
} else {
return qfalse;
}
si->Shutdown = S_Base_Shutdown;
si->StartSound = S_Base_StartSound;
si->StartLocalSound = S_Base_StartLocalSound;
si->StartBackgroundTrack = S_Base_StartBackgroundTrack;
si->StopBackgroundTrack = S_Base_StopBackgroundTrack;
si->RawSamples = S_Base_RawSamples;
si->StopAllSounds = S_Base_StopAllSounds;
si->ClearLoopingSounds = S_Base_ClearLoopingSounds;
si->AddLoopingSound = S_Base_AddLoopingSound;
si->AddRealLoopingSound = S_Base_AddRealLoopingSound;
si->StopLoopingSound = S_Base_StopLoopingSound;
si->Respatialize = S_Base_Respatialize;
si->UpdateEntityPosition = S_Base_UpdateEntityPosition;
si->Update = S_Base_Update;
si->DisableSounds = S_Base_DisableSounds;
si->BeginRegistration = S_Base_BeginRegistration;
si->RegisterSound = S_Base_RegisterSound;
si->ClearSoundBuffer = S_Base_ClearSoundBuffer;
si->SoundInfo = S_Base_SoundInfo;
si->SoundList = S_Base_SoundList;
return qtrue;
}