Added the event system

This commit is contained in:
Raynaldo Rivera 2010-02-13 04:47:59 +00:00
parent 16f222c8a5
commit 08800c5bad
11 changed files with 438 additions and 39 deletions

View File

@ -11,12 +11,23 @@
#include <AL/alc.h>
#include "../Headers/cMutex.h"
#include <string>
#include <list>
namespace cAudio
{
class cAudioCapture : public IAudioCapture
{
public:
enum Events{
ON_INIT,
ON_UPDATE,
ON_RELEASE,
ON_BEGINCAPTURE,
ON_ENDCAPTURE,
ON_USERREQUESTEDBUFFER,
};
cAudioCapture();
~cAudioCapture();
@ -91,6 +102,17 @@ namespace cAudio
//! Grabs a list of available devices, as well as the default system one
void getAvailableDevices();
//!Registers a new event handler to audio capture
virtual void registerEventHandler(ICaptureEventHandler* handler);
//!Unregisters specified event handler from audio capture
virtual void unRegisterEventHandler(ICaptureEventHandler* handler);
//!Unregisters all event handlers attached to audio capture
virtual void unRegisterAllEventHandlers();
private:
void signalEvent(Events sevent);
protected:
//Mutex for thread syncronization
cAudioMutex Mutex;
@ -106,6 +128,7 @@ namespace cAudio
std::vector<char> CaptureBuffer;
std::vector<std::string> AvailableDevices;
std::string DefaultDevice;
std::list<ICaptureEventHandler*> eventHandlerList;
bool Supported;
bool Ready;

View File

@ -26,6 +26,16 @@ namespace cAudio
class cAudioManager : public IAudioManager
{
public:
enum Events{
ON_INIT,
ON_UPDATE,
ON_RELEASE,
ON_SOURCECREATE,
ON_DECODERREGISTER,
ON_DATASOURCEREGISTER,
};
cAudioManager() : Device(NULL), Context(NULL), EFXSupported(false), Initialized(false) { }
virtual ~cAudioManager() { }
@ -79,6 +89,12 @@ namespace cAudio
//!Checks if the source type is registered.
virtual bool isSourceRegistered(const char* source);
//!Registers a new event handler to the manager
virtual void registerEventHandler(IManagerEventHandler* handler);
//!Unregisters specified event handler from manager
virtual void unRegisterEventHandler(IManagerEventHandler* handler) ;
//!Unregisters all event handlers attached to the manager
virtual void unRegisterAllEventHandlers();
//! Grabs a list of available devices, as well as the default system one
void getAvailableDevices();
@ -90,6 +106,10 @@ namespace cAudio
#endif
private:
//Signals a event to all event handlers
void signalEvent(Events sevent);
//Mutex for thread syncronization
cAudioMutex Mutex;
@ -112,6 +132,9 @@ namespace cAudio
std::map<std::string, IAudioDecoderFactory*> decodermap;
//! Archive map that holds all datasource types
std::map<std::string, IDataSource*> datasourcemap;
//! List of all attached event handlers
std::list<IManagerEventHandler*> eventHandlerList;
//! The listener object
cListener initlistener;

View File

@ -4,6 +4,7 @@
#ifndef CAUDIOSOURCE_H_INCLUDED
#define CAUDIOSOURCE_H_INCLUDED
#include <list>
#include <string>
#include <vector>
#include <AL/al.h>
@ -17,9 +18,20 @@
namespace cAudio
{
class cAudioSource : public IAudioSource
{
public:
enum Events{
ON_INIT,
ON_UPDATE,
ON_RELEASE,
ON_PLAY,
ON_PAUSE,
ON_STOP,
};
#ifdef CAUDIO_EFX_ENABLED
cAudioSource(IAudioDecoder* decoder, ALCcontext* context, cEFXFunctions* oALFunctions);
#else
@ -158,6 +170,13 @@ namespace cAudio
//!Returns the override for the doppler velocity vector
virtual const cVector3 getDopplerVelocity() const;
//!Registers a new event handler to source
virtual void registerEventHandler(ISourceEventHandler* handler);
//!Unregisters specified event handler from source
virtual void unRegisterEventHandler(ISourceEventHandler* handler);
//!Unregisters all event handlers attached to source
virtual void unRegisterAllEventHandlers();
#ifdef CAUDIO_EFX_ENABLED
//! Returns the number of effects at one time this source can support
virtual unsigned int getNumEffectSlotsAvailable() const;
@ -184,6 +203,8 @@ namespace cAudio
bool checkError();
//Streams audio data from the decoder into a buffer
bool stream(ALuint buffer);
//Signals a event to all event handlers
void signalEvent(Events sevent);
//Converts our audio format enum to OpenAL's
ALenum convertAudioFormatEnum(AudioFormats format);
@ -202,6 +223,8 @@ namespace cAudio
//Stores whether the source is ready to be used
bool Valid;
std::list<ISourceEventHandler*> eventHandlerList;
#ifdef CAUDIO_EFX_ENABLED
//Holds pointers to all the EFX related functions
cEFXFunctions* EFX;

View File

@ -75,6 +75,7 @@ namespace cAudio
Ready = true;
checkError();
getLogger()->logDebug("AudioCapture", "OpenAL Capture Device Opened.");
return true;
}
}
@ -96,6 +97,7 @@ namespace cAudio
CaptureDevice = NULL;
Ready = false;
getLogger()->logDebug("AudioCapture", "OpenAL Capture Device Closed.");
signalEvent(ON_RELEASE);
}
checkError();
CaptureBuffer.clear();
@ -106,6 +108,7 @@ namespace cAudio
{
cAudioMutexBasicLock lock(Mutex);
shutdownOpenALDevice();
signalEvent(ON_RELEASE);
}
void cAudioCapture::getAvailableDevices()
@ -175,6 +178,7 @@ namespace cAudio
alcCaptureSamples(CaptureDevice, &CaptureBuffer[oldBufferSize], AvailableSamples);
checkError();
getLogger()->logDebug("AudioCapture", "Captured %i bytes of audio data.", availbuffersize);
signalEvent(ON_UPDATE);
}
}
}
@ -191,6 +195,7 @@ namespace cAudio
alcCaptureStart(CaptureDevice);
Capturing = true;
getLogger()->logDebug("AudioCapture", "OpenAL Capture Started.");
signalEvent(ON_BEGINCAPTURE);
}
checkError();
return Capturing;
@ -208,6 +213,7 @@ namespace cAudio
updateCaptureBuffer(true);
checkError();
getLogger()->logDebug("AudioCapture", "OpenAL Capture Stopped.");
signalEvent(ON_ENDCAPTURE);
}
Capturing = false;
}
@ -223,7 +229,7 @@ namespace cAudio
CaptureBuffer.erase(CaptureBuffer.begin(), CaptureBuffer.begin()+sizeToCopy);
getLogger()->logDebug("AudioCapture", "Copied out %i bytes of data out of %i bytes in the buffer at user request.", sizeToCopy, internalBufferSize);
signalEvent(ON_USERREQUESTEDBUFFER);
return sizeToCopy;
}
return 0;
@ -296,6 +302,7 @@ namespace cAudio
SampleSize = 4;
shutdownOpenALDevice();
signalEvent(ON_INIT);
return initOpenALDevice();
}
@ -386,4 +393,96 @@ namespace cAudio
{
return RunAudioCaptureThread;
}
void cAudioCapture::registerEventHandler(ICaptureEventHandler* handler)
{
if(handler)
{
eventHandlerList.push_back(handler);
}
}
void cAudioCapture::unRegisterEventHandler(ICaptureEventHandler* handler)
{
if(handler)
{
eventHandlerList.remove(handler);
}
}
void cAudioCapture::unRegisterAllEventHandlers()
{
std::list<ICaptureEventHandler*>::iterator it = eventHandlerList.begin();
if(it != eventHandlerList.end())
{
for(it; it != eventHandlerList.end(); it++){
eventHandlerList.remove((*it));
}
}
}
void cAudioCapture::signalEvent(Events sevent)
{
std::list<ICaptureEventHandler*>::iterator it = eventHandlerList.begin();
if(it != eventHandlerList.end()){
switch(sevent){
case ON_INIT:
for(it; it != eventHandlerList.end(); it++){
(*it)->onInit();
}
break;
case ON_UPDATE:
for(it; it != eventHandlerList.end(); it++){
(*it)->onUpdate();
}
break;
case ON_RELEASE:
for(it; it != eventHandlerList.end(); it++){
(*it)->onRelease();
}
break;
case ON_BEGINCAPTURE:
for(it; it != eventHandlerList.end(); it++){
(*it)->onBeginCapture();
}
break;
case ON_ENDCAPTURE:
for(it; it != eventHandlerList.end(); it++){
(*it)->onEndCapture();
}
break;
case ON_USERREQUESTEDBUFFER:
for(it; it != eventHandlerList.end(); it++){
(*it)->onUserRequestBuffer();
}
break;
}
}
}
};

