Initial patch for in-game VoIP support!

This commit is contained in:
Ryan C. Gordon 2008-06-01 07:51:23 +00:00
parent 0ee3960225
commit 12326a9eac
19 changed files with 1185 additions and 127 deletions

View file

@ -1253,35 +1253,37 @@ ALuint S_AL_SrcGet(srcHandle_t src)
//===========================================================================
static srcHandle_t streamSourceHandle = -1;
static qboolean streamPlaying = qfalse;
static ALuint streamSource;
static srcHandle_t streamSourceHandles[MAX_RAW_STREAMS];
static qboolean streamPlaying[MAX_RAW_STREAMS];
static ALuint streamSources[MAX_RAW_STREAMS];
/*
=================
S_AL_AllocateStreamChannel
=================
*/
static void S_AL_AllocateStreamChannel( void )
static void S_AL_AllocateStreamChannel( int stream )
{
if ((stream < 0) || (stream >= MAX_RAW_STREAMS))
return;
// Allocate a streamSource at high priority
streamSourceHandle = S_AL_SrcAlloc(SRCPRI_STREAM, -2, 0);
if(streamSourceHandle == -1)
streamSourceHandles[stream] = S_AL_SrcAlloc(SRCPRI_STREAM, -2, 0);
if(streamSourceHandles[stream] == -1)
return;
// Lock the streamSource so nobody else can use it, and get the raw streamSource
S_AL_SrcLock(streamSourceHandle);
streamSource = S_AL_SrcGet(streamSourceHandle);
S_AL_SrcLock(streamSourceHandles[stream]);
streamSources[stream] = S_AL_SrcGet(streamSourceHandles[stream]);
// Set some streamSource parameters
qalSourcei (streamSource, AL_BUFFER, 0 );
qalSourcei (streamSource, AL_LOOPING, AL_FALSE );
qalSource3f(streamSource, AL_POSITION, 0.0, 0.0, 0.0);
qalSource3f(streamSource, AL_VELOCITY, 0.0, 0.0, 0.0);
qalSource3f(streamSource, AL_DIRECTION, 0.0, 0.0, 0.0);
qalSourcef (streamSource, AL_ROLLOFF_FACTOR, 0.0 );
qalSourcei (streamSource, AL_SOURCE_RELATIVE, AL_TRUE );
qalSourcei (streamSources[stream], AL_BUFFER, 0 );
qalSourcei (streamSources[stream], AL_LOOPING, AL_FALSE );
qalSource3f(streamSources[stream], AL_POSITION, 0.0, 0.0, 0.0);
qalSource3f(streamSources[stream], AL_VELOCITY, 0.0, 0.0, 0.0);
qalSource3f(streamSources[stream], AL_DIRECTION, 0.0, 0.0, 0.0);
qalSourcef (streamSources[stream], AL_ROLLOFF_FACTOR, 0.0 );
qalSourcei (streamSources[stream], AL_SOURCE_RELATIVE, AL_TRUE );
}
/*
@ -1289,12 +1291,15 @@ static void S_AL_AllocateStreamChannel( void )
S_AL_FreeStreamChannel
=================
*/
static void S_AL_FreeStreamChannel( void )
static void S_AL_FreeStreamChannel( int stream )
{
if ((stream < 0) || (stream >= MAX_RAW_STREAMS))
return;
// Release the output streamSource
S_AL_SrcUnlock(streamSourceHandle);
streamSource = 0;
streamSourceHandle = -1;
S_AL_SrcUnlock(streamSourceHandles[stream]);
streamSources[stream] = 0;
streamSourceHandles[stream] = -1;
}
/*
@ -1303,20 +1308,23 @@ S_AL_RawSamples
=================
*/
static
void S_AL_RawSamples(int samples, int rate, int width, int channels, const byte *data, float volume)
void S_AL_RawSamples(int stream, int samples, int rate, int width, int channels, const byte *data, float volume)
{
ALuint buffer;
ALuint format;
if ((stream < 0) || (stream >= MAX_RAW_STREAMS))
return;
format = S_AL_Format( width, channels );
// Create the streamSource if necessary
if(streamSourceHandle == -1)
if(streamSourceHandles[stream] == -1)
{
S_AL_AllocateStreamChannel();
S_AL_AllocateStreamChannel(stream);
// Failed?
if(streamSourceHandle == -1)
if(streamSourceHandles[stream] == -1)
{
Com_Printf( S_COLOR_RED "ERROR: Can't allocate streaming streamSource\n");
return;
@ -1328,10 +1336,10 @@ void S_AL_RawSamples(int samples, int rate, int width, int channels, const byte
qalBufferData(buffer, format, (ALvoid *)data, (samples * width * channels), rate);
// Shove the data onto the streamSource
qalSourceQueueBuffers(streamSource, 1, &buffer);
qalSourceQueueBuffers(streamSources[stream], 1, &buffer);
// Volume
qalSourcef (streamSource, AL_GAIN, volume * s_volume->value * s_alGain->value);
qalSourcef (streamSources[stream], AL_GAIN, volume * s_volume->value * s_alGain->value);
}
/*
@ -1340,40 +1348,43 @@ S_AL_StreamUpdate
=================
*/
static
void S_AL_StreamUpdate( void )
void S_AL_StreamUpdate( int stream )
{
int numBuffers;
ALint state;
if(streamSourceHandle == -1)
if ((stream < 0) || (stream >= MAX_RAW_STREAMS))
return;
if(streamSourceHandles[stream] == -1)
return;
// Un-queue any buffers, and delete them
qalGetSourcei( streamSource, AL_BUFFERS_PROCESSED, &numBuffers );
qalGetSourcei( streamSources[stream], AL_BUFFERS_PROCESSED, &numBuffers );
while( numBuffers-- )
{
ALuint buffer;
qalSourceUnqueueBuffers(streamSource, 1, &buffer);
qalSourceUnqueueBuffers(streamSources[stream], 1, &buffer);
qalDeleteBuffers(1, &buffer);
}
// Start the streamSource playing if necessary
qalGetSourcei( streamSource, AL_BUFFERS_QUEUED, &numBuffers );
qalGetSourcei( streamSources[stream], AL_BUFFERS_QUEUED, &numBuffers );
qalGetSourcei(streamSource, AL_SOURCE_STATE, &state);
qalGetSourcei(streamSources[stream], AL_SOURCE_STATE, &state);
if(state == AL_STOPPED)
{
streamPlaying = qfalse;
streamPlaying[stream] = qfalse;
// If there are no buffers queued up, release the streamSource
if( !numBuffers )
S_AL_FreeStreamChannel( );
S_AL_FreeStreamChannel( stream );
}
if( !streamPlaying && numBuffers )
if( !streamPlaying[stream] && numBuffers )
{
qalSourcePlay( streamSource );
streamPlaying = qtrue;
qalSourcePlay( streamSources[stream] );
streamPlaying[stream] = qtrue;
}
}
@ -1383,14 +1394,17 @@ S_AL_StreamDie
=================
*/
static
void S_AL_StreamDie( void )
void S_AL_StreamDie( int stream )
{
if(streamSourceHandle == -1)
if ((stream < 0) || (stream >= MAX_RAW_STREAMS))
return;
streamPlaying = qfalse;
qalSourceStop(streamSource);
S_AL_FreeStreamChannel();
if(streamSourceHandles[stream] == -1)
return;
streamPlaying[stream] = qfalse;
qalSourceStop(streamSources[stream]);
S_AL_FreeStreamChannel(stream);
}
@ -1682,6 +1696,11 @@ void S_AL_MusicUpdate( void )
static ALCdevice *alDevice;
static ALCcontext *alContext;
#if USE_VOIP
static ALCdevice *alCaptureDevice;
static cvar_t *s_alCapture;
#endif
#ifdef _WIN32
#define ALDRIVER_DEFAULT "OpenAL32.dll"
#define ALDEVICE_DEFAULT "Generic Software"
@ -1699,9 +1718,11 @@ S_AL_StopAllSounds
static
void S_AL_StopAllSounds( void )
{
int i;
S_AL_SrcShutup();
S_AL_StopBackgroundTrack();
S_AL_StreamDie();
for (i = 0; i < MAX_RAW_STREAMS; i++)
S_AL_StreamDie(i);
}
/*
@ -1742,11 +1763,14 @@ S_AL_Update
static
void S_AL_Update( void )
{
int i;
// Update SFX channels
S_AL_SrcUpdate();
// Update streams
S_AL_StreamUpdate();
for (i = 0; i < MAX_RAW_STREAMS; i++)
S_AL_StreamUpdate(i);
S_AL_MusicUpdate();
// Doppler
@ -1820,6 +1844,47 @@ void S_AL_SoundList( void )
{
}
#if USE_VOIP
static
void S_AL_StartCapture( void )
{
if (alCaptureDevice != NULL)
qalcCaptureStart(alCaptureDevice);
}
static
int S_AL_AvailableCaptureSamples( void )
{
int retval = 0;
if (alCaptureDevice != NULL)
{
ALint samples = 0;
qalcGetIntegerv(alCaptureDevice, ALC_CAPTURE_SAMPLES, sizeof (samples), &samples);
retval = (int) samples;
}
return retval;
}
static
void S_AL_Capture( int samples, byte *data )
{
if (alCaptureDevice != NULL)
qalcCaptureSamples(alCaptureDevice, data, samples);
}
void S_AL_StopCapture( void )
{
if (alCaptureDevice != NULL)
qalcCaptureStop(alCaptureDevice);
}
void S_AL_MasterGain( float gain )
{
qalListenerf(AL_GAIN, gain);
}
#endif
/*
=================
S_AL_SoundInfo
@ -1832,7 +1897,8 @@ void S_AL_SoundInfo( void )
Com_Printf( " Vendor: %s\n", qalGetString( AL_VENDOR ) );
Com_Printf( " Version: %s\n", qalGetString( AL_VERSION ) );
Com_Printf( " Renderer: %s\n", qalGetString( AL_RENDERER ) );
Com_Printf( " Extensions: %s\n", qalGetString( AL_EXTENSIONS ) );
Com_Printf( " AL Extensions: %s\n", qalGetString( AL_EXTENSIONS ) );
Com_Printf( " ALC Extensions: %s\n", qalcGetString( NULL, ALC_EXTENSIONS ) );
if(qalcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT"))
{
Com_Printf(" Device: %s\n", qalcGetString(alDevice, ALC_DEVICE_SPECIFIER));
@ -1849,7 +1915,9 @@ static
void S_AL_Shutdown( void )
{
// Shut down everything
S_AL_StreamDie( );
int i;
for (i = 0; i < MAX_RAW_STREAMS; i++)
S_AL_StreamDie(i);
S_AL_StopBackgroundTrack( );
S_AL_SrcShutdown( );
S_AL_BufferShutdown( );
@ -1857,6 +1925,21 @@ void S_AL_Shutdown( void )
qalcDestroyContext(alContext);
qalcCloseDevice(alDevice);
#if USE_VOIP
if (alCaptureDevice != NULL) {
qalcCaptureStop(alCaptureDevice);
qalcCaptureCloseDevice(alCaptureDevice);
alCaptureDevice = NULL;
Com_Printf( "OpenAL capture device closed.\n" );
}
#endif
for (i = 0; i < MAX_RAW_STREAMS; i++) {
streamSourceHandles[i] = -1;
streamPlaying[i] = qfalse;
streamSources[i] = 0;
}
QAL_Shutdown();
}
@ -1872,11 +1955,18 @@ qboolean S_AL_Init( soundInterface_t *si )
#ifdef USE_OPENAL
qboolean enumsupport, founddev = qfalse;
int i;
if( !si ) {
return qfalse;
}
for (i = 0; i < MAX_RAW_STREAMS; i++) {
streamSourceHandles[i] = -1;
streamPlaying[i] = qfalse;
streamSources[i] = 0;
}
// New console variables
s_alPrecache = Cvar_Get( "s_alPrecache", "1", CVAR_ARCHIVE );
s_alGain = Cvar_Get( "s_alGain", "0.4", CVAR_ARCHIVE );
@ -1977,6 +2067,36 @@ qboolean S_AL_Init( soundInterface_t *si )
qalDopplerFactor( s_alDopplerFactor->value );
qalDopplerVelocity( s_alDopplerSpeed->value );
#if USE_VOIP
// !!! FIXME: some of these alcCaptureOpenDevice() values should be cvars.
// !!! FIXME: add support for capture device enumeration.
// !!! FIXME: add some better error reporting.
s_alCapture = Cvar_Get( "s_alCapture", "1", CVAR_ARCHIVE );
if (!s_alCapture->integer) {
Com_Printf("OpenAL capture support disabled by user ('+set s_alCapture 1' to enable)\n");
#if USE_MUMBLE
} else if (cl_useMumble->integer) {
Com_Printf("OpenAL capture support disabled for Mumble support\n");
#endif
} else {
// !!! FIXME: Apple has a 1.1-compliant OpenAL, which includes
// !!! FIXME: capture support, but they don't list it in the
// !!! FIXME: extension string. We need to check the version string,
// !!! FIXME: then the extension string, but that's too much trouble,
// !!! FIXME: so we'll just check the function pointer for now.
//if (qalcIsExtensionPresent(NULL, "ALC_EXT_capture")) {
if (qalcCaptureOpenDevice == NULL) {
Com_Printf("No ALC_EXT_capture support, can't record audio.\n");
} else {
Com_Printf("OpenAL default capture device is '%s'\n",
qalcGetString(NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER));
alCaptureDevice = qalcCaptureOpenDevice(NULL, 8000, AL_FORMAT_MONO16, 4096);
Com_Printf( "OpenAL capture device %s.\n",
(alCaptureDevice == NULL) ? "failed to open" : "opened");
}
}
#endif
si->Shutdown = S_AL_Shutdown;
si->StartSound = S_AL_StartSound;
si->StartLocalSound = S_AL_StartLocalSound;
@ -1998,6 +2118,14 @@ qboolean S_AL_Init( soundInterface_t *si )
si->SoundInfo = S_AL_SoundInfo;
si->SoundList = S_AL_SoundList;
#if USE_VOIP
si->StartCapture = S_AL_StartCapture;
si->AvailableCaptureSamples = S_AL_AvailableCaptureSamples;
si->Capture = S_AL_Capture;
si->StopCapture = S_AL_StopCapture;
si->MasterGain = S_AL_MasterGain;
#endif
return qtrue;
#else
return qfalse;