void cOAL_Device::SetListenerVelocity (const float* apVel ) { DEF_FUNC_NAME ("cOAL_Device::SetListenerVelocity()"); FUNC_USES_AL; RUN_AL_FUNC(alListenerfv (AL_VELOCITY,apVel)); }
void cOAL_EffectSlot::SetAutoAdjust( bool abAuto ) { DEF_FUNC_NAME(""); FUNC_USES_AL; RUN_AL_FUNC( alAuxiliaryEffectSloti (mlObjectId, AL_EFFECTSLOT_AUXILIARY_SEND_AUTO, (ALboolean) abAuto)); }
void cOAL_Device::SetListenerPosition (const float* apPos ) { DEF_FUNC_NAME ("cOAL_Device::SetListenerPosition()"); FUNC_USES_AL; RUN_AL_FUNC(alListenerfv ( AL_POSITION, apPos )); }
void cOAL_Device::SetDistanceModel(eOAL_DistanceModel aModel) { DEF_FUNC_NAME("OAL_SetDistanceModel"); FUNC_USES_AL; ALenum distModel; switch(aModel) { case eOAL_DistanceModel_Inverse: distModel = AL_INVERSE_DISTANCE; break; case eOAL_DistanceModel_Inverse_Clamped: distModel = AL_INVERSE_DISTANCE_CLAMPED; break; case eOAL_DistanceModel_Linear: distModel = AL_LINEAR_DISTANCE; break; case eOAL_DistanceModel_Linear_Clamped: distModel = AL_LINEAR_DISTANCE_CLAMPED; break; case eOAL_DistanceModel_Exponent: distModel = AL_EXPONENT_DISTANCE; break; case eOAL_DistanceModel_Exponent_Clamped: distModel = AL_EXPONENT_DISTANCE_CLAMPED; break; case eOAL_DistanceModel_None: distModel = AL_NONE; default: break; } RUN_AL_FUNC(alDistanceModel(distModel)); }
void cOAL_OggStream::Destroy() { DEF_FUNC_NAME("cOAL_OggStream::Unload()"); // If we loaded a stream, clear the handle to the Ogg Vorbis file if(mbIsValidHandle) ov_clear(&movStreamHandle); }
bool cOAL_EffectSlot::IsValidObject() { DEF_FUNC_NAME("cOAL_EffectSlot::IsValidObject()"); FUNC_USES_AL; return (alIsAuxiliaryEffectSlot(mlObjectId) == AL_TRUE); }
bool cOAL_EffectSlot::DestroyLowLevelID() { DEF_FUNC_NAME("cOAL_EffectSlot::DestroyLowLevelID()"); FUNC_USES_AL; RUN_AL_FUNC(alDeleteAuxiliaryEffectSlots(1,&mlObjectId)); return (!AL_ERROR_OCCURED && !IsValidObject()); }
bool cOAL_EffectSlot::CreateLowLevelID() { DEF_FUNC_NAME("cOAL_EffectSlot::CreateLowLevelID()"); FUNC_USES_AL; RUN_AL_FUNC(alGenAuxiliaryEffectSlots(1,&mlObjectId)); return (!AL_ERROR_OCCURED && IsValidObject()); }
string cOAL_Device::GetDefaultDeviceName() { DEF_FUNC_NAME(cOAL_Device::GetDefaultDeviceName); FUNC_USES_ALC; string sDev = alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER); return sDev; }
void cOAL_Device::SetListenerOrientation(const float* apForward, const float* apUp) { DEF_FUNC_NAME ("cOAL_Device::SetListenerOrientation()"); FUNC_USES_AL; float fOrientation[6] = { apForward[0], apForward[1], apForward[2], apUp[0], apUp[1], apUp[2] }; RUN_AL_FUNC(alListenerfv ( AL_ORIENTATION, fOrientation )); }
bool cOAL_EffectSlot::AttachEffect ( cOAL_Effect *apEffect ) { DEF_FUNC_NAME("cOAL_EffectSlot::AttachEffect()"); FUNC_USES_AL; mpEffect = apEffect; RUN_AL_FUNC ( alAuxiliaryEffectSloti (mlObjectId, AL_EFFECTSLOT_EFFECT, ((mpEffect == NULL)? AL_EFFECT_NULL : mpEffect->GetEffectID()) ) ); return !AL_ERROR_OCCURED; }
void cOAL_EffectSlot::SetGain ( float afGain ) { DEF_FUNC_NAME(""); FUNC_USES_AL; if (afGain <0) afGain = 0; if (afGain >1) afGain = 1; RUN_AL_FUNC( alAuxiliaryEffectSlotf (mlObjectId, AL_EFFECTSLOT_GAIN, afGain)); }
void cOAL_Device::SetListenerGain ( float afGain ) { DEF_FUNC_NAME ("cOAL_Device::SetListenerGain()"); FUNC_USES_AL; if ( afGain < 0 ) afGain = 0; if ( afGain > 1 ) afGain = 1; RUN_AL_FUNC(alListenerf ( AL_GAIN, afGain )); }
bool cOAL_Device::RegainContext() { DEF_FUNC_NAME("cOAL_Device::RegainContext"); FUNC_USES_ALC; if (mpContext == NULL) return false; bool bSuccess = RUN_ALC_FUNC((alcMakeContextCurrent(mpContext) == AL_TRUE)); if (bSuccess) { RUN_ALC_FUNC(alcProcessContext(mpContext)); } return bSuccess; }
bool cOAL_OggStream::Stream(cOAL_Buffer* apDestBuffer) { DEF_FUNC_NAME("cOAL_OggStream::Stream()"); FUNC_USES_AL; long lDataSize = 0; //hpl::Log("Streaming...\n"); double fStartTime = GetTime(); // Loop which loads chunks of decoded data into a buffer while(lDataSize < (int)mlBufferSize) { long lChunkSize = ov_read(&movStreamHandle, mpPCMBuffer+lDataSize, mlBufferSize-lDataSize, SYS_ENDIANNESS, 2, 1, &mlCurrent_section); // If we get a 0, then we are at the end of the file if(lChunkSize == 0) { break; } // If we get a negative value, then something went wrong. Clean up and set error status. else if(lChunkSize == OV_HOLE) ; else if(lChunkSize==OV_EINVAL || lChunkSize==OV_EBADLINK || lChunkSize<0) mbStatus = false; else lDataSize += lChunkSize; } // Bind the data to the Buffer Object if(lDataSize) apDestBuffer->Feed(mpPCMBuffer, lDataSize, fStartTime); else mbEOF = true; if(AL_ERROR_OCCURED) { //hpl::Log("%s\n", OAL_GetALErrorString().c_str()); mbStatus = false; } return (lDataSize != 0); }
void cOAL_Device::Close () { DEF_FUNC_NAME("cOAL_Device::Close()"); FUNC_USES_ALC; LogMsg("",eOAL_LogVerbose_Low, eOAL_LogMsg_Command, "Closing device...\n" ); LogMsg("",eOAL_LogVerbose_Low, eOAL_LogMsg_Info, "Cleaning up Samples...\n" ); //Delete samples { for(tSampleListIt it = mlstSamples.begin(); it!=mlstSamples.end(); ++it ) delete (*it); mlstSamples.clear(); } LogMsg("",eOAL_LogVerbose_Low, eOAL_LogMsg_Info, "Cleaning up Streams...\n" ); { for (tStreamListIt it=mlstStreams.begin();it!=mlstStreams.end(); ++it ) delete (*it); mlstStreams.clear(); } if(mpSourceManager) { LogMsg("",eOAL_LogVerbose_Low, eOAL_LogMsg_Info, "Cleaning up Source Manager...\n" ); mpSourceManager->Destroy(); delete mpSourceManager; mpSourceManager = NULL; } if (mpEFXManager) { LogMsg("",eOAL_LogVerbose_Low, eOAL_LogMsg_Info, "Cleaning up EFX Manager...\n" ); mpEFXManager->Destroy(); delete mpEFXManager; mpEFXManager = NULL; } LogMsg("",eOAL_LogVerbose_Low, eOAL_LogMsg_Info, "Cleaning up Context and closing Low Level Device...\n" ); //Delete device and context. RUN_ALC_FUNC(alcMakeContextCurrent ( NULL )); RUN_ALC_FUNC(alcDestroyContext ( mpContext )); RUN_ALC_FUNC(alcCloseDevice ( mpDevice )); if (!ALC_ERROR_OCCURED) LogMsg("",eOAL_LogVerbose_Low, eOAL_LogMsg_Info, "Done\n" ); }
void cOAL_EffectSlot::Update() { DEF_FUNC_NAME(""); FUNC_USES_AL; if (mpEffect) { mpEffect->Lock(); if (mpEffect->NeedsUpdate()) { RUN_AL_FUNC( alAuxiliaryEffectSloti(mlObjectId, AL_EFFECTSLOT_EFFECT, mpEffect->GetEffectID()) ); //LogMsg("",eOAL_LogVerbose_Medium, eOAL_LogMsg_Info, "Slot updated\n"); mpEffect->SetUpdated(); } mpEffect->Unlock(); } }
bool cOAL_OggStream::CreateFromFile(const wstring &asFilename) { DEF_FUNC_NAME("cOAL_OggStream::Load()"); if(mbStatus==false) return false; int lOpenResult; FILE *pStreamFile = OpenFileW(asFilename, L"rb"); if (pStreamFile == NULL) return false; msFilename = asFilename; // If not an Ogg file, set status and exit lOpenResult = ov_open_callbacks(pStreamFile, &movStreamHandle, NULL, 0, OV_CALLBACKS_DEFAULT); if(lOpenResult<0) { fclose(pStreamFile); mbIsValidHandle = false; mbStatus = false; return false; } mbIsValidHandle = true; // Get file info vorbis_info *viFileInfo = ov_info ( &movStreamHandle, -1 ); mlChannels = viFileInfo->channels; mlFrequency = viFileInfo->rate; mlSamples = (long) ov_pcm_total ( &movStreamHandle, -1 ); mFormat = (mlChannels == 2) ? AL_FORMAT_STEREO16 : AL_FORMAT_MONO16; mfTotalTime = ov_time_total( &movStreamHandle, -1 ); return true; }
//------------------------------------------------------------------------- vector<string> cOAL_Device::GetOutputDevices() { DEF_FUNC_NAME(cOAL_Device::GetOutputDevices); FUNC_USES_ALC; vector<string> devices; bool bEnumerate = RUN_ALC_FUNC(alcIsExtensionPresent(NULL, (const ALCchar*)"ALC_ENUMERATION_EXT") == AL_TRUE); bool bEnumerate_all = RUN_ALC_FUNC(alcIsExtensionPresent(NULL, (const ALCchar*)"ALC_ENUMERATE_ALL_EXT") == AL_TRUE); if (bEnumerate) { const char *s; if (bEnumerate_all) { // walk devices s = alcGetString(NULL, ALC_ALL_DEVICES_SPECIFIER); } else { s = alcGetString(NULL, ALC_DEVICE_SPECIFIER); } while (*s != '\0') { devices.push_back(string(s)); // find next string while (*s++ != '\0') ; } } return devices; }
bool cOAL_Device::Init( cOAL_Init_Params& acParams ) { DEF_FUNC_NAME(cOAL_Device::Init); FUNC_USES_ALC; FUNC_USES_AL; LogMsg("",eOAL_LogVerbose_Low, eOAL_LogMsg_Command, "Initializing device: %s...\n", (acParams.msDeviceName == "")? "\"preferred\"":acParams.msDeviceName.c_str() ); LogMsg("",eOAL_LogVerbose_High, eOAL_LogMsg_Info, "Configuring streaming options:\n"); cOAL_Stream::SetBufferSize(acParams.mlStreamingBufferSize); LogMsg("",eOAL_LogVerbose_High, eOAL_LogMsg_Info, "\tSetting buffer size to %d bytes\n",cOAL_Stream::GetBufferSize()); cOAL_Stream::SetBufferCount(acParams.mlStreamingBufferCount); LogMsg("",eOAL_LogVerbose_High, eOAL_LogMsg_Info, "\tSetting queue length to %d buffers\n",cOAL_Stream::GetBufferCount()); LogMsg("",eOAL_LogVerbose_Low, eOAL_LogMsg_Info, "Attempting to open device...\n" ); // Open the device, if fails return false if(acParams.msDeviceName.empty()) mpDevice = alcOpenDevice(NULL); else mpDevice = alcOpenDevice( acParams.msDeviceName.c_str() ); if(mpDevice == NULL) { LogMsg("",eOAL_LogVerbose_Low, eOAL_LogMsg_Error, "Error opening device\n" ); return false; } LogMsg("",eOAL_LogVerbose_Low, eOAL_LogMsg_Info, "Success.\n" ); // Get ALC extensions ( ie EFX ) LogMsg("",eOAL_LogVerbose_Low, eOAL_LogMsg_Info, "Checking present ALC extensions\n" ); for (int i = 0; i < NUM_ALC_EXTENSIONS; ++i) { mvbExtensions[i] = RUN_ALC_FUNC((alcIsExtensionPresent(mpDevice,sExtensionNames[i].c_str()) == ALC_TRUE)); if (mvbExtensions[i]) { LogMsg("",eOAL_LogVerbose_High, eOAL_LogMsg_Info, "\t%s\n",sExtensionNames[i].c_str() ); } } ALCint lAttrList[] = { ALC_FREQUENCY, acParams.mlOutputFreq, #ifdef __APPLE__ #else ALC_MONO_SOURCES, acParams.mbVoiceManagement ? 256 : acParams.mlMinMonoSourcesHint, ALC_STEREO_SOURCES, acParams.mbVoiceManagement ? 0 : acParams.mlMinStereoSourcesHint, #endif ALC_MAX_AUXILIARY_SENDS, acParams.mlNumSendsHint, 0, }; LogMsg("",eOAL_LogVerbose_Low, eOAL_LogMsg_Info, "Creating context\n"); // Create and set a context mpContext = RUN_ALC_FUNC(alcCreateContext ( mpDevice, lAttrList )); RUN_ALC_FUNC(alcMakeContextCurrent ( mpContext )); if (ALC_ERROR_OCCURED) { LogMsg("",eOAL_LogVerbose_Low, eOAL_LogMsg_Error, "Error creating context\n"); return false; } ///////////////////////////////////////////////// //Retrieve device info, such as extensions LogMsg("",eOAL_LogVerbose_Low, eOAL_LogMsg_Info, "Checking present AL extensions\n" ); for (int i = NUM_ALC_EXTENSIONS; i < NUM_EXTENSIONS; ++i) { mvbExtensions[i] = RUN_AL_FUNC((alIsExtensionPresent(sExtensionNames[i].c_str()) == AL_TRUE)); if (mvbExtensions[i]) LogMsg("",eOAL_LogVerbose_High, eOAL_LogMsg_Info, "\t%s\n",sExtensionNames[i].c_str() ); } LogMsg("",eOAL_LogVerbose_Low, eOAL_LogMsg_Info, "Retrieving Output Devices\n"); vector<string> llDevices = GetOutputDevices(); vector<string>::iterator it; for (it = llDevices.begin(); it != llDevices.end(); ++it) { LogMsg("",eOAL_LogVerbose_Low, eOAL_LogMsg_Info, "\t%s\n", (*it).c_str()); } LogMsg("",eOAL_LogVerbose_Low, eOAL_LogMsg_Info, "Retrieving info\n" ); // Get device name msDeviceName = RUN_ALC_FUNC(alcGetString(mpDevice, ALC_DEVICE_SPECIFIER)); // Get vendor name (just fancy stuff,not very useful) msVendorName = RUN_ALC_FUNC(alGetString( AL_VENDOR )); //Get renderer info msRenderer = RUN_ALC_FUNC(alGetString ( AL_RENDERER )); // Get the OpenAL impl. version RUN_ALC_FUNC(alcGetIntegerv ( mpDevice, ALC_MAJOR_VERSION, sizeof(ALCint), &mlMajorVersion )); RUN_ALC_FUNC(alcGetIntegerv ( mpDevice, ALC_MINOR_VERSION, sizeof(ALCint), &mlMinorVersion )); RUN_ALC_FUNC(alcGetIntegerv ( mpDevice, ALC_MAX_AUXILIARY_SENDS, sizeof(ALCint), &mlEFXSends)); LogMsg("",eOAL_LogVerbose_High, eOAL_LogMsg_Info, "Device name: %s\n", msDeviceName.c_str() ); LogMsg("",eOAL_LogVerbose_High, eOAL_LogMsg_Info, "OpenAL version: %d.%d\n", mlMajorVersion, mlMinorVersion ); // Check device version if ( (mlMajorVersion < acParams.mlMajorVersionReq) || ((mlMajorVersion == acParams.mlMajorVersionReq) && (mlMinorVersion < acParams.mlMinorVersionReq)) ) { LogMsg("",eOAL_LogVerbose_None, eOAL_LogMsg_Error, "Version required: %d.%d\n",acParams.mlMajorVersionReq,acParams.mlMinorVersionReq); return false; } // If alSourceNumHint == -1, create as many sources as possible if (acParams.mlNumSourcesHint == -1) acParams.mlNumSourcesHint = 4096; ///////////////////////////////////////////////// //Start EFX if requested if (acParams.mbUseEFX && IsExtensionAvailable (OAL_ALC_EXT_EFX)) { LogMsg("",eOAL_LogVerbose_Low, eOAL_LogMsg_Info, "Starting EFX on request\n" ); mpEFXManager = new cOAL_EFXManager; mbEFXActive = mpEFXManager->Initialize( acParams.mlNumSlotsHint, mlEFXSends, acParams.mbUseThread, acParams.mlSlotUpdateFreq ); if (!mbEFXActive) { mpEFXManager->Destroy(); delete mpEFXManager; } } LogMsg("",eOAL_LogVerbose_Low, eOAL_LogMsg_Info, "Creating Source Manager\n" ); //Create The source manager mpSourceManager = new cOAL_SourceManager; if ( mpSourceManager->Initialize( acParams.mbVoiceManagement, acParams.mlNumSourcesHint, acParams.mbUseThread, acParams.mlUpdateFreq, mlEFXSends ) == false) { LogMsg("",eOAL_LogVerbose_None, eOAL_LogMsg_Error, "Error creating Source Manager\n"); return false; } return true; }
bool cOAL_OggSample::CreateFromFile(const wstring &asFilename) { DEF_FUNC_NAME("cOAL_OggSample::Load()"); FUNC_USES_AL; if(mbStatus==false) return false; Reset(); char *pPCMBuffer; bool bEOF = false; int lOpenResult; int lCurrent_section; long lDataSize = 0; msFilename = asFilename; FILE *fileHandle = OpenFileW(asFilename, L"rb"); // If no file is present, set the error status and return if(!fileHandle) { mbStatus = false; return false; } // If not an Ogg file, set status and exit OggVorbis_File ovFileHandle; if((lOpenResult = ov_open_callbacks(fileHandle, &ovFileHandle, NULL, 0, gCallbacks))<0) { fclose ( fileHandle ); mbStatus = false; return false; } // Get file info vorbis_info *viFileInfo = ov_info ( &ovFileHandle, -1 ); mlChannels = viFileInfo->channels; mFormat = (mlChannels == 2)?AL_FORMAT_STEREO16:AL_FORMAT_MONO16; mlFrequency = viFileInfo->rate; mlSamples = (long) ov_pcm_total ( &ovFileHandle, -1 ); mfTotalTime = ov_time_total( &ovFileHandle, -1 ); // Reserve memory for 'mlChannels' channels of 'mlSamples' * 2 bytes of data each int lSizeInBytes = mlSamples * mlChannels * GetBytesPerSample(); pPCMBuffer = (char *) malloc (lSizeInBytes); memset (pPCMBuffer, 0, lSizeInBytes); // Loop which loads chunks of decoded data into a buffer while(!bEOF) { long lChunkSize = ov_read ( &ovFileHandle , pPCMBuffer + lDataSize , STREAMING_BLOCK_SIZE , SYS_ENDIANNESS , 2, 1, &lCurrent_section ); if(lChunkSize == 0) bEOF = true; // If we get a negative value, then something went wrong. Clean up and set error status. else if(lChunkSize < 0) { free(pPCMBuffer); ov_clear(&ovFileHandle); // ov_clear closes the file handle for us mbStatus = false; return false; } else lDataSize += lChunkSize; } cOAL_Buffer* pBuffer = mvBuffers[0]; if(lDataSize) { // If something went wrong, set error status. Clean up afterwards. mbStatus = pBuffer->Feed((ALvoid*)pPCMBuffer, lDataSize); } free(pPCMBuffer); ov_clear(&ovFileHandle); // ov_clear closes the file handle for us return true; }