View File

@ -163,6 +163,7 @@ namespace cAudio
#endif
Initialized = true;
signalEvent(ON_INIT);
return true;
}
@ -208,7 +209,7 @@ namespace cAudio
audioSources.push_back(audio);
getLogger()->logInfo("AudioManager", "Streaming Audio Source (%s) created from file %s.", audioName.c_str(), path.c_str());
signalEvent(ON_SOURCECREATE);
return audio;
}
getLogger()->logError("AudioManager", "Failed to create Audio Source (%s): Error creating audio source.", audioName.c_str());
@ -248,6 +249,7 @@ namespace cAudio
IAudioSource* guy = createFromMemory(name, tempbuf, length, getExt(path).c_str());
delete[]tempbuf;
tempsource->drop();
signalEvent(ON_SOURCECREATE);
return guy;
}
getLogger()->logError("AudioManager", "Failed to create Audio Source (%s): Could not allocate enough memory.", audioName.c_str());
@ -304,7 +306,7 @@ namespace cAudio
audioSources.push_back(audio);
getLogger()->logInfo("AudioManager", "Audio Source (%s) successfully created from memory.", audioName.c_str());
signalEvent(ON_SOURCECREATE);
return audio;
}
audio->drop();
@ -368,7 +370,7 @@ namespace cAudio
audioSources.push_back(audio);
getLogger()->logInfo("AudioManager", "Audio Source (%s) successfully created from raw data.", audioName.c_str());
signalEvent(ON_SOURCECREATE);
return audio;
}
audio->drop();
@ -432,7 +434,7 @@ namespace cAudio
audioSources.push_back(audio);
getLogger()->logInfo("AudioManager", "Audio Source (%s) successfully created from raw data. Using ($s) source", audioName.c_str(),src.c_str());
signalEvent(ON_SOURCECREATE);
return audio;
}
@ -473,7 +475,7 @@ namespace cAudio
std::string ident = safeCStr(identifier);
datasourcemap[ident] = datasource;
getLogger()->logInfo("AudioManager","Audio source %s registered.", ident.c_str());
signalEvent(ON_DATASOURCEREGISTER);
return true;
}
@ -505,6 +507,7 @@ namespace cAudio
std::string ext = safeCStr(extension);
decodermap[ext] = factory;
getLogger()->logInfo("AudioManager", "Audio Decoder for extension .%s registered.", ext.c_str());
signalEvent(ON_DECODERREGISTER);
return true;
}
@ -528,6 +531,96 @@ namespace cAudio
return (it != decodermap.end());
}
void cAudioManager::registerEventHandler(IManagerEventHandler* handler)
{
if(handler)
{
eventHandlerList.push_back(handler);
}
}
void cAudioManager::unRegisterEventHandler(IManagerEventHandler* handler)
{
if(handler)
{
eventHandlerList.remove(handler);
}
}
void cAudioManager::unRegisterAllEventHandlers()
{
std::list<IManagerEventHandler*>::iterator it = eventHandlerList.begin();
if(it != eventHandlerList.end())
{
for(it; it != eventHandlerList.end(); it++){
eventHandlerList.remove((*it));
}
}
}
void cAudioManager::signalEvent(Events sevent)
{
std::list<IManagerEventHandler*>::iterator it = eventHandlerList.begin();
if(it != eventHandlerList.end()){
switch(sevent){
case ON_INIT:
for(it; it != eventHandlerList.end(); it++){
(*it)->onInit();
}
break;
case ON_UPDATE:
for(it; it != eventHandlerList.end(); it++){
(*it)->onUpdate();
}
break;
case ON_RELEASE:
for(it; it != eventHandlerList.end(); it++){
(*it)->onRelease();
}
break;
case ON_SOURCECREATE:
for(it; it != eventHandlerList.end(); it++){
(*it)->onSourceCreate();
}
break;
case ON_DECODERREGISTER:
for(it; it != eventHandlerList.end(); it++){
(*it)->onDecoderRegister();
}
break;
case ON_DATASOURCEREGISTER:
for(it; it != eventHandlerList.end(); it++){
(*it)->onDataSourceRegister();
}
break;
}
}
}
IAudioDecoderFactory* cAudioManager::getAudioDecoderFactory(const char* extension)
{
cAudioMutexBasicLock lock(Mutex);
@ -565,6 +658,8 @@ namespace cAudio
}
audioSources.clear();
audioIndex.clear();
signalEvent(ON_RELEASE);
}
void cAudioManager::release(IAudioSource* source)
@ -608,6 +703,7 @@ namespace cAudio
}
}
}
signalEvent(ON_UPDATE);
}
//!Shuts down cAudio. Deletes all audio sources in process

View File

@ -58,6 +58,7 @@ namespace cAudio
EffectSlotsAvailable = (numSlots <= CAUDIO_SOURCE_MAX_EFFECT_SLOTS) ? numSlots : CAUDIO_SOURCE_MAX_EFFECT_SLOTS;
#endif
signalEvent(ON_INIT);
}
cAudioSource::~cAudioSource()
@ -78,6 +79,7 @@ namespace cAudio
Filter->drop();
Filter = NULL;
#endif
unRegisterAllEventHandlers();
}
bool cAudioSource::play()
@ -112,6 +114,7 @@ namespace cAudio
alSourcePlay(Source);
checkError();
getLogger()->logDebug("Audio Source", "Source playing.");
signalEvent(ON_PLAY);
return true;
}
@ -143,6 +146,7 @@ namespace cAudio
alSourcePause(Source);
checkError();
getLogger()->logDebug("Audio Source", "Source paused.");
signalEvent(ON_PAUSE);
}
void cAudioSource::stop()
@ -153,6 +157,7 @@ namespace cAudio
Decoder->setPosition(0, false);
checkError();
getLogger()->logDebug("Audio Source", "Source stopped.");
signalEvent(ON_STOP);
}
void cAudioSource::loop(const bool& loop)
@ -203,6 +208,7 @@ namespace cAudio
checkError();
}
signalEvent(ON_UPDATE);
return active;
}
@ -218,6 +224,7 @@ namespace cAudio
alDeleteBuffers(CAUDIO_SOURCE_NUM_BUFFERS, Buffers);
checkError();
getLogger()->logDebug("Audio Source", "Audio source released.");
signalEvent(ON_RELEASE);
}
const bool cAudioSource::isValid() const
@ -709,4 +716,95 @@ namespace cAudio
}
}
#endif
void cAudioSource::registerEventHandler(ISourceEventHandler* handler)
{
if(handler)
{
eventHandlerList.push_back(handler);
}
}
void cAudioSource::unRegisterEventHandler(ISourceEventHandler* handler)
{
if(handler)
{
eventHandlerList.remove(handler);
}
}
void cAudioSource::unRegisterAllEventHandlers()
{
std::list<ISourceEventHandler*>::iterator it = eventHandlerList.begin();
if(it != eventHandlerList.end())
{
for(it; it != eventHandlerList.end(); it++){
eventHandlerList.remove((*it));
}
}
}
void cAudioSource::signalEvent(Events sevent)
{
std::list<ISourceEventHandler*>::iterator it = eventHandlerList.begin();
if(it != eventHandlerList.end()){
switch(sevent){
case ON_INIT:
for(it; it != eventHandlerList.end(); it++){
(*it)->onInit();
}
break;
case ON_UPDATE:
for(it; it != eventHandlerList.end(); it++){
(*it)->onUpdate();
}
break;
case ON_RELEASE:
for(it; it != eventHandlerList.end(); it++){
(*it)->onRelease();
}
break;
case ON_PLAY:
for(it; it != eventHandlerList.end(); it++){
(*it)->onPlay();
}
break;
case ON_PAUSE:
for(it; it != eventHandlerList.end(); it++){
(*it)->onPause();
}
break;
case ON_STOP:
for(it; it != eventHandlerList.end(); it++){
(*it)->onStop();
}
break;
}
}
}
}

View File

@ -415,6 +415,10 @@
RelativePath=".\include\IAudioSource.h"
>
</File>
<File
RelativePath=".\include\ICaptureEventHandler.h"
>
</File>
<File
RelativePath=".\include\IDataSource.h"
>
@ -443,6 +447,10 @@
RelativePath=".\include\ILogReceiver.h"
>
</File>
<File
RelativePath=".\include\IManagerEventHandler.h"
>
</File>
<File
RelativePath=".\include\IPluginManager.h"
>
@ -451,6 +459,10 @@
RelativePath=".\include\IRefCounted.h"
>
</File>
<File
RelativePath=".\include\ISourceEventHandler.h"
>
</File>
</Filter>
<Filter
Name="Util"

View File

@ -7,6 +7,7 @@
#include "EAudioFormats.h"
#include "cAudioDefines.h"
#include "ICaptureEventHandler.h"
namespace cAudio
{
@ -91,6 +92,14 @@ namespace cAudio
//! Returns the current size of the internal audio buffer in bytes
virtual unsigned int getCurrentCapturedAudioSize() = 0;
//!Registers a new event handler to audio capture
virtual void registerEventHandler(ICaptureEventHandler* handler) = 0;
//!Unregisters specified event handler from audio capture
virtual void unRegisterEventHandler(ICaptureEventHandler* handler) = 0;
//!Unregisters all event handlers attached to audio capture
virtual void unRegisterAllEventHandlers() = 0;
};
//! Creates an interface to an Audio Capture Object

View File

@ -9,6 +9,7 @@
#include "cAudioDefines.h"
#include "EAudioFormats.h"
#include "IAudioEffects.h"
#include "IManagerEventHandler.h"
namespace cAudio
{
@ -71,6 +72,13 @@ namespace cAudio
//!Checks if the source type is registered.
virtual bool isSourceRegistered(const char* source) = 0;
//!Registers a new event handler to the manager
virtual void registerEventHandler(IManagerEventHandler* handler) = 0;
//!Unregisters specified event handler from manager
virtual void unRegisterEventHandler(IManagerEventHandler* handler) = 0;
//!Unregisters all event handlers attached to the manager
virtual void unRegisterAllEventHandlers() = 0;
//!Returns an interface for the listener
virtual IListener* getListener() = 0;

View File

@ -11,6 +11,7 @@
#include "cVector3.h"
#include "IEffect.h"
#include "IFilter.h"
#include "ISourceEventHandler.h"
namespace cAudio
{
@ -151,6 +152,13 @@ namespace cAudio
//! Returns the override for the doppler velocity vector
virtual const cVector3 getDopplerVelocity() const = 0;
//!Registers a new event handler to source
virtual void registerEventHandler(ISourceEventHandler* handler) = 0;
//!Unregisters specified event handler from source
virtual void unRegisterEventHandler(ISourceEventHandler* handler) = 0;
//!Unregisters all event handlers attached to source
virtual void unRegisterAllEventHandlers() = 0;
#ifdef CAUDIO_EFX_ENABLED
//! Returns the number of effects at one time this source can support
virtual unsigned int getNumEffectSlotsAvailable() const = 0;

View File

@ -16,33 +16,33 @@ cMP3Decoder::cMP3Decoder(IDataSource* stream) : IAudioDecoder(stream), Context(0
if(!Context || mpaudec_init(Context) < 0)
{
delete Context;
Context = 0x0;
delete Context;
Context = 0x0;
return;
}
//Check to see if we need to skip the idv3 header
char idv3Header[10];
int amountRead = Stream->read(idv3Header, 10);
if (amountRead == 10 && idv3Header[0] == 'I' && idv3Header[1] == 'D' && idv3Header[2] == '3')
{
int versionMajor = idv3Header[3];
int versionMinor = idv3Header[4];
int flags = idv3Header[5];
int size = 0;
size = (idv3Header[6] & 0x7f) << (3*7);
size |= (idv3Header[7] & 0x7f) << (2*7);
size |= (idv3Header[8] & 0x7f) << (1*7);
size |= (idv3Header[9] & 0x7f) ;
size += 10;
DataOffset = size;
Stream->seek(DataOffset, false);
}
else
{
if (amountRead == 10 && idv3Header[0] == 'I' && idv3Header[1] == 'D' && idv3Header[2] == '3')
{
int versionMajor = idv3Header[3];
int versionMinor = idv3Header[4];
int flags = idv3Header[5];
int size = 0;
size = (idv3Header[6] & 0x7f) << (3*7);
size |= (idv3Header[7] & 0x7f) << (2*7);
size |= (idv3Header[8] & 0x7f) << (1*7);
size |= (idv3Header[9] & 0x7f) ;
size += 10;
DataOffset = size;
Stream->seek(DataOffset, false);
}
else
{
Stream->seek(0, false);
}
@ -70,10 +70,10 @@ cMP3Decoder::cMP3Decoder(IDataSource* stream) : IAudioDecoder(stream), Context(0
cMP3Decoder::~cMP3Decoder()
{
if (Context)
{
mpaudec_clear(Context);
delete Context;
if (Context)
{
mpaudec_clear(Context);
delete Context;
}
if(CurrentPacket.data)
@ -194,14 +194,14 @@ bool cMP3Decoder::setPosition(int position, bool relative)
//Just reload from scratch
Stream->seek(DataOffset, false);
MPAuDecContext oldContext = *Context;
mpaudec_clear(Context);
mpaudec_init(Context);
Context->bit_rate = oldContext.bit_rate;
Context->channels = oldContext.channels;
Context->frame_size = oldContext.frame_size;
MPAuDecContext oldContext = *Context;
mpaudec_clear(Context);
mpaudec_init(Context);
Context->bit_rate = oldContext.bit_rate;
Context->channels = oldContext.channels;
Context->frame_size = oldContext.frame_size;
Context->sample_rate = oldContext.sample_rate;
Context->parse_only = 1;