diff options
Diffstat (limited to 'source/snd_main.c')
-rw-r--r-- | source/snd_main.c | 302 |
1 files changed, 180 insertions, 122 deletions
diff --git a/source/snd_main.c b/source/snd_main.c index 9930967..1c60fc4 100644 --- a/source/snd_main.c +++ b/source/snd_main.c @@ -26,16 +26,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Internal sound data & structures // ======================================================================= -// only begin attenuating sound volumes when outside the FULLVOLUME range -#define SOUND_FULLVOLUME 80 - -#define SOUND_LOOPATTENUATE 0.003 - int s_registration_sequence; channel_t channels[MAX_CHANNELS]; -qboolean sound_started; +sndstarted_t s_started; dma_t dma; @@ -67,16 +62,16 @@ static int s_beginofs; cvar_t *s_khz; cvar_t *s_volume; cvar_t *s_testsound; +cvar_t *s_ambient; +cvar_t *s_show; static cvar_t *s_enable; #if USE_DSOUND static cvar_t *s_direct; #endif #ifdef _DEBUG -static cvar_t *s_show; #endif static cvar_t *s_mixahead; -static cvar_t *s_ambient; void WAVE_FillAPI( snddmaAPI_t *api ); @@ -84,6 +79,8 @@ void WAVE_FillAPI( snddmaAPI_t *api ); void DS_FillAPI( snddmaAPI_t *api ); #endif +static void S_ClearBuffer (void); + snddmaAPI_t snddma; /* @@ -93,18 +90,25 @@ console functions */ static void S_SoundInfo_f( void ) { - if( !sound_started ) { + if( !s_started ) { Com_Printf( "Sound system not started.\n" ); return; } + +#if USE_OPENAL + if( s_started == SS_OAL ) { + AL_SoundInfo(); + return; + } +#endif - Com_Printf( "%5d stereo\n", dma.channels - 1 ); + Com_Printf( "%5d channels\n", dma.channels ); Com_Printf( "%5d samples\n", dma.samples ); Com_Printf( "%5d samplepos\n", dma.samplepos ); Com_Printf( "%5d samplebits\n", dma.samplebits ); Com_Printf( "%5d submission_chunk\n", dma.submission_chunk ); Com_Printf( "%5d speed\n", dma.speed ); - Com_Printf( "0x%p dma buffer\n", dma.buffer ); + Com_Printf( "%p dma buffer\n", dma.buffer ); } @@ -120,7 +124,12 @@ static void S_SoundList_f( void ) { continue; sc = sfx->cache; if( sc ) { - size = sc->length * sc->width; +#if USE_OPENAL + if( s_started == SS_OAL ) + size = sc->size; + else +#endif + size = sc->length * sc->width; total += size; if( sc->loopstart >= 0 ) Com_Printf( "L" ); @@ -161,50 +170,62 @@ void S_Init( void ) { Com_Printf( "------- S_Init -------\n" ); - s_khz = Cvar_Get( "s_khz", "22", CVAR_ARCHIVE|CVAR_SOUND ); +#if USE_OPENAL + if( s_enable->integer > 1 ) { + if( !AL_Init() ) { + Cvar_Set( "s_enable", "1" ); + } else + s_started = SS_OAL; + + } + if( !s_started ) +#endif + { + s_khz = Cvar_Get( "s_khz", "22", CVAR_ARCHIVE|CVAR_SOUND ); + s_mixahead = Cvar_Get( "s_mixahead", "0.2", CVAR_ARCHIVE ); + s_testsound = Cvar_Get( "s_testsound", "0", 0 ); #if USE_DSOUND - s_direct = Cvar_Get( "s_direct", "1", CVAR_ARCHIVE|CVAR_SOUND ); - if( s_direct->integer ) { - DS_FillAPI( &snddma ); - ret = snddma.Init(); - if( ret != SIS_SUCCESS ) { - Cvar_Set( "s_direct", "0" ); + s_direct = Cvar_Get( "s_direct", "1", CVAR_ARCHIVE|CVAR_SOUND ); + if( s_direct->integer ) { + DS_FillAPI( &snddma ); + ret = snddma.Init(); + if( ret != SIS_SUCCESS ) { + Cvar_Set( "s_direct", "0" ); + } } - } #endif - if( ret != SIS_SUCCESS ) { - WAVE_FillAPI( &snddma ); - ret = snddma.Init(); if( ret != SIS_SUCCESS ) { - Cvar_Set( "s_enable", "0" ); - return; + WAVE_FillAPI( &snddma ); + ret = snddma.Init(); + if( ret != SIS_SUCCESS ) { + Cvar_Set( "s_enable", "0" ); + return; + } } + + S_ClearBuffer(); + + Com_Printf( "sound sampling rate: %i\n", dma.speed ); + s_started = SS_DMA; } s_volume = Cvar_Get( "s_volume", "0.7", CVAR_ARCHIVE ); - s_mixahead = Cvar_Get( "s_mixahead", "0.2", CVAR_ARCHIVE ); #ifdef _DEBUG s_show = Cvar_Get( "s_show", "0", 0 ); #endif - s_testsound = Cvar_Get( "s_testsound", "0", 0 ); s_ambient = Cvar_Get( "s_ambient", "1", 0 ); Cmd_Register( c_sound ); S_InitScaletable(); - sound_started = qtrue; num_sfx = 0; paintedtime = 0; s_registration_sequence = 1; - Com_Printf( "sound sampling rate: %i\n", dma.speed ); - - S_StopAllSounds(); - Com_Printf( "----------------------\n" ); } @@ -213,6 +234,18 @@ void S_Init( void ) { // Shutdown sound engine // ======================================================================= +static void S_FreeSound( sfx_t *sfx ) { +#if USE_OPENAL + if( s_started == SS_OAL ) + AL_DeleteSfx( sfx ); +#endif + if( sfx->cache ) + Z_Free( sfx->cache ); + if( sfx->truename ) + Z_Free( sfx->truename ); + memset( sfx, 0, sizeof( *sfx ) ); +} + void S_FreeAllSounds( void ) { int i; sfx_t *sfx; @@ -221,38 +254,35 @@ void S_FreeAllSounds( void ) { for( i = 0, sfx = known_sfx; i < num_sfx; i++, sfx++ ) { if( !sfx->name[0] ) continue; - if( sfx->cache ) - Z_Free( sfx->cache ); - if( sfx->truename ) - Z_Free( sfx->truename ); - memset( sfx, 0, sizeof( *sfx ) ); + S_FreeSound( sfx ); } num_sfx = 0; } void S_Shutdown( void ) { - if( !sound_started ) + if( !s_started ) return; - snddma.Shutdown(); - - sound_started = qfalse; + S_StopAllSounds(); + S_FreeAllSounds(); -#if USE_DSOUND - s_direct->changed = NULL; +#if USE_OPENAL + if( s_started == SS_OAL ) + AL_Shutdown(); + else #endif - s_khz->changed = NULL; + snddma.Shutdown(); - Cmd_Deregister( c_sound ); + s_started = SS_NOT; - S_FreeAllSounds(); + Cmd_Deregister( c_sound ); Z_LeakTest( TAG_SOUND ); } void S_Activate( void ) { - if( sound_started && snddma.Activate ) { + if( s_started == SS_DMA && snddma.Activate ) { S_StopAllSounds(); snddma.Activate( cls.active == ACT_ACTIVATED ? qtrue : qfalse ); } @@ -268,7 +298,7 @@ void S_Activate( void ) { S_SfxForHandle ================== */ -static sfx_t *S_SfxForHandle( qhandle_t hSfx ) { +sfx_t *S_SfxForHandle( qhandle_t hSfx ) { if( !hSfx ) { return NULL; } @@ -353,7 +383,7 @@ S_RegisterSound qhandle_t S_RegisterSound( const char *name ) { sfx_t *sfx; - if( !sound_started ) + if( !s_started ) return 0; sfx = S_FindName( name ); @@ -389,18 +419,18 @@ void S_EndRegistration( void ) { continue; if( sfx->registration_sequence != s_registration_sequence ) { // don't need this sound - if( sfx->cache ) // it is possible to have a leftover - Z_Free( sfx->cache ); // from a server that didn't finish loading - if( sfx->truename ) - Z_Free( sfx->truename ); - memset( sfx, 0, sizeof( *sfx ) ); - } else { - // make sure it is paged in - sc = sfx->cache; - if( sc ) { - size = sc->length * sc->width; - Com_PageInMemory( sc, size ); - } + S_FreeSound( sfx ); + continue; + } +#if USE_OPENAL + if( s_started == SS_OAL ) + continue; +#endif + // make sure it is paged in + sc = sfx->cache; + if( sc ) { + size = sc->length * sc->width; + Com_PageInMemory( sc, size ); } } @@ -424,7 +454,7 @@ S_PickChannel picks a channel based on priorities, empty slots, number of channels ================= */ -static channel_t *S_PickChannel( int entnum, int entchannel ) { +channel_t *S_PickChannel( int entnum, int entchannel ) { int ch_idx; int first_to_die; int life_left; @@ -462,6 +492,10 @@ static channel_t *S_PickChannel( int entnum, int entchannel ) { return NULL; ch = &channels[first_to_die]; +#if USE_OPENAL + if( s_started == SS_OAL && ch->sfx ) + AL_StopChannel( ch ); +#endif memset( ch, 0, sizeof( *ch ) ); return ch; @@ -474,7 +508,7 @@ S_SpatializeOrigin Used for spatializing channels and autosounds ================= */ -void S_SpatializeOrigin( const vec3_t origin, float master_vol, float dist_mult, int *left_vol, int *right_vol ) { +static void S_SpatializeOrigin( const vec3_t origin, float master_vol, float dist_mult, int *left_vol, int *right_vol ) { vec_t dot; vec_t dist; vec_t lscale, rscale, scale; @@ -505,6 +539,8 @@ void S_SpatializeOrigin( const vec3_t origin, float master_vol, float dist_mult, lscale = 0.5 * ( 1.0 - dot ); } + master_vol *= 255.0; + // add in distance effect scale = ( 1.0 - dist ) * rscale; *right_vol = (int)( master_vol * scale ); @@ -522,13 +558,13 @@ void S_SpatializeOrigin( const vec3_t origin, float master_vol, float dist_mult, S_Spatialize ================= */ -void S_Spatialize( channel_t *ch ) { +static void S_Spatialize( channel_t *ch ) { vec3_t origin; // anything coming from the view entity will always be full volume if( ch->entnum == -1 || ch->entnum == listener_entnum ) { - ch->leftvol = ch->master_vol; - ch->rightvol = ch->master_vol; + ch->leftvol = ch->master_vol * 255; + ch->rightvol = ch->master_vol * 255; return; } @@ -624,7 +660,12 @@ void S_IssuePlaysound( playsound_t *ps ) { VectorCopy( ps->origin, ch->origin ); ch->fixed_origin = ps->fixed_origin; - S_Spatialize( ch ); +#if USE_OPENAL + if( s_started == SS_OAL ) + AL_PlayChannel( ch ); + else +#endif + S_Spatialize( ch ); ch->pos = 0; ch->end = paintedtime + sc->length; @@ -678,6 +719,24 @@ static sfx_t *S_RegisterSexedSound( int entnum, const char *base ) { // Start a sound effect // ======================================================================= +static int S_DriftBeginofs( float timeofs ) { + int start; + + // drift s_beginofs + start = cl.servertime * 0.001 * dma.speed + s_beginofs; + if( start < paintedtime ) { + start = paintedtime; + s_beginofs = start - ( cl.servertime * 0.001 * dma.speed ); + } else if ( start > paintedtime + 0.3 * dma.speed ) { + start = paintedtime + 0.1 * dma.speed; + s_beginofs = start - ( cl.servertime * 0.001 * dma.speed ); + } else { + s_beginofs -= 10; + } + + return timeofs ? start + timeofs * dma.speed : paintedtime; +} + /* ==================== S_StartSound @@ -687,14 +746,12 @@ if pos is NULL, the sound will be dynamically sourced from the entity Entchannel 0 will never override a playing sound ==================== */ -void S_StartSound( const vec3_t origin, int entnum, int entchannel, qhandle_t hSfx, float fvol, float attenuation, float timeofs ) { +void S_StartSound( const vec3_t origin, int entnum, int entchannel, qhandle_t hSfx, float vol, float attenuation, float timeofs ) { sfxcache_t *sc; - int vol; playsound_t *ps, *sort; - int start; sfx_t *sfx; - if( !sound_started ) + if( !s_started ) return; if( !( sfx = S_SfxForHandle( hSfx ) ) ) { @@ -710,8 +767,6 @@ void S_StartSound( const vec3_t origin, int entnum, int entchannel, qhandle_t hS if( !sc ) return; // couldn't load the sound's data - vol = fvol*255; - // make the playsound_t ps = S_AllocPlaysound(); if( !ps ) @@ -730,22 +785,12 @@ void S_StartSound( const vec3_t origin, int entnum, int entchannel, qhandle_t hS ps->volume = vol; ps->sfx = sfx; - // drift s_beginofs - start = cl.servertime * 0.001 * dma.speed + s_beginofs; - if( start < paintedtime ) { - start = paintedtime; - s_beginofs = start - ( cl.servertime * 0.001 * dma.speed ); - } else if ( start > paintedtime + 0.3 * dma.speed ) { - start = paintedtime + 0.1 * dma.speed; - s_beginofs = start - ( cl.servertime * 0.001 * dma.speed ); - } else { - s_beginofs -= 10; - } - - if( !timeofs ) - ps->begin = paintedtime; +#if USE_OPENAL + if( s_started == SS_OAL ) + ps->begin = paintedtime + timeofs * 1000; else - ps->begin = start + timeofs * dma.speed; +#endif + ps->begin = S_DriftBeginofs( timeofs ); // sort into the pending sound list for( sort = s_pendingplays.next ; sort != &s_pendingplays && sort->begin < ps->begin ; sort = sort->next ) @@ -765,14 +810,14 @@ S_StartLocalSound ================== */ void S_StartLocalSound( const char *sound ) { - if( sound_started ) { + if( s_started ) { qhandle_t sfx = S_RegisterSound( sound ); S_StartSound( NULL, listener_entnum, 0, sfx, 1, 1, 0 ); } } void S_StartLocalSound_( const char *sound ) { - if( sound_started ) { + if( s_started ) { qhandle_t sfx = S_RegisterSound( sound ); S_StartSound( NULL, listener_entnum, 256, sfx, 1, 1, 0 ); } @@ -784,11 +829,11 @@ void S_StartLocalSound_( const char *sound ) { S_ClearBuffer ================== */ -void S_ClearBuffer (void) +static void S_ClearBuffer (void) { int clear; - - if (!sound_started) + + if (s_started != SS_DMA) return; if (dma.samplebits == 8) @@ -811,7 +856,7 @@ void S_StopAllSounds(void) { int i; - if (!sound_started) + if (!s_started) return; // clear all the playsounds @@ -827,12 +872,35 @@ void S_StopAllSounds(void) s_playsounds[i].next->prev = &s_playsounds[i]; } +#if USE_OPENAL + if( s_started == SS_OAL ) + AL_StopAllChannels(); +#endif + // clear all the channels memset(channels, 0, sizeof(channels)); S_ClearBuffer (); } +void S_BuildSoundList( int *sounds ) { + int i; + int num; + entity_state_t *ent; + + for( i = 0; i < cl.frame.numEntities; i++ ) { + num = ( cl.frame.firstEntity + i ) & PARSE_ENTITIES_MASK; + ent = &cl.entityStates[num]; + if( s_ambient->integer == 2 && !ent->modelindex ) { + sounds[i] = 0; + } else if( s_ambient->integer == 3 && ent->number != listener_entnum ) { + sounds[i] = 0; + } else { + sounds[i] = ent->sound; + } + } +} + /* ================== S_AddLoopSounds @@ -854,27 +922,11 @@ static void S_AddLoopSounds (void) entity_state_t *ent; centity_t *cent; - if( sv_paused->integer ) { - return; - } - if( cls.state != ca_active ) { - return; - } - if( !s_ambient->integer ) { + if( cls.state != ca_active || sv_paused->integer || !s_ambient->integer ) { return; } - for( i = 0; i < cl.frame.numEntities; i++ ) { - num = ( cl.frame.firstEntity + i ) & PARSE_ENTITIES_MASK; - ent = &cl.entityStates[num]; - if( s_ambient->integer == 2 && !ent->modelindex ) { - sounds[i] = 0; - } else if( s_ambient->integer == 3 && ent->number != listener_entnum ) { - sounds[i] = 0; - } else { - sounds[i] = ent->sound; - } - } + S_BuildSoundList( sounds ); for( i = 0; i < cl.frame.numEntities; i++ ) { if (!sounds[i]) @@ -892,7 +944,7 @@ static void S_AddLoopSounds (void) cent = &cl_entities[ent->number]; // find the total contribution of all sounds of this type - S_SpatializeOrigin (cent->lerp_origin, 255.0, SOUND_LOOPATTENUATE, + S_SpatializeOrigin (cent->lerp_origin, 1.0, SOUND_LOOPATTENUATE, &left_total, &right_total); for (j=i+1 ; j<cl.frame.numEntities ; j++) { @@ -904,7 +956,7 @@ static void S_AddLoopSounds (void) ent = &cl.entityStates[num]; cent = &cl_entities[ent->number]; - S_SpatializeOrigin (cent->lerp_origin, 255.0, SOUND_LOOPATTENUATE, + S_SpatializeOrigin (cent->lerp_origin, 1.0, SOUND_LOOPATTENUATE, &left, &right); left_total += left; right_total += right; @@ -1008,22 +1060,17 @@ void S_Update( void ) { return; } - if (!sound_started) + if (!s_started) return; // if the laoding plaque is up, clear everything // out to make sure we aren't looping a dirty // dma buffer while loading - if (cls.state == ca_loading ) - { - /* S_ClearBuffer should be already done in S_StopAllSounds */ + if (cls.state == ca_loading) { + // S_ClearBuffer should be already done in S_StopAllSounds return; } - // rebuild scale tables if volume is modified - if (s_volume->modified) - S_InitScaletable (); - // set listener entity number // other parameters should be already set up by CL_CalcViewValues if( cl.clientNum == -1 || cl.frame.clientNum == CLIENTNUM_NONE ) { @@ -1032,6 +1079,17 @@ void S_Update( void ) { listener_entnum = cl.frame.clientNum + 1; } +#if USE_OPENAL + if( s_started == SS_OAL ) { + AL_Update(); + return; + } +#endif + + // rebuild scale tables if volume is modified + if (s_volume->modified) + S_InitScaletable (); + // update spatialization for dynamic sounds ch = channels; for (i=0 ; i<MAX_CHANNELS; i++, ch++) |