diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/qal_api.c | 4 | ||||
-rw-r--r-- | source/qal_api.h | 1 | ||||
-rw-r--r-- | source/snd_al.c | 85 | ||||
-rw-r--r-- | source/snd_dma.c | 3 | ||||
-rw-r--r-- | source/snd_local.h | 1 | ||||
-rw-r--r-- | source/snd_main.c | 7 | ||||
-rw-r--r-- | source/snd_mem.c | 27 | ||||
-rw-r--r-- | source/snd_mix.c | 2 |
8 files changed, 79 insertions, 51 deletions
diff --git a/source/qal_api.c b/source/qal_api.c index c2f53e7..eb62ea4 100644 --- a/source/qal_api.c +++ b/source/qal_api.c @@ -46,6 +46,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. QAL( LPALCCAPTURESAMPLES, alcCaptureSamples ); static cvar_t *al_driver; +static cvar_t *al_device; static void *handle; static ALCdevice *device; @@ -81,6 +82,7 @@ QAL_IMP qboolean QAL_Init( void ) { al_driver = Cvar_Get( "al_driver", DEFAULT_OPENAL_DRIVER, 0 ); + al_device = Cvar_Get( "al_device", "", 0 ); Sys_LoadLibrary( al_driver->string, NULL, &handle ); if( !handle ) { @@ -93,7 +95,7 @@ QAL_IMP #undef QAL Com_DPrintf( "...opening OpenAL device: " ); - device = qalcOpenDevice( NULL ); + device = qalcOpenDevice( al_device->string[0] ? al_device->string : NULL ); if( !device ) { goto fail; } diff --git a/source/qal_api.h b/source/qal_api.h index 74c8c51..4a1896e 100644 --- a/source/qal_api.h +++ b/source/qal_api.h @@ -18,6 +18,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#define AL_NO_PROTOTYPES #include <AL/al.h> #define QAL_IMP \ diff --git a/source/snd_al.c b/source/snd_al.c index 20f5afa..66c169b 100644 --- a/source/snd_al.c +++ b/source/snd_al.c @@ -23,7 +23,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "qal_api.h" // translates from AL coordinate system to quake -#define OAL_POS3f(v) -v[1], v[2], -v[0] +#define AL_UnpackVector(v) -v[1],v[2],-v[0] +#define AL_CopyVector(a,b) ((b)[0]=-(a)[1],(b)[1]=(a)[2],(b)[2]=-(a)[0]) + +// OpenAL implementation should support at least this number of sources +#define MIN_CHANNELS 16 static ALuint s_srcnums[MAX_CHANNELS]; static int s_framecount; @@ -33,37 +37,55 @@ void AL_SoundInfo( void ) { Com_Printf( "AL_RENDERER: %s\n", qalGetString( AL_RENDERER ) ); Com_Printf( "AL_VERSION: %s\n", qalGetString( AL_VERSION ) ); Com_Printf( "AL_EXTENSIONS: %s\n", qalGetString( AL_EXTENSIONS ) ); -} - -static void AL_ShowError( const char *func ) { - ALenum err; - - if( ( err = qalGetError() ) != AL_NO_ERROR ) { - Com_EPrintf( "%s: %s\n", func, qalGetString( err ) ); - } + Com_Printf( "Number of sources: %d\n", s_numchannels ); } qboolean AL_Init( void ) { + int i; + if( !QAL_Init() ) { Com_EPrintf( "OpenAL failed to initialize.\n" ); return qfalse; } + // check for linear distance extension + if( !qalIsExtensionPresent( "AL_EXT_LINEAR_DISTANCE" ) ) { + Com_EPrintf( "Required AL_EXT_LINEAR_DISTANCE extension is missing.\n" ); + goto fail; + } + // generate source names - qalGenSources( MAX_CHANNELS, s_srcnums ); - AL_ShowError( __func__ ); + qalGetError(); + for( i = 0; i < MAX_CHANNELS; i++ ) { + qalGenSources( 1, &s_srcnums[i] ); + if( qalGetError() != AL_NO_ERROR ) { + break; + } + } + + if( i < MIN_CHANNELS ) { + Com_EPrintf( "Required at least %d sources, but got %d.\n", MIN_CHANNELS, i ); + goto fail; + } + + s_numchannels = i; Com_Printf( "OpenAL initialized.\n" ); return qtrue; + +fail: + QAL_Shutdown(); + return qfalse; } void AL_Shutdown( void ) { Com_Printf( "Shutting down OpenAL.\n" ); - if( s_srcnums[0] ) { + if( s_numchannels ) { // delete source names - qalDeleteSources( MAX_CHANNELS, s_srcnums ); + qalDeleteSources( s_numchannels, s_srcnums ); memset( s_srcnums, 0, sizeof( s_srcnums ) ); + s_numchannels = 0; } QAL_Shutdown(); @@ -76,12 +98,17 @@ sfxcache_t *AL_UploadSfx( sfx_t *s ) { ALuint name; if( !size ) { + s->error = Q_ERR_TOO_FEW; return NULL; } + qalGetError(); qalGenBuffers( 1, &name ); qalBufferData( name, format, s_info.data, size, s_info.rate ); - AL_ShowError( __func__ ); + if( qalGetError() != AL_NO_ERROR ) { + s->error = Q_ERR_LIBRARY_ERROR; + return NULL; + } // allocate placeholder sfxcache sc = s->cache = S_Malloc( sizeof( *sc ) ); @@ -120,7 +147,7 @@ static void AL_Spatialize( channel_t *ch ) { CL_GetEntitySoundOrigin( ch->entnum, origin ); } - qalSource3f( ch->srcnum, AL_POSITION, OAL_POS3f( origin ) ); + qalSource3f( ch->srcnum, AL_POSITION, AL_UnpackVector( origin ) ); } void AL_StopChannel( channel_t *ch ) { @@ -132,7 +159,6 @@ void AL_StopChannel( channel_t *ch ) { // stop it qalSourceStop( ch->srcnum ); qalSourcei( ch->srcnum, AL_BUFFER, AL_NONE ); - AL_ShowError( __func__ ); memset (ch, 0, sizeof(*ch)); } @@ -145,6 +171,7 @@ void AL_PlayChannel( channel_t *ch ) { #endif ch->srcnum = s_srcnums[ch - channels]; + qalGetError(); qalSourcei( ch->srcnum, AL_BUFFER, sc->bufnum ); //qalSourcei( ch->srcnum, AL_LOOPING, sc->loopstart == -1 ? AL_FALSE : AL_TRUE ); qalSourcei( ch->srcnum, AL_LOOPING, ch->autosound ? AL_TRUE : AL_FALSE ); @@ -157,7 +184,9 @@ void AL_PlayChannel( channel_t *ch ) { // play it qalSourcePlay( ch->srcnum ); - AL_ShowError( __func__ ); + if( qalGetError() != AL_NO_ERROR ) { + AL_StopChannel( ch ); + } } static void AL_IssuePlaysounds( void ) { @@ -179,7 +208,7 @@ void AL_StopAllChannels( void ) { channel_t *ch; ch = channels; - for( i = 0; i < MAX_CHANNELS; i++, ch++ ) { + for( i = 0; i < s_numchannels; i++, ch++ ) { if (!ch->sfx) continue; AL_StopChannel( ch ); @@ -191,7 +220,7 @@ static channel_t *AL_FindLoopingSound( int entnum, sfx_t *sfx ) { channel_t *ch; ch = channels; - for( i = 0; i < MAX_CHANNELS; i++, ch++ ) { + for( i = 0; i < s_numchannels; i++, ch++ ) { if( !ch->sfx ) continue; if( !ch->autosound ) @@ -202,6 +231,7 @@ static channel_t *AL_FindLoopingSound( int entnum, sfx_t *sfx ) { continue; return ch; } + return NULL; } @@ -269,20 +299,17 @@ void AL_Update( void ) { paintedtime = cl.time; - qalListener3f( AL_POSITION, OAL_POS3f( listener_origin ) ); - orientation[0] = -listener_forward[1]; - orientation[1] = listener_forward[2]; - orientation[2] = -listener_forward[0]; - orientation[3] = -listener_up[1]; - orientation[4] = listener_up[2]; - orientation[5] = -listener_up[0]; + // set listener parameters + qalListener3f( AL_POSITION, AL_UnpackVector( listener_origin ) ); + AL_CopyVector( listener_forward, orientation ); + AL_CopyVector( listener_up, orientation + 3 ); qalListenerfv( AL_ORIENTATION, orientation ); qalListenerf( AL_GAIN, s_volume->value ); qalDistanceModel( AL_LINEAR_DISTANCE_CLAMPED ); // update spatialization for dynamic sounds ch = channels; - for( i = 0; i < MAX_CHANNELS; i++, ch++ ) { + for( i = 0; i < s_numchannels; i++, ch++ ) { if( !ch->sfx ) continue; @@ -295,9 +322,9 @@ void AL_Update( void ) { } else { ALenum state; + qalGetError(); qalGetSourcei( ch->srcnum, AL_SOURCE_STATE, &state ); - AL_ShowError( __func__ ); - if( state == AL_STOPPED ) { + if( qalGetError() != AL_NO_ERROR || state == AL_STOPPED ) { AL_StopChannel( ch ); continue; } diff --git a/source/snd_dma.c b/source/snd_dma.c index 3e9bc6f..6ef4d00 100644 --- a/source/snd_dma.c +++ b/source/snd_dma.c @@ -76,6 +76,8 @@ qboolean DMA_Init( void ) { S_InitScaletable(); + s_numchannels = MAX_CHANNELS; + Com_Printf( "sound sampling rate: %i\n", dma.speed ); return qtrue; @@ -83,6 +85,7 @@ qboolean DMA_Init( void ) { void DMA_Shutdown( void ) { snddma.Shutdown(); + s_numchannels = 0; } void DMA_Activate( void ) { diff --git a/source/snd_local.h b/source/snd_local.h index b0e72fa..3ff7685 100644 --- a/source/snd_local.h +++ b/source/snd_local.h @@ -166,6 +166,7 @@ extern sndstarted_t s_started; #define MAX_CHANNELS 32 extern channel_t channels[MAX_CHANNELS]; +extern int s_numchannels; extern int paintedtime; extern playsound_t s_pendingplays; diff --git a/source/snd_main.c b/source/snd_main.c index 29e739b..adde37b 100644 --- a/source/snd_main.c +++ b/source/snd_main.c @@ -29,6 +29,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. int s_registration_sequence; channel_t channels[MAX_CHANNELS]; +int s_numchannels; sndstarted_t s_started; @@ -483,7 +484,7 @@ channel_t *S_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 = 0; ch_idx < MAX_CHANNELS; ch_idx++ ) { + for( ch_idx = 0; ch_idx < s_numchannels; ch_idx++ ) { ch = &channels[ch_idx]; // channel 0 never overrides unless out of channels if( ch->entnum == entnum && ch->entchannel == entchannel && entchannel != 0 ) { @@ -987,7 +988,7 @@ void S_Update( void ) { // update spatialization for dynamic sounds ch = channels; - for (i=0 ; i<MAX_CHANNELS; i++, ch++) + for (i=0 ; i<s_numchannels; i++, ch++) { if (!ch->sfx) continue; @@ -1015,7 +1016,7 @@ void S_Update( void ) { { int total = 0; ch = channels; - for (i=0 ; i<MAX_CHANNELS; i++, ch++) + for (i=0 ; i<s_numchannels; i++, ch++) if (ch->sfx && (ch->leftvol || ch->rightvol) ) { Com_Printf ("%3i %3i %s\n", ch->leftvol, ch->rightvol, ch->sfx->name); diff --git a/source/snd_mem.c b/source/snd_mem.c index a884f07..54656f5 100644 --- a/source/snd_mem.c +++ b/source/snd_mem.c @@ -43,6 +43,7 @@ static sfxcache_t *ResampleSfx( sfx_t *sfx ) { outcount = s_info.samples / stepscale; if( !outcount ) { Com_DPrintf( "%s resampled to zero length\n", s_info.name ); + sfx->error = Q_ERR_TOO_FEW; return NULL; } @@ -307,7 +308,6 @@ sfxcache_t *S_LoadSound (sfx_t *s) { sfxcache_t *sc; size_t len; char *name; - qerror_t ret; if (s->name[0] == '*') return NULL; @@ -332,14 +332,14 @@ sfxcache_t *S_LoadSound (sfx_t *s) { else len = Q_concat( namebuffer, sizeof( namebuffer ), "sound/", name, NULL ); if( len >= sizeof( namebuffer ) ) { - ret = Q_ERR_NAMETOOLONG; - goto fail1; + s->error = Q_ERR_NAMETOOLONG; + return NULL; } len = FS_LoadFile (namebuffer, (void **)&data); if (!data) { - ret = len; - goto fail1; + s->error = len; + return NULL; } memset( &s_info, 0, sizeof( s_info ) ); @@ -348,29 +348,22 @@ sfxcache_t *S_LoadSound (sfx_t *s) { iff_data = data; iff_end = data + len; if( !GetWavinfo() ) { - ret = Q_ERR_INVALID_FORMAT; - goto fail2; + s->error = Q_ERR_INVALID_FORMAT; + goto fail; } #if USE_OPENAL - if( s_started == SS_OAL ) + if( s_started == SS_OAL ) { sc = AL_UploadSfx( s ); - else + } else #endif #if USE_SNDDMA sc = ResampleSfx( s ) #endif ; - ret = Q_ERR_SUCCESS; -fail2: +fail: FS_FreeFile( data ); -fail1: - // don't spam about missing or invalid sounds (action mod hack) - if( ret && ret != Q_ERR_NOENT && ret != Q_ERR_INVALID_FORMAT ) { - Com_EPrintf( "Couldn't load %s: %s\n", namebuffer, Q_ErrorString( ret ) ); - } - s->error = ret; return sc; } diff --git a/source/snd_mix.c b/source/snd_mix.c index d8aa204..4192163 100644 --- a/source/snd_mix.c +++ b/source/snd_mix.c @@ -205,7 +205,7 @@ void S_PaintChannels(int endtime) { // paint in the channels. ch = channels; - for (i=0; i<MAX_CHANNELS ; i++, ch++) { + for (i=0; i<s_numchannels ; i++, ch++) { ltime = paintedtime; while (ltime < end) { |