/* * SF_Init */ bool SF_Init( void *hwnd, int maxEntities, bool verbose ) { soundpool = S_MemAllocPool( "OpenAL sound module" ); s_num_ent_spats = 0; #ifdef OPENAL_RUNTIME if( !QAL_Init( ALDRIVER, verbose ) ) { #ifdef ALDRIVER_ALT if( !QAL_Init( ALDRIVER_ALT, verbose ) ) #endif { Com_Printf( "Failed to load OpenAL library: %s\n", ALDRIVER ); return false; } } #endif s_volume = trap_Cvar_Get( "s_volume", "0.8", CVAR_ARCHIVE ); s_musicvolume = trap_Cvar_Get( "s_musicvolume", "0.15", CVAR_ARCHIVE ); s_doppler = trap_Cvar_Get( "s_doppler", "1.0", CVAR_ARCHIVE ); s_sound_velocity = trap_Cvar_Get( "s_sound_velocity", "10976", CVAR_DEVELOPER ); s_stereo2mono = trap_Cvar_Get ( "s_stereo2mono", "0", CVAR_ARCHIVE ); s_globalfocus = trap_Cvar_Get( "s_globalfocus", "0", CVAR_ARCHIVE ); #ifdef ENABLE_PLAY trap_Cmd_AddCommand( "play", SF_Play_f ); #endif trap_Cmd_AddCommand( "music", SF_Music_f ); trap_Cmd_AddCommand( "stopmusic", SF_StopBackgroundTrack ); trap_Cmd_AddCommand( "prevmusic", SF_PrevBackgroundTrack ); trap_Cmd_AddCommand( "nextmusic", SF_NextBackgroundTrack ); trap_Cmd_AddCommand( "pausemusic", SF_PauseBackgroundTrack ); trap_Cmd_AddCommand( "soundlist", SF_SoundList_f ); trap_Cmd_AddCommand( "s_devices", SF_ListDevices_f ); s_cmdPipe = S_CreateSoundCmdPipe(); if( !s_cmdPipe ) { return false; } s_backThread = trap_Thread_Create( S_BackgroundUpdateProc, s_cmdPipe ); S_IssueInitCmd( s_cmdPipe, hwnd, maxEntities, verbose ); S_FinishSoundCmdPipe( s_cmdPipe ); if( !alContext ) { return false; } S_InitBuffers(); return true; }
/* * Initializes the OpenAL backend */ qboolean AL_Init(void) { int i; if (!QAL_Init()) { Com_Printf("ERROR: OpenAL failed to initialize.\n"); return false; } s_openal_maxgain = Cvar_Get("s_openal_maxgain", "1.0", CVAR_ARCHIVE); /* check for linear distance extension */ if (!qalIsExtensionPresent("AL_EXT_LINEAR_DISTANCE")) { Com_Printf("ERROR: Required AL_EXT_LINEAR_DISTANCE extension is missing.\n"); QAL_Shutdown(); return false; } /* generate source names */ qalGetError(); qalGenSources(1, &streamSource); if (qalGetError() != AL_NO_ERROR) { Com_Printf("ERROR: Couldn't get a single Source.\n"); QAL_Shutdown(); return false; } else { /* -1 because we already got one channel for streaming */ for (i = 0; i < MAX_CHANNELS - 1; i++) { qalGenSources(1, &s_srcnums[i]); if (qalGetError() != AL_NO_ERROR) { break; } } if (i < MIN_CHANNELS - 1) { Com_Printf("ERROR: Required at least %d sources, but got %d.\n", MIN_CHANNELS, i + 1); QAL_Shutdown(); return false; } } s_numchannels = i; AL_InitStreamSource(); AL_InitUnderwaterFilter(); Com_Printf("Number of OpenAL sources: %d\n\n", s_numchannels); return true; }
qboolean AL_Init(void) { int i; Com_DPrintf("Initializing OpenAL\n"); if (!QAL_Init()) { goto fail0; } // check for linear distance extension if (!qalIsExtensionPresent("AL_EXT_LINEAR_DISTANCE")) { Com_SetLastError("AL_EXT_LINEAR_DISTANCE extension is missing"); goto fail1; } // generate source names qalGetError(); for (i = 0; i < MAX_CHANNELS; i++) { qalGenSources(1, &s_srcnums[i]); if (qalGetError() != AL_NO_ERROR) { break; } } Com_DPrintf("Got %d AL sources\n", i); if (i < MIN_CHANNELS) { Com_SetLastError("Insufficient number of AL sources"); goto fail1; } s_numchannels = i; Com_Printf("OpenAL initialized.\n"); return qtrue; fail1: QAL_Shutdown(); fail0: Com_EPrintf("Failed to initialize OpenAL: %s\n", Com_GetLastError()); return qfalse; }
/* ================= AL_StartOpenAL ================= */ static qboolean AL_StartOpenAL () { // Initialize our QAL dynamic bindings if (!QAL_Init()) return false; // Get device list if (alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT")) alConfig.deviceList = alcGetString(NULL, ALC_DEVICE_SPECIFIER); else alConfig.deviceList = "DirectSound3D\0DirectSound\0MMSYSTEM\0\0"; // Initialize the device, context, etc... if (AL_InitDriver()) return true; // Shutdown QAL QAL_Shutdown(); return false; }
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 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 SndAl_InitCapture( qboolean usingAL ) { const char *inputdevice = NULL; #ifdef USE_OPENAL_DLOPEN // Load QAL if we are called from the base sound driver if ( !usingAL ) { s_alDriver = si.Cvar_Get( "s_alDriver", ALDRIVER_DEFAULT, CVAR_ARCHIVE | CVAR_LATCH ); if ( !QAL_Init( s_alDriver->string ) ) { si.Printf( PRINT_ALL, "Failed to load library: \"%s\".\n", s_alDriver->string ); return; } } #endif // !!! FIXME: some of these alcCaptureOpenDevice() values should be cvars. // !!! FIXME: add support for capture device enumeration. // !!! FIXME: add some better error reporting. s_alCapture = si.Cvar_Get( "s_alCapture", "1", CVAR_ARCHIVE | CVAR_LATCH ); if ( !s_alCapture->integer ) { si.Printf( PRINT_ALL, "OpenAL capture support disabled by user ('+set s_alCapture 1' to enable)\n" ); } else { if ( !qalcIsExtensionPresent( NULL, "ALC_EXT_capture" ) ) { si.Printf( PRINT_ALL, "No ALC_EXT_CAPTURE support, can't record audio.\n" ); } else { char inputdevicenames[ 16384 ] = ""; const char *inputdevicelist; const char *defaultinputdevice; int curlen; capture_ext = qtrue; // get all available input devices + the default input device name. inputdevicelist = qalcGetString( NULL, ALC_CAPTURE_DEVICE_SPECIFIER ); defaultinputdevice = qalcGetString( NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER ); // dump a list of available devices to a cvar for the user to see. #ifndef MACOS_X while ( ( curlen = strlen( inputdevicelist ) ) ) { si.strcat( inputdevicenames, sizeof( inputdevicenames ), inputdevicelist ); si.strcat( inputdevicenames, sizeof( inputdevicenames ), "\n" ); inputdevicelist += curlen + 1; } #endif s_alAvailableInputDevices = si.Cvar_Get( "s_alAvailableInputDevices", inputdevicenames, CVAR_ROM | CVAR_NORESTART ); // !!! FIXME: 8000Hz is what Speex narrowband mode needs, but we // !!! FIXME: should probably open the capture device after // !!! FIXME: initializing Speex so we can change to wideband // !!! FIXME: if we like. si.Printf( PRINT_ALL, "OpenAL default capture device is '%s'\n", defaultinputdevice ); alCaptureDevice = qalcCaptureOpenDevice( inputdevice, 8000, AL_FORMAT_MONO16, 4096 ); if ( !alCaptureDevice && inputdevice ) { si.Printf( PRINT_ALL, "Failed to open OpenAL Input device '%s', trying default.\n", inputdevice ); alCaptureDevice = qalcCaptureOpenDevice( NULL, 8000, AL_FORMAT_MONO16, 4096 ); } si.Printf( PRINT_ALL, "OpenAL capture device %s.\n", ( alCaptureDevice == NULL ) ? "failed to open" : "opened" ); } } }
qboolean SndAl_Init( void ) { const char *device = NULL; // Original console variables s_volume = si.Cvar_Get( "s_volume", "0.8", CVAR_ARCHIVE ); s_musicVolume = si.Cvar_Get( "s_musicvolume", "0.25", CVAR_ARCHIVE ); s_doppler = si.Cvar_Get( "s_doppler", "1", CVAR_ARCHIVE ); // New console variables s_precache = si.Cvar_Get( "al_precache", "1", CVAR_ARCHIVE ); s_gain = si.Cvar_Get( "al_gain", "0.4", CVAR_ARCHIVE ); s_sources = si.Cvar_Get( "al_sources", "64", CVAR_ARCHIVE ); s_dopplerFactor = si.Cvar_Get( "al_dopplerfactor", "1.0", CVAR_ARCHIVE ); s_dopplerSpeed = si.Cvar_Get( "al_dopplerspeed", "2200", CVAR_ARCHIVE ); s_minDistance = si.Cvar_Get( "al_mindistance", "80", CVAR_ARCHIVE ); s_rolloff = si.Cvar_Get( "al_rolloff", "0.25", CVAR_ARCHIVE ); s_alDevice = si.Cvar_Get( "al_device", "", CVAR_ARCHIVE | CVAR_LATCH ); #ifdef USE_OPENAL_DLOPEN s_alDriver = si.Cvar_Get( "al_driver", ALDRIVER_DEFAULT, CVAR_ARCHIVE ); #endif // USE_OPENAL_DLOPEN #ifdef USE_OPENAL_DLOPEN // Load QAL if ( !QAL_Init( s_alDriver->string ) ) { si.Printf( PRINT_ALL, "not initializing.\n" ); return qfalse; } #endif // USE_OPENAL_DLOPEN // Open default device device = s_alDevice->string; if ( device && !*device ) { device = NULL; } if ( qalcIsExtensionPresent( NULL, "ALC_ENUMERATION_EXT" ) ) { char devicenames[ 1024 ] = ""; const char *devicelist; #ifdef _WIN32 const char *defaultdevice; #endif int curlen; // get all available devices + the default device name. devicelist = qalcGetString( NULL, ALC_DEVICE_SPECIFIER ); #ifdef _WIN32 defaultdevice = qalcGetString( NULL, ALC_DEFAULT_DEVICE_SPECIFIER ); // check whether the default device is generic hardware. If it is, change to // Generic Software as that one works more reliably with various sound systems. // If it's not, use OpenAL's default selection as we don't want to ignore // native hardware acceleration. if ( !device && !strcmp( defaultdevice, "Generic Hardware" ) ) { device = "Generic Software"; } #endif // dump a list of available devices to a cvar for the user to see. #ifndef MACOS_X while ( ( curlen = strlen( devicelist ) ) ) { strcat( devicenames, devicelist ); strcat( devicenames, "\n" ); devicelist += curlen + 1; } #endif s_alAvailableDevices = si.Cvar_Get( "al_AvailableDevices", devicenames, CVAR_ROM | CVAR_NORESTART ); } alDevice = qalcOpenDevice( device ); if ( !alDevice && device ) { si.Printf( PRINT_ALL, "Failed to open OpenAL device '%s', trying default.\n", device ); alDevice = qalcOpenDevice( NULL ); } if ( !alDevice ) { #ifdef USE_OPENAL_DLOPEN QAL_Shutdown(); #endif si.Printf( PRINT_ALL, "Failed to open OpenAL device.\n" ); return qfalse; } // Create OpenAL context alContext = qalcCreateContext( alDevice, NULL ); if ( !alContext ) { #ifdef USE_OPENAL_DLOPEN QAL_Shutdown(); #endif qalcCloseDevice( alDevice ); si.Printf( PRINT_ALL, "Failed to create context\n" ); return qfalse; } qalcMakeContextCurrent( alContext ); qalcProcessContext( alContext ); // Print OpenAL information si.Printf( PRINT_ALL, "OpenAL initialised\n" ); si.Printf( PRINT_ALL, " Vendor: %s\n", qalGetString( AL_VENDOR ) ); si.Printf( PRINT_ALL, " Version: %s\n", qalGetString( AL_VERSION ) ); si.Printf( PRINT_ALL, " Renderer: %s\n", qalGetString( AL_RENDERER ) ); si.Printf( PRINT_ALL, " AL Extensions: %s\n", qalGetString( AL_EXTENSIONS ) ); si.Printf( PRINT_ALL, " ALC Extensions: %s\n", qalcGetString( alDevice, ALC_EXTENSIONS ) ); if ( qalcIsExtensionPresent( NULL, "ALC_ENUMERATION_EXT" ) ) { si.Printf( PRINT_ALL, " Device: %s\n", qalcGetString( alDevice, ALC_DEVICE_SPECIFIER ) ); si.Printf( PRINT_ALL, "Available Devices:\n%s", s_alAvailableDevices->string ); } // Check for Linux shutdown race condition if ( !strcmp( qalGetString( AL_VENDOR ), "J. Valenzuela" ) ) { snd_shutdown_bug = qtrue; } // Initialize sources, buffers, music al_buf_init(); al_src_init(); // Set up OpenAL parameters (doppler, etc) qalDistanceModel( AL_INVERSE_DISTANCE_CLAMPED ); qalDopplerFactor( s_dopplerFactor->value ); qalDopplerVelocity( s_dopplerSpeed->value );; // Add commands si.Cmd_AddCommand( "play", S_Play_f ); si.Cmd_AddCommand( "music", S_Music_f ); #ifdef USE_VOIP SndAl_InitCapture( qtrue ); #endif // Init successful si.Printf( PRINT_ALL, "initialization successful\n" ); return qtrue; }
/* ================= S_AL_Init ================= */ qboolean S_AL_Init( soundInterface_t *si ) { #if USE_OPENAL qboolean enumsupport, founddev = qfalse; if( !si ) { return qfalse; } // New console variables s_alPrecache = Cvar_Get( "s_alPrecache", "1", CVAR_ARCHIVE ); s_alGain = Cvar_Get( "s_alGain", "0.4", CVAR_ARCHIVE ); s_alSources = Cvar_Get( "s_alSources", "96", CVAR_ARCHIVE ); s_alDopplerFactor = Cvar_Get( "s_alDopplerFactor", "1.0", CVAR_ARCHIVE ); s_alDopplerSpeed = Cvar_Get( "s_alDopplerSpeed", "2200", CVAR_ARCHIVE ); s_alMinDistance = Cvar_Get( "s_alMinDistance", "120", CVAR_CHEAT ); s_alMaxDistance = Cvar_Get("s_alMaxDistance", "1024", CVAR_CHEAT); s_alRolloff = Cvar_Get( "s_alRolloff", "2", CVAR_CHEAT); s_alGraceDistance = Cvar_Get("s_alGraceDistance", "512", CVAR_CHEAT); s_alDriver = Cvar_Get( "s_alDriver", ALDRIVER_DEFAULT, CVAR_ARCHIVE ); // Load QAL if( !QAL_Init( s_alDriver->string ) ) { Com_Printf( "Failed to load library: \"%s\".\n", s_alDriver->string ); return qfalse; } // Device enumeration support (extension is implemented reasonably only on Windows right now). if((enumsupport = qalcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT"))) { char devicenames[1024] = ""; const char *devicelist; const char *defaultdevice; int curlen; // get all available devices + the default device name. devicelist = qalcGetString(NULL, ALC_DEVICE_SPECIFIER); defaultdevice = qalcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER); #ifdef _WIN32 // check whether the default device is generic hardware. If it is, change to // Generic Software as that one works more reliably with various sound systems. // If it's not, use OpenAL's default selection as we don't want to ignore // native hardware acceleration. if(!strcmp(defaultdevice, "Generic Hardware")) s_alDevice = Cvar_Get("s_alDevice", ALDEVICE_DEFAULT, CVAR_ARCHIVE | CVAR_LATCH); else #endif s_alDevice = Cvar_Get("s_alDevice", defaultdevice, CVAR_ARCHIVE | CVAR_LATCH); // dump a list of available devices to a cvar for the user to see. while((curlen = strlen(devicelist))) { Q_strcat(devicenames, sizeof(devicenames), devicelist); Q_strcat(devicenames, sizeof(devicenames), "\n"); // check whether the device we want to load is available at all. if(!strcmp(s_alDevice->string, devicelist)) founddev = qtrue; devicelist += curlen + 1; } s_alAvailableDevices = Cvar_Get("s_alAvailableDevices", devicenames, CVAR_ROM | CVAR_NORESTART); if(!founddev) { Cvar_ForceReset("s_alDevice"); founddev = 1; } } if(founddev) alDevice = qalcOpenDevice(s_alDevice->string); else alDevice = qalcOpenDevice(NULL); if( !alDevice ) { QAL_Shutdown( ); Com_Printf( "Failed to open OpenAL device.\n" ); return qfalse; } if(enumsupport) Cvar_Set("s_alDevice", qalcGetString(alDevice, ALC_DEVICE_SPECIFIER)); // Create OpenAL context alContext = qalcCreateContext( alDevice, NULL ); if( !alContext ) { QAL_Shutdown( ); qalcCloseDevice( alDevice ); Com_Printf( "Failed to create OpenAL context.\n" ); return qfalse; } qalcMakeContextCurrent( alContext ); // Initialize sources, buffers, music S_AL_BufferInit( ); S_AL_SrcInit( ); // Set up OpenAL parameters (doppler, etc) qalDistanceModel(AL_INVERSE_DISTANCE_CLAMPED); qalDopplerFactor( s_alDopplerFactor->value ); qalDopplerVelocity( s_alDopplerSpeed->value ); si->Shutdown = S_AL_Shutdown; si->StartSound = S_AL_StartSound; si->StartLocalSound = S_AL_StartLocalSound; si->StartBackgroundTrack = S_AL_StartBackgroundTrack; si->StopBackgroundTrack = S_AL_StopBackgroundTrack; si->RawSamples = S_AL_RawSamples; si->StopAllSounds = S_AL_StopAllSounds; si->ClearLoopingSounds = S_AL_ClearLoopingSounds; si->AddLoopingSound = S_AL_AddLoopingSound; si->AddRealLoopingSound = S_AL_AddRealLoopingSound; si->StopLoopingSound = S_AL_StopLoopingSound; si->Respatialize = S_AL_Respatialize; si->UpdateEntityPosition = S_AL_UpdateEntityPosition; si->Update = S_AL_Update; si->DisableSounds = S_AL_DisableSounds; si->BeginRegistration = S_AL_BeginRegistration; si->RegisterSound = S_AL_RegisterSound; si->ClearSoundBuffer = S_AL_ClearSoundBuffer; si->SoundInfo = S_AL_SoundInfo; si->SoundList = S_AL_SoundList; return qtrue; #else return qfalse; #endif }
/* ================= S_AL_Init ================= */ 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", "1.0", CVAR_ARCHIVE ); s_alSources = Cvar_Get( "s_alSources", "96", CVAR_ARCHIVE ); s_alDopplerFactor = Cvar_Get( "s_alDopplerFactor", "1.0", CVAR_ARCHIVE ); s_alDopplerSpeed = Cvar_Get( "s_alDopplerSpeed", "2200", CVAR_ARCHIVE ); s_alMinDistance = Cvar_Get( "s_alMinDistance", "120", CVAR_CHEAT ); s_alMaxDistance = Cvar_Get("s_alMaxDistance", "1024", CVAR_CHEAT); s_alRolloff = Cvar_Get( "s_alRolloff", "2", CVAR_CHEAT); s_alGraceDistance = Cvar_Get("s_alGraceDistance", "512", CVAR_CHEAT); s_alDriver = Cvar_Get( "s_alDriver", ALDRIVER_DEFAULT, CVAR_ARCHIVE ); // Load QAL if( !QAL_Init( s_alDriver->string ) ) { Com_Printf( "Failed to load library: \"%s\".\n", s_alDriver->string ); return qfalse; } // Device enumeration support (extension is implemented reasonably only on Windows right now). if((enumsupport = qalcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT"))) { char devicenames[1024] = ""; const char *devicelist; const char *defaultdevice; int curlen; // get all available devices + the default device name. devicelist = qalcGetString(NULL, ALC_DEVICE_SPECIFIER); defaultdevice = qalcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER); #ifdef _WIN32 // check whether the default device is generic hardware. If it is, change to // Generic Software as that one works more reliably with various sound systems. // If it's not, use OpenAL's default selection as we don't want to ignore // native hardware acceleration. if(!strcmp(defaultdevice, "Generic Hardware")) s_alDevice = Cvar_Get("s_alDevice", ALDEVICE_DEFAULT, CVAR_ARCHIVE | CVAR_LATCH); else #endif s_alDevice = Cvar_Get("s_alDevice", defaultdevice, CVAR_ARCHIVE | CVAR_LATCH); // dump a list of available devices to a cvar for the user to see. while((curlen = strlen(devicelist))) { Q_strcat(devicenames, sizeof(devicenames), devicelist); Q_strcat(devicenames, sizeof(devicenames), "\n"); // check whether the device we want to load is available at all. if(!strcmp(s_alDevice->string, devicelist)) founddev = qtrue; devicelist += curlen + 1; } s_alAvailableDevices = Cvar_Get("s_alAvailableDevices", devicenames, CVAR_ROM | CVAR_NORESTART); if(!founddev) { Cvar_ForceReset("s_alDevice"); founddev = 1; } } if(founddev) alDevice = qalcOpenDevice(s_alDevice->string); else alDevice = qalcOpenDevice(NULL); if( !alDevice ) { QAL_Shutdown( ); Com_Printf( "Failed to open OpenAL device.\n" ); return qfalse; } if(enumsupport) Cvar_Set("s_alDevice", qalcGetString(alDevice, ALC_DEVICE_SPECIFIER)); // Create OpenAL context alContext = qalcCreateContext( alDevice, NULL ); if( !alContext ) { QAL_Shutdown( ); qalcCloseDevice( alDevice ); Com_Printf( "Failed to create OpenAL context.\n" ); return qfalse; } qalcMakeContextCurrent( alContext ); // Initialize sources, buffers, music S_AL_BufferInit( ); S_AL_SrcInit( ); // Set up OpenAL parameters (doppler, etc) qalDistanceModel(AL_INVERSE_DISTANCE_CLAMPED); qalDopplerFactor( s_alDopplerFactor->value ); qalDopplerVelocity( s_alDopplerSpeed->value ); #ifdef 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 | CVAR_LATCH ); 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 { #ifdef MACOS_X // !!! 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 (qalcCaptureOpenDevice == NULL) #else if (!qalcIsExtensionPresent(NULL, "ALC_EXT_capture")) #endif { Com_Printf("No ALC_EXT_capture support, can't record audio.\n"); } else { // !!! FIXME: 8000Hz is what Speex narrowband mode needs, but we // !!! FIXME: should probably open the capture device after // !!! FIXME: initializing Speex so we can change to wideband // !!! FIXME: if we like. 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; si->StartBackgroundTrack = S_AL_StartBackgroundTrack; si->StopBackgroundTrack = S_AL_StopBackgroundTrack; si->RawSamples = S_AL_RawSamples; si->StopAllSounds = S_AL_StopAllSounds; si->ClearLoopingSounds = S_AL_ClearLoopingSounds; si->AddLoopingSound = S_AL_AddLoopingSound; si->AddRealLoopingSound = S_AL_AddRealLoopingSound; si->StopLoopingSound = S_AL_StopLoopingSound; si->Respatialize = S_AL_Respatialize; si->UpdateEntityPosition = S_AL_UpdateEntityPosition; si->Update = S_AL_Update; si->DisableSounds = S_AL_DisableSounds; si->BeginRegistration = S_AL_BeginRegistration; si->RegisterSound = S_AL_RegisterSound; si->SoundDuration = S_AL_SoundDuration; si->ClearSoundBuffer = S_AL_ClearSoundBuffer; si->SoundInfo = S_AL_SoundInfo; si->SoundList = S_AL_SoundList; #ifdef 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; #endif }
/* * S_Init */ qboolean S_Init( void *hwnd, int maxEntities, qboolean verbose ) { int numDevices; int userDeviceNum = -1; char *devices, *defaultDevice; soundpool = S_MemAllocPool( "OpenAL sound module" ); alDevice = NULL; alContext = NULL; #ifdef OPENAL_RUNTIME if( !QAL_Init( ALDRIVER, verbose ) ) { #ifdef ALDRIVER_ALT if( !QAL_Init( ALDRIVER_ALT, verbose ) ) #endif { Com_Printf( "Failed to load OpenAL library: %s\n", ALDRIVER ); goto fail_no_device; } } #endif // get system default device identifier defaultDevice = ( char * )qalcGetString( NULL, ALC_DEFAULT_DEVICE_SPECIFIER ); if( !defaultDevice ) { Com_Printf( "Failed to get openAL default device\n" ); goto fail_no_device; } s_openAL_device = trap_Cvar_Get( "s_openAL_device", ALDEVICE_DEFAULT ? ALDEVICE_DEFAULT : defaultDevice, CVAR_ARCHIVE|CVAR_LATCH_SOUND ); devices = ( char * )qalcGetString( NULL, ALC_DEVICE_SPECIFIER ); for( numDevices = 0; *devices; devices += strlen( devices ) + 1, numDevices++ ) { if( !Q_stricmp( s_openAL_device->string, devices ) ) { userDeviceNum = numDevices; // force case sensitive if( strcmp( s_openAL_device->string, devices ) ) trap_Cvar_ForceSet( "s_openAL_device", devices ); } } if( !numDevices ) { Com_Printf( "Failed to get openAL devices\n" ); goto fail_no_device; } // the device assigned by the user is not available if( userDeviceNum == -1 ) { Com_Printf( "'s_openAL_device': incorrect device name, reseting to default\n" ); trap_Cvar_ForceSet( "s_openAL_device", ALDEVICE_DEFAULT ? ALDEVICE_DEFAULT : defaultDevice ); devices = ( char * )qalcGetString( NULL, ALC_DEVICE_SPECIFIER ); for( numDevices = 0; *devices; devices += strlen( devices ) + 1, numDevices++ ) { if( !Q_stricmp( s_openAL_device->string, devices ) ) userDeviceNum = numDevices; } if( userDeviceNum == -1 ) trap_Cvar_ForceSet( "s_openAL_device", defaultDevice ); } alDevice = qalcOpenDevice( (const ALchar *)s_openAL_device->string ); if( !alDevice ) { Com_Printf( "Failed to open device\n" ); goto fail_no_device; } // Create context alContext = qalcCreateContext( alDevice, NULL ); if( !alContext ) { Com_Printf( "Failed to create context\n" ); goto fail; } qalcMakeContextCurrent( alContext ); if( verbose ) { Com_Printf( "OpenAL initialized\n" ); if( numDevices ) { int i; Com_Printf( " Devices: " ); devices = ( char * )qalcGetString( NULL, ALC_DEVICE_SPECIFIER ); for( i = 0; *devices; devices += strlen( devices ) + 1, i++ ) Com_Printf( "%s%s", devices, ( i < numDevices - 1 ) ? ", " : "" ); Com_Printf( "\n" ); if( defaultDevice && *defaultDevice ) Com_Printf( " Default system device: %s\n", defaultDevice ); Com_Printf( "\n" ); } Com_Printf( " Device: %s\n", qalcGetString( alDevice, ALC_DEVICE_SPECIFIER ) ); 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 ) ); } // Check for Linux shutdown race condition if( !Q_stricmp( qalGetString( AL_VENDOR ), "J. Valenzuela" ) ) snd_shutdown_bug = qtrue; s_volume = trap_Cvar_Get( "s_volume", "0.8", CVAR_ARCHIVE ); s_musicvolume = trap_Cvar_Get( "s_musicvolume", "0.5", CVAR_ARCHIVE ); s_doppler = trap_Cvar_Get( "s_doppler", "1.0", CVAR_ARCHIVE ); s_sound_velocity = trap_Cvar_Get( "s_sound_velocity", "10976", CVAR_DEVELOPER ); s_stereo2mono = trap_Cvar_Get ( "s_stereo2mono", "0", CVAR_ARCHIVE ); qalDopplerFactor( s_doppler->value ); qalDopplerVelocity( s_sound_velocity->value > 0.0f ? s_sound_velocity->value : 0.0f ); if( qalSpeedOfSound ) // opelAL 1.1 only. alDopplerVelocity being deprecated qalSpeedOfSound( s_sound_velocity->value > 0.0f ? s_sound_velocity->value : 0.0f ); s_doppler->modified = qfalse; S_SetAttenuationModel( S_DEFAULT_ATTENUATION_MODEL, S_DEFAULT_ATTENUATION_MAXDISTANCE, S_DEFAULT_ATTENUATION_REFDISTANCE ); S_LockBackgroundTrack( qfalse ); if( !S_InitDecoders( verbose ) ) { Com_Printf( "Failed to init decoders\n" ); goto fail; } if( !S_InitBuffers() ) { Com_Printf( "Failed to init buffers\n" ); goto fail; } if( !S_InitSources( maxEntities, verbose ) ) { Com_Printf( "Failed to init sources\n" ); goto fail; } #ifdef ENABLE_PLAY trap_Cmd_AddCommand( "play", S_Play ); #endif trap_Cmd_AddCommand( "music", S_Music ); trap_Cmd_AddCommand( "stopmusic", S_StopMusic ); trap_Cmd_AddCommand( "prevmusic", S_PrevMusic ); trap_Cmd_AddCommand( "nextmusic", S_NextMusic ); trap_Cmd_AddCommand( "pausemusic", S_PauseMusic ); trap_Cmd_AddCommand( "soundlist", S_SoundList ); trap_Cmd_AddCommand( "s_devices", S_ListDevices ); return qtrue; fail: if( alContext ) { if( !snd_shutdown_bug ) qalcMakeContextCurrent( NULL ); qalcDestroyContext( alContext ); alContext = NULL; } if( alDevice ) { qalcCloseDevice( alDevice ); alDevice = NULL; } fail_no_device: S_MemFreePool( &soundpool ); return qfalse; }