Added cross-platform Mutex and Thread classes.

Made cAudio, cAudioCapture, cAudioManager and other classes thread safe.
Made cAudioManager use a seperate update thread by default.
Added cAudioSleep, a cross-platform sleep() function
Moved global defines to cAudioDefines
Added defines to disable thread safety or the internal update thread if the user wishes it
Updated tutorials to reflect the changes made
This commit is contained in:
Joshua Jones 2009-08-29 11:24:31 +00:00
parent 008f1e76c9
commit 75ece68dcf
24 changed files with 533 additions and 42 deletions

View File

@ -3,6 +3,8 @@
#include "../../include/IAudioManager.h"
//Include IAudio so we can create cAudio objects
#include "../../include/IAudio.h"
//Include our version of Sleep to free CPU usage
#include "../../include/cAudioSleep.h"
using namespace std;
@ -27,11 +29,8 @@ int main(int argc, char* argv[])
//Set the IAudio Sound to play2d and loop
mysound->play2d(true);
while(mysound->playing())
{
//Playback sound
manager->update();
}
//Sleep for 10,000 ms to let the sound play in the worker thread
cAudio::cAudioSleep(10000);
}
//Delete all IAudio sounds

View File

@ -11,6 +11,8 @@
#include "../../include/IAudio.h"
//Include The cAudio vector class
#include "../../include/cVector3.h"
//Include our version of Sleep to free CPU usage
#include "../../include/cAudioSleep.h"
using namespace std;
@ -44,10 +46,12 @@ int main(int argc, char* argv[])
while(mysound->playing())
{
//Playback sound
x+=0.001f * 0.017453293f; //0.001 degrees a frame
x+=0.1f * 0.017453293f; //0.1 degrees a frame
float realX = sinf(x)*10.f;
mysound->setPosition(cAudio::cVector3(realX,0.0,-5.0));
manager->update();
//Sleep for 1 ms to free some CPU
cAudio::cAudioSleep(1);
}
}

View File

@ -11,6 +11,8 @@
#include "../../include/IAudio.h"
//Include The cAudio vector class
#include "../../include/cVector3.h"
//Include our version of Sleep to free CPU usage
#include "../../include/cAudioSleep.h"
//Our Bling sound
#include "bling.h"
@ -39,8 +41,8 @@ int main(int argc, char* argv[])
while(mysound->playing())
{
//Playback sound
manager->update();
//Sleep for 10 ms to free some CPU
cAudio::cAudioSleep(10);
}
}

View File

@ -4,6 +4,8 @@
#include "../../include/IAudioManager.h"
//Include IAudio so we can create cAudio objects
#include "../../include/IAudio.h"
//Include our version of Sleep to free CPU usage
#include "../../include/cAudioSleep.h"
using namespace std;
@ -61,13 +63,18 @@ int main(int argc, char* argv[])
while(currentsize < targetRecordSize)
{
currentsize = capture->getCurrentCapturedAudioSize();
//Run the main update loop to keep audio data flowing in
manager->update();
//Sleep for 1 ms to free some CPU
cAudio::cAudioSleep(1);
}
}
capture->stopCapture();
cout << "Capture stopped... \n \n";
//Grab the total size again, ensures we get ALL the audio data
//Not completely necessary, as starting a capture again will clear the old audio data
currentsize = capture->getCurrentCapturedAudioSize();
char* buffer = new char[currentsize];
capture->getCapturedAudio(buffer, currentsize);
@ -85,8 +92,8 @@ int main(int argc, char* argv[])
while(mysound->playing())
{
//Playback sound
manager->update();
//Sleep for 10 ms to free some CPU
cAudio::cAudioSleep(10);
}
}
}

View File

