Sound::Sound() : m_bgm(0), m_bgm_source(0) { // Ensure Core is initialized get_Core(); #ifndef DISABLE_AL if(!alutInit(0, 0)) throw Sound_Init_Failure(); // Check for Vorbis extension functionality; seems to always fail :( #ifdef _MACOSX alIsExtensionPresent(const_cast<ALubyte *>(reinterpret_cast<const ALubyte *>("AL_EXT_vorbis"))); #else alIsExtensionPresent("AL_EXT_vorbis"); #endif //cerr << "Valid Audio Formats: " << alutGetMIMETypes(ALUT_LOADER_BUFFER) << endl; ALfloat listener_position[] = {0.0f, 0.0f, 0.0f}; ALfloat listener_velocity[] = {0.0f, 0.0f, 0.0f}; ALfloat listener_forward_and_up[] = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}; alListenerfv(AL_POSITION, listener_position); alListenerfv(AL_VELOCITY, listener_velocity); alListenerfv(AL_ORIENTATION, listener_forward_and_up); #endif }
hsBool plEAXListener::Init( void ) { #ifdef EAX_SDK_AVAILABLE if( fInited ) return true; if(!alIsExtensionPresent((ALchar *)"EAX4.0")) // is eax 4 supported { if(!alIsExtensionPresent((ALchar *) "EAX4.0Emulated")) // is an earlier version of eax supported { plStatusLog::AddLineS("audio.log", "EAX not supported"); return false; } else { plStatusLog::AddLineS("audio.log", "EAX 4 Emulated supported"); } } else { plStatusLog::AddLineS("audio.log", "EAX 4 available"); } // EAX is supported s_EAXGet = (EAXGet)alGetProcAddress((ALchar *)"EAXGet"); s_EAXSet = (EAXSet)alGetProcAddress((ALchar *)"EAXSet"); if(!s_EAXGet || ! s_EAXSet) { IFail( "EAX initialization failed", true ); return false; } fInited = true; #if 1 try { // Make an EAX call here to prevent problems on WDM driver unsigned int lRoom = -10000; SetGlobalEAXProperty(DSPROPSETID_EAX_ListenerProperties, DSPROPERTY_EAXLISTENER_ROOM, &lRoom, sizeof( unsigned int )); } catch ( ... ) { plStatusLog::AddLineS("audio.log", "Unable to set EAX Property Set, disabling EAX..."); plgAudioSys::EnableEAX(false); return false; } #endif ClearProcessCache(); return true; #else /* !EAX_SDK_AVAILABLE */ plStatusLog::AddLineS("audio.log", "EAX disabled in this build"); return false; #endif }
AUD_OpenALDevice::AUD_OpenALDevice(AUD_Specs specs, int buffersize) { // cannot determine how many channels or which format OpenAL uses, but // it at least is able to play 16 bit stereo audio specs.channels = AUD_CHANNELS_STEREO; specs.format = AUD_FORMAT_S16; m_device = alcOpenDevice(NULL); if(!m_device) AUD_THROW(AUD_ERROR_OPENAL); // at least try to set the frequency ALCint attribs[] = { ALC_FREQUENCY, specs.rate, 0 }; ALCint* attributes = attribs; if(specs.rate == AUD_RATE_INVALID) attributes = NULL; m_context = alcCreateContext(m_device, attributes); alcMakeContextCurrent(m_context); alcGetIntegerv(m_device, ALC_FREQUENCY, 1, (ALCint*)&specs.rate); // check for specific formats and channel counts to be played back if(alIsExtensionPresent("AL_EXT_FLOAT32") == AL_TRUE) specs.format = AUD_FORMAT_FLOAT32; m_useMC = alIsExtensionPresent("AL_EXT_MCFORMATS") == AL_TRUE; alGetError(); m_converter = new AUD_ConverterFactory(specs); AUD_NEW("factory") m_specs = specs; m_buffersize = buffersize; m_playing = false; m_playingSounds = new std::list<AUD_OpenALHandle*>(); AUD_NEW("list") m_pausedSounds = new std::list<AUD_OpenALHandle*>(); AUD_NEW("list") m_bufferedFactories = new std::list<AUD_OpenALBufferedFactory*>(); AUD_NEW("list") pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init(&m_mutex, &attr); pthread_mutexattr_destroy(&attr); }
hsBool plAudioCapsDetector::IDetectEAX( ) { #ifdef EAX_SDK_AVAILABLE hsBool gotSupport = true; if(!alIsExtensionPresent((ALchar *)"EAX4.0")) // is eax 4 supported { if(!alIsExtensionPresent((ALchar *) "EAX4.0Emulated")) // is an earlier version of eax supported { kLogMe 0xff00ff00, "EAX not supported"); gotSupport = false; } else {
static ALenum get_al_format(int format) { switch (format) { case AF_FORMAT_U8P: return AL_FORMAT_MONO8; case AF_FORMAT_S16P: return AL_FORMAT_MONO16; case AF_FORMAT_FLOATP: if (alIsExtensionPresent((ALchar*)"AL_EXT_float32") == AL_TRUE) return AL_FORMAT_MONO_FLOAT32; break; case AF_FORMAT_DOUBLEP: if (alIsExtensionPresent((ALchar*)"AL_EXT_double") == AL_TRUE) return AL_FORMAT_MONO_DOUBLE_EXT; break; } return AL_FALSE; }
ALenum Source::getFormat(int channels, int bitDepth) const { if (channels == 1 && bitDepth == 8) return AL_FORMAT_MONO8; else if (channels == 1 && bitDepth == 16) return AL_FORMAT_MONO16; else if (channels == 2 && bitDepth == 8) return AL_FORMAT_STEREO8; else if (channels == 2 && bitDepth == 16) return AL_FORMAT_STEREO16; #ifdef AL_EXT_MCFORMATS if (alIsExtensionPresent("AL_EXT_MCFORMATS")) { if (channels == 6 && bitDepth == 8) return AL_FORMAT_51CHN8; else if (channels == 6 && bitDepth == 16) return AL_FORMAT_51CHN16; else if (channels == 8 && bitDepth == 8) return AL_FORMAT_71CHN8; else if (channels == 8 && bitDepth == 16) return AL_FORMAT_71CHN16; } #endif return 0; }
/*! Dynamically Loads the OpenAL DLL if present and binds all the functions. * If there is no DLL or an unexpected error occurs binding functions the * stub functions are automatically bound. */ bool OpenALDLLInit() { OpenALDLLShutdown(); const char* libName = "libopenal.so"; // these are relative to the current working directory const char* searchPath[] = { "lib", "tplib", // superceeded by "lib", here for backass compatibility "", // i.e.: current working directory NULL // this must be last }; char openalPath[4096]; for (int i = 0; searchPath[i] != NULL; ++i) { dSprintf(openalPath, sizeof(openalPath), "%s/%s/%s", Platform::getWorkingDirectory(), searchPath[i], libName); Con::printf(" Searching for OpenAl at location : %s", openalPath); dlHandle = dlopen(openalPath, RTLD_NOW); if (dlHandle != NULL) { // found it Con::printf(" Loading OpenAL: %s", openalPath); break; } } if (dlHandle == NULL) { // couldn't find it in our searchPath, try the system path dlHandle = dlopen(libName, RTLD_NOW); if (dlHandle != NULL) Con::printf(" Loading OpenAL from system (dlopen) path"); } if (dlHandle != NULL) { // if the DLL loaded bind the OpenAL function pointers if(bindOpenALFunctions()) { // if EAX is available bind it's function pointers if (alIsExtensionPresent((ALubyte*)"EAX" )) bindEAXFunctions(); return(true); } // an error occured, shutdown OpenALDLLShutdown(); } else { Con::errorf(ConsoleLogEntry::General, " Error loading OpenAL Library: %s", dlerror()); } return(false); }
void al_isextensionpresent( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { if (NULL == alIsExtensionPresent) mogl_glunsupported("alIsExtensionPresent"); plhs[0]=mxCreateDoubleMatrix(1,1,mxREAL); *mxGetPr(plhs[0])=(double)alIsExtensionPresent((const ALchar*)mxGetData(prhs[0])); }
ALboolean ALFWIsXRAMSupported() { ALboolean bXRAM = AL_FALSE; if (alIsExtensionPresent("EAX-RAM") == AL_TRUE) { // Get X-RAM Function pointers eaxSetBufferMode = (EAXSetBufferMode)alGetProcAddress("EAXSetBufferMode"); eaxGetBufferMode = (EAXGetBufferMode)alGetProcAddress("EAXGetBufferMode"); if (eaxSetBufferMode && eaxGetBufferMode) { eXRAMSize = alGetEnumValue("AL_EAX_RAM_SIZE"); eXRAMFree = alGetEnumValue("AL_EAX_RAM_FREE"); eXRAMAuto = alGetEnumValue("AL_STORAGE_AUTOMATIC"); eXRAMHardware = alGetEnumValue("AL_STORAGE_HARDWARE"); eXRAMAccessible = alGetEnumValue("AL_STORAGE_ACCESSIBLE"); if (eXRAMSize && eXRAMFree && eXRAMAuto && eXRAMHardware && eXRAMAccessible) bXRAM = AL_TRUE; } } return bXRAM; }
HEFFECT CALL HGE_Impl::Effect_Load(const char *filename, DWORD size) { DWORD _size, length, samples; void *data; if(hOpenAL) { if(bSilent) return 1; if(size) { data=(void *)filename; _size=size; } else { data=Resource_Load(filename, &_size); if(!data) return 0; } const BYTE *magic = (const BYTE *) data; const bool isOgg = ( (_size > 4) && (magic[0] == 'O') && (magic[1] == 'g') && (magic[2] == 'g') && (magic[3] == 'S') ); // !!! FIXME: we currently expect Ogg Vorbis, since this is all we // !!! FIXME: need at the moment. if (!isOgg) { if(!size) Resource_Free(data); return 0; } // !!! FIXME: alternately, stream ogg data? void *allocation_decompressed = NULL; void *decompressed = NULL; ALsizei decompressed_size = 0; ALsizei freq = 0; ALenum fmt = AL_FORMAT_STEREO16; if (isOgg) { if (alIsExtensionPresent((const ALchar *) "AL_EXT_vorbis")) { fmt = alGetEnumValue((const ALchar *) "AL_FORMAT_VORBIS_EXT"); decompressed = data; decompressed_size = _size; } else { allocation_decompressed = decompress_vorbis((const BYTE *) data, _size, &decompressed_size, &fmt, &freq); decompressed = allocation_decompressed; } } ALuint bid = 0; alGenBuffers(1, &bid); alBufferData(bid, fmt, decompressed, decompressed_size, freq); free(allocation_decompressed); // not delete[] ! if(!size) Resource_Free(data); return (HEFFECT) bid; } else return 0; }
int main(int argc, char **argv) { StreamPlayer *player; int i; /* Print out usage if no file was specified */ if(argc < 2) { fprintf(stderr, "Usage: %s <filenames...>\n", argv[0]); return 1; } if(InitAL() != 0) return 1; if(alIsExtensionPresent("AL_SOFT_buffer_samples")) { printf("AL_SOFT_buffer_samples supported!\n"); alBufferSamplesSOFT = alGetProcAddress("alBufferSamplesSOFT"); alIsBufferFormatSupportedSOFT = alGetProcAddress("alIsBufferFormatSupportedSOFT"); } else printf("AL_SOFT_buffer_samples not supported\n"); player = NewPlayer(); /* Play each file listed on the command line */ for(i = 1;i < argc;i++) { if(!OpenPlayerFile(player, argv[i])) continue; printf("Playing %s (%s, %s, %dhz)\n", argv[i], TypeName(player->type), ChannelsName(player->channels), player->rate); fflush(stdout); if(!StartPlayer(player)) { ClosePlayerFile(player); continue; } while(UpdatePlayer(player)) Sleep(10); /* All done with this file. Close it and go to the next */ ClosePlayerFile(player); } printf("Done.\n"); /* All files done. Delete the player, and close OpenAL */ DeletePlayer(player); player = NULL; CloseAL(); return 0; }
static int lua_alIsExtensionPresent(lua_State* lua_state) { const ALchar* string_name; ALboolean ret_val; string_name = lua_tostring(lua_state, 1); ret_val = alIsExtensionPresent(string_name); lua_pushboolean(lua_state, ret_val); return 1; }
bool AudioDevice::isExtensionSupported(const std::string& extension) { ensureALInit(); if ((extension.length() > 2) && (extension.substr(0, 3) == "ALC")) return alcIsExtensionPresent(audioDevice, extension.c_str()) != AL_FALSE; else return alIsExtensionPresent(extension.c_str()) != AL_FALSE; }
OPAL_SOUND_MGR bool SoundManager::isOggExtensionPresent( void ) { if ( alIsExtensionPresent( "AL_EXT_vorbis" ) != AL_TRUE ) { printf("ERROR: SoundManager::isOggExtensionPresent : Ogg Vorbis extension not availablee!\n"); bOggExtensionPresent = false; return false; } return true; }
OpenALDevice::OpenALDevice(DeviceSpecs specs, int buffersize, std::string name) : m_playing(false), m_buffersize(buffersize) { // cannot determine how many channels or which format OpenAL uses, but // it at least is able to play 16 bit stereo audio specs.format = FORMAT_S16; if(name.empty()) m_device = alcOpenDevice(nullptr); else m_device = alcOpenDevice(name.c_str()); if(!m_device) AUD_THROW(DeviceException, "The audio device couldn't be opened with OpenAL."); // at least try to set the frequency ALCint attribs[] = { ALC_FREQUENCY, (ALCint)specs.rate, 0 }; ALCint* attributes = attribs; if(specs.rate == RATE_INVALID) attributes = nullptr; m_context = alcCreateContext(m_device, attributes); alcMakeContextCurrent(m_context); alcGetIntegerv(m_device, ALC_FREQUENCY, 1, (ALCint*)&specs.rate); // check for specific formats and channel counts to be played back if(alIsExtensionPresent("AL_EXT_FLOAT32") == AL_TRUE) specs.format = FORMAT_FLOAT32; m_useMC = alIsExtensionPresent("AL_EXT_MCFORMATS") == AL_TRUE; if((!m_useMC && specs.channels > CHANNELS_STEREO) || specs.channels == CHANNELS_STEREO_LFE || specs.channels == CHANNELS_SURROUND5) specs.channels = CHANNELS_STEREO; alGetError(); alcGetError(m_device); m_specs = specs; }
bool AudioDevice::isExtensionSupported(const std::string& extension) { // Create a temporary audio device in case none exists yet. // This device will not be used in this function and merely // makes sure there is a valid OpenAL device for extension // queries if none has been created yet. std::auto_ptr<AudioDevice> device; if (!audioDevice) device.reset(new AudioDevice); if ((extension.length() > 2) && (extension.substr(0, 3) == "ALC")) return alcIsExtensionPresent(audioDevice, extension.c_str()) != AL_FALSE; else return alIsExtensionPresent(extension.c_str()) != AL_FALSE; }
static void loadExtensions(void) { #ifdef WIN32 // Check for EAX 2.0. hasEAX = alIsExtensionPresent((ALchar*) "EAX2.0"); if(hasEAX) { EAXGet = (ALenum (*)(const struct _GUID*, ALuint, ALuint, ALvoid*, ALuint))alGetProcAddress("EAXGet"); EAXSet = (ALenum (*)(const struct _GUID*, ALuint, ALuint, ALvoid*, ALuint))alGetProcAddress("EAXSet"); if(!EAXGet || !EAXSet) hasEAX = false; } #else hasEAX = false; #endif }
void SoundManager::init() { for (int i = 0; i < kChannelCount; i++) _channels[i] = 0; for (int i = 0; i < kSoundTypeMAX; i++) _types[i].gain = 1.0; _curChannel = 1; _curID = 1; _dev = alcOpenDevice(0); _hasSound = _dev != 0; if (!_hasSound) warning("Failed to open OpenAL device. Disabling sound output"); _ctx = 0; _hasMultiChannel = false; _format51 = 0; if (_hasSound) { _ctx = alcCreateContext(_dev, 0); alcMakeContextCurrent(_ctx); if (!_ctx) throw Common::Exception("Could not create OpenAL context"); _hasMultiChannel = alIsExtensionPresent("AL_EXT_MCFORMATS"); _format51 = alGetEnumValue("AL_FORMAT_51CHN16"); } if (!createThread()) throw Common::Exception("Failed to create sound thread: %s", SDL_GetError()); _ready = true; if (!_hasSound) return; setListenerGain(ConfigMan.getDouble("volume", 1.0)); setTypeGain(kSoundTypeMusic, ConfigMan.getDouble("volume_music", 1.0)); setTypeGain(kSoundTypeSFX , ConfigMan.getDouble("volume_sfx" , 1.0)); setTypeGain(kSoundTypeVoice, ConfigMan.getDouble("volume_voice", 1.0)); setTypeGain(kSoundTypeVideo, ConfigMan.getDouble("volume_video", 1.0)); }
bool AudioDevice::isExtensionSupported(const std::string& extension) { // Create a temporary audio device in case none exists yet. // This device will not be used in this function and merely // makes sure there is a valid OpenAL device for extension // queries if none has been created yet. // // Using an std::vector for this since auto_ptr is deprecated // and we have no better STL facility for dynamically allocating // a temporary instance with strong exception guarantee. std::vector<AudioDevice> device; if (!audioDevice) device.resize(1); if ((extension.length() > 2) && (extension.substr(0, 3) == "ALC")) return alcIsExtensionPresent(audioDevice, extension.c_str()) != AL_FALSE; else return alIsExtensionPresent(extension.c_str()) != AL_FALSE; }
Pool::Pool() : sources() , totalSources(0) { // Clear errors. alGetError(); // Generate sources. for (int i = 0; i < MAX_SOURCES; i++) { alGenSources(1, &sources[i]); // We might hit an implementation-dependent limit on the total number // of sources before reaching MAX_SOURCES. if (alGetError() != AL_NO_ERROR) break; totalSources++; } if (totalSources < 4) throw love::Exception("Could not generate sources."); #ifdef AL_SOFT_direct_channels ALboolean hasext = alIsExtensionPresent("AL_SOFT_direct_channels"); #endif // Make all sources available initially. for (int i = 0; i < totalSources; i++) { #ifdef AL_SOFT_direct_channels if (hasext) { // Bypass virtualization of speakers for multi-channel sources in OpenAL Soft. alSourcei(sources[i], AL_DIRECT_CHANNELS_SOFT, AL_TRUE); } #endif available.push(sources[i]); } }
/* ================= AL_InitExtensions ================= */ static void AL_InitExtensions (void) { if (!s_openal_extensions->intvalue) { Com_Printf("*** IGNORING OPENAL EXTENSIONS ***\n", LOG_CLIENT); return; } Com_Printf("Initializing OpenAL extensions\n", LOG_CLIENT); if (alIsExtensionPresent("EAX2.0")) { if (s_openal_eax->intvalue) { alConfig.eax = true; Com_Printf("...using EAX2.0\n", LOG_CLIENT); } else Com_Printf("...ignoring EAX2.0\n", LOG_CLIENT); } else Com_Printf("...EAX2.0 not found\n", LOG_CLIENT); }
static Context *CreateContext(MFDevice *pDevice) { AudioDevice &device = *(AudioDevice*)pDevice->pInternal; if(!device.pDevice) device.pDevice = alcOpenDevice(pDevice->strings[MFDS_ID]); if(!device.pDevice) return NULL; Context *pContext = (Context*)MFHeap_Alloc(sizeof(Context)); pContext->pContext = alcCreateContext(device.pDevice, NULL); pContext->pDevice = pDevice; pContext->pRender = &device; Context *pOld = MakeCurrent(pContext); const char *pVersion = alGetString(AL_VERSION); const char *pExtensions = alGetString(AL_EXTENSIONS); MFDebug_Log(0, MFStr("OpenAL Version: %s", pVersion)); MFDebug_Log(0, MFStr("OpenAL Extensions: %s", pExtensions)); pContext->ext.static_buffer = alIsExtensionPresent("ALC_EXT_STATIC_BUFFER") == AL_TRUE; pContext->ext.offset = alIsExtensionPresent("AL_EXT_OFFSET") == AL_TRUE; pContext->ext.float32 = alIsExtensionPresent("AL_EXT_float32") == AL_TRUE; pContext->ext.source_radius = alIsExtensionPresent("AL_EXT_SOURCE_RADIUS") == AL_TRUE; pContext->ext.buffer_sub_data = alIsExtensionPresent("AL_SOFT_buffer_sub_data") == AL_TRUE; pContext->ext.buffer_samples = alIsExtensionPresent("AL_SOFT_buffer_samples") == AL_TRUE; if(pContext->ext.static_buffer) alBufferDataStatic = (PFNALBUFFERDATASTATICPROC)alGetProcAddress("alBufferDataStatic"); if(pContext->ext.buffer_sub_data) alBufferSubDataSOFT = (PFNALBUFFERSUBDATASOFTPROC)alGetProcAddress("alBufferSubDataSOFT"); alListener3f(AL_POSITION, 0, 0, 0); alListener3f(AL_VELOCITY, 0, 0, 0); alListener3f(AL_ORIENTATION, 0, 0, -1); MakeCurrent(pOld); return pContext; }
value lime_al_is_extension_present (value extname) { return alloc_bool (alIsExtensionPresent (val_string (extname))); }
/* =================== idSoundSample::Load Loads based on name, possibly doing a MakeDefault if necessary =================== */ void idSoundSample::Load( void ) { defaultSound = false; purged = false; hardwareBuffer = false; timestamp = GetNewTimeStamp(); if( timestamp == FILE_NOT_FOUND_TIMESTAMP ) { common->DWarning( "Couldn't load sound '%s' using default", name.c_str() ); MakeDefault(); return; } // load it idWaveFile fh; waveformatex_t info; if( fh.Open( name, &info ) == -1 ) { common->DWarning( "Couldn't load sound '%s' using default", name.c_str() ); MakeDefault(); return; } if( info.nChannels != 1 && info.nChannels != 2 ) { common->Warning( "idSoundSample: %s has %i channels, using default", name.c_str(), info.nChannels ); fh.Close(); MakeDefault(); return; } if( info.wBitsPerSample != 16 ) { common->Warning( "idSoundSample: %s is %dbits, expected 16bits using default", name.c_str(), info.wBitsPerSample ); fh.Close(); MakeDefault(); return; } if( info.nSamplesPerSec != 44100 && info.nSamplesPerSec != 22050 && info.nSamplesPerSec != 11025 ) { common->Warning( "idSoundCache: %s is %dHz, expected 11025, 22050 or 44100 Hz. Using default", name.c_str(), info.nSamplesPerSec ); fh.Close(); MakeDefault(); return; } objectInfo = info; objectSize = fh.GetOutputSize(); objectMemSize = fh.GetMemorySize(); nonCacheData = ( byte * )soundCacheAllocator.Alloc( objectMemSize ); fh.Read( nonCacheData, objectMemSize, NULL ); // optionally convert it to 22kHz to save memory CheckForDownSample(); // create hardware audio buffers if( idSoundSystemLocal::useOpenAL ) { // PCM loads directly if( objectInfo.wFormatTag == WAVE_FORMAT_TAG_PCM ) { alGetError(); alGenBuffers( 1, &openalBuffer ); if( alGetError() != AL_NO_ERROR ) { common->Error( "idSoundCache: error generating OpenAL hardware buffer" ); } if( alIsBuffer( openalBuffer ) ) { alGetError(); alBufferData( openalBuffer, objectInfo.nChannels == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16, nonCacheData, objectMemSize, objectInfo.nSamplesPerSec ); if( alGetError() != AL_NO_ERROR ) { common->Error( "idSoundCache: error loading data into OpenAL hardware buffer" ); } else { hardwareBuffer = true; } } } // OGG decompressed at load time (when smaller than s_decompressionLimit seconds, 6 seconds by default) if( objectInfo.wFormatTag == WAVE_FORMAT_TAG_OGG ) { #if defined(MACOS_X) if( ( objectSize < ( ( int ) objectInfo.nSamplesPerSec * idSoundSystemLocal::s_decompressionLimit.GetInteger() ) ) ) { #else if( ( alIsExtensionPresent( ID_ALCHAR "EAX-RAM" ) == AL_TRUE ) && ( objectSize < ( ( int ) objectInfo.nSamplesPerSec * idSoundSystemLocal::s_decompressionLimit.GetInteger() ) ) ) { #endif alGetError(); alGenBuffers( 1, &openalBuffer ); if( alGetError() != AL_NO_ERROR ) { common->Error( "idSoundCache: error generating OpenAL hardware buffer" ); } if( alIsBuffer( openalBuffer ) ) { idSampleDecoder *decoder = idSampleDecoder::Alloc(); float *destData = ( float * )soundCacheAllocator.Alloc( ( LengthIn44kHzSamples() + 1 ) * sizeof( float ) ); // Decoder *always* outputs 44 kHz data decoder->Decode( this, 0, LengthIn44kHzSamples(), destData ); // Downsample back to original frequency (save memory) if( objectInfo.nSamplesPerSec == 11025 ) { for( int i = 0; i < objectSize; i++ ) { if( destData[i * 4] < -32768.0f ) { ( ( short * )destData )[i] = -32768; } else if( destData[i * 4] > 32767.0f ) { ( ( short * )destData )[i] = 32767; } else { ( ( short * )destData )[i] = idMath::FtoiFast( destData[i * 4] ); } } } else if( objectInfo.nSamplesPerSec == 22050 ) { for( int i = 0; i < objectSize; i++ ) { if( destData[i * 2] < -32768.0f ) { ( ( short * )destData )[i] = -32768; } else if( destData[i * 2] > 32767.0f ) { ( ( short * )destData )[i] = 32767; } else { ( ( short * )destData )[i] = idMath::FtoiFast( destData[i * 2] ); } } } else { for( int i = 0; i < objectSize; i++ ) { if( destData[i] < -32768.0f ) { ( ( short * )destData )[i] = -32768; } else if( destData[i] > 32767.0f ) { ( ( short * )destData )[i] = 32767; } else { ( ( short * )destData )[i] = idMath::FtoiFast( destData[i] ); } } } alGetError(); alBufferData( openalBuffer, objectInfo.nChannels == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16, destData, objectSize * sizeof( short ), objectInfo.nSamplesPerSec ); if( alGetError() != AL_NO_ERROR ) { common->Error( "idSoundCache: error loading data into OpenAL hardware buffer" ); } else { hardwareBuffer = true; } soundCacheAllocator.Free( ( byte * )destData ); idSampleDecoder::Free( decoder ); } } } } fh.Close(); } /* =================== idSoundSample::PurgeSoundSample =================== */ void idSoundSample::PurgeSoundSample() { purged = true; if( hardwareBuffer && idSoundSystemLocal::useOpenAL ) { alGetError(); alDeleteBuffers( 1, &openalBuffer ); if( alGetError() != AL_NO_ERROR ) { common->Error( "idSoundCache: error unloading data from OpenAL hardware buffer" ); } else { openalBuffer = 0; hardwareBuffer = false; } } if( amplitudeData ) { soundCacheAllocator.Free( amplitudeData ); amplitudeData = NULL; } if( nonCacheData ) { soundCacheAllocator.Free( nonCacheData ); nonCacheData = NULL; } }
Sound_Renderer_AL::Sound_Renderer_AL() : m_device(0), m_context(0), m_bgm(0), m_bgm_source(0) { #ifndef _MACOSX #ifdef _WINDOWS m_openal32 = LoadLibrary("OpenAL32.dll"); #else m_openal32 = LoadLibrary("libopenal.so"); #endif if(!m_openal32) { std::cerr << "Loading OpenAL32.dll failed." << std::endl; throw Sound_Init_Failure(); } g_alBufferData = (alBufferData_fcn)GetProcAddress(m_openal32, "alBufferData"); g_alcCloseDevice = (alcCloseDevice_fcn)GetProcAddress(m_openal32, "alcCloseDevice"); g_alcCreateContext = (alcCreateContext_fcn)GetProcAddress(m_openal32, "alcCreateContext"); g_alcDestroyContext = (alcDestroyContext_fcn)GetProcAddress(m_openal32, "alcDestroyContext"); g_alIsExtensionPresent = (alIsExtensionPresent_fcn)GetProcAddress(m_openal32, "alIsExtensionPresent"); g_alcMakeContextCurrent = (alcMakeContextCurrent_fcn)GetProcAddress(m_openal32, "alcMakeContextCurrent"); g_alcOpenDevice = (alcOpenDevice_fcn)GetProcAddress(m_openal32, "alcOpenDevice"); g_alDeleteBuffers = (alDeleteBuffers_fcn)GetProcAddress(m_openal32, "alDeleteBuffers"); g_alDeleteSources = (alDeleteSources_fcn)GetProcAddress(m_openal32, "alDeleteSources"); g_alGenBuffers = (alGenBuffers_fcn)GetProcAddress(m_openal32, "alGenBuffers"); g_alGetError = (alGetError_fcn)GetProcAddress(m_openal32, "alGetError"); g_alGetListenerf = (alGetListenerf_fcn)GetProcAddress(m_openal32, "alGetListenerf"); g_alGetListenerfv = (alGetListenerfv_fcn)GetProcAddress(m_openal32, "alGetListenerfv"); g_alGetSourcef = (alGetSourcef_fcn)GetProcAddress(m_openal32, "alGetSourcef"); g_alGetSourcefv = (alGetSourcefv_fcn)GetProcAddress(m_openal32, "alGetSourcefv"); g_alGetSourcei = (alGetSourcei_fcn)GetProcAddress(m_openal32, "alGetSourcei"); g_alGenSources = (alGenSources_fcn)GetProcAddress(m_openal32, "alGenSources"); g_alListenerf = (alListenerf_fcn)GetProcAddress(m_openal32, "alListenerf"); g_alListenerfv = (alListenerfv_fcn)GetProcAddress(m_openal32, "alListenerfv"); g_alSourcef = (alSourcef_fcn)GetProcAddress(m_openal32, "alSourcef"); g_alSourcefv = (alSourcefv_fcn)GetProcAddress(m_openal32, "alSourcefv"); g_alSourcei = (alSourcei_fcn)GetProcAddress(m_openal32, "alSourcei"); g_alSourcePause = (alSourcePause_fcn)GetProcAddress(m_openal32, "alSourcePause"); g_alSourcePlay = (alSourcePlay_fcn)GetProcAddress(m_openal32, "alSourcePlay"); g_alSourceStop = (alSourceStop_fcn)GetProcAddress(m_openal32, "alSourceStop"); if(!g_alBufferData || !g_alcCloseDevice || !g_alcCreateContext || !g_alcDestroyContext || !g_alIsExtensionPresent || !g_alcMakeContextCurrent || !g_alcOpenDevice || !g_alDeleteBuffers || !g_alDeleteSources || !g_alGenBuffers || !g_alGetError || !g_alGetListenerf || !g_alGetListenerfv || !g_alGetSourcef || !g_alGetSourcefv || !g_alGetSourcei || !g_alGenSources || !g_alListenerf || !g_alListenerfv || !g_alSourcef || !g_alSourcefv || !g_alSourcei || !g_alSourcePause || !g_alSourcePlay || !g_alSourceStop) { std::cerr << "Loading OpenAL32.dll failed." << std::endl; zero_handles(); FreeLibrary(m_openal32); throw Sound_Init_Failure(); } #ifdef _WINDOWS m_libvorbisfile = LoadLibrary("libvorbisfile.dll"); #else m_libvorbisfile = LoadLibrary("libvorbisfile.so"); #endif if(!m_libvorbisfile) { std::cerr << "Loading libvorbisfile.dll failed." << std::endl; zero_handles(); FreeLibrary(m_openal32); throw Sound_Init_Failure(); } g_ov_clear = (ov_clear_fcn)GetProcAddress(m_libvorbisfile, "ov_clear"); g_ov_info = (ov_info_fcn)GetProcAddress(m_libvorbisfile, "ov_info"); g_ov_fopen = (ov_fopen_fcn)GetProcAddress(m_libvorbisfile, "ov_fopen"); g_ov_pcm_total = (ov_pcm_total_fcn)GetProcAddress(m_libvorbisfile, "ov_pcm_total"); g_ov_read = (ov_read_fcn)GetProcAddress(m_libvorbisfile, "ov_read"); if(!g_ov_clear || !g_ov_info || !g_ov_fopen || !g_ov_pcm_total || !g_ov_read) { std::cerr << "Loading libvorbisfile.dll failed." << std::endl; zero_handles(); FreeLibrary(m_libvorbisfile); FreeLibrary(m_openal32); throw Sound_Init_Failure(); } #else g_alBufferData = (alBufferData_fcn)::alBufferData; g_alcCloseDevice = (alcCloseDevice_fcn)::alcCloseDevice; g_alcCreateContext = (alcCreateContext_fcn)::alcCreateContext; g_alcDestroyContext = (alcDestroyContext_fcn)::alcDestroyContext; g_alIsExtensionPresent = (alIsExtensionPresent_fcn)::alIsExtensionPresent; g_alcMakeContextCurrent = (alcMakeContextCurrent_fcn)::alcMakeContextCurrent; g_alcOpenDevice = (alcOpenDevice_fcn)::alcOpenDevice; g_alDeleteBuffers = (alDeleteBuffers_fcn)::alDeleteBuffers; g_alDeleteSources = (alDeleteSources_fcn)::alDeleteSources; g_alGenBuffers = (alGenBuffers_fcn)::alGenBuffers; g_alGetError = (alGetError_fcn)::alGetError; g_alGetListenerf = (alGetListenerf_fcn)::alGetListenerf; g_alGetListenerfv = (alGetListenerfv_fcn)::alGetListenerfv; g_alGetSourcef = (alGetSourcef_fcn)::alGetSourcef; g_alGetSourcefv = (alGetSourcefv_fcn)::alGetSourcefv; g_alGetSourcei = (alGetSourcei_fcn)::alGetSourcei; g_alGenSources = (alGenSources_fcn)::alGenSources; g_alListenerf = (alListenerf_fcn)::alListenerf; g_alListenerfv = (alListenerfv_fcn)::alListenerfv; g_alSourcef = (alSourcef_fcn)::alSourcef; g_alSourcefv = (alSourcefv_fcn)::alSourcefv; g_alSourcei = (alSourcei_fcn)::alSourcei; g_alSourcePause = (alSourcePause_fcn)::alSourcePause; g_alSourcePlay = (alSourcePlay_fcn)::alSourcePlay; g_alSourceStop = (alSourceStop_fcn)::alSourceStop; g_ov_clear = (ov_clear_fcn)::ov_clear; g_ov_info = (ov_info_fcn)::ov_info; g_ov_fopen = (ov_fopen_fcn)::ov_fopen; g_ov_pcm_total = (ov_pcm_total_fcn)::ov_pcm_total; g_ov_read = (ov_read_fcn)::ov_read; #endif m_device = alcOpenDevice()(0); if(!m_device) { zero_handles(); FreeLibrary(m_libvorbisfile); FreeLibrary(m_openal32); throw Sound_Init_Failure(); } m_context = alcCreateContext()(m_device, 0); if(!m_context) { alcCloseDevice()(m_device); zero_handles(); FreeLibrary(m_libvorbisfile); FreeLibrary(m_openal32); throw Sound_Init_Failure(); } if(!alcMakeContextCurrent()(m_context)) { alcDestroyContext()(m_context); alcCloseDevice()(m_device); zero_handles(); FreeLibrary(m_libvorbisfile); FreeLibrary(m_openal32); throw Sound_Init_Failure(); } // Check for Vorbis extension functionality; seems to always fail :( alIsExtensionPresent()("AL_EXT_vorbis"); //cerr << "Valid Audio Formats: " << alutGetMIMETypes(ALUT_LOADER_BUFFER) << std::endl; ALfloat listener_position[] = {0.0f, 0.0f, 0.0f}; ALfloat listener_velocity[] = {0.0f, 0.0f, 0.0f}; ALfloat listener_forward_and_up[] = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}; alListenerfv()(AL_POSITION, listener_position); alListenerfv()(AL_VELOCITY, listener_velocity); alListenerfv()(AL_ORIENTATION, listener_forward_and_up); }
static GstCaps * gst_openal_helper_probe_caps (ALCcontext * context) { static const struct { gint count; GstAudioChannelPosition positions[8]; } chans[] = { { 1, { GST_AUDIO_CHANNEL_POSITION_MONO} }, { 2, { GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT} }, { 4, { GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT} }, { 6, { GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, GST_AUDIO_CHANNEL_POSITION_LFE1, GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT} }, { 7, { GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, GST_AUDIO_CHANNEL_POSITION_LFE1, GST_AUDIO_CHANNEL_POSITION_REAR_CENTER, GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT} }, { 8, { GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, GST_AUDIO_CHANNEL_POSITION_LFE1, GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT, GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT} },}; GstStructure *structure; guint64 channel_mask; GstCaps *caps; ALCcontext *old; old = pushContext (context); caps = gst_caps_new_empty (); if (alIsExtensionPresent ("AL_EXT_MCFORMATS")) { const char *fmt32[] = { "AL_FORMAT_MONO_FLOAT32", "AL_FORMAT_STEREO_FLOAT32", "AL_FORMAT_QUAD32", "AL_FORMAT_51CHN32", "AL_FORMAT_61CHN32", "AL_FORMAT_71CHN32", NULL }, *fmt16[] = { "AL_FORMAT_MONO16", "AL_FORMAT_STEREO16", "AL_FORMAT_QUAD16", "AL_FORMAT_51CHN16", "AL_FORMAT_61CHN16", "AL_FORMAT_71CHN16", NULL}, *fmt8[] = { "AL_FORMAT_MONO8", "AL_FORMAT_STEREO8", "AL_FORMAT_QUAD8", "AL_FORMAT_51CHN8", "AL_FORMAT_61CHN8", "AL_FORMAT_71CHN8", NULL}; int i; if (alIsExtensionPresent ("AL_EXT_FLOAT32")) { for (i = 0; fmt32[i]; i++) { ALenum value = alGetEnumValue (fmt32[i]); if (checkALError () != AL_NO_ERROR || value == 0 || value == -1) continue; structure = gst_structure_new ("audio/x-raw", "format", G_TYPE_STRING, GST_AUDIO_NE (F32), "rate", GST_TYPE_INT_RANGE, OPENAL_MIN_RATE, OPENAL_MAX_RATE, "channels", G_TYPE_INT, chans[i].count, NULL); if (chans[i].count > 2) { gst_audio_channel_positions_to_mask (chans[i].positions, chans[i].count, FALSE, &channel_mask); gst_structure_set (structure, "channel-mask", GST_TYPE_BITMASK, channel_mask, NULL); } gst_caps_append_structure (caps, structure); } } for (i = 0; fmt16[i]; i++) { ALenum value = alGetEnumValue (fmt16[i]); if (checkALError () != AL_NO_ERROR || value == 0 || value == -1) continue; structure = gst_structure_new ("audio/x-raw", "format", G_TYPE_STRING, GST_AUDIO_NE (S16), "rate", GST_TYPE_INT_RANGE, OPENAL_MIN_RATE, OPENAL_MAX_RATE, "channels", G_TYPE_INT, chans[i].count, NULL); if (chans[i].count > 2) { gst_audio_channel_positions_to_mask (chans[i].positions, chans[i].count, FALSE, &channel_mask); gst_structure_set (structure, "channel-mask", GST_TYPE_BITMASK, channel_mask, NULL); } gst_caps_append_structure (caps, structure); } for (i = 0; fmt8[i]; i++) { ALenum value = alGetEnumValue (fmt8[i]); if (checkALError () != AL_NO_ERROR || value == 0 || value == -1) continue; structure = gst_structure_new ("audio/x-raw", "format", G_TYPE_STRING, G_STRINGIFY (U8), "rate", GST_TYPE_INT_RANGE, OPENAL_MIN_RATE, OPENAL_MAX_RATE, "channels", G_TYPE_INT, chans[i].count, NULL); if (chans[i].count > 2) { gst_audio_channel_positions_to_mask (chans[i].positions, chans[i].count, FALSE, &channel_mask); gst_structure_set (structure, "channel-mask", GST_TYPE_BITMASK, channel_mask, NULL); } gst_caps_append_structure (caps, structure); } } else { if (alIsExtensionPresent ("AL_EXT_FLOAT32")) { structure = gst_structure_new ("audio/x-raw", "format", G_TYPE_STRING, GST_AUDIO_NE (F32), "rate", GST_TYPE_INT_RANGE, OPENAL_MIN_RATE, OPENAL_MAX_RATE, "channels", GST_TYPE_INT_RANGE, 1, 2, NULL); gst_caps_append_structure (caps, structure); } structure = gst_structure_new ("audio/x-raw", "format", G_TYPE_STRING, GST_AUDIO_NE (S16), "rate", GST_TYPE_INT_RANGE, OPENAL_MIN_RATE, OPENAL_MAX_RATE, "channels", GST_TYPE_INT_RANGE, 1, 2, NULL); gst_caps_append_structure (caps, structure); structure = gst_structure_new ("audio/x-raw", "format", G_TYPE_STRING, G_STRINGIFY (U8), "rate", GST_TYPE_INT_RANGE, OPENAL_MIN_RATE, OPENAL_MAX_RATE, "channels", GST_TYPE_INT_RANGE, 1, 2, NULL); gst_caps_append_structure (caps, structure); } if (alIsExtensionPresent ("AL_EXT_double")) { structure = gst_structure_new ("audio/x-raw", "format", G_TYPE_STRING, GST_AUDIO_NE (F64), "rate", GST_TYPE_INT_RANGE, OPENAL_MIN_RATE, OPENAL_MAX_RATE, "channels", GST_TYPE_INT_RANGE, 1, 2, NULL); gst_caps_append_structure (caps, structure); } if (alIsExtensionPresent ("AL_EXT_IMA4")) { structure = gst_structure_new ("audio/x-adpcm", "layout", G_TYPE_STRING, "ima", "rate", GST_TYPE_INT_RANGE, OPENAL_MIN_RATE, OPENAL_MAX_RATE, "channels", GST_TYPE_INT_RANGE, 1, 2, NULL); gst_caps_append_structure (caps, structure); } if (alIsExtensionPresent ("AL_EXT_ALAW")) { structure = gst_structure_new ("audio/x-alaw", "rate", GST_TYPE_INT_RANGE, OPENAL_MIN_RATE, OPENAL_MAX_RATE, "channels", GST_TYPE_INT_RANGE, 1, 2, NULL); gst_caps_append_structure (caps, structure); } if (alIsExtensionPresent ("AL_EXT_MULAW_MCFORMATS")) { const char *fmtmulaw[] = { "AL_FORMAT_MONO_MULAW", "AL_FORMAT_STEREO_MULAW", "AL_FORMAT_QUAD_MULAW", "AL_FORMAT_51CHN_MULAW", "AL_FORMAT_61CHN_MULAW", "AL_FORMAT_71CHN_MULAW", NULL }; int i; for (i = 0; fmtmulaw[i]; i++) { ALenum value = alGetEnumValue (fmtmulaw[i]); if (checkALError () != AL_NO_ERROR || value == 0 || value == -1) continue; structure = gst_structure_new ("audio/x-mulaw", "rate", GST_TYPE_INT_RANGE, OPENAL_MIN_RATE, OPENAL_MAX_RATE, "channels", G_TYPE_INT, chans[i].count, NULL); if (chans[i].count > 2) { gst_audio_channel_positions_to_mask (chans[i].positions, chans[i].count, FALSE, &channel_mask); gst_structure_set (structure, "channel-mask", GST_TYPE_BITMASK, channel_mask, NULL); } gst_caps_append_structure (caps, structure); } } else if (alIsExtensionPresent ("AL_EXT_MULAW")) { structure = gst_structure_new ("audio/x-mulaw", "rate", GST_TYPE_INT_RANGE, OPENAL_MIN_RATE, OPENAL_MAX_RATE, "channels", GST_TYPE_INT_RANGE, 1, 2, NULL); gst_caps_append_structure (caps, structure); } popContext (old, context); return caps; }
ALenum GetSampleFormat(ALuint channels, ALuint bits, bool isFloat) { #define CHECK_FMT_RET(f) do { \ ALenum fmt = alGetEnumValue(#f); \ if(alGetError() == AL_NO_ERROR && fmt != 0 && fmt != -1) \ return fmt; \ } while(0) if(!isFloat) { if(bits == 8) { if(channels == 1) CHECK_FMT_RET(AL_FORMAT_MONO8); if(channels == 2) CHECK_FMT_RET(AL_FORMAT_STEREO8); if(alIsExtensionPresent("AL_EXT_MCFORMATS")) { if(channels == 4) CHECK_FMT_RET(AL_FORMAT_QUAD8); if(channels == 6) CHECK_FMT_RET(AL_FORMAT_51CHN8); if(channels == 7) CHECK_FMT_RET(AL_FORMAT_61CHN8); if(channels == 8) CHECK_FMT_RET(AL_FORMAT_71CHN8); } if(alIsExtensionPresent("AL_LOKI_quadriphonic")) { if(channels == 4) CHECK_FMT_RET(AL_FORMAT_QUAD8_LOKI); } SetError("Unsupported 8-bit channel count\n"); return AL_NONE; } if(bits == 16) { if(channels == 1) CHECK_FMT_RET(AL_FORMAT_MONO16); if(channels == 2) CHECK_FMT_RET(AL_FORMAT_STEREO16); if(alIsExtensionPresent("AL_EXT_MCFORMATS")) { if(channels == 4) CHECK_FMT_RET(AL_FORMAT_QUAD16); if(channels == 6) CHECK_FMT_RET(AL_FORMAT_51CHN16); if(channels == 7) CHECK_FMT_RET(AL_FORMAT_61CHN16); if(channels == 8) CHECK_FMT_RET(AL_FORMAT_71CHN16); } if(alIsExtensionPresent("AL_LOKI_quadriphonic")) { if(channels == 4) CHECK_FMT_RET(AL_FORMAT_QUAD16_LOKI); } SetError("Unsupported 16-bit channel count\n"); return AL_NONE; } SetError("Unsupported PCM bit depth\n"); return AL_NONE; } if(bits == 32 && alIsExtensionPresent("AL_EXT_FLOAT32")) { if(channels == 1) CHECK_FMT_RET(AL_FORMAT_MONO_FLOAT32); if(channels == 2) CHECK_FMT_RET(AL_FORMAT_STEREO_FLOAT32); if(alIsExtensionPresent("AL_EXT_MCFORMATS")) { if(channels == 4) CHECK_FMT_RET(AL_FORMAT_QUAD32); if(channels == 6) CHECK_FMT_RET(AL_FORMAT_51CHN32); if(channels == 7) CHECK_FMT_RET(AL_FORMAT_61CHN32); if(channels == 8) CHECK_FMT_RET(AL_FORMAT_71CHN32); } SetError("Unsupported float32 channel count\n"); return AL_NONE; } if(bits == 64 && alIsExtensionPresent("AL_EXT_DOUBLE")) { if(channels == 1) CHECK_FMT_RET(AL_FORMAT_MONO_DOUBLE_EXT); if(channels == 2) CHECK_FMT_RET(AL_FORMAT_STEREO_DOUBLE_EXT); SetError("Unsupported double channel count\n"); return AL_NONE; } #undef CHECK_FMT_RET SetError("Unsupported float bit depth\n"); return AL_NONE; }
/* * Init call */ ALDeviceList::ALDeviceList() { ALDEVICEINFO ALDeviceInfo; char *devices; s32 index; const char *defaultDeviceName = NULL; const char *actualDeviceName = NULL; // DeviceInfo vector stores, for each enumerated device, it's device name, selection status, spec version #, and extension support vDeviceInfo.empty(); vDeviceInfo.reserve(10); defaultDeviceIndex = 0; // grab function pointers for 1.0-API functions, and if successful proceed to enumerate all devices //if (LoadOAL10Library(NULL, &ALFunction) == TRUE) { if (alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT")) { devices = (char *)alcGetString(NULL, ALC_DEVICE_SPECIFIER); defaultDeviceName = (char *)alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER); index = 0; // go through device list (each device terminated with a single NULL, list terminated with double NULL) while (devices != NULL && strlen(devices) > 0) { if (strcmp(defaultDeviceName, devices) == 0) { defaultDeviceIndex = index; } ALCdevice *device = alcOpenDevice(devices); if (device) { ALCcontext *context = alcCreateContext(device, NULL); if (context) { alcMakeContextCurrent(context); // if new actual device name isn't already in the list, then add it... actualDeviceName = alcGetString(device, ALC_DEVICE_SPECIFIER); bool bNewName = true; for (s32 i = 0; i < GetNumDevices(); i++) { if (strcmp(GetDeviceName(i), actualDeviceName) == 0) { bNewName = false; } } if ((bNewName) && (actualDeviceName != NULL) && (strlen(actualDeviceName) > 0)) { ALDeviceInfo.bSelected = true; ALDeviceInfo.strDeviceName = actualDeviceName; alcGetIntegerv(device, ALC_MAJOR_VERSION, sizeof(s32), &ALDeviceInfo.iMajorVersion); alcGetIntegerv(device, ALC_MINOR_VERSION, sizeof(s32), &ALDeviceInfo.iMinorVersion); ALDeviceInfo.pvstrExtensions = new vector<string>; // Check for ALC Extensions if (alcIsExtensionPresent(device, "ALC_EXT_CAPTURE") == AL_TRUE) ALDeviceInfo.pvstrExtensions->push_back("ALC_EXT_CAPTURE"); if (alcIsExtensionPresent(device, "ALC_EXT_EFX") == AL_TRUE) ALDeviceInfo.pvstrExtensions->push_back("ALC_EXT_EFX"); // Check for AL Extensions if (alIsExtensionPresent("AL_EXT_OFFSET") == AL_TRUE) ALDeviceInfo.pvstrExtensions->push_back("AL_EXT_OFFSET"); if (alIsExtensionPresent("AL_EXT_LINEAR_DISTANCE") == AL_TRUE) ALDeviceInfo.pvstrExtensions->push_back("AL_EXT_LINEAR_DISTANCE"); if (alIsExtensionPresent("AL_EXT_EXPONENT_DISTANCE") == AL_TRUE) ALDeviceInfo.pvstrExtensions->push_back("AL_EXT_EXPONENT_DISTANCE"); if (alIsExtensionPresent("EAX2.0") == AL_TRUE) ALDeviceInfo.pvstrExtensions->push_back("EAX2.0"); if (alIsExtensionPresent("EAX3.0") == AL_TRUE) ALDeviceInfo.pvstrExtensions->push_back("EAX3.0"); if (alIsExtensionPresent("EAX4.0") == AL_TRUE) ALDeviceInfo.pvstrExtensions->push_back("EAX4.0"); if (alIsExtensionPresent("EAX5.0") == AL_TRUE) ALDeviceInfo.pvstrExtensions->push_back("EAX5.0"); if (alIsExtensionPresent("EAX-RAM") == AL_TRUE) ALDeviceInfo.pvstrExtensions->push_back("EAX-RAM"); // Get Source Count ALDeviceInfo.uiSourceCount = GetMaxNumSources(); vDeviceInfo.push_back(ALDeviceInfo); } alcMakeContextCurrent(NULL); alcDestroyContext(context); } alcCloseDevice(device); } devices += strlen(devices) + 1; index += 1; } } //} ResetFilters(); }
ALboolean CDECL wine_alIsExtensionPresent(const ALchar* extname) { return alIsExtensionPresent(extname); }
static int get_formats_openal(out123_handle *ao) { return MPG123_ENC_SIGNED_16|MPG123_ENC_UNSIGNED_8|((alIsExtensionPresent((ALubyte*)"AL_EXT_float32") == AL_TRUE) ? MPG123_ENC_FLOAT_32 : 0); }