cAudioManager.cpp

00001 // Copyright (c) 2008-2010 Raynaldo (Wildicv) Rivera, Joshua (Dark_Kilauea) Jones
00002 // This file is part of the "cAudio Engine"
00003 // For conditions of distribution and use, see copyright notice in cAudio.h
00004 
00005 #include "../Headers/cAudioManager.h"
00006 #include "../Headers/cFileSource.h"
00007 #include "../Headers/cMemorySource.h"
00008 #include "../Headers/cUtils.h"
00009 #include "../Headers/cOggAudioDecoderFactory.h"
00010 #include "../Headers/cWavAudioDecoderFactory.h"
00011 #include "../Headers/cRawAudioDecoderFactory.h"
00012 #include "../Headers/cThread.h"
00013 #include "../include/cAudioSleep.h"
00014 #include "../Headers/cLogger.h"
00015 #include "../Headers/cPluginManager.h"
00016 #include "../include/cAudioPlatform.h"
00017 #include "../Headers/cFileSourceFactory.h"
00018 
00019 #include <set>
00020 #include <string.h>
00021 #include <algorithm>
00022 
00023 #ifdef CAUDIO_EFX_ENABLED
00024 
00025 #ifdef CAUDIO_PLATFORM_WIN
00026         #include <AL/efx.h>
00027         #include <AL/efx-creative.h>
00028         #include <AL/xram.h>
00029 #endif
00030 
00031 #ifdef CAUDIO_PLATFORM_LINUX
00032         #include <AL/alext.h>
00033 #endif
00034 
00035 #endif
00036 
00037 namespace cAudio
00038 {
00039         static bool RunAudioManagerThread(false);
00040 
00041 #ifdef CAUDIO_COMPILE_WITH_OGG_DECODER
00042         static cOggAudioDecoderFactory OggDecoderFactory;
00043 #endif
00044 #ifdef CAUDIO_COMPILE_WITH_WAV_DECODER
00045         static cWavAudioDecoderFactory WavDecoderFactory;
00046 #endif
00047 
00048         static cRawAudioDecoderFactory RawDecoderFactory;
00049 
00050         static cFileSourceFactory FileSourceFactory;
00051 
00052         //Note: OpenAL is threadsafe, so a mutex only needs to protect the class state
00053 #ifdef CAUDIO_USE_INTERNAL_THREAD
00054         static cAudioMutex AudioManagerObjectsMutex;
00055         static std::set<IAudioManager*> AudioManagerObjects;
00056 
00057         CAUDIO_DECLARE_THREAD_FUNCTION(AudioManagerUpdateThread)
00058         {
00059                 while(RunAudioManagerThread)
00060                 {
00061                         AudioManagerObjectsMutex.lock();
00062                         std::set<IAudioManager*>::iterator it;
00063                         for ( it=AudioManagerObjects.begin() ; it != AudioManagerObjects.end(); it++ )
00064                         {
00065                                 (*it)->update();
00066                         }
00067                         AudioManagerObjectsMutex.unlock();
00068                         cAudioSleep(1);
00069                 }
00070                 return 0;
00071         }
00072 #endif
00073 
00074     bool cAudioManager::initialize(const char* deviceName, int outputFrequency, int eaxEffectSlots)
00075     {
00076                 cAudioMutexBasicLock lock(Mutex);
00077 
00078                 if(Initialized)
00079                         return false;
00080 
00081                 //Stores the context attributes (MAX of 4, with 2 zeros to terminate)
00082                 ALint attribs[6] = { 0 };
00083 
00084                 unsigned int currentAttrib = 0;
00085                 if(outputFrequency > 0)
00086                 {
00087                         attribs[currentAttrib++] = ALC_FREQUENCY;
00088                         attribs[currentAttrib++] = outputFrequency;
00089                 }
00090 #ifdef CAUDIO_EFX_ENABLED
00091                 if(eaxEffectSlots > 0)
00092                 {
00093                         attribs[currentAttrib++] = ALC_MAX_AUXILIARY_SENDS;
00094                         attribs[currentAttrib++] = eaxEffectSlots;
00095                 }
00096 #endif
00097 
00098                 //Create a new device
00099                 Device = alcOpenDevice(deviceName);
00100                 //Check if device can be created
00101                 if (Device == NULL)
00102                 {
00103                         getLogger()->logError("AudioManager", "Failed to Create OpenAL Device.");
00104                         checkError();
00105                         return false;
00106                 }
00107 
00108                 Context = alcCreateContext(Device, attribs);
00109                 if (Context == NULL)
00110                 {
00111                         getLogger()->logError("AudioManager", "Failed to Create OpenAL Context.");
00112                         checkError();
00113                         alcCloseDevice(Device);
00114                         Device = NULL;
00115                         return false;
00116                 }
00117 
00118                 if(!alcMakeContextCurrent(Context))
00119                 {
00120                         getLogger()->logError("AudioManager", "Failed to make OpenAL Context current.");
00121                         checkError();
00122                         alcDestroyContext(Context);
00123                         alcCloseDevice(Device);
00124                         Context = NULL;
00125                         Device = NULL;
00126                         return false;
00127                 }
00128 
00129 #ifdef CAUDIO_EFX_ENABLED
00130                 initEffects.getEFXInterface()->Mutex.lock();
00131                 EFXSupported = initEffects.getEFXInterface()->CheckEFXSupport(Device);
00132                 initEffects.getEFXInterface()->Mutex.unlock();
00133                 initEffects.checkEFXSupportDetails();
00134 #endif
00135 
00136                 getLogger()->logInfo("AudioManager", "OpenAL Version: %s", alGetString(AL_VERSION));
00137                 getLogger()->logInfo("AudioManager", "Vendor: %s", alGetString(AL_VENDOR));
00138                 getLogger()->logInfo("AudioManager", "Renderer: %s", alGetString(AL_RENDERER));
00139 #ifdef CAUDIO_EFX_ENABLED
00140                 if(EFXSupported)
00141                 {
00142                         int EFXMajorVersion = 0;
00143                         int EFXMinorVersion = 0;
00144                         alcGetIntegerv(Device, ALC_EFX_MAJOR_VERSION, 1, &EFXMajorVersion);
00145                         alcGetIntegerv(Device, ALC_EFX_MINOR_VERSION, 1, &EFXMinorVersion);
00146                         getLogger()->logInfo("AudioManager", "EFX Version: %i.%i", EFXMajorVersion, EFXMinorVersion);
00147                         getLogger()->logInfo("AudioManager", "EFX supported and enabled.");
00148                 }
00149                 else
00150                 {
00151                         getLogger()->logWarning("AudioManager", "EFX is not supported, EFX disabled.");
00152                 }
00153 #endif
00154                 getLogger()->logInfo("AudioManager", "Supported Extensions: %s", alGetString(AL_EXTENSIONS));
00155 
00156                 Initialized = true;
00157                 return true;
00158     }
00159 
00160     IAudioSource* cAudioManager::create(const char* name, const char* filename, bool stream)
00161     {
00162                 cAudioMutexBasicLock lock(Mutex);
00163 
00164                 std::string audioName = safeCStr(name);
00165                 std::string path = safeCStr(filename);
00166 
00167                 std::string ext = getExt(path);
00168                 IAudioDecoderFactory* factory = getAudioDecoderFactory(ext.c_str());
00169 
00170                 if(factory)
00171                 {
00172                         for(int i=0; i<dataSourcePriorityList.size(); ++i)
00173                         {
00174                                 IDataSourceFactory* dataFactory = datasourcemap[dataSourcePriorityList[i].second];
00175                                 if(dataFactory)
00176                                 {
00177                                         IDataSource* source = dataFactory->CreateDataSource(filename, stream);
00178                                         if(source && source->isValid())
00179                                         {
00180                                                 IAudioDecoder* decoder = factory->CreateAudioDecoder(source);
00181                                                 source->drop();
00182                                                 if(decoder && decoder->isValid())
00183                                                 {
00184 #ifdef CAUDIO_EFX_ENABLED
00185                                                         IAudioSource* audio = new cAudioSource(decoder, Context, initEffects.getEFXInterface());
00186 #else
00187                                                         IAudioSource* audio = new cAudioSource(decoder, Context);
00188 #endif
00189                                                         decoder->drop();
00190 
00191                                                         if(audio && audio->isValid())
00192                                                         {
00193                                                                 if(!audioName.empty())
00194                                                                         audioIndex[audioName] = audio;
00195 
00196                                                                 audioSources.push_back(audio);
00197 
00198                                                                 getLogger()->logInfo("AudioManager", "Audio Source (%s) created from file %s from Data Source %s.", audioName.c_str(), path.c_str(), dataSourcePriorityList[i].second.c_str());
00199                                                                 
00200                                                                 return audio;
00201                                                         }
00202                                                         getLogger()->logError("AudioManager", "Failed to create Audio Source (%s): Error creating audio source.", audioName.c_str());
00203                                                         audio->drop();
00204                                                         return NULL;
00205                                                 }
00206                                                 getLogger()->logError("AudioManager", "Failed to create Audio Source (%s): Audio data could not be decoded by (.%s) decoder.", audioName.c_str(), ext.c_str());
00207                                                 decoder->drop();
00208                                                 return NULL;
00209                                         }
00210                                         if(source)
00211                                                 source->drop();
00212                                 }
00213                         }
00214                         getLogger()->logError("AudioManager", "Failed to create Audio Source (%s): File could not be found (.%s).", audioName.c_str(), path.c_str());
00215                         return NULL;
00216                 }
00217                 getLogger()->logError("AudioManager", "Failed to create Audio Source (%s): No decoder could be found for (.%s).", audioName.c_str(), ext.c_str());
00218                 return NULL;
00219     }
00220 
00221     IAudioSource* cAudioManager::createFromMemory(const char* name, const char* data, size_t length, const char* extension)
00222     {
00223                 cAudioMutexBasicLock lock(Mutex);
00224 
00225                 std::string audioName = safeCStr(name);
00226                 std::string ext = safeCStr(extension);
00227                 IAudioDecoderFactory* factory = getAudioDecoderFactory(ext.c_str());
00228                 if(factory)
00229                 {
00230                         cMemorySource* source = new cMemorySource(data, length, true);
00231                         if(source)
00232                         {
00233                                 if(source->isValid())
00234                                 {
00235                                         IAudioDecoder* decoder = factory->CreateAudioDecoder(source);
00236                                         source->drop();
00237                                         if(decoder)
00238                                         {
00239                                                 if(decoder->isValid())
00240                                                 {
00241 #ifdef CAUDIO_EFX_ENABLED
00242                                                         IAudioSource* audio = new cAudioSource(decoder, Context, initEffects.getEFXInterface());
00243 #else
00244                                                         IAudioSource* audio = new cAudioSource(decoder, Context);
00245 #endif
00246                                                         decoder->drop();
00247 
00248                                                         if(audio)
00249                                                         {
00250                                                                 if(audio->isValid())
00251                                                                 {
00252                                                                         if(!audioName.empty())
00253                                                                                 audioIndex[audioName] = audio;
00254 
00255                                                                         audioSources.push_back(audio);
00256 
00257                                                                         getLogger()->logInfo("AudioManager", "Audio Source (%s) successfully created from memory.", audioName.c_str());
00258                                                                         
00259                                                                         return audio;
00260                                                                 }
00261                                                                 audio->drop();
00262                                                                 getLogger()->logError("AudioManager", "Failed to create Audio Source (%s): Error creating audio source.", audioName.c_str());
00263                                                                 return NULL;
00264                                                         }
00265                                                         getLogger()->logError("AudioManager", "Failed to create Audio Source (%s): Could not allocate enough memory.", audioName.c_str());
00266                                                         return NULL;
00267                                                 }
00268                                                 decoder->drop();
00269                                                 getLogger()->logError("AudioManager", "Failed to create Audio Source (%s): Audio data could not be decoded by (.%s) decoder.", audioName.c_str(), ext.c_str());
00270                                                 return NULL;
00271                                         }
00272                                         getLogger()->logError("AudioManager", "Failed to create Audio Source (%s): Could not allocate enough memory for decoder.", audioName.c_str());
00273                                         return NULL;
00274                                 }
00275                                 source->drop();
00276                                 getLogger()->logError("AudioManager", "Failed to create Audio Source (%s): Audio data is corrupt.", audioName.c_str());
00277                                 return NULL;
00278                         }
00279                         getLogger()->logError("AudioManager", "Failed to create Audio Source (%s): Could not allocate enough memory.", audioName.c_str());
00280                         return NULL;
00281                 }
00282                 getLogger()->logError("AudioManager", "Failed to create Audio Source (%s): Codec (.%s) is not supported.", audioName.c_str(), ext.c_str());
00283                 return NULL;
00284     }
00285 
00286         IAudioSource* cAudioManager::createFromRaw(const char* name, const char* data, size_t length, unsigned int frequency, AudioFormats format)
00287         {
00288                 cAudioMutexBasicLock lock(Mutex);
00289 
00290                 std::string audioName = safeCStr(name);
00291                 IAudioDecoderFactory* factory = getAudioDecoderFactory("raw");
00292                 if(factory)
00293                 {
00294                         cMemorySource* source = new cMemorySource(data, length, true);
00295                         if(source)
00296                         {
00297                                 if(source->isValid())
00298                                 {
00299                                         IAudioDecoder* decoder = ((cRawAudioDecoderFactory*)factory)->CreateAudioDecoder(source, frequency, format);
00300                                         source->drop();
00301                                         if(decoder)
00302                                         {
00303                                                 if(decoder->isValid())
00304                                                 {
00305 #ifdef CAUDIO_EFX_ENABLED
00306                                                         IAudioSource* audio = new cAudioSource(decoder, Context, initEffects.getEFXInterface());
00307 #else
00308                                                         IAudioSource* audio = new cAudioSource(decoder, Context);
00309 #endif
00310                                                         decoder->drop();
00311 
00312                                                         if(audio)
00313                                                         {
00314                                                                 if(audio->isValid())
00315                                                                 {
00316                                                                         if(!audioName.empty())
00317                                                                                 audioIndex[audioName] = audio;
00318 
00319                                                                         audioSources.push_back(audio);
00320 
00321                                                                         getLogger()->logInfo("AudioManager", "Audio Source (%s) successfully created from raw data.", audioName.c_str());
00322                                                                         
00323                                                                         return audio;
00324                                                                 }
00325                                                                 audio->drop();
00326                                                                 getLogger()->logError("AudioManager", "Failed to create Audio Source (%s): Error creating audio source.", audioName.c_str());
00327                                                                 return NULL;
00328                                                         }
00329                                                         getLogger()->logError("AudioManager", "Failed to create Audio Source (%s): Could not allocate enough memory.", audioName.c_str());
00330                                                         return NULL;
00331                                                 }
00332                                                 decoder->drop();
00333                                                 getLogger()->logError("AudioManager", "Failed to create Audio Source (%s): Audio data could not be decoded by (.%s) decoder.", audioName.c_str(), "raw");
00334                                                 return NULL;
00335                                         }
00336                                         getLogger()->logError("AudioManager", "Failed to create Audio Source (%s): Could not allocate enough memory for decoder.", audioName.c_str());
00337                                         return NULL;
00338                                 }
00339                                 source->drop();
00340                                 getLogger()->logError("AudioManager", "Failed to create Audio Source (%s): Audio data is corrupt.", audioName.c_str());
00341                                 return NULL;
00342                         }
00343                         getLogger()->logError("AudioManager", "Failed to create Audio Source (%s): Could not allocate enough memory.", audioName.c_str());
00344                         return NULL;
00345                 }
00346                 getLogger()->logError("AudioManager", "Failed to create Audio Source (%s): Codec (.%s) is not supported.", audioName.c_str(), "raw");
00347                 return NULL;
00348         }
00349 
00350     bool cAudioManager::registerAudioDecoder(IAudioDecoderFactory* factory, const char* extension)
00351     {
00352                 cAudioMutexBasicLock lock(Mutex);
00353                 std::string ext = safeCStr(extension);
00354         decodermap[ext] = factory;
00355                 getLogger()->logInfo("AudioManager", "Audio Decoder for extension .%s registered.", ext.c_str());
00356                 return true;
00357     }
00358 
00359         void cAudioManager::unRegisterAudioDecoder(const char* extension)
00360         {
00361                 cAudioMutexBasicLock lock(Mutex);
00362                 std::string ext = safeCStr(extension);
00363                 std::map<std::string, IAudioDecoderFactory*>::iterator it = decodermap.find(ext);
00364                 if(it != decodermap.end())
00365                 {
00366                         decodermap.erase(it);
00367                         getLogger()->logInfo("AudioManager", "Audio Decoder for extension .%s unregistered.", ext.c_str());
00368                 }
00369         }
00370 
00371         bool cAudioManager::isAudioDecoderRegistered(const char* extension)
00372         {
00373                 cAudioMutexBasicLock lock(Mutex);
00374                 std::string ext = safeCStr(extension);
00375                 std::map<std::string, IAudioDecoderFactory*>::iterator it = decodermap.find(ext);
00376                 return (it != decodermap.end());
00377         }
00378 
00379         IAudioDecoderFactory* cAudioManager::getAudioDecoderFactory(const char* extension)
00380         {
00381                 cAudioMutexBasicLock lock(Mutex);
00382                 std::string ext = safeCStr(extension);
00383                 std::map<std::string, IAudioDecoderFactory*>::iterator it = decodermap.find(ext);
00384                 if(it != decodermap.end())
00385                 {
00386                         return it->second;
00387                 }
00388                 return NULL;
00389         }
00390 
00391         void cAudioManager::unRegisterAllAudioDecoders()
00392         {
00393                 cAudioMutexBasicLock lock(Mutex);
00394                 decodermap.clear();
00395         }
00396 
00397         bool compareDataSourcePriorities(std::pair<int, std::string> left, std::pair<int, std::string> right)
00398         {
00399                 return (left.first > right.first);
00400         }
00401 
00402         bool cAudioManager::registerDataSource(IDataSourceFactory* factory, const char* name, int priority)
00403         {
00404                 cAudioMutexBasicLock lock(Mutex);
00405                 std::string safeName = safeCStr(name);
00406         datasourcemap[safeName] = factory;
00407                 dataSourcePriorityList.push_back(std::pair<int, std::string>(priority, safeName));
00408                 std::sort(dataSourcePriorityList.begin(), dataSourcePriorityList.end(), compareDataSourcePriorities);
00409 
00410                 getLogger()->logInfo("AudioManager", "Data Source named %s registered (Priority %i).", safeName.c_str(), priority);
00411                 return true;
00412         }
00413 
00414         void cAudioManager::unRegisterDataSource(const char* name)
00415         {
00416                 cAudioMutexBasicLock lock(Mutex);
00417                 std::string safeName = safeCStr(name);
00418                 std::map<std::string, IDataSourceFactory*>::iterator it = datasourcemap.find(safeName);
00419                 if(it != datasourcemap.end())
00420                 {
00421                         datasourcemap.erase(it);
00422                         getLogger()->logInfo("AudioManager", "Data Source named %s unregistered.", safeName.c_str());
00423                 }
00424 
00425                 for(int i=0; i<dataSourcePriorityList.size(); ++i)
00426                 {
00427                         if(dataSourcePriorityList[i].second == safeName)
00428                         {
00429                                 dataSourcePriorityList.erase(dataSourcePriorityList.begin()+i);
00430                                 break;
00431                         }
00432                 }
00433 
00434                 std::sort(dataSourcePriorityList.begin(), dataSourcePriorityList.end(), compareDataSourcePriorities);
00435         }
00436 
00437         bool cAudioManager::isDataSourceRegistered(const char* name)
00438         {
00439                 cAudioMutexBasicLock lock(Mutex);
00440                 std::string safeName = safeCStr(name);
00441                 std::map<std::string, IDataSourceFactory*>::iterator it = datasourcemap.find(safeName);
00442                 return (it != datasourcemap.end());
00443         }
00444 
00445         IDataSourceFactory* cAudioManager::getDataSourceFactory(const char* name)
00446         {
00447                 cAudioMutexBasicLock lock(Mutex);
00448                 std::string safeName = safeCStr(name);
00449                 std::map<std::string, IDataSourceFactory*>::iterator it = datasourcemap.find(safeName);
00450                 if(it != datasourcemap.end())
00451                 {
00452                         return it->second;
00453                 }
00454                 return NULL;
00455         }
00456 
00457         void cAudioManager::unRegisterAllDataSources()
00458         {
00459                 cAudioMutexBasicLock lock(Mutex);
00460                 datasourcemap.clear();
00461                 dataSourcePriorityList.clear();
00462         }
00463 
00464         void cAudioManager::registerEventHandler(IManagerEventHandler* handler)
00465         {
00466                 if(handler)
00467                 {
00468                         eventHandlerList.push_back(handler);
00469                 }
00470         }
00471 
00472         void cAudioManager::unRegisterEventHandler(IManagerEventHandler* handler)
00473         {
00474                 if(handler)
00475                 {
00476                         eventHandlerList.remove(handler);
00477                 }
00478         }
00479 
00480         void cAudioManager::unRegisterAllEventHandlers()
00481         {
00482                 eventHandlerList.clear();
00483         }
00484 
00485         void cAudioManager::signalEvent(Events sevent)
00486         {
00487                 cAudioMutexBasicLock lock(Mutex);
00488                 std::list<IManagerEventHandler*>::iterator it = eventHandlerList.begin();
00489 
00490                 if(it != eventHandlerList.end())
00491                 {
00492                         switch(sevent)
00493                         {
00494                                 case ON_INIT: 
00495                                         
00496                                         for(it; it != eventHandlerList.end(); it++)
00497                                         {
00498                                                 (*it)->onInit();
00499                                         }
00500 
00501                                         break;
00502                                 
00503                                 case ON_UPDATE:
00504 
00505                                         for(it; it != eventHandlerList.end(); it++)
00506                                         {
00507                                                 (*it)->onUpdate();
00508                                         }
00509 
00510                                         break;
00511 
00512                                 case ON_RELEASE:
00513 
00514                                         for(it; it != eventHandlerList.end(); it++)
00515                                         {
00516                                                 (*it)->onRelease();
00517                                         }
00518 
00519                                         break;
00520 
00521                                 case ON_SOURCECREATE:
00522 
00523                                         for(it; it != eventHandlerList.end(); it++)
00524                                         {
00525                                                 (*it)->onSourceCreate();
00526                                         }
00527 
00528                                         break;
00529 
00530                                 case ON_DECODERREGISTER:
00531 
00532                                         for(it; it != eventHandlerList.end(); it++)
00533                                         {
00534                                                 (*it)->onDecoderRegister();
00535                                         }
00536 
00537                                         break;
00538 
00539                                 case ON_DATASOURCEREGISTER:
00540 
00541                                         for(it; it != eventHandlerList.end(); it++)
00542                                         {
00543                                                 (*it)->onDataSourceRegister();
00544                                         }
00545 
00546                                         break;
00547                         }
00548                 }
00549         }
00550 
00551     IAudioSource* cAudioManager::getSoundByName(const char* name)
00552     {
00553                 cAudioMutexBasicLock lock(Mutex);
00554                 std::string audioName = safeCStr(name);
00555         std::map<std::string,IAudioSource*>::iterator i = audioIndex.find(audioName);
00556         if (i == audioIndex.end())
00557                 {
00558                         return NULL;
00559                 }
00560         return i->second;
00561     }
00562 
00563     void cAudioManager::releaseAllSources()
00564     {
00565                 cAudioMutexBasicLock lock(Mutex);
00566                 for(unsigned int i=0; i<audioSources.size(); ++i)
00567                 {
00568                         IAudioSource* source = audioSources[i];
00569                         if(source)
00570                                 source->drop();
00571                 }
00572                 audioSources.clear();
00573                 audioIndex.clear();
00574     }
00575 
00576         void cAudioManager::release(IAudioSource* source)
00577         {
00578                 if(source)
00579                 {
00580                         cAudioMutexBasicLock lock(Mutex);
00581                         std::map<std::string,IAudioSource*>::iterator it = audioIndex.begin();
00582                         for ( it=audioIndex.begin(); it != audioIndex.end(); it++ )
00583                         {
00584                                 if( it->second == source )
00585                                 {
00586                                         audioIndex.erase(it);
00587                                         break;
00588                                 }
00589                         }
00590                         for(unsigned int i=0; i<audioSources.size(); ++i)
00591                         {
00592                                 if(source == audioSources[i])
00593                                 {
00594                                         source->drop();
00595                                         audioSources.erase(audioSources.begin()+i);
00596                                         break;
00597                                 }
00598                         }
00599                 }
00600         }
00601 
00602     void cAudioManager::update()
00603     {
00604                 cAudioMutexBasicLock lock(Mutex);
00605         for(unsigned int i=0; i<audioSources.size(); ++i)
00606                 {
00607                         IAudioSource* source = audioSources[i];
00608             if (source->isValid())
00609             {
00610                 if (source->update())
00611                 {
00612 
00613                 }
00614             }
00615         }
00616     }
00617 
00618     void cAudioManager::shutDown()
00619     {
00620                 if(Initialized)
00621                 {
00622                         cAudioMutexBasicLock lock(Mutex);
00623                         releaseAllSources();
00624                         //Reset context to null
00625                         alcMakeContextCurrent(NULL);
00626                         //Delete the context
00627                         alcDestroyContext(Context);
00628                         Context = NULL;
00629                         //Close the device
00630                         alcCloseDevice(Device);
00631                         Device = NULL;
00632                         Initialized = false;
00633                         getLogger()->logInfo("AudioManager", "Manager successfully shutdown.");
00634                 }
00635     }
00636 
00637         bool cAudioManager::checkError()
00638         {
00639                 int error = alGetError();
00640                 const char* errorString;
00641 
00642         if (error != AL_NO_ERROR)
00643         {
00644                         errorString = alGetString(error);
00645                         getLogger()->logError("AudioManager", "OpenAL Error: %s.", errorString);
00646                         return true;
00647         }
00648 
00649                 if(Device)
00650                 {
00651                         error = alcGetError(Device);
00652                         if (error != AL_NO_ERROR)
00653                         {
00654                                 errorString = alGetString(error);
00655                                 getLogger()->logError("AudioManager", "OpenAL Error: %s.", errorString);
00656                                 return true;
00657                         }
00658                 }
00659                 return false;
00660         }
00661 
00662         void cAudioManager::getAvailableDevices()
00663         {
00664                 // Get list of available Playback Devices
00665                 cAudioMutexBasicLock lock(Mutex);
00666                 if( alcIsExtensionPresent(NULL, "ALC_ENUMERATE_ALL_EXT") == AL_TRUE )
00667                 {
00668                         const char* deviceList = alcGetString(NULL, ALC_ALL_DEVICES_SPECIFIER);
00669                         if (deviceList)
00670                         {
00671                                 while(*deviceList)
00672                                 {
00673                                         std::string device(deviceList);
00674                                         AvailableDevices.push_back(device);
00675                                         deviceList += strlen(deviceList) + 1;
00676                                 }
00677                         }
00678 
00679                         // Get the name of the 'default' capture device
00680                         DefaultDevice = alcGetString(NULL, ALC_DEFAULT_ALL_DEVICES_SPECIFIER);
00681                 }
00682                 else if( alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT") == AL_TRUE )
00683                 {
00684                         const char* deviceList = alcGetString(NULL, ALC_DEVICE_SPECIFIER);
00685                         if (deviceList)
00686                         {
00687                                 while(*deviceList)
00688                                 {
00689                                         std::string device(deviceList);
00690                                         AvailableDevices.push_back(device);
00691                                         deviceList += strlen(deviceList) + 1;
00692                                 }
00693                         }
00694 
00695                         // Get the name of the 'default' capture device
00696                         DefaultDevice = alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
00697                 }
00698         }
00699 
00700         const char* cAudioManager::getAvailableDeviceName(unsigned int index)
00701         {
00702                 cAudioMutexBasicLock lock(Mutex);
00703                 if(!AvailableDevices.empty())
00704                 {
00705                         //Bounds check
00706                         if( index > (AvailableDevices.size()-1) ) index = (AvailableDevices.size()-1);
00707                         const char* deviceName = AvailableDevices[index].c_str();
00708                         return deviceName;
00709                 }
00710                 return "";
00711         }
00712 
00713         unsigned int cAudioManager::getAvailableDeviceCount()
00714         {
00715                 cAudioMutexBasicLock lock(Mutex);
00716                 return AvailableDevices.size();
00717         }
00718 
00719         const char* cAudioManager::getDefaultDeviceName()
00720         {
00721                 cAudioMutexBasicLock lock(Mutex);
00722                 return DefaultDevice.empty() ? "" : DefaultDevice.c_str();
00723         }
00724 
00725         CAUDIO_API IAudioManager* createAudioManager(bool initializeDefault)
00726         {
00727                 cAudioManager* manager = new cAudioManager;
00728                 if(manager)
00729                 {
00730                         if(initializeDefault)
00731                                 manager->initialize();
00732 
00733                         manager->getAvailableDevices();
00734 
00735 #ifdef CAUDIO_COMPILE_WITH_OGG_DECODER
00736                         manager->registerAudioDecoder(&OggDecoderFactory, "ogg");
00737 #endif
00738 #ifdef CAUDIO_COMPILE_WITH_WAV_DECODER
00739                         manager->registerAudioDecoder(&WavDecoderFactory, "wav");
00740 #endif
00741 
00742                         manager->registerAudioDecoder(&RawDecoderFactory, "raw");
00743 
00744                         manager->registerDataSource(&FileSourceFactory, "FileSystem", 0);
00745 
00746                         std::vector<IAudioPlugin*> plugins = cPluginManager::Instance()->getPluginList();
00747                         for(unsigned int i = 0; i < plugins.size(); ++i)
00748                         {
00749                                 plugins[i]->onCreateAudioManager(manager);
00750                         }
00751 
00752 #ifdef CAUDIO_USE_INTERNAL_THREAD
00753                         AudioManagerObjectsMutex.lock();
00754                         AudioManagerObjects.insert(manager);
00755 
00756                         //First time launch of thread
00757                         if(!RunAudioManagerThread && AudioManagerObjects.size() > 0)
00758                                 RunAudioManagerThread = (cAudioThread::SpawnThread(AudioManagerUpdateThread, NULL) == 0);
00759                         AudioManagerObjectsMutex.unlock();
00760 #endif
00761                 }
00762                 return manager;
00763         }
00764 
00765         CAUDIO_API void destroyAudioManager(IAudioManager* manager)
00766         {
00767                 if(manager)
00768                 {
00769 #ifdef CAUDIO_USE_INTERNAL_THREAD
00770                         AudioManagerObjectsMutex.lock();
00771                         AudioManagerObjects.erase(manager);
00772 
00773                         //Kill the thread if there are no objects to process anymore
00774                         if(RunAudioManagerThread && AudioManagerObjects.empty())
00775                                 RunAudioManagerThread = false;
00776                         AudioManagerObjectsMutex.unlock();
00777 #endif
00778                         std::vector<IAudioPlugin*> plugins = cPluginManager::Instance()->getPluginList();
00779                         for(unsigned int i = 0; i < plugins.size(); ++i)
00780                         {
00781                                 plugins[i]->onDestroyAudioManager(manager);
00782                         }
00783 
00784                         manager->unRegisterAllAudioDecoders();
00785                         manager->unRegisterAllDataSources();
00786                         manager->unRegisterAllEventHandlers();
00787                         manager->shutDown();
00788 
00789                         delete manager;
00790                         manager = NULL;
00791                 }
00792         }
00793 
00794         CAUDIO_API bool isAudioManagerThreadRunning()
00795         {
00796                 return RunAudioManagerThread;
00797         }
00798 
00799 };
 All Classes Namespaces Functions Variables Enumerations

Generated on Sat Feb 20 22:55:08 2010 for cAudio by  doxygen 1.6.2