@ -8,6 +8,7 @@
#define BUFFER_SIZE ( 1024 * 32 )
#include "../include/IAudio.h"
#include "../Include/cVector3.h"
#include "../Headers/cMutex.h"
namespace cAudio
{
@ -82,6 +83,8 @@ namespace cAudio
protected:
private:
//Mutex for thread syncronization
cAudioMutex Mutex;
//!empties the queue
void empty();
//!checks openal error state

View File

@ -5,6 +5,7 @@
#include <vector>
#include <AL/al.h>
#include <AL/alc.h>
#include "../Headers/cMutex.h"
namespace cAudio
{
@ -74,6 +75,9 @@ namespace cAudio
//! Returns the current size of the internal audio buffer in bytes
virtual unsigned int getCurrentCapturedAudioSize();
protected:
//Mutex for thread syncronization
cAudioMutex Mutex;
bool initOpenALDevice();
void shutdownOpenALDevice();

View File

@ -8,6 +8,7 @@
#include "cListener.h"
#include "cAudioCapture.h"
#include "../include/IAudioManager.h"
#include "../Headers/cMutex.h"
namespace cAudio
{
@ -52,15 +53,22 @@ namespace cAudio
virtual IListener* getListener() { return &initlistener; }
virtual IAudioCapture* getAudioCapture() { return &initCapture; }
virtual bool IsThreadRunning() { return RunThread; }
static cAudioManager* Instance()
{
return &m_cAudioManager;
}
protected:
cAudioManager(){ }
cAudioManager() : RunThread(false){ }
private:
//Mutex for thread syncronization
cAudioMutex Mutex;
bool RunThread;
//!Global cAudioManager
static cAudioManager m_cAudioManager;
//!The map that holds the cAudio objects

View File

@ -2,6 +2,7 @@
#define CLISTENER_H_INCLUDED
#include "../include/IListener.h"
#include "../Headers/cMutex.h"
namespace cAudio
{
@ -41,6 +42,8 @@ namespace cAudio
//!Returns the global volume modifier for all sources
virtual float getMasterVolume(void) const { return MasterGain; }
protected:
cAudioMutex Mutex;
cVector3 Position;
cVector3 Direction;
cVector3 UpVector;

52
Headers/cMutex.h Normal file
View File

@ -0,0 +1,52 @@
#ifndef CAUDIOMUTEX_H
#define CAUDIOMUTEX_H
#include "../include/cAudioDefines.h"
#ifdef CAUDIO_MAKE_THREAD_SAFE
#ifdef _WIN32
#include <windows.h> //Basic windows include
#else
#include <pthread.h> //Assumed linux system
#endif
#endif
namespace cAudio
{
//Basic mutex class used for internal thread locking
#ifdef CAUDIO_MAKE_THREAD_SAFE
class cAudioMutex
{
public:
cAudioMutex();
~cAudioMutex();
void lock();
void unlock();
private:
void initialize();
#ifdef _WIN32
CRITICAL_SECTION criticalSection;
#else
pthread_mutex_t Mutex;
#endif
bool Initialized;
};
#else
//Dud class to disable the mutex
class cAudioMutex
{
public:
cAudioMutex();
~cAudioMutex();
void lock();
void unlock();
private:
void initialize();
bool Initialized;
};
#endif
};
#endif //! CAUDIOMUTEX_H

View File

@ -3,6 +3,7 @@
#include "../include/IAudioDecoderFactory.h"
#include "cOggDecoder.h"
#include "../Headers/cMutex.h"
namespace cAudio
{
@ -15,10 +16,14 @@ class cOggAudioDecoderFactory : public IAudioDecoderFactory
IAudioDecoder* CreateAudioDecoder(IDataSource* stream)
{
return new cOggDecoder(stream);
Mutex.lock();
IAudioDecoder* decoder = new cOggDecoder(stream);
Mutex.unlock();
return decoder;
}
protected:
cAudioMutex Mutex;
private:
};

View File

@ -3,7 +3,7 @@
#include "../include/IAudioDecoderFactory.h"
#include "cRawDecoder.h"
#include "../Headers/cMutex.h"
namespace cAudio
{
@ -16,14 +16,21 @@ class cRawAudioDecoderFactory : public IAudioDecoderFactory
IAudioDecoder* CreateAudioDecoder(IDataSource* stream)
{
return new cRawDecoder(stream, 22050, EAF_16BIT_MONO);
Mutex.lock();
IAudioDecoder* decoder = new cRawDecoder(stream, 22050, EAF_16BIT_MONO);
Mutex.unlock();
return decoder;
}
IAudioDecoder* CreateAudioDecoder(IDataSource* stream, unsigned int frequency = 22050, AudioFormats format = EAF_16BIT_MONO)
{
return new cRawDecoder(stream, frequency, format);
Mutex.lock();
IAudioDecoder* decoder = new cRawDecoder(stream, frequency, format);
Mutex.unlock();
return decoder;
}
protected:
cAudioMutex Mutex;
private:
};

30
Headers/cThread.h Normal file
View File

@ -0,0 +1,30 @@
#ifndef CAUDIOTHREAD_H
#define CAUDIOTHREAD_H
#include "../include/cAudioDefines.h"
//Helper defines in order to make sure the function is declared right for use as a thread
#ifdef _WIN32
#define CAUDIO_DECLARE_THREAD_FUNCTION(functionName) unsigned __stdcall functionName( void* arguments )
#else
#define CAUDIO_DECLARE_THREAD_FUNCTION(functionName) void* functionName( void* arguments )
#endif
namespace cAudio
{
class cAudioThread
{
public:
// Really basic function to spawn a single detached thread
/** \param start_address The function you want to call
// \param arg Any arguments to pass to the function
// \return 0 if successful, otherwise an error */
#ifdef _WIN32
static int SpawnThread( unsigned __stdcall start_address( void* ), void *arg);
#else
static int SpawnThread( void* start_address( void* ), void *arg);
#endif
};
};
#endif //! CAUDIOTHREAD_H

View File

@ -3,7 +3,7 @@
#include "../include/IAudioDecoderFactory.h"
#include "cWavDecoder.h"
#include "../Headers/cMutex.h"
namespace cAudio
{
@ -16,9 +16,13 @@ class cWavAudioDecoderFactory : public IAudioDecoderFactory
IAudioDecoder* CreateAudioDecoder(IDataSource* stream)
{
return new cWavDecoder(stream);
Mutex.lock();
IAudioDecoder* decoder = new cWavDecoder(stream);
Mutex.unlock();
return decoder;
}
protected:
cAudioMutex Mutex;
private:
};

View File

@ -7,6 +7,7 @@ namespace cAudio
{
cAudio::cAudio(IAudioDecoder* decoder) : Decoder(decoder)
{
Mutex.lock();
streaming = false;
playaudio = false;
pauseaudio = false;
@ -16,16 +17,20 @@ namespace cAudio
alGenBuffers(3, buffers);
//Creates one source to be stored.
alGenSources(1, &source);
Mutex.unlock();
}
cAudio::~cAudio()
{
Mutex.lock();
delete Decoder;
Mutex.unlock();
}
//!Stops all playing sound sources and deletes the sources and buffers
void cAudio::release()
{
Mutex.lock();
//Stops the audio source
alSourceStop(source);
empty();
@ -33,38 +38,50 @@ namespace cAudio
alDeleteSources(1, &source);
//deletes the last filled buffer
alDeleteBuffers(3, buffers);
Mutex.unlock();
}
//!Plays back sound source
bool cAudio::playback()
{
return playing();
Mutex.lock();
bool play = playing();
Mutex.unlock();
return play;
}
bool cAudio::paused()
{
Mutex.lock();
ALenum state = 0;
alGetSourcei(source, AL_SOURCE_STATE, &state);
Mutex.unlock();
return (state == AL_PAUSED);
}
//!checks to see if audio source is playing if it is returns true
bool cAudio::playing()
{
Mutex.lock();
ALenum state = 0;
alGetSourcei(source, AL_SOURCE_STATE, &state);
Mutex.unlock();
return (state == AL_PLAYING);
}
//!updates the sound source by refilling the buffers with ogg data.
bool cAudio::update()
{
Mutex.lock();
if(!isvalid() || !playing())
{
Mutex.unlock();
return false;
}
int processed = 0;
bool active = true;
@ -83,6 +100,7 @@ namespace cAudio
if(active)
alSourceQueueBuffers(source, 1, &buffer);
}
Mutex.unlock();
return active;
}
@ -160,21 +178,27 @@ namespace cAudio
//!checks to see if the given ogg file is valid
bool cAudio::isvalid()
{
return (Decoder != 0);
Mutex.lock();
bool state = (Decoder != 0);
Mutex.unlock();
return state;
}
//!Sets the sound source relativity to follow the listener to give the illusion of stereo 2d sound
void cAudio::play2d(bool loop)
{
Mutex.lock();
alSourcei (source, AL_SOURCE_RELATIVE, true);
toloop = loop;
play();
alSourcePlay(source);
Mutex.unlock();
}
//!Plays the given audio file with 3d position
void cAudio::play3d(cVector3 position, float soundstr, bool loop)
{
Mutex.lock();
this->position = position;
this->strength = soundstr;
alSourcei (source, AL_SOURCE_RELATIVE, false);
@ -183,67 +207,86 @@ namespace cAudio
toloop = loop;
play();
alSourcePlay(source);
Mutex.unlock();
}
//!Used to tell the soundsource to loop or not
void cAudio::loop(bool loop)
{
Mutex.lock();
toloop = loop;
Mutex.unlock();
}
//!Used to move the audio sources position after the initial creation
void cAudio::setPosition(const cVector3 position)
{
Mutex.lock();
this->position = position;
alSource3f(source, AL_POSITION, position.x, position.y, position.z);
Mutex.unlock();
}
//!Used to set the velocity of the audio source.
void cAudio::setVelocity(const cVector3 velocity)
{
Mutex.lock();
this->velocity = velocity;
alSource3f(source, AL_VELOCITY, velocity.x, velocity.y, velocity.z);
Mutex.unlock();
}
//!Used to set the direction of the audio source
void cAudio::setDirection(const cVector3 direction)
{
Mutex.lock();
this->direction = direction;
alSource3f(source, AL_DIRECTION, direction.x, direction.y, direction.z);
Mutex.unlock();
}
//!Used to set the sound strength or roll off factor
void cAudio::setStrength(const float soundstrength)
{
Mutex.lock();
alSourcef(source, AL_ROLLOFF_FACTOR, soundstrength);
Mutex.unlock();
}
//!Used to set the pitch of the audio file
void cAudio::setPitch(const float pitch)
{
Mutex.lock();
this->pitch = pitch;
alSourcef (source, AL_PITCH, pitch);
Mutex.unlock();
}
//!Used to set the volume of the audio source
void cAudio::setVolume(const float volume)
{
Mutex.lock();
this->volume = volume;
alSourcef(source, AL_GAIN, volume);
Mutex.unlock();
}
//!Used to set the doppler strength of the audio sources doppler effect
void cAudio::setDopplerStrength(const float dstrength)
{
Mutex.lock();
this->dstrength = dstrength;
alSourcef(source, AL_DOPPLER_FACTOR, dstrength);
Mutex.unlock();
}
//!Used to set the doppler velocity of the audio source
void cAudio::setDopplerVelocity(const cVector3 dvelocity)
{
Mutex.lock();
this->dvelocity = dvelocity;
alSource3f(source, AL_DOPPLER_VELOCITY, dvelocity.x, dvelocity.y, dvelocity.z);
Mutex.unlock();
}
const cVector3& cAudio::getPosition()const
@ -289,15 +332,18 @@ namespace cAudio
//!Allows us to seek through a stream
void cAudio::seek(float secs)
{
Mutex.lock();
if(Decoder->isSeekingSupported())
{
Decoder->seek(secs, false);
}
Mutex.unlock();
}
//!Used to play the audio source
bool cAudio::play()
{
Mutex.lock();
playaudio = true;
if (!paused())
{
@ -316,22 +362,27 @@ namespace cAudio
//Stores the sources 3 buffers to be used in the queue
alSourceQueueBuffers(source, queueSize, buffers);
}
alSourcePlay(source);
alSourcePlay(source);
Mutex.unlock();
return true;
}
//!Used to stop the audio source
void cAudio::stop()
{
Mutex.lock();
playaudio = false;
alSourceStop(source);
Mutex.unlock();
}
//!Used to pause the audio source
void cAudio::pause()
{
Mutex.lock();
playaudio = false;
alSourcePause(source);
Mutex.unlock();
}
}

View File

@ -15,17 +15,20 @@ namespace cAudio
bool cAudioCapture::checkCaptureExtension()
{
Mutex.lock();
// Check for Capture Extension support
ALCdevice* pDevice;
ALCcontext* pContext;
pContext = alcGetCurrentContext();
pDevice = alcGetContextsDevice(pContext);
Supported = ( alcIsExtensionPresent(pDevice, "ALC_EXT_CAPTURE") == AL_TRUE );
Mutex.unlock();
return Supported;
}
bool cAudioCapture::initOpenALDevice()
{
Mutex.lock();
if(Supported)
{
if(CaptureDevice)
@ -35,14 +38,17 @@ namespace cAudio
if(CaptureDevice)
{
Ready = true;
Mutex.unlock();
return true;
}
}
Mutex.unlock();
return false;
}
void cAudioCapture::shutdownOpenALDevice()
{
Mutex.lock();
if(Supported)
{
if(Capturing)
@ -55,15 +61,19 @@ namespace cAudio
Ready = false;
}
}
Mutex.unlock();
}
void cAudioCapture::shutdown()
{
Mutex.lock();
shutdownOpenALDevice();
Mutex.unlock();
}
void cAudioCapture::updateCaptureBuffer(bool force)
{
Mutex.lock();
if(Capturing && CaptureDevice && Ready)
{
int AvailableSamples = 0;
@ -82,10 +92,12 @@ namespace cAudio
}
}
}
Mutex.unlock();
}
bool cAudioCapture::beginCapture()
{
Mutex.lock();
if(!Capturing)
{
CaptureBuffer.clear();
@ -94,49 +106,65 @@ namespace cAudio
alcCaptureStart(CaptureDevice);
Capturing = true;
}
Mutex.unlock();
return Capturing;
}
else
{
Mutex.unlock();
return false;
}
}
void cAudioCapture::stopCapture()
{
Mutex.lock();
if(CaptureDevice && Ready)
{
alcCaptureStop(CaptureDevice);
updateCaptureBuffer(true);
}
Capturing = false;
Mutex.unlock();
}
unsigned int cAudioCapture::getCapturedAudio(void* outputBuffer, unsigned int outputBufferSize)
{
Mutex.lock();
if(outputBuffer && outputBufferSize > 0)
{
int sizeToCopy = (outputBufferSize >= CaptureBuffer.size()) ? CaptureBuffer.size() : outputBufferSize;
memcpy(outputBuffer, &CaptureBuffer[0], sizeToCopy);
CaptureBuffer.erase(CaptureBuffer.begin(), CaptureBuffer.begin()+sizeToCopy);
Mutex.unlock();
return sizeToCopy;
}
Mutex.unlock();
return 0;
}
unsigned int cAudioCapture::getCurrentCapturedAudioSize()
{
return CaptureBuffer.size();
Mutex.lock();
unsigned int size = CaptureBuffer.size();
Mutex.unlock();
return size;
}
bool cAudioCapture::setFrequency(unsigned int frequency)
{
Mutex.lock();
Frequency = frequency;
shutdownOpenALDevice();
return initOpenALDevice();
bool state = initOpenALDevice();
Mutex.unlock();
return state;
}
bool cAudioCapture::setFormat(AudioFormats format)
{
Mutex.lock();
Format = format;
if(Format == EAF_8BIT_MONO)
SampleSize = 1;
@ -148,19 +176,25 @@ namespace cAudio
SampleSize = 4;
shutdownOpenALDevice();
return initOpenALDevice();
bool state = initOpenALDevice();
Mutex.unlock();
return state;
}
bool cAudioCapture::setInternalBufferSize(unsigned int internalBufferSize)
{
Mutex.lock();
InternalBufferSize = internalBufferSize;
shutdownOpenALDevice();
return initOpenALDevice();
bool state = initOpenALDevice();
Mutex.unlock();
return state;
}
bool cAudioCapture::initialize(unsigned int frequency, AudioFormats format, unsigned int internalBufferSize)
{
Mutex.lock();
Frequency = frequency;
InternalBufferSize = internalBufferSize;
@ -175,6 +209,8 @@ namespace cAudio
SampleSize = 4;
shutdownOpenALDevice();
return initOpenALDevice();
bool state = initOpenALDevice();
Mutex.unlock();
return state;
}
};

