00001
00002
00003
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
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
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
00099 Device = alcOpenDevice(deviceName);
00100
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
00625 alcMakeContextCurrent(NULL);
00626
00627 alcDestroyContext(Context);
00628 Context = NULL;
00629
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
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
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
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
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
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
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 };