summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/qal_api.c4
-rw-r--r--source/qal_api.h1
-rw-r--r--source/snd_al.c85
-rw-r--r--source/snd_dma.c3
-rw-r--r--source/snd_local.h1
-rw-r--r--source/snd_main.c7
-rw-r--r--source/snd_mem.c27
-rw-r--r--source/snd_mix.c2
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) {