View File

@ -5,6 +5,8 @@
#include "../Headers/cOggAudioDecoderFactory.h"
#include "../Headers/cWavAudioDecoderFacotry.h"
#include "../Headers/cRawAudioDecoderFactory.h"
#include "../Headers/cThread.h"
#include "../include/cAudioSleep.h"
#include <AL/al.h>
#include <AL/alc.h>
@ -22,9 +24,23 @@ namespace cAudio
}
cAudioManager cAudioManager::m_cAudioManager;
CAUDIO_DECLARE_THREAD_FUNCTION(UpdateThread)
{
while(true)
{
if(!cAudioManager::Instance()->IsThreadRunning())
{
return 0;
}
cAudioManager::Instance()->update();
cAudioSleep(1);
}
}
//!Initialize the listener,openal,and mikmod
void cAudioManager::init(int argc,char* argv[])
{
Mutex.lock();
//Make a Openal context pointer
ALCcontext *Context;
//Make a openal device pointer
@ -48,11 +64,18 @@ namespace cAudio
registerAudioDecoder(new cOggAudioDecoderFactory, "ogg");
registerAudioDecoder(new cWavAudioDecoderFactory, "wav");
registerAudioDecoder(new cRawAudioDecoderFactory, "raw");
Mutex.unlock();
#ifdef CAUDIO_USE_INTERNAL_THREAD
RunThread = (cAudioThread::SpawnThread(UpdateThread, NULL) == 0);
#endif
}
//!create a sound source
IAudio* cAudioManager::createFromFile(const std::string& identifier,const std::string& file,bool stream)
{
Mutex.lock();
if(stream){
cFileSource* source = new cFileSource(file);
if(source->isValid())
@ -62,16 +85,19 @@ namespace cAudio
if(!factory)
{
delete source;
Mutex.unlock();
return NULL;
}
IAudioDecoder* decoder = factory->CreateAudioDecoder(source);
IAudio* audio = new cAudio(decoder);
audiomap[identifier] = audio;
Mutex.unlock();
return audio;
}
else
{
delete source;
Mutex.unlock();
return NULL;
}
}
@ -85,6 +111,7 @@ namespace cAudio
IAudio* guy = createFromMemory(identifier,tempbuf,length,getExt(file));
delete[]tempbuf;
delete tempsource;
Mutex.unlock();
return guy;
}
}
@ -92,6 +119,7 @@ namespace cAudio
//!Loads the ogg file from memory *virtual file systems*
IAudio* cAudioManager::createFromMemory(const std::string& identifier, const char* data, size_t length, std::string ext)
{
Mutex.lock();
cMemorySource* source = new cMemorySource(data,length,true);
if(source->isValid())
{
@ -99,22 +127,26 @@ namespace cAudio
if(!factory)
{
delete source;
Mutex.unlock();
return NULL;
}
IAudioDecoder* decoder = factory->CreateAudioDecoder(source);
IAudio* audio = new cAudio(decoder);
audiomap[identifier] = audio;
Mutex.unlock();
return audio;
}
else
{
delete source;
Mutex.unlock();
return NULL;
}
}
IAudio* cAudioManager::createFromRaw(const std::string& identifier,const char* data, size_t length, unsigned int frequency, AudioFormats format)
{
Mutex.lock();
cMemorySource* source = new cMemorySource(data,length,true);
if(source->isValid())
{
@ -122,63 +154,83 @@ namespace cAudio
if(!factory)
{
delete source;
Mutex.unlock();
return NULL;
}
IAudioDecoder* decoder = ((cRawAudioDecoderFactory*)factory)->CreateAudioDecoder(source, frequency, format);
IAudio* audio = new cAudio(decoder);
audiomap[identifier] = audio;
Mutex.unlock();
return audio;
}
else
{
delete source;
Mutex.unlock();
return NULL;
}
}
bool cAudioManager::registerAudioDecoder(IAudioDecoderFactory* factory, std::string extension)
{
Mutex.lock();
decodermap[extension] = factory;
Mutex.unlock();
return true;
}
void cAudioManager::unRegisterAudioDecoder(std::string extension)
{
Mutex.lock();
std::map<std::string, IAudioDecoderFactory*>::iterator it = decodermap.find(extension);
if(it != decodermap.end())
{
delete it->second;
decodermap.erase(it);
}
Mutex.unlock();
}
bool cAudioManager::isAudioDecoderRegistered(std::string extension)
{
Mutex.lock();
std::map<std::string, IAudioDecoderFactory*>::iterator it = decodermap.find(extension);
return (it != decodermap.end());
bool result = (it != decodermap.end());
Mutex.unlock();
return result;
}
IAudioDecoderFactory* cAudioManager::getAudioDecoderFactory(std::string extension)
{
Mutex.lock();
std::map<std::string, IAudioDecoderFactory*>::iterator it = decodermap.find(extension);
if(it != decodermap.end())
{
Mutex.unlock();
return it->second;
}
Mutex.unlock();
return NULL;
}
//!grabs the selected audio file via the identifier
IAudio *cAudioManager::getSound(std::string identifier)
{
Mutex.lock();
std::map<std::string,IAudio*>::iterator i = audiomap.find(identifier);
if (i == audiomap.end()){return NULL;}
if (i == audiomap.end())
{
Mutex.unlock();
return NULL;
}
Mutex.unlock();
return i->second;
}
//!Releases the selected audio source
void cAudioManager::release()
{
Mutex.lock();
std::map<std::string,IAudio*>::iterator i = audiomap.begin();
while ( i != audiomap.end())
{
@ -194,11 +246,13 @@ namespace cAudio
it++;
}
decodermap.clear();
Mutex.unlock();
}
//!Updates all audiosources created
void cAudioManager::update()
{
Mutex.lock();
std::map<std::string,IAudio*>::iterator i = audiomap.begin();
for (i = audiomap.begin(); i != audiomap.end() ; i++)
{
@ -216,11 +270,13 @@ namespace cAudio
}
}
initCapture.updateCaptureBuffer();
Mutex.unlock();
}
//!Shuts down cAudio. Deletes all audio sources in process
void cAudioManager::shutDown()
{
Mutex.lock();
//Create a openal context pointer
ALCcontext *Context;
//Create a openal device pointer
@ -239,18 +295,24 @@ namespace cAudio
alcDestroyContext(Context);
//Close the device
alcCloseDevice(Device);
Mutex.unlock();
RunThread = false;
}
//!Sets the listeners position.
void cAudioManager::setListenerPos(float x,float y,float z)
{
Mutex.lock();
initlistener.setPosition(cVector3(x,y,z));
Mutex.unlock();
}
//!Sets the listener orientation
void cAudioManager::setListenerOrientation(float ux,float uy,float uz)
{
Mutex.lock();
initlistener.setUpVector(cVector3(ux,uy,uz));
Mutex.unlock();
}
}

