Initial patch for in-game VoIP support!
This commit is contained in:
parent
0ee3960225
commit
12326a9eac
19 changed files with 1185 additions and 127 deletions
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue