2010-02-09 05:18:39 +01:00
// Copyright (c) 2008-2010 Raynaldo (Wildicv) Rivera, Joshua (Dark_Kilauea) Jones
// This file is part of the "cAudio Engine"
// For conditions of distribution and use, see copyright notice in cAudio.h
2009-06-21 05:24:30 +02:00
# include "../Headers/cAudioManager.h"
# include "../Headers/cFileSource.h"
# include "../Headers/cMemorySource.h"
# include "../Headers/cUtils.h"
# include "../Headers/cOggAudioDecoderFactory.h"
2009-12-07 23:25:08 +01:00
# include "../Headers/cWavAudioDecoderFactory.h"
2009-08-11 19:57:20 +02:00
# include "../Headers/cRawAudioDecoderFactory.h"
2009-08-29 13:24:31 +02:00
# include "../Headers/cThread.h"
# include "../include/cAudioSleep.h"
2009-11-20 04:39:56 +01:00
# include "../Headers/cLogger.h"
2010-02-09 06:58:27 +01:00
# include "../Headers/cPluginManager.h"
2010-02-09 07:08:46 +01:00
# include "../include/cAudioPlatform.h"
2009-11-20 04:39:56 +01:00
# include <set>
2010-02-09 06:33:32 +01:00
# include <string.h>
2010-02-09 07:08:46 +01:00
# ifdef CAUDIO_PLATFORM_WIN
2010-02-09 06:33:32 +01:00
# include <AL/efx.h>
# include <AL/efx-creative.h>
# include <AL/xram.h>
# endif
2010-02-09 07:08:46 +01:00
# ifdef CAUDIO_PLATFORM_LINUX
2010-02-09 06:33:32 +01:00
# include <AL/alext.h>
# endif
2009-06-21 05:24:30 +02:00
2009-08-08 07:51:32 +02:00
# define LOAD_AL_FUNC(x) (x = (typeof(x))alGetProcAddress(#x))
2009-06-21 05:24:30 +02:00
namespace cAudio
{
2009-11-20 04:39:56 +01:00
static bool RunAudioManagerThread ( false ) ;
# ifdef CAUDIO_COMPILE_WITH_OGG_DECODER
static cOggAudioDecoderFactory OggDecoderFactory ;
# endif
# ifdef CAUDIO_COMPILE_WITH_WAV_DECODER
static cWavAudioDecoderFactory WavDecoderFactory ;
# endif
# ifdef CAUDIO_COMPILE_WITH_RAW_DECODER
static cRawAudioDecoderFactory RawDecoderFactory ;
# endif
//Note: OpenAL is threadsafe, so a mutex only needs to protect the class state
# ifdef CAUDIO_USE_INTERNAL_THREAD
static cAudioMutex AudioManagerObjectsMutex ;
static std : : set < IAudioManager * > AudioManagerObjects ;
2009-06-21 05:24:30 +02:00
2009-11-20 04:39:56 +01:00
CAUDIO_DECLARE_THREAD_FUNCTION ( AudioManagerUpdateThread )
2009-08-29 13:24:31 +02:00
{
2009-11-20 04:39:56 +01:00
while ( RunAudioManagerThread )
2009-08-29 13:24:31 +02:00
{
2009-11-20 04:39:56 +01:00
AudioManagerObjectsMutex . lock ( ) ;
std : : set < IAudioManager * > : : iterator it ;
for ( it = AudioManagerObjects . begin ( ) ; it ! = AudioManagerObjects . end ( ) ; it + + )
2009-08-29 13:24:31 +02:00
{
2009-11-20 04:39:56 +01:00
( * it ) - > update ( ) ;
2009-08-29 13:24:31 +02:00
}
2009-11-20 04:39:56 +01:00
AudioManagerObjectsMutex . unlock ( ) ;
2009-08-29 13:24:31 +02:00
cAudioSleep ( 1 ) ;
}
2009-11-20 04:39:56 +01:00
return 0 ;
2009-08-29 13:24:31 +02:00
}
2009-11-20 04:39:56 +01:00
# endif
2009-08-29 13:24:31 +02:00
2009-06-21 05:24:30 +02:00
//!Initialize the listener,openal,and mikmod
2009-11-20 04:39:56 +01:00
bool cAudioManager : : initialize ( const char * deviceName , int outputFrequency , int eaxEffectSlots )
2009-06-21 05:24:30 +02:00
{
2009-12-07 23:25:08 +01:00
cAudioMutexBasicLock lock ( Mutex ) ;
if ( Initialized )
2010-01-11 01:39:08 +01:00
return false ;
2009-11-20 04:39:56 +01:00
//Stores the context attributes (MAX of 4, with 2 zeros to terminate)
ALint attribs [ 6 ] = { 0 } ;
unsigned int currentAttrib = 0 ;
if ( outputFrequency > 0 )
{
attribs [ currentAttrib + + ] = ALC_FREQUENCY ;
attribs [ currentAttrib + + ] = outputFrequency ;
}
if ( eaxEffectSlots > 0 )
{
attribs [ currentAttrib + + ] = ALC_MAX_AUXILIARY_SENDS ;
attribs [ currentAttrib + + ] = eaxEffectSlots ;
}
2009-08-27 01:46:18 +02:00
//Create a new device
2009-11-20 04:39:56 +01:00
Device = alcOpenDevice ( deviceName ) ;
2009-08-27 01:46:18 +02:00
//Check if device can be created
2009-11-20 04:39:56 +01:00
if ( Device = = NULL )
{
getLogger ( ) - > logError ( " AudioManager " , " Failed to Create OpenAL Device. " ) ;
checkError ( ) ;
return false ;
2009-11-15 18:11:38 +01:00
}
2009-08-08 07:51:32 +02:00
2009-11-20 04:39:56 +01:00
Context = alcCreateContext ( Device , attribs ) ;
if ( Context = = NULL )
{
getLogger ( ) - > logError ( " AudioManager " , " Failed to Create OpenAL Context. " ) ;
checkError ( ) ;
2009-12-07 23:25:08 +01:00
alcCloseDevice ( Device ) ;
Device = NULL ;
2009-11-20 04:39:56 +01:00
return false ;
}
2009-09-03 05:00:03 +02:00
2009-11-20 04:39:56 +01:00
if ( ! alcMakeContextCurrent ( Context ) )
{
getLogger ( ) - > logError ( " AudioManager " , " Failed to make OpenAL Context current. " ) ;
checkError ( ) ;
2009-12-07 23:25:08 +01:00
alcDestroyContext ( Context ) ;
alcCloseDevice ( Device ) ;
Context = NULL ;
Device = NULL ;
2009-11-20 04:39:56 +01:00
return false ;
}
2009-08-08 07:51:32 +02:00
2010-01-11 01:39:08 +01:00
# ifdef CAUDIO_EFX_ENABLED
initEffects . getEFXInterface ( ) - > Mutex . lock ( ) ;
EFXSupported = initEffects . getEFXInterface ( ) - > CheckEFXSupport ( Device ) ;
initEffects . getEFXInterface ( ) - > Mutex . unlock ( ) ;
initEffects . checkEFXSupportDetails ( ) ;
# endif
2009-11-20 04:39:56 +01:00
getLogger ( ) - > logInfo ( " AudioManager " , " OpenAL Version: %s " , alGetString ( AL_VERSION ) ) ;
getLogger ( ) - > logInfo ( " AudioManager " , " Vendor: %s " , alGetString ( AL_VENDOR ) ) ;
getLogger ( ) - > logInfo ( " AudioManager " , " Renderer: %s " , alGetString ( AL_RENDERER ) ) ;
2010-01-11 01:39:08 +01:00
# ifdef CAUDIO_EFX_ENABLED
2009-12-07 23:25:08 +01:00
if ( EFXSupported )
{
int EFXMajorVersion = 0 ;
int EFXMinorVersion = 0 ;
alcGetIntegerv ( Device , ALC_EFX_MAJOR_VERSION , 1 , & EFXMajorVersion ) ;
alcGetIntegerv ( Device , ALC_EFX_MINOR_VERSION , 1 , & EFXMinorVersion ) ;
getLogger ( ) - > logInfo ( " AudioManager " , " EFX Version: %i.%i " , EFXMajorVersion , EFXMinorVersion ) ;
getLogger ( ) - > logInfo ( " AudioManager " , " EFX supported and enabled. " ) ;
}
else
{
getLogger ( ) - > logWarning ( " AudioManager " , " EFX is not supported, EFX disabled. " ) ;
}
# endif
2009-11-20 04:39:56 +01:00
getLogger ( ) - > logInfo ( " AudioManager " , " Supported Extensions: %s " , alGetString ( AL_EXTENSIONS ) ) ;
2009-08-11 19:57:20 +02:00
2009-11-20 04:39:56 +01:00
# ifdef CAUDIO_COMPILE_WITH_OGG_DECODER
registerAudioDecoder ( & OggDecoderFactory , " ogg " ) ;
# endif
# ifdef CAUDIO_COMPILE_WITH_WAV_DECODER
registerAudioDecoder ( & WavDecoderFactory , " wav " ) ;
# endif
# ifdef CAUDIO_COMPILE_WITH_RAW_DECODER
registerAudioDecoder ( & RawDecoderFactory , " raw " ) ;
# endif
2009-08-29 13:24:31 +02:00
2009-12-07 23:25:08 +01:00
Initialized = true ;
2009-11-20 04:39:56 +01:00
return true ;
2009-06-21 05:24:30 +02:00
}
//!create a sound source
2009-12-01 02:41:15 +01:00
IAudio * cAudioManager : : createFromFile ( const char * name , const char * pathToFile , bool stream )
2009-06-21 05:24:30 +02:00
{
2009-12-07 23:25:08 +01:00
cAudioMutexBasicLock lock ( Mutex ) ;
2009-12-01 02:41:15 +01:00
std : : string audioName = safeCStr ( name ) ;
std : : string path = safeCStr ( pathToFile ) ;
2009-12-07 23:25:08 +01:00
std : : string ext = getExt ( path ) ;
IAudioDecoderFactory * factory = getAudioDecoderFactory ( ext . c_str ( ) ) ;
if ( factory )
2009-12-01 02:41:15 +01:00
{
2009-12-07 23:25:08 +01:00
if ( stream )
{
cFileSource * source = new cFileSource ( path ) ;
if ( source )
2009-08-11 19:57:20 +02:00
{
2009-12-07 23:25:08 +01:00
if ( source - > isValid ( ) )
{
IAudioDecoder * decoder = factory - > CreateAudioDecoder ( source ) ;
source - > drop ( ) ;
if ( decoder )
{
if ( decoder - > isValid ( ) )
{
2010-01-11 01:39:08 +01:00
IAudio * audio = new cAudio ( decoder , Context , initEffects . getEFXInterface ( ) ) ;
2009-12-07 23:25:08 +01:00
decoder - > drop ( ) ;
if ( audio )
{
if ( audio - > isValid ( ) )
{
if ( ! audioName . empty ( ) )
audioIndex [ audioName ] = audio ;
audioSources . push_back ( audio ) ;
getLogger ( ) - > logInfo ( " AudioManager " , " Streaming Audio Source (%s) created from file %s. " , audioName . c_str ( ) , path . c_str ( ) ) ;
return audio ;
}
getLogger ( ) - > logError ( " AudioManager " , " Failed to create Audio Source (%s): Error creating audio source. " , audioName . c_str ( ) ) ;
audio - > drop ( ) ;
return NULL ;
}
getLogger ( ) - > logError ( " AudioManager " , " Failed to create Audio Source (%s): Could not allocate enough memory. " , audioName . c_str ( ) ) ;
return NULL ;
}
getLogger ( ) - > logError ( " AudioManager " , " Failed to create Audio Source (%s): Audio data could not be decoded by (.%s) decoder. " , audioName . c_str ( ) , ext . c_str ( ) ) ;
decoder - > drop ( ) ;
return NULL ;
}
getLogger ( ) - > logError ( " AudioManager " , " Failed to create Audio Source (%s): Could not allocate enough memory. " , audioName . c_str ( ) ) ;
return NULL ;
}
source - > drop ( ) ;
getLogger ( ) - > logError ( " AudioManager " , " Failed to create Audio Source (%s): Could not load file %s. " , audioName . c_str ( ) , path . c_str ( ) ) ;
return NULL ;
}
getLogger ( ) - > logError ( " AudioManager " , " Failed to create Audio Source (%s): Could not allocate enough memory. " , audioName . c_str ( ) ) ;
return NULL ;
}
else
{
cFileSource * tempsource = new cFileSource ( path ) ;
if ( tempsource )
{
if ( tempsource - > isValid ( ) )
{
int length = tempsource - > getSize ( ) ;
char * tempbuf = new char [ length ] ;
if ( tempbuf )
{
tempsource - > read ( tempbuf , length ) ;
IAudio * guy = createFromMemory ( name , tempbuf , length , getExt ( path ) . c_str ( ) ) ;
delete [ ] tempbuf ;
tempsource - > drop ( ) ;
return guy ;
}
getLogger ( ) - > logError ( " AudioManager " , " Failed to create Audio Source (%s): Could not allocate enough memory. " , audioName . c_str ( ) ) ;
tempsource - > drop ( ) ;
return NULL ;
}
getLogger ( ) - > logError ( " AudioManager " , " Failed to create Audio Source (%s): Audio data is corrupt. " , audioName . c_str ( ) ) ;
tempsource - > drop ( ) ;
return NULL ;
}
getLogger ( ) - > logError ( " AudioManager " , " Failed to create Audio Source (%s): Could not allocate enough memory. " , audioName . c_str ( ) ) ;
return NULL ;
}
}
getLogger ( ) - > logError ( " AudioManager " , " Failed to create Audio Source (%s): Codec (.%s) is not supported. " , audioName . c_str ( ) , ext . c_str ( ) ) ;
return NULL ;
2009-06-21 05:24:30 +02:00
}
//!Loads the ogg file from memory *virtual file systems*
2009-12-01 02:41:15 +01:00
IAudio * cAudioManager : : createFromMemory ( const char * name , const char * data , size_t length , const char * extension )
2009-06-21 05:24:30 +02:00
{
2009-12-07 23:25:08 +01:00
cAudioMutexBasicLock lock ( Mutex ) ;
2009-12-01 02:41:15 +01:00
std : : string audioName = safeCStr ( name ) ;
std : : string ext = safeCStr ( extension ) ;
2009-12-07 23:25:08 +01:00
IAudioDecoderFactory * factory = getAudioDecoderFactory ( ext . c_str ( ) ) ;
if ( factory )
{
cMemorySource * source = new cMemorySource ( data , length , true ) ;
if ( source )
{
if ( source - > isValid ( ) )
{
IAudioDecoder * decoder = factory - > CreateAudioDecoder ( source ) ;
source - > drop ( ) ;
if ( decoder )
{
if ( decoder - > isValid ( ) )
{
2010-01-11 01:39:08 +01:00
IAudio * audio = new cAudio ( decoder , Context , initEffects . getEFXInterface ( ) ) ;
2009-12-07 23:25:08 +01:00
decoder - > drop ( ) ;
if ( audio )
{
if ( audio - > isValid ( ) )
{
if ( ! audioName . empty ( ) )
audioIndex [ audioName ] = audio ;
audioSources . push_back ( audio ) ;
getLogger ( ) - > logInfo ( " AudioManager " , " Audio Source (%s) successfully created from memory. " , audioName . c_str ( ) ) ;
return audio ;
}
audio - > drop ( ) ;
getLogger ( ) - > logError ( " AudioManager " , " Failed to create Audio Source (%s): Error creating audio source. " , audioName . c_str ( ) ) ;
return NULL ;
}
getLogger ( ) - > logError ( " AudioManager " , " Failed to create Audio Source (%s): Could not allocate enough memory. " , audioName . c_str ( ) ) ;
return NULL ;
}
decoder - > drop ( ) ;
getLogger ( ) - > logError ( " AudioManager " , " Failed to create Audio Source (%s): Audio data could not be decoded by (.%s) decoder. " , audioName . c_str ( ) , ext . c_str ( ) ) ;
return NULL ;
}
getLogger ( ) - > logError ( " AudioManager " , " Failed to create Audio Source (%s): Could not allocate enough memory for decoder. " , audioName . c_str ( ) ) ;
return NULL ;
}
source - > drop ( ) ;
getLogger ( ) - > logError ( " AudioManager " , " Failed to create Audio Source (%s): Audio data is corrupt. " , audioName . c_str ( ) ) ;
return NULL ;
}
getLogger ( ) - > logError ( " AudioManager " , " Failed to create Audio Source (%s): Could not allocate enough memory. " , audioName . c_str ( ) ) ;
return NULL ;
}
getLogger ( ) - > logError ( " AudioManager " , " Failed to create Audio Source (%s): Codec (.%s) is not supported. " , audioName . c_str ( ) , ext . c_str ( ) ) ;
return NULL ;
2009-06-21 05:24:30 +02:00
}
2009-12-01 02:41:15 +01:00
IAudio * cAudioManager : : createFromRaw ( const char * name , const char * data , size_t length , unsigned int frequency , AudioFormats format )
2009-08-11 19:57:20 +02:00
{
2009-12-07 23:25:08 +01:00
cAudioMutexBasicLock lock ( Mutex ) ;
2009-12-01 02:41:15 +01:00
2009-12-07 23:25:08 +01:00
std : : string audioName = safeCStr ( name ) ;
IAudioDecoderFactory * factory = getAudioDecoderFactory ( " raw " ) ;
if ( factory )
{
cMemorySource * source = new cMemorySource ( data , length , true ) ;
if ( source )
{
if ( source - > isValid ( ) )
{
IAudioDecoder * decoder = ( ( cRawAudioDecoderFactory * ) factory ) - > CreateAudioDecoder ( source , frequency , format ) ;
source - > drop ( ) ;
if ( decoder )
{
if ( decoder - > isValid ( ) )
{
2010-01-11 01:39:08 +01:00
IAudio * audio = new cAudio ( decoder , Context , initEffects . getEFXInterface ( ) ) ;
2009-12-07 23:25:08 +01:00
decoder - > drop ( ) ;
if ( audio )
{
if ( audio - > isValid ( ) )
{
if ( ! audioName . empty ( ) )
audioIndex [ audioName ] = audio ;
audioSources . push_back ( audio ) ;
getLogger ( ) - > logInfo ( " AudioManager " , " Audio Source (%s) successfully created from raw data. " , audioName . c_str ( ) ) ;
return audio ;
}
audio - > drop ( ) ;
getLogger ( ) - > logError ( " AudioManager " , " Failed to create Audio Source (%s): Error creating audio source. " , audioName . c_str ( ) ) ;
return NULL ;
}
getLogger ( ) - > logError ( " AudioManager " , " Failed to create Audio Source (%s): Could not allocate enough memory. " , audioName . c_str ( ) ) ;
return NULL ;
}
decoder - > drop ( ) ;
getLogger ( ) - > logError ( " AudioManager " , " Failed to create Audio Source (%s): Audio data could not be decoded by (.%s) decoder. " , audioName . c_str ( ) , " raw " ) ;
return NULL ;
}
getLogger ( ) - > logError ( " AudioManager " , " Failed to create Audio Source (%s): Could not allocate enough memory for decoder. " , audioName . c_str ( ) ) ;
return NULL ;
}
source - > drop ( ) ;
getLogger ( ) - > logError ( " AudioManager " , " Failed to create Audio Source (%s): Audio data is corrupt. " , audioName . c_str ( ) ) ;
return NULL ;
}
getLogger ( ) - > logError ( " AudioManager " , " Failed to create Audio Source (%s): Could not allocate enough memory. " , audioName . c_str ( ) ) ;
return NULL ;
}
getLogger ( ) - > logError ( " AudioManager " , " Failed to create Audio Source (%s): Codec (.%s) is not supported. " , audioName . c_str ( ) , " raw " ) ;
return NULL ;
2009-08-11 19:57:20 +02:00
}
2009-12-01 02:41:15 +01:00
bool cAudioManager : : registerAudioDecoder ( IAudioDecoderFactory * factory , const char * extension )
2009-06-21 05:24:30 +02:00
{
2009-12-07 23:25:08 +01:00
cAudioMutexBasicLock lock ( Mutex ) ;
2009-12-01 02:41:15 +01:00
std : : string ext = safeCStr ( extension ) ;
decodermap [ ext ] = factory ;
getLogger ( ) - > logInfo ( " AudioManager " , " Audio Decoder for extension .%s registered. " , ext . c_str ( ) ) ;
2009-08-11 19:57:20 +02:00
return true ;
2009-06-21 05:24:30 +02:00
}
2009-12-01 02:41:15 +01:00
void cAudioManager : : unRegisterAudioDecoder ( const char * extension )
2009-08-11 19:57:20 +02:00
{
2009-12-07 23:25:08 +01:00
cAudioMutexBasicLock lock ( Mutex ) ;
2009-12-01 02:41:15 +01:00
std : : string ext = safeCStr ( extension ) ;
std : : map < std : : string , IAudioDecoderFactory * > : : iterator it = decodermap . find ( ext ) ;
2009-08-11 19:57:20 +02:00
if ( it ! = decodermap . end ( ) )
{
decodermap . erase ( it ) ;
2009-12-01 02:41:15 +01:00
getLogger ( ) - > logInfo ( " AudioManager " , " Audio Decoder for extension .%s unregistered. " , ext . c_str ( ) ) ;
2009-08-11 19:57:20 +02:00
}
}
2009-12-01 02:41:15 +01:00
bool cAudioManager : : isAudioDecoderRegistered ( const char * extension )
2009-08-11 19:57:20 +02:00
{
2009-12-07 23:25:08 +01:00
cAudioMutexBasicLock lock ( Mutex ) ;
2009-12-01 02:41:15 +01:00
std : : string ext = safeCStr ( extension ) ;
std : : map < std : : string , IAudioDecoderFactory * > : : iterator it = decodermap . find ( ext ) ;
2009-12-07 23:25:08 +01:00
return ( it ! = decodermap . end ( ) ) ;
2009-08-11 19:57:20 +02:00
}
2009-12-01 02:41:15 +01:00
IAudioDecoderFactory * cAudioManager : : getAudioDecoderFactory ( const char * extension )
2009-08-11 19:57:20 +02:00
{
2009-12-07 23:25:08 +01:00
cAudioMutexBasicLock lock ( Mutex ) ;
2009-12-01 02:41:15 +01:00
std : : string ext = safeCStr ( extension ) ;
std : : map < std : : string , IAudioDecoderFactory * > : : iterator it = decodermap . find ( ext ) ;
2009-08-11 19:57:20 +02:00
if ( it ! = decodermap . end ( ) )
{
return it - > second ;
}
return NULL ;
}
2009-06-21 05:24:30 +02:00
//!grabs the selected audio file via the identifier
2009-12-01 02:41:15 +01:00
IAudio * cAudioManager : : getSoundByName ( const char * name )
2009-06-21 05:24:30 +02:00
{
2009-12-07 23:25:08 +01:00
cAudioMutexBasicLock lock ( Mutex ) ;
2009-12-01 02:41:15 +01:00
std : : string audioName = safeCStr ( name ) ;
std : : map < std : : string , IAudio * > : : iterator i = audioIndex . find ( audioName ) ;
if ( i = = audioIndex . end ( ) )
2009-08-29 13:24:31 +02:00
{
return NULL ;
}
2009-06-21 05:24:30 +02:00
return i - > second ;
}
//!Releases the selected audio source
void cAudioManager : : release ( )
{
2009-12-07 23:25:08 +01:00
cAudioMutexBasicLock lock ( Mutex ) ;
2009-12-01 02:41:15 +01:00
for ( unsigned int i = 0 ; i < audioSources . size ( ) ; + + i )
{
IAudio * source = audioSources [ i ] ;
if ( source )
2009-12-07 23:25:08 +01:00
source - > drop ( ) ;
2009-12-01 02:41:15 +01:00
}
audioSources . clear ( ) ;
audioIndex . clear ( ) ;
2009-06-21 05:24:30 +02:00
}
2010-01-19 05:04:40 +01:00
void cAudioManager : : release ( IAudio * source )
{
if ( source )
{
cAudioMutexBasicLock lock ( Mutex ) ;
std : : map < std : : string , IAudio * > : : iterator it = audioIndex . begin ( ) ;
for ( it = audioIndex . begin ( ) ; it ! = audioIndex . end ( ) ; it + + )
{
if ( it - > second = = source )
{
audioIndex . erase ( it ) ;
break ;
}
}
for ( unsigned int i = 0 ; i < audioSources . size ( ) ; + + i )
{
if ( source = = audioSources [ i ] )
{
source - > drop ( ) ;
audioSources . erase ( audioSources . begin ( ) + i ) ;
break ;
}
}
}
}
2009-06-21 05:24:30 +02:00
//!Updates all audiosources created
void cAudioManager : : update ( )
{
2009-12-07 23:25:08 +01:00
cAudioMutexBasicLock lock ( Mutex ) ;
2009-12-01 02:41:15 +01:00
for ( unsigned int i = 0 ; i < audioSources . size ( ) ; + + i )
{
IAudio * source = audioSources [ i ] ;
if ( source - > isValid ( ) )
2009-06-21 05:24:30 +02:00
{
2009-12-01 02:41:15 +01:00
if ( source - > update ( ) )
2009-06-21 05:24:30 +02:00
{
}
}
}
}
//!Shuts down cAudio. Deletes all audio sources in process
void cAudioManager : : shutDown ( )
{
2009-12-07 23:25:08 +01:00
if ( Initialized )
{
cAudioMutexBasicLock lock ( Mutex ) ;
release ( ) ;
//Reset context to null
alcMakeContextCurrent ( NULL ) ;
//Delete the context
alcDestroyContext ( Context ) ;
Context = NULL ;
//Close the device
alcCloseDevice ( Device ) ;
Device = NULL ;
Initialized = false ;
getLogger ( ) - > logInfo ( " AudioManager " , " Manager successfully shutdown. " ) ;
}
2009-06-21 05:24:30 +02:00
}
2010-01-11 01:39:08 +01:00
bool cAudioManager : : checkError ( )
2009-11-20 04:39:56 +01:00
{
int error = alGetError ( ) ;
const char * errorString ;
if ( error ! = AL_NO_ERROR )
{
errorString = alGetString ( error ) ;
getLogger ( ) - > logError ( " AudioManager " , " OpenAL Error: %s. " , errorString ) ;
2010-01-11 01:39:08 +01:00
return true ;
2009-11-20 04:39:56 +01:00
}
if ( Device )
{
error = alcGetError ( Device ) ;
if ( error ! = AL_NO_ERROR )
{
errorString = alGetString ( error ) ;
getLogger ( ) - > logError ( " AudioManager " , " OpenAL Error: %s. " , errorString ) ;
2010-01-11 01:39:08 +01:00
return true ;
2009-11-20 04:39:56 +01:00
}
}
2010-01-11 01:39:08 +01:00
return false ;
2009-11-20 04:39:56 +01:00
}
void cAudioManager : : getAvailableDevices ( )
{
// Get list of available Playback Devices
2009-12-07 23:25:08 +01:00
cAudioMutexBasicLock lock ( Mutex ) ;
2009-11-20 04:39:56 +01:00
if ( alcIsExtensionPresent ( NULL , " ALC_ENUMERATE_ALL_EXT " ) = = AL_TRUE )
{
const char * deviceList = alcGetString ( NULL , ALC_ALL_DEVICES_SPECIFIER ) ;
if ( deviceList )
{
while ( * deviceList )
{
std : : string device ( deviceList ) ;
AvailableDevices . push_back ( device ) ;
deviceList + = strlen ( deviceList ) + 1 ;
}
}
// Get the name of the 'default' capture device
DefaultDevice = alcGetString ( NULL , ALC_DEFAULT_ALL_DEVICES_SPECIFIER ) ;
}
else if ( alcIsExtensionPresent ( NULL , " ALC_ENUMERATION_EXT " ) = = AL_TRUE )
{
const char * deviceList = alcGetString ( NULL , ALC_DEVICE_SPECIFIER ) ;
if ( deviceList )
{
while ( * deviceList )
{
std : : string device ( deviceList ) ;
AvailableDevices . push_back ( device ) ;
deviceList + = strlen ( deviceList ) + 1 ;
}
}
// Get the name of the 'default' capture device
DefaultDevice = alcGetString ( NULL , ALC_DEFAULT_DEVICE_SPECIFIER ) ;
}
}
2009-06-21 05:24:30 +02:00
2009-11-20 04:39:56 +01:00
const char * cAudioManager : : getAvailableDeviceName ( unsigned int index )
{
2009-12-07 23:25:08 +01:00
cAudioMutexBasicLock lock ( Mutex ) ;
2009-11-20 04:39:56 +01:00
if ( ! AvailableDevices . empty ( ) )
{
//Bounds check
if ( index > ( AvailableDevices . size ( ) - 1 ) ) index = ( AvailableDevices . size ( ) - 1 ) ;
const char * deviceName = AvailableDevices [ index ] . c_str ( ) ;
return deviceName ;
}
return " " ;
}
unsigned int cAudioManager : : getAvailableDeviceCount ( )
{
2009-12-07 23:25:08 +01:00
cAudioMutexBasicLock lock ( Mutex ) ;
return AvailableDevices . size ( ) ;
2009-11-20 04:39:56 +01:00
}
const char * cAudioManager : : getDefaultDeviceName ( )
{
2009-12-07 23:25:08 +01:00
cAudioMutexBasicLock lock ( Mutex ) ;
return DefaultDevice . empty ( ) ? " " : DefaultDevice . c_str ( ) ;
2009-11-20 04:39:56 +01:00
}
CAUDIO_API IAudioManager * createAudioManager ( bool initializeDefault )
{
cAudioManager * manager = new cAudioManager ;
if ( manager )
{
if ( initializeDefault )
manager - > initialize ( ) ;
manager - > getAvailableDevices ( ) ;
2010-02-10 05:46:00 +01:00
std : : vector < IAudioPlugin * > plugins = cPluginManager : : Instance ( ) - > getPluginList ( ) ;
2010-02-09 06:58:27 +01:00
for ( unsigned int i = 0 ; i < plugins . size ( ) ; + + i )
{
plugins [ i ] - > onCreateAudioManager ( manager ) ;
}
2009-11-20 04:39:56 +01:00
# ifdef CAUDIO_USE_INTERNAL_THREAD
AudioManagerObjectsMutex . lock ( ) ;
AudioManagerObjects . insert ( manager ) ;
//First time launch of thread
if ( ! RunAudioManagerThread & & AudioManagerObjects . size ( ) > 0 )
RunAudioManagerThread = ( cAudioThread : : SpawnThread ( AudioManagerUpdateThread , NULL ) = = 0 ) ;
AudioManagerObjectsMutex . unlock ( ) ;
# endif
}
return manager ;
}
CAUDIO_API void destroyAudioManager ( IAudioManager * manager )
{
if ( manager )
{
# ifdef CAUDIO_USE_INTERNAL_THREAD
AudioManagerObjectsMutex . lock ( ) ;
AudioManagerObjects . erase ( manager ) ;
//Kill the thread if there are no objects to process anymore
if ( RunAudioManagerThread & & AudioManagerObjects . empty ( ) )
RunAudioManagerThread = false ;
AudioManagerObjectsMutex . unlock ( ) ;
# endif
2010-02-10 05:46:00 +01:00
std : : vector < IAudioPlugin * > plugins = cPluginManager : : Instance ( ) - > getPluginList ( ) ;
2010-02-09 06:58:27 +01:00
for ( unsigned int i = 0 ; i < plugins . size ( ) ; + + i )
{
plugins [ i ] - > onDestroyAudioManager ( manager ) ;
}
2010-02-10 05:46:00 +01:00
manager - > shutDown ( ) ;
2010-02-09 06:58:27 +01:00
2009-11-20 04:39:56 +01:00
delete manager ;
manager = NULL ;
}
}
CAUDIO_API bool isAudioManagerThreadRunning ( )
{
return RunAudioManagerThread ;
}
2009-06-21 05:24:30 +02:00
2009-11-20 04:39:56 +01:00
} ;