22
Source/cAudioSleep.cpp Normal file
View File

@ -0,0 +1,22 @@
#ifdef _WIN32
#include <windows.h> //Basic windows include for Sleep();
#else
#include <unistd.h> //Assumed linux system, include for usleep()
#include <time.h>
#endif //If you need to support another platform, simply add a define for it
#include "../include/cAudioSleep.h"
namespace cAudio
{
void cAudioSleep(unsigned int ms)
{
#ifdef _WIN32
Sleep(ms);
#else
usleep(ms*1000); //convert from milliseconds to microseconds
#endif
}
};

View File

@ -5,37 +5,49 @@ namespace cAudio
{
void cListener::setPosition(const cVector3 pos)
{
Mutex.lock();
Position = pos;
alListener3f(AL_POSITION, Position.x, Position.y, Position.z);
Mutex.unlock();
}
void cListener::setDirection(const cVector3 dir)
{
Mutex.lock();
Direction = dir;
float orient[6] = {Direction[0], Direction[1], Direction[2], UpVector[0], UpVector[1], UpVector[2]};
alListenerfv(AL_ORIENTATION, orient);
Mutex.unlock();
}
void cListener::setUpVector(const cVector3 up)
{
Mutex.lock();
UpVector = up;
float orient[6] = {Direction[0], Direction[1], Direction[2], UpVector[0], UpVector[1], UpVector[2]};
alListenerfv(AL_ORIENTATION, orient);
Mutex.unlock();
}
void cListener::setVelocity(const cVector3 vel)
{
Mutex.lock();
Velocity = vel;
alListener3f(AL_VELOCITY, Velocity.x, Velocity.y, Velocity.z);
Mutex.unlock();
}
void cListener::setMasterVolume(const float volume)
{
Mutex.lock();
MasterGain = volume;
alListenerf(AL_GAIN, MasterGain);
Mutex.unlock();
}
void cListener::move(const cVector3 pos)
{
Mutex.lock();
Velocity = pos - Position;
Position = pos;
alListener3f(AL_POSITION, Position.x, Position.y, Position.z);
alListener3f(AL_VELOCITY, Velocity.x, Velocity.y, Velocity.z);
Mutex.unlock();
}
};

83
Source/cMutex.cpp Normal file
View File

@ -0,0 +1,83 @@
#include "../Headers/cMutex.h"
namespace cAudio
{
#ifdef CAUDIO_MAKE_THREAD_SAFE
cAudioMutex::cAudioMutex() : Initialized(false)
{
}
cAudioMutex::~cAudioMutex()
{
if(!Initialized)
return;
#ifdef _WIN32
DeleteCriticalSection(&criticalSection);
#else
pthread_mutex_destroy(&Mutex);
#endif
}
void cAudioMutex::lock(void)
{
if(!Initialized)
initialize();
#ifdef _WIN32
EnterCriticalSection(&criticalSection);
#else
int error = pthread_mutex_lock(&Mutex);
#endif
}
void cAudioMutex::unlock(void)
{
if(!Initialized)
return;
#ifdef _WIN32
LeaveCriticalSection(&criticalSection);
#else
int error = pthread_mutex_unlock(&Mutex);
#endif
}
void cAudioMutex::initialize(void)
{
#ifdef _WIN32
InitializeCriticalSection(&criticalSection);
#else
pthread_mutexattr_t attr;
int error = pthread_mutexattr_init(&attr);
error = pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE);
error = pthread_mutex_init(&Mutex, &attr);
error = pthread_mutexattr_destroy(&attr);
#endif
Initialized=true;
}
#else
cAudioMutex::cAudioMutex() : Initialized(false)
{
}
cAudioMutex::~cAudioMutex()
{
//Do nothing
}
void cAudioMutex::lock(void)
{
//Do nothing
}
void cAudioMutex::unlock(void)
{
//Do nothing
}
void cAudioMutex::initialize(void)
{
//Do nothing
}
#endif
};

39
Source/cThread.cpp Normal file
View File

@ -0,0 +1,39 @@
#include "../Headers/cThread.h"
#ifdef _WIN32
#include <windows.h> //Basic windows includes
#include <process.h>
#else
#include <pthread.h> //Assumed linux system
#endif
namespace cAudio
{
#ifdef _WIN32
int cAudioThread::SpawnThread( unsigned __stdcall start_address( void* ), void *arg)
{
HANDLE threadHandle;
unsigned threadID = 0;
threadHandle = (HANDLE) _beginthreadex(NULL,0,start_address,arg,0,&threadID);
int state = (threadHandle==0) ? 1 : 0;
if(state == 0)
CloseHandle( threadHandle );
return state;
}
#else
int cAudioThread::SpawnThread( void* start_address( void* ), void *arg)
{
pthread_t threadHandle;
pthread_attr_t attr;
pthread_attr_init( &attr );
pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_DETACHED );
return pthread_create( &threadHandle, &attr, start_address, arg );
}
#endif
};

View File

@ -198,6 +198,10 @@
RelativePath=".\Headers\cMemorySource.h"
>
</File>
<File
RelativePath=".\Headers\cMutex.h"
>
</File>
<File
RelativePath=".\Headers\cOggAudioDecoderFactory.h"
>
@ -214,6 +218,10 @@
RelativePath=".\Headers\cRawDecoder.h"
>
</File>
<File
RelativePath=".\Headers\cThread.h"
>
</File>
<File
RelativePath=".\Headers\cWavAudioDecoderFacotry.h"
>
@ -246,6 +254,10 @@
RelativePath=".\Source\cAudioManager.cpp"
>
</File>
<File
RelativePath=".\Source\cAudioSleep.cpp"
>
</File>
<File
RelativePath=".\Source\cFileSource.cpp"
>
@ -258,6 +270,10 @@
RelativePath=".\Source\cMemorySource.cpp"
>
</File>
<File
RelativePath=".\Source\cMutex.cpp"
>
</File>
<File
RelativePath=".\Source\cOggAudioDecoderFactory.cpp"
>
@ -270,6 +286,10 @@
RelativePath=".\Source\cRawDecoder.cpp"
>
</File>
<File
RelativePath=".\Source\cThread.cpp"
>
</File>
<File
RelativePath=".\Source\cWavAudioDecoderFactory.cpp"
>
@ -282,6 +302,14 @@
<Filter
Name="Include"
>
<File
RelativePath=".\include\cAudioDefines.h"
>
</File>
<File
RelativePath=".\include\cAudioSleep.h"
>
</File>
<File
RelativePath=".\include\EAudioFormats.h"
>

View File

@ -3,18 +3,7 @@
#include <string>
#include "IListener.h"
#include "IAudioCapture.h"
#ifndef CAUDIO_STATIC_LIB
#ifdef CAUDIO_EXPORTS
#define CAUDIO_API __declspec(dllexport)
#else
#define CAUDIO_API//! __declspec(dllimport)
#endif // CAUDIO_EXPORTS
#else
#define CAUDIO_API
#endif // CAUDIO_STATIC_LIB
#include "cAudioDefines.h"
namespace cAudio
{
@ -62,6 +51,8 @@ namespace cAudio
//!Returns an interface for audio capture
virtual IAudioCapture* getAudioCapture() = 0;
virtual bool IsThreadRunning() = 0;
virtual ~IAudioManager() {}
protected:
private:

28
include/cAudioDefines.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef CAUDIODEFINES_H
#define CAUDIODEFINES_H
//Global define for exporting the library
#ifndef CAUDIO_STATIC_LIB
#ifdef CAUDIO_EXPORTS
#define CAUDIO_API __declspec(dllexport)
#else
#define CAUDIO_API//! __declspec(dllimport)
#endif // CAUDIO_EXPORTS
#else
#define CAUDIO_API
#endif // CAUDIO_STATIC_LIB
//Define for making the entire library Thread Safe, comment out to disable
//Will also disable internal threading by the library
#define CAUDIO_MAKE_THREAD_SAFE
#ifdef CAUDIO_MAKE_THREAD_SAFE
//Define enables threading for the main update loop. Disable to run the internal update loop yourself
//NOTE: Internal threading should NOT be used if the library is not thread safe!
#define CAUDIO_USE_INTERNAL_THREAD
#endif
#endif //! CAUDIODEFINES_H

11
include/cAudioSleep.h Normal file
View File

@ -0,0 +1,11 @@
#ifndef CAUDIOSLEEP_H
#define CAUDIOSLEEP_H
#include "cAudioDefines.h"
namespace cAudio
{
CAUDIO_API void cAudioSleep(unsigned int ms);
};
#endif //! CAUDIOSLEEP_H