add static source type, various bug and compiler error/warning fixes

This commit is contained in:
Arthur Danskin 2015-09-27 15:11:51 -07:00
parent 5c93210189
commit 36943a1885
45 changed files with 1095 additions and 550 deletions

View File

@ -4,8 +4,7 @@
#pragma once #pragma once
#include <al.h> #include "cOpenALUtil.h"
#include <alc.h>
#include "cMutex.h" #include "cMutex.h"
#include "cMemoryOverride.h" #include "cMemoryOverride.h"
#include "IAudioCapture.h" #include "IAudioCapture.h"
@ -36,8 +35,8 @@ namespace cAudio
virtual void updateCaptureBuffer(bool force = false); virtual void updateCaptureBuffer(bool force = false);
virtual void shutdown(); virtual void shutdown();
virtual bool isUpdateThreadRunning() virtual bool isUpdateThreadRunning()
{ {
return (AudioThread != NULL && AudioThread->isRunning()); return (AudioThread != NULL && AudioThread->isRunning());
} }
virtual const char* getDeviceName() { return toUTF8(DeviceName); } virtual const char* getDeviceName() { return toUTF8(DeviceName); }
@ -68,7 +67,7 @@ namespace cAudio
cAudioMutex Mutex; cAudioMutex Mutex;
//! Our update thread //! Our update thread
IThread* AudioThread; IThread* AudioThread;
bool initOpenALDevice(); bool initOpenALDevice();
@ -92,4 +91,4 @@ namespace cAudio
ALenum convertAudioFormatEnum(AudioFormats format); ALenum convertAudioFormatEnum(AudioFormats format);
void signalEvent(Events sevent); void signalEvent(Events sevent);
}; };
}; };

View File

@ -18,6 +18,7 @@
namespace cAudio namespace cAudio
{ {
class IAudioSource; class IAudioSource;
class IAudioBuffer;
class cAudioManager : public IAudioManager, public cMemoryOverride, public IThreadWorker class cAudioManager : public IAudioManager, public cMemoryOverride, public IThreadWorker
{ {
@ -31,11 +32,11 @@ namespace cAudio
ON_DATASOURCEREGISTER, ON_DATASOURCEREGISTER,
}; };
cAudioManager() : AudioThread(NULL), AudioContext(NULL), Initialized(false), MasterVolume(1.0f) { } cAudioManager() : Initialized(false), AudioThread(NULL), AudioContext(NULL), MasterVolume(1.0f) { }
virtual ~cAudioManager(); virtual ~cAudioManager();
virtual bool initialize(const char* deviceName = 0x0, int outputFrequency = -1, int eaxEffectSlots = 4); virtual bool initialize(const char* deviceName = 0x0, int outputFrequency = -1, int eaxEffectSlots = 4);
virtual void shutDown(); virtual void shutDown();
virtual void update(); virtual void update();
virtual IAudioSource* getSoundByName(const char* name); virtual IAudioSource* getSoundByName(const char* name);
virtual void releaseAllSources(); virtual void releaseAllSources();
@ -46,6 +47,10 @@ namespace cAudio
virtual void setMasterVolume(float vol); virtual void setMasterVolume(float vol);
virtual float getMasterVolume() const; virtual float getMasterVolume() const;
virtual void setSpeedOfSound(float speed);
virtual float getSpeedOfSound() const;
virtual void setDopplerFactor(float factor) const;
virtual float getDopplerFactor() const;
virtual void stopAllSounds(); virtual void stopAllSounds();
virtual IAudioSource* create(const char* name, const char* filename, bool stream = false); virtual IAudioSource* create(const char* name, const char* filename, bool stream = false);
@ -53,6 +58,9 @@ namespace cAudio
virtual IAudioSource* createFromRaw(const char* name, const char* data, size_t length, unsigned int frequency, AudioFormats format); virtual IAudioSource* createFromRaw(const char* name, const char* data, size_t length, unsigned int frequency, AudioFormats format);
virtual IAudioSource* createFromAudioBuffer(const char* name, AudioCaptureBuffer* pBiffer, unsigned int frequency, AudioFormats format); virtual IAudioSource* createFromAudioBuffer(const char* name, AudioCaptureBuffer* pBiffer, unsigned int frequency, AudioFormats format);
virtual IAudioBuffer* createBuffer(const char* filename);
virtual IAudioSource* createStatic(IAudioBuffer* buffer);
virtual bool registerAudioDecoder(IAudioDecoderFactory* factory, const char* extension); virtual bool registerAudioDecoder(IAudioDecoderFactory* factory, const char* extension);
virtual void unRegisterAudioDecoder(const char* extension); virtual void unRegisterAudioDecoder(const char* extension);
virtual bool isAudioDecoderRegistered(const char* extension); virtual bool isAudioDecoderRegistered(const char* extension);
@ -77,6 +85,8 @@ namespace cAudio
virtual IAudioEffects* getEffects(); virtual IAudioEffects* getEffects();
#endif #endif
virtual cAudioMutex *getMutex() { return &Mutex; }
protected: protected:
virtual void run(); virtual void run();
@ -101,6 +111,7 @@ namespace cAudio
typedef cAudioMap<cAudioString, IAudioSource*>::Type::iterator audioIndexIterator; typedef cAudioMap<cAudioString, IAudioSource*>::Type::iterator audioIndexIterator;
//! Holds all managed audio sources //! Holds all managed audio sources
cAudioVector<IAudioSource*>::Type audioSources; cAudioVector<IAudioSource*>::Type audioSources;
cAudioVector<IAudioSource*>::Type updateSources;
//! Holds audio sources which gets deleted from the audioManager //! Holds audio sources which gets deleted from the audioManager
cAudioVector<IAudioSource*>::Type managedAudioSources; cAudioVector<IAudioSource*>::Type managedAudioSources;
//! Holds audio sources which gets deleted from the audioManager //! Holds audio sources which gets deleted from the audioManager

View File

@ -7,9 +7,8 @@
#include <list> #include <list>
#include <string> #include <string>
#include <vector> #include <vector>
#include <al.h>
#include <alc.h>
#include "cOpenALUtil.h"
#include "cMutex.h" #include "cMutex.h"
#include "cEFXFunctions.h" #include "cEFXFunctions.h"
#include "cMemoryOverride.h" #include "cMemoryOverride.h"
@ -21,8 +20,8 @@
namespace cAudio namespace cAudio
{ {
class cAudioSource : public IAudioSource, public cMemoryOverride class cAudioSourceBase : public IAudioSource, public cMemoryOverride
{ {
public: public:
@ -34,38 +33,13 @@ namespace cAudio
ON_STOP, ON_STOP,
}; };
#if CAUDIO_EFX_ENABLED == 1 cAudioSourceBase(IAudioDeviceContext* context);
cAudioSource(IAudioDecoder* decoder, IAudioDeviceContext* context, cEFXFunctions* oALFunctions); virtual ~cAudioSourceBase();
#else
cAudioSource(IAudioDecoder* decoder, IAudioDeviceContext* context);
#endif
~cAudioSource();
virtual bool play(); virtual bool isPlaying() const;
virtual bool play2d(const bool& toLoop = false); virtual bool isPaused() const;
virtual bool play3d(const cVector3& position, const float& soundstr = 1.0 , const bool& toLoop = false); virtual bool isStopped() const;
virtual void pause();
virtual void stop();
virtual void loop(const bool& toLoop);
virtual bool seek(const float& seconds, bool relative = false);
virtual float getTotalAudioTime();
virtual int getTotalAudioSize();
virtual int getCompressedAudioSize();
virtual float getCurrentAudioTime();
virtual int getCurrentAudioPosition();
virtual int getCurrentCompressedAudioPosition();
virtual bool update();
virtual const bool isValid() const;
virtual const bool isPlaying() const;
virtual const bool isPaused() const;
virtual const bool isStopped() const;
virtual const bool isLooping() const;
virtual void setPosition(const cVector3& position); virtual void setPosition(const cVector3& position);
virtual void setVelocity(const cVector3& velocity); virtual void setVelocity(const cVector3& velocity);
virtual void setDirection(const cVector3& direction); virtual void setDirection(const cVector3& direction);
@ -89,31 +63,90 @@ namespace cAudio
virtual void move(const cVector3& position); virtual void move(const cVector3& position);
virtual const cVector3 getPosition() const; virtual cVector3 getPosition() const;
virtual const cVector3 getVelocity() const; virtual cVector3 getVelocity() const;
virtual const cVector3 getDirection() const; virtual cVector3 getDirection() const;
virtual const float getRolloffFactor() const; virtual float getRolloffFactor() const;
virtual const float getStrength() const; virtual float getStrength() const;
virtual const float getMinDistance() const; virtual float getMinDistance() const;
virtual const float getMaxDistance() const; virtual float getMaxDistance() const;
virtual const float getPitch() const; virtual bool isRelative() const;
virtual const float getVolume() const; virtual float calculateGain() const;
virtual const float getMinVolume() const;
virtual const float getMaxVolume() const;
virtual const float getInnerConeAngle() const; virtual float getPitch() const;
virtual const float getOuterConeAngle() const; virtual float getVolume() const;
virtual const float getOuterConeVolume() const; virtual float getMinVolume() const;
virtual float getMaxVolume() const;
virtual const float getDopplerStrength() const; virtual float getInnerConeAngle() const;
virtual const cVector3 getDopplerVelocity() const; virtual float getOuterConeAngle() const;
virtual float getOuterConeVolume() const;
virtual float getDopplerStrength() const;
virtual cVector3 getDopplerVelocity() const;
virtual void registerEventHandler(ISourceEventHandler* handler); virtual void registerEventHandler(ISourceEventHandler* handler);
virtual void unRegisterEventHandler(ISourceEventHandler* handler); virtual void unRegisterEventHandler(ISourceEventHandler* handler);
virtual void unRegisterAllEventHandlers(); virtual void unRegisterAllEventHandlers();
protected:
//! Mutex for thread synchronization
cAudioMutex Mutex;
//! Signals a event to all event handlers
void signalEvent(Events sevent);
//! The context that owns this source
IAudioDeviceContext* Context;
//! Holds the current volume
float Volume;
//! OpenAL source
ALuint Source;
ALenum oldState;
//! List of registered event handlers
cAudioVector<ISourceEventHandler*>::Type eventHandlerList;
};
class cAudioSource : public cAudioSourceBase {
public:
#if CAUDIO_EFX_ENABLED == 1
cAudioSource(IAudioDecoder* decoder, IAudioDeviceContext* context, cEFXFunctions* oALFunctions);
#else
cAudioSource(IAudioDecoder* decoder, IAudioDeviceContext* context);
#endif
~cAudioSource();
virtual bool play();
virtual bool play2d(const bool& toLoop = false);
virtual bool play3d(const cVector3& position, const float& soundstr = 1.0 , const bool& toLoop = false);
virtual void pause();
virtual void stop();
virtual void loop(const bool& toLoop);
virtual bool seek(const float& seconds, bool relative = false);
virtual bool setBuffer(IAudioBuffer* buffer) { return false; }
virtual IAudioBuffer *getBuffer() { return NULL; }
virtual float getTotalAudioTime();
virtual int getTotalAudioSize();
virtual int getCompressedAudioSize();
virtual float getCurrentAudioTime();
virtual int getCurrentAudioPosition();
virtual int getCurrentCompressedAudioPosition();
virtual bool update();
virtual bool isValid() const;
virtual bool isLooping() const;
virtual bool drop(); //! Override the default behavior virtual bool drop(); //! Override the default behavior
#if CAUDIO_EFX_ENABLED == 1 #if CAUDIO_EFX_ENABLED == 1
@ -126,31 +159,14 @@ namespace cAudio
#endif #endif
private: private:
//! Mutex for thread synchronization
cAudioMutex Mutex;
//! Empties the current working buffer queue //! Empties the current working buffer queue
void empty(); void empty();
//! Checks for OpenAL errors and reports them
bool checkError() const;
//! Streams audio data from the decoder into a buffer //! Streams audio data from the decoder into a buffer
bool stream(ALuint 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);
//! The context that owns this source
IAudioDeviceContext* Context;
//! Holds the current volume
float Volume;
//! Internal audio buffers //! Internal audio buffers
ALuint Buffers[CAUDIO_SOURCE_NUM_BUFFERS]; ALuint Buffers[CAUDIO_SOURCE_NUM_BUFFERS];
//! OpenAL source
ALuint Source;
ALenum oldState;
//! cAudio decoder being used to stream data //! cAudio decoder being used to stream data
IAudioDecoder* Decoder; IAudioDecoder* Decoder;
@ -159,8 +175,10 @@ namespace cAudio
//! Stores whether the source is ready to be used //! Stores whether the source is ready to be used
bool Valid; bool Valid;
//! List of registered event handlers //! position of first buffer in seconds
cAudioList<ISourceEventHandler*>::Type eventHandlerList; float BufferTime;
//! position of first buffer in bytes
int BufferPosition;
#if CAUDIO_EFX_ENABLED == 1 #if CAUDIO_EFX_ENABLED == 1
//! Holds pointers to all the EFX related functions //! Holds pointers to all the EFX related functions

View File

@ -0,0 +1,248 @@
#include "cAudioSource.h"
namespace cAudio
{
class cAudioBuffer : public IAudioBuffer
{
ALuint Buffer;
bool Valid;
float TotalTime;
public:
cAudioBuffer(IAudioDecoder *decoder)
{
Buffer = 0;
Valid = false;
TotalTime = decoder->getTotalTime();
decoder->setPosition(0, false);
const int totalSize = decoder->getTotalSize()&~1;
if (totalSize > 0)
{
cAudioVector<char>::Type data(totalSize, 0);
int totalread = 0;
unsigned errorcount = 0;
while (totalread < totalSize)
{
const int actualread = decoder->readAudioData(&data[totalread], totalSize - totalread);
if (actualread > 0) {
totalread += actualread;
} else if (actualread < 0) {
++errorcount;
getLogger()->logDebug("Audio Buffer", "Decoder returned an error: %i (%i of 3)", actualread, errorcount);
if(errorcount >= 3) {
break;
}
} else {
break;
}
}
if (totalread != totalSize) {
getLogger()->logError("Audio Buffer", "Stopped short");
}
alGenBuffers(1, &Buffer);
checkALError();
const ALsizei freq = decoder->getFrequency();
const ALenum format = convertAudioFormatEnum(decoder->getFormat());
getLogger()->logDebug("Audio Buffer", "Buffered %d bytes of data into buffer %d at %d hz.", totalread, (int)Buffer, (int)freq);
alBufferData(Buffer, format, &data[0], data.size(), freq);
checkALError();
Valid = true;
}
}
~cAudioBuffer()
{
if (Valid)
{
alDeleteBuffers(1, &Buffer);
}
}
bool isValid() const { return Valid; }
unsigned getBuffer() const { return Buffer; }
int getChannels() const
{
ALint channels = 0;
alGetBufferi(Buffer, AL_CHANNELS, &channels);
return channels;
}
int getTotalAudioSize() const
{
ALint size = -1;
alGetBufferi(Buffer, AL_SIZE, &size);
return size;
}
float getTotalAudioTime() const { return TotalTime; }
};
class cAudioStaticSource : public cAudioSourceBase
{
IAudioBuffer* Buffer;
public:
cAudioStaticSource(IAudioBuffer* buffer, IAudioDeviceContext* context)
: cAudioSourceBase(context), Buffer(NULL)
{
setBuffer(buffer);
}
~cAudioStaticSource()
{
if (Buffer)
Buffer->drop();
}
bool setBuffer(IAudioBuffer* buffer)
{
if (isPlaying())
stop();
if (Buffer)
Buffer->drop();
Buffer = buffer;
if (Buffer) {
Buffer->grab();
alSourcei(Source, AL_BUFFER, Buffer->getBuffer());
checkALError();
}
return true;
}
IAudioBuffer *getBuffer()
{
return Buffer;
}
bool play()
{
alSourcePlay(Source);
checkALError();
getLogger()->logDebug("Audio Static Source", "Source playing.");
signalEvent(ON_PLAY);
oldState = AL_PLAYING;
return true;
}
bool play2d(const bool& toLoop)
{
alSourcei(Source, AL_SOURCE_RELATIVE, true);
alSourcei(Source, AL_LOOPING, toLoop);
checkALError();
return play();
}
bool play3d(const cVector3& position, const float& soundstr, const bool& toLoop)
{
alSourcei(Source, AL_SOURCE_RELATIVE, false);
alSourcei(Source, AL_LOOPING, toLoop);
checkALError();
setPosition(position);
setStrength(soundstr);
return play();
}
void pause()
{
alSourcePause(Source);
checkALError();
getLogger()->logDebug("Audio Static Source", "Source paused.");
signalEvent(ON_PAUSE);
oldState = AL_PAUSED;
}
void stop()
{
alSourceStop(Source);
alSourceRewind(Source);
checkALError();
getLogger()->logDebug("Audio Static Source", "Source stopped.");
signalEvent(ON_STOP);
oldState = AL_STOPPED;
}
void loop(const bool& toLoop)
{
alSourcei(Source, AL_LOOPING, toLoop);
checkALError();
}
bool seek(const float& seconds, bool relative)
{
float start = relative ? getCurrentAudioTime() : 0.f;
alSourcef(Source, AL_SEC_OFFSET, start + seconds);
checkALError();
return true;
}
float getTotalAudioTime() { return Buffer ? Buffer->getTotalAudioTime() : 0.f; }
int getTotalAudioSize() { return Buffer ? Buffer->getTotalAudioSize() : 0; }
int getCompressedAudioSize() { return -1; }
float getCurrentAudioTime()
{
float time = -1;
alGetSourcef(Source, AL_SEC_OFFSET, &time);
return time;
}
int getCurrentAudioPosition()
{
int offset = -1;
alGetSourcei(Source, AL_BYTE_OFFSET, &offset);
return offset;
}
int getCurrentCompressedAudioPosition() { return -1; }
bool update()
{
if(isValid() || isPlaying()) {
signalEvent(ON_UPDATE);
}
ALenum state;
alGetSourcei(Source, AL_SOURCE_STATE, &state);
checkALError();
if(state == AL_STOPPED && oldState != state)
{
getLogger()->logDebug("Audio Static Source", "Source stopped.");
signalEvent(ON_STOP);
oldState = state;
}
return state != AL_STOPPED;
}
bool isValid() const
{
return Buffer ? Buffer->isValid() : false;
}
bool isLooping() const
{
ALint looping = false;
alGetSourcei(Source, AL_LOOPING, &looping);
return looping == AL_TRUE;
}
#if CAUDIO_EFX_ENABLED == 1
virtual unsigned int getNumEffectSlotsAvailable() const { return 0; }
virtual bool attachEffect(unsigned int slot, IEffect* effect) { return false; }
virtual void removeEffect(unsigned int slot) {}
virtual bool attachFilter(IFilter* filter) { return false; }
virtual void removeFilter() {}
#endif
};
}

View File

@ -7,9 +7,7 @@
#include "cAudioDefines.h" #include "cAudioDefines.h"
#if CAUDIO_MAKE_THREAD_SAFE == 1 #if CAUDIO_MAKE_THREAD_SAFE == 1
#ifdef CAUDIO_PLATFORM_WIN #ifndef CAUDIO_PLATFORM_WIN
#include <windows.h> //Basic windows include
#else
#include <pthread.h> //Assumed linux system #include <pthread.h> //Assumed linux system
#endif #endif
#endif #endif
@ -61,4 +59,4 @@ namespace cAudio
protected: protected:
cAudioMutex* Mutex; cAudioMutex* Mutex;
}; };
}; };

View File

@ -4,14 +4,13 @@
#pragma once #pragma once
#include <al.h>
#include <alc.h>
#include "IAudioDeviceContext.h" #include "IAudioDeviceContext.h"
#include "cMemoryOverride.h" #include "cMemoryOverride.h"
#include "cMutex.h" #include "cMutex.h"
#include "cAudioEffects.h" #include "cAudioEffects.h"
#include "cOpenALUtil.h"
namespace cAudio namespace cAudio
{ {
class cOpenALDeviceContext : public IAudioDeviceContext, public cMemoryOverride class cOpenALDeviceContext : public IAudioDeviceContext, public cMemoryOverride
@ -26,30 +25,30 @@ namespace cAudio
virtual IAudioEffects* getEffects() const; virtual IAudioEffects* getEffects() const;
ALCcontext* getOpenALContext() const; ALCcontext* getOpenALContext() const;
private: private:
//! Check for OpenAL errors //! Check for OpenAL errors
bool checkError(); bool checkError();
//! Mutex for thread synchronization //! Mutex for thread synchronization
cAudioMutex Mutex; cAudioMutex Mutex;
//! An OpenAL context pointer //! An OpenAL context pointer
ALCcontext* Context; ALCcontext* Context;
//! An OpenAL device pointer //! An OpenAL device pointer
ALCdevice* Device; ALCdevice* Device;
IAudioManager* AudioManager; IAudioManager* AudioManager;
bool Initialized; bool Initialized;
//! Holds whether EFX is supported //! Holds whether EFX is supported
bool EFXSupported; bool EFXSupported;
#if CAUDIO_EFX_ENABLED == 1 #if CAUDIO_EFX_ENABLED == 1
//! Interface for audio effects //! Interface for audio effects
cAudioEffects initEffects; cAudioEffects initEffects;
#endif #endif
}; };
} }

69
cAudio/Headers/cOpenALUtil.h Executable file
View File

@ -0,0 +1,69 @@
#ifndef CAUDIO_COPENALUTIL_H
#define CAUDIO_COPENALUTIL_H
#include "cAudio.h"
#if !defined(CAUDIO_PLATFORM_LINUX)
#include <OpenAL/al.h>
#include <OpenAL/alc.h>
#else
#include <AL/al.h>
#include <AL/alc.h>
#endif
#if DEBUG
#ifndef __func__
#define __func__ __FUNCTION__
#endif
#define checkALError() checkALErrorInternal(__FILE__, __func__, __LINE__)
#else
#define checkALError() (false)
#endif
namespace cAudio {
//! Checks for OpenAL errors and reports them
inline bool checkALErrorInternal(const char* file, const char *func, int line)
{
ALenum error = AL_NO_ERROR;
bool anyError = false;
while ((error = alGetError()) != AL_NO_ERROR)
{
const char* errorString = alGetString(error);
if(error == AL_OUT_OF_MEMORY) {
getLogger()->logCritical("Audio Source", "OpenAL Error: %s:%d:%s, %s.", file, line, func, errorString);
} else if (error == -1) {
// this occurs randomly and relatively freqently with Apple's OpenAL and does not seem to cause serious problems.
getLogger()->logWarning("Audio Source", "OpenAL Warning %s:%d:%s, %s.", file, line, func, errorString);
} else {
getLogger()->logError("Audio Source", "OpenAL Error: %s:%d:%s, %s.", file, line, func, errorString);
}
anyError = true;
}
return anyError;
}
//! Converts our audio format enum to OpenAL's
inline ALenum convertAudioFormatEnum(AudioFormats format)
{
switch(format)
{
case EAF_8BIT_MONO:
return AL_FORMAT_MONO8;
case EAF_16BIT_MONO:
return AL_FORMAT_MONO16;
case EAF_8BIT_STEREO:
return AL_FORMAT_STEREO8;
case EAF_16BIT_STEREO:
return AL_FORMAT_STEREO16;
default:
return AL_FORMAT_MONO8;
};
}
}
#endif

View File

@ -13,8 +13,6 @@
#ifdef CAUDIO_COMPILE_WITH_PLUGIN_SUPPORT #ifdef CAUDIO_COMPILE_WITH_PLUGIN_SUPPORT
#ifdef CAUDIO_PLATFORM_WIN #ifdef CAUDIO_PLATFORM_WIN
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
struct HINSTANCE__; struct HINSTANCE__;
typedef struct HINSTANCE__* hInstance; typedef struct HINSTANCE__* hInstance;

View File

@ -8,11 +8,10 @@
#include "cAudioDefines.h" #include "cAudioDefines.h"
#include "IThread.h" #include "IThread.h"
#ifdef CAUDIO_PLATFORM_WIN #ifdef CAUDIO_PLATFORM_WIN
#include <windows.h> //Basic windows includes #include <process.h>
#include <process.h> #else
#else #include <pthread.h> //Assumed linux system
#include <pthread.h> //Assumed linux system
#endif #endif
namespace cAudio namespace cAudio
@ -44,4 +43,4 @@ namespace cAudio
bool IsInit; bool IsInit;
bool Loop; bool Loop;
}; };
}; };

View File

@ -9,8 +9,6 @@
#include "cAudioString.h" #include "cAudioString.h"
#ifdef CAUDIO_PLATFORM_WIN #ifdef CAUDIO_PLATFORM_WIN
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
# include <direct.h> # include <direct.h>
# include <io.h> # include <io.h>
#endif #endif
@ -25,14 +23,14 @@ namespace cAudio
{ {
//! Grabs the current extention of a given string. //! Grabs the current extention of a given string.
static cAudioString getExt(const cAudioString& filename) inline cAudioString getExt(const cAudioString& filename)
{ {
if(filename.find_last_of(_CTEXT(".")) == cAudioString::npos) return filename; if(filename.find_last_of(_CTEXT(".")) == cAudioString::npos) return filename;
return filename.substr(filename.find_last_of(_CTEXT(".")) + 1, filename.length()-filename.find_last_of(_CTEXT("."))-1); return filename.substr(filename.find_last_of(_CTEXT(".")) + 1, filename.length()-filename.find_last_of(_CTEXT("."))-1);
} }
//! Returns a list of files/directories in the supplied directory. Used internally for auto-installation of plugins. //! Returns a list of files/directories in the supplied directory. Used internally for auto-installation of plugins.
static cAudioVector<cAudioString>::Type getFilesInDirectory(cAudioString path) inline cAudioVector<cAudioString>::Type getFilesInDirectory(cAudioString path)
{ {
cAudioVector<cAudioString>::Type FileList; cAudioVector<cAudioString>::Type FileList;
#ifdef CAUDIO_PLATFORM_WIN #ifdef CAUDIO_PLATFORM_WIN

View File

@ -14,4 +14,4 @@ namespace cAudio
EAF_16BIT_MONO, EAF_16BIT_MONO,
EAF_16BIT_STEREO EAF_16BIT_STEREO
}; };
}; };

View File

@ -150,4 +150,4 @@ namespace cAudio
char* buffer; char* buffer;
size_t length; size_t length;
}; };
}; };

View File

@ -17,5 +17,6 @@ namespace cAudio
virtual void update() = 0; virtual void update() = 0;
virtual IAudioManager* getAudioManager() const = 0; virtual IAudioManager* getAudioManager() const = 0;
virtual IAudioEffects* getEffects() const = 0; virtual IAudioEffects* getEffects() const = 0;
virtual ~IAudioDeviceContext(){}
}; };
} }

View File

@ -24,5 +24,6 @@ namespace cAudio
virtual cAudioString getDeviceDescription(unsigned int idx) = 0; virtual cAudioString getDeviceDescription(unsigned int idx) = 0;
virtual cAudioString getDefaultDeviceName() = 0; virtual cAudioString getDefaultDeviceName() = 0;
virtual bool isSupported() = 0; virtual bool isSupported() = 0;
virtual ~IAudioDeviceList(){}
}; };
} }

View File

@ -234,4 +234,4 @@ namespace cAudio
}; };
}; };
#endif #endif

View File

@ -15,8 +15,10 @@
namespace cAudio namespace cAudio
{ {
class IAudioSource; class IAudioSource;
class IAudioBuffer;
class IAudioDecoderFactory; class IAudioDecoderFactory;
class AudioCaptureBuffer; class AudioCaptureBuffer;
class cAudioMutex;
//! Interface for the playback capabilities of cAudio. //! Interface for the playback capabilities of cAudio.
class IAudioManager class IAudioManager
@ -89,6 +91,18 @@ namespace cAudio
//! Get the master volume. //! Get the master volume.
virtual float getMasterVolume() const = 0; virtual float getMasterVolume() const = 0;
//! Set Speed of Sound (for doppler computations)
virtual void setSpeedOfSound(float speed) = 0;
//! Get Speed of Sound (for doppler computations)
virtual float getSpeedOfSound() const = 0;
//! Set Doppler Factor
virtual void setDopplerFactor(float factor) const = 0;
//! Get Doppler Factor
virtual float getDopplerFactor() const = 0;
//! Stops all playing sounds. //! Stops all playing sounds.
virtual void stopAllSounds() = 0; virtual void stopAllSounds() = 0;
@ -133,6 +147,20 @@ namespace cAudio
*/ */
virtual IAudioSource* createFromAudioBuffer(const char* name, AudioCaptureBuffer* pBiffer, unsigned int frequency, AudioFormats format) = 0; virtual IAudioSource* createFromAudioBuffer(const char* name, AudioCaptureBuffer* pBiffer, unsigned int frequency, AudioFormats format) = 0;
//! Creates a Audio Sample using the highest priority data source that has the referenced filename
/**
\param filename: Path to the file to load audio data from.
\return A pointer to an Audio Source or NULL if creation failed.
*/
virtual IAudioBuffer* createBuffer(const char* filename) = 0;
//! Creates an Audio Source from an Audio Buffer object (see createAudioBuffer())
/**
\param buffer: The buffer to play, or NULL to create an empty static source
\return A pointer to an Audio Source or NULL if creation failed.
*/
virtual IAudioSource* createStatic(IAudioBuffer* buffer) = 0;
//! Register an Audio Decoder. //! Register an Audio Decoder.
/** /**
\param factory: Pointer to the factory instance to use. \param factory: Pointer to the factory instance to use.
@ -207,6 +235,8 @@ namespace cAudio
//! Returns the interface for the listener. //! Returns the interface for the listener.
virtual IListener* getListener() = 0; virtual IListener* getListener() = 0;
virtual cAudioMutex *getMutex() = 0;
#if CAUDIO_EFX_ENABLED == 1 #if CAUDIO_EFX_ENABLED == 1
//! Returns the interface for audio effects. //! Returns the interface for audio effects.
virtual IAudioEffects* getEffects() = 0; virtual IAudioEffects* getEffects() = 0;

View File

@ -52,4 +52,4 @@ namespace cAudio
\param capture: Pointer to the soon to be destroyed capture interface. */ \param capture: Pointer to the soon to be destroyed capture interface. */
virtual void onDestoryAudioCapture(IAudioCapture* capture) { } virtual void onDestoryAudioCapture(IAudioCapture* capture) { }
}; };
}; };

View File

@ -14,6 +14,20 @@
namespace cAudio namespace cAudio
{ {
//! interface for a sample (audio buffer): completely loaded into memory, shareable across sources
class IAudioBuffer : public IRefCounted
{
public:
virtual ~IAudioBuffer() {}
virtual bool isValid() const = 0;
virtual unsigned getBuffer() const = 0;
virtual int getChannels() const = 0;
virtual int getTotalAudioSize() const = 0;
virtual float getTotalAudioTime() const = 0;
};
//! Interface for a single audio source, which allow you to manipulate sound sources (speakers) in 2D or 3D space. //! Interface for a single audio source, which allow you to manipulate sound sources (speakers) in 2D or 3D space.
class IAudioSource : public IRefCounted class IAudioSource : public IRefCounted
{ {
@ -39,7 +53,7 @@ namespace cAudio
\param toLoop: Whether to loop (restart) the audio when the end is reached. \param toLoop: Whether to loop (restart) the audio when the end is reached.
\return True if the source is playing, false if not. */ \return True if the source is playing, false if not. */
virtual bool play3d(const cVector3& position, const float& soundstr = 1.0 , const bool& toLoop = false) = 0; virtual bool play3d(const cVector3& position, const float& soundstr = 1.0 , const bool& toLoop = false) = 0;
//! Pauses playback of the sound source. //! Pauses playback of the sound source.
virtual void pause() = 0; virtual void pause() = 0;
@ -57,6 +71,15 @@ namespace cAudio
\return True on success, False if the codec does not support seeking. */ \return True on success, False if the codec does not support seeking. */
virtual bool seek(const float& seconds, bool relative = false) = 0; virtual bool seek(const float& seconds, bool relative = false) = 0;
//! Change the audio buffer associated with the source
/** Note: Only supported on sources created with createFromBuffer() or createForBuffer()
\return True on success, False if the sample does not support setting buffers or is currently playing */
virtual bool setBuffer(IAudioBuffer* buffer) = 0;
//! Get the audio buffer associated with the source
/** \return buffer on succes, NULL if no buffer or sample is streaming */
virtual IAudioBuffer *getBuffer() = 0;
//! Returns the total amount of time in the audio stream. See IAudioDecoder for details. //! Returns the total amount of time in the audio stream. See IAudioDecoder for details.
virtual float getTotalAudioTime() = 0; virtual float getTotalAudioTime() = 0;
@ -79,19 +102,19 @@ namespace cAudio
virtual bool update() = 0; virtual bool update() = 0;
//! Returns if the source is ready to be used. //! Returns if the source is ready to be used.
virtual const bool isValid() const = 0; virtual bool isValid() const = 0; //
//! Returns if the source is playing. //! Returns if the source is playing.
virtual const bool isPlaying() const = 0; virtual bool isPlaying() const = 0;
//! Returns if the source is paused. //! Returns if the source is paused.
virtual const bool isPaused() const = 0; virtual bool isPaused() const = 0;
//! Returns if the source is stopped. //! Returns if the source is stopped.
virtual const bool isStopped() const = 0; virtual bool isStopped() const = 0;
//! Returns if the source is looping. //! Returns if the source is looping.
virtual const bool isLooping() const = 0; virtual bool isLooping() const = 0;
//! Sets the position of the source in 3D space. //! Sets the position of the source in 3D space.
/** /**
@ -183,52 +206,58 @@ namespace cAudio
virtual void move(const cVector3& position) = 0; virtual void move(const cVector3& position) = 0;
//! Returns the audio objects position //! Returns the audio objects position
virtual const cVector3 getPosition() const = 0; virtual cVector3 getPosition() const = 0;
//! Returns the audio objects velocity //! Returns the audio objects velocity
virtual const cVector3 getVelocity() const = 0; virtual cVector3 getVelocity() const = 0;
//! Returns the audio objects direction //! Returns the audio objects direction
virtual const cVector3 getDirection() const = 0; virtual cVector3 getDirection() const = 0;
//! Returns the factor used in attenuating the source over distance //! Returns the factor used in attenuating the source over distance
virtual const float getRolloffFactor() const = 0; virtual float getRolloffFactor() const = 0;
//! Returns the strength of the source //! Returns the strength of the source
virtual const float getStrength() const = 0; virtual float getStrength() const = 0;
//! Returns the distance from the source where attenuation will begin //! Returns the distance from the source where attenuation will begin
virtual const float getMinDistance() const = 0; virtual float getMinDistance() const = 0;
//! Returns the distance from the source where attenuation will stop //! Returns the distance from the source where attenuation will stop
virtual const float getMaxDistance() const = 0; virtual float getMaxDistance() const = 0;
//! Return true for 2d sounds, false for 3d sounds
virtual bool isRelative() const = 0;
//! Return gain, taking into account volume as well as distance attenuation
virtual float calculateGain() const = 0;
//! Returns the pitch of the source //! Returns the pitch of the source
virtual const float getPitch() const = 0; virtual float getPitch() const = 0;
//! Returns the source volume before attenuation and other effects //! Returns the source volume before attenuation and other effects
virtual const float getVolume() const = 0; virtual float getVolume() const = 0;
//! Returns the minimum volume that the source can be attenuated to //! Returns the minimum volume that the source can be attenuated to
virtual const float getMinVolume() const = 0; virtual float getMinVolume() const = 0;
//! Returns the maximum volume that the source can achieve //! Returns the maximum volume that the source can achieve
virtual const float getMaxVolume() const = 0; virtual float getMaxVolume() const = 0;
//! Returns the angle of the inner sound cone of the source //! Returns the angle of the inner sound cone of the source
virtual const float getInnerConeAngle() const = 0; virtual float getInnerConeAngle() const = 0;
//! Returns the angle of the outer sound cone of the source //! Returns the angle of the outer sound cone of the source
virtual const float getOuterConeAngle() const = 0; virtual float getOuterConeAngle() const = 0;
//! Returns how much the volume of the source is scaled in the outer cone //! Returns how much the volume of the source is scaled in the outer cone
virtual const float getOuterConeVolume() const = 0; virtual float getOuterConeVolume() const = 0;
//! Returns the doppler strength, which enhances or diminishes the doppler effect //! Returns the doppler strength, which enhances or diminishes the doppler effect
virtual const float getDopplerStrength() const = 0; virtual float getDopplerStrength() const = 0;
//! Returns the override for the doppler velocity vector //! Returns the override for the doppler velocity vector
virtual const cVector3 getDopplerVelocity() const = 0; virtual cVector3 getDopplerVelocity() const = 0;
//! Registers a new event handler to this source //! Registers a new event handler to this source
/** /**
@ -272,4 +301,4 @@ namespace cAudio
protected: protected:
private: private:
}; };
}; };

View File

@ -29,5 +29,6 @@ namespace cAudio
//! This function is called whe user requests data from the capture buffer. //! This function is called whe user requests data from the capture buffer.
virtual void onUserRequestBuffer() = 0; virtual void onUserRequestBuffer() = 0;
virtual ~ICaptureEventHandler(){}
}; };
}; };

View File

@ -33,7 +33,7 @@ namespace cAudio
{ {
public: public:
ILogReceiver() { } ILogReceiver() { }
~ILogReceiver() { } virtual ~ILogReceiver() { }
//! Called on every logged message that is greater than or equal to the minimum log level. //! Called on every logged message that is greater than or equal to the minimum log level.
/** /**

View File

@ -27,6 +27,8 @@ namespace cAudio
//! This function is called when a data source is registered. //! This function is called when a data source is registered.
virtual void onDataSourceRegister() = 0; virtual void onDataSourceRegister() = 0;
virtual ~IManagerEventHandler(){}
}; };
}; };

View File

@ -28,5 +28,7 @@ namespace cAudio
//! Returns the largest possible single allocation that can be made. //! Returns the largest possible single allocation that can be made.
virtual size_t getMaxAllocationSize() = 0; virtual size_t getMaxAllocationSize() = 0;
virtual ~IMemoryProvider() {}
}; };
}; };

View File

@ -15,7 +15,7 @@ namespace cAudio
{ {
public: public:
IPluginManager() { } IPluginManager() { }
~IPluginManager() { } virtual ~IPluginManager() { }
//! Installs a plugin using a statically linked plugin implementation. //! Installs a plugin using a statically linked plugin implementation.
/** /**

View File

@ -11,19 +11,21 @@ namespace cAudio
{ {
public: public:
//! This function is called when a source updates its buffers. //! This function is called when a source updates its buffers.
virtual void onUpdate() = 0; virtual void onUpdate(){}
//! This function is called when a source is released and soon to be deleted. //! This function is called when a source is released and soon to be deleted.
virtual void onRelease() = 0; virtual void onRelease(){}
//! This function is called when a source starts playing. //! This function is called when a source starts playing.
virtual void onPlay() = 0; virtual void onPlay(){}
//! This function is called when a source stopped playback. //! This function is called when a source stopped playback.
virtual void onStop() = 0; virtual void onStop(){}
//! This function is called when a source is paused. //! This function is called when a source is paused.
virtual void onPause() = 0; virtual void onPause(){}
virtual ~ISourceEventHandler(){}
}; };
}; };

View File

@ -13,11 +13,13 @@ namespace cAudio
virtual void join() = 0; virtual void join() = 0;
virtual void shutdown() = 0; virtual void shutdown() = 0;
virtual bool isRunning() = 0; virtual bool isRunning() = 0;
virtual ~IThread(){}
}; };
class IThreadWorker class IThreadWorker
{ {
public: public:
virtual void run() = 0; virtual void run() = 0;
virtual ~IThreadWorker(){}
}; };
} }

View File

@ -7,7 +7,7 @@
#include "cAudioDefines.h" #include "cAudioDefines.h"
#include "IMemoryProvider.h" #include "IMemoryProvider.h"
#ifdef CAUDIO_DEBUG #if 0 /* defined(CAUDIO_DEBUG) */
#define CAUDIO_NEW new (__FILE__, __LINE__, __FUNCTION__) #define CAUDIO_NEW new (__FILE__, __LINE__, __FUNCTION__)
#define CAUDIO_DELETE delete #define CAUDIO_DELETE delete
#define CAUDIO_MALLOC(size) cAudio::getMemoryProvider()->Allocate(size, __FILE__, __LINE__, __FUNCTION__) #define CAUDIO_MALLOC(size) cAudio::getMemoryProvider()->Allocate(size, __FILE__, __LINE__, __FUNCTION__)
@ -25,4 +25,4 @@ namespace cAudio
/** Used by cAudio for all allocations of memory /** Used by cAudio for all allocations of memory
\return A pointer to the memory provider */ \return A pointer to the memory provider */
CAUDIO_API IMemoryProvider* getMemoryProvider(); CAUDIO_API IMemoryProvider* getMemoryProvider();
}; };

View File

@ -47,3 +47,20 @@
# define CAUDIO_COMPILER_MINGW # define CAUDIO_COMPILER_MINGW
# endif # endif
#endif #endif
#ifdef CAUDIO_PLATFORM_WIN
#ifndef NOMINMAX
#define NOMINMAX
#endif
#define WIN32_LEAN_AND_MEAN
#define _CRT_SECURE_NO_WARNINGS 1
#if defined(_DEBUG) && !defined(DEBUG)
#define DEBUG _DEBUG
#endif
#ifndef DEBUG
#define _SECURE_SCL 0
#define _HAS_ITERATOR_DEBUGGING 0
#endif
#include <windows.h> //Basic windows includes
#endif

View File

@ -11,4 +11,4 @@ namespace cAudio
//! Causes the current thread to give up control for a certain duration. //! Causes the current thread to give up control for a certain duration.
/** \param ms: amount of miliseconds to sleep */ /** \param ms: amount of miliseconds to sleep */
CAUDIO_API void cAudioSleep(unsigned int ms); CAUDIO_API void cAudioSleep(unsigned int ms);
}; };

View File

@ -13,8 +13,6 @@
#include <stdlib.h> #include <stdlib.h>
#ifdef CAUDIO_PLATFORM_WIN #ifdef CAUDIO_PLATFORM_WIN
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
# include <direct.h> # include <direct.h>
# include <io.h> # include <io.h>
#endif #endif
@ -26,12 +24,12 @@ namespace cAudio
# define _CTEXT(x) L ## x # define _CTEXT(x) L ## x
# define cstrcmp wcscmp # define cstrcmp wcscmp
# define cAudioChar wchar_t # define cAudioChar wchar_t
# define cfopen _wfopen # define cfopen(N, M) _wfopen((N).c_str(), L ## M)
#else #else
# define _CTEXT(x) x # define _CTEXT(x) x
# define cstrcmp strcmp # define cstrcmp strcmp
# define cAudioChar char # define cAudioChar char
# define cfopen fopen # define cfopen(N, M) fopen(toUTF8(N), M)
#endif #endif
#if CAUDIO_REROUTE_STRING_ALLOCATIONS == 1 #if CAUDIO_REROUTE_STRING_ALLOCATIONS == 1
@ -46,55 +44,13 @@ namespace cAudio
#if defined(CAUDIO_PLATFORM_WIN) #if defined(CAUDIO_PLATFORM_WIN)
static const TCHAR* toWINSTR(const char* str)
{
#if (defined(UNICODE) || defined(_UNICODE))
static int id = 0;
static wchar_t buffer[8][1024];
id = ++id & 0x7;
int slen = strlen(str);
int buff_size = MultiByteToWideChar(CP_UTF8, 0, str, (int)(slen < 1023 ? slen : 1023), buffer[id], 1023);
buffer[id][buff_size] = 0;
buffer[id][1023] = 0;
return buffer[id];
#else
return str;
#endif
}
static const TCHAR* toWINSTR(const wchar_t* str)
{
#if (defined(UNICODE) || defined(_UNICODE))
return str;
#else
static int id = 0;
static char buffer[8][1024];
id = ++id & 0x7;
int slen = wcslen(str);
int buff_size = WideCharToMultiByte(CP_UTF8, 0, str, (int)(slen < 1023 ? slen : 1023), buffer[id], 1023, 0, false);
buffer[id][buff_size] = 0;
buffer[id][1023] = 0;
return buffer[id];
#endif
}
static wchar_t* charToWChar(const char* text)
{
size_t size = strlen(text) + 1;
wchar_t* wa = new wchar_t[size];
mbstowcs(wa, text, size);
return wa;
}
static const char* toUTF8(const cAudioString& str) static const char* toUTF8(const cAudioString& str)
{ {
static int id = 0; static int id = 0;
static char buffer[8][1024]; static char buffer[8][1024];
id = ++id & 0x7; id = ++id & 0x7;
int buff_size = WideCharToMultiByte(CP_UTF8, 0, charToWChar(str.c_str()), (int)(str.size() < 1023 ? str.size() : 1023), buffer[id], 1023, 0, false); int buff_size = WideCharToMultiByte(CP_UTF8, 0, str.c_str(), (int)(str.size() < 1023 ? str.size() : 1023), buffer[id], 1023, 0, false);
buffer[id][buff_size] = 0; buffer[id][buff_size] = 0;
buffer[id][1023] = 0; buffer[id][1023] = 0;
return buffer[id]; return buffer[id];
@ -102,34 +58,20 @@ namespace cAudio
static cAudioString fromUTF8(const char* str) static cAudioString fromUTF8(const char* str)
{ {
wchar_t* buffer = 0; int str_len = (int)strlen(str);
int buff_size = MultiByteToWideChar(CP_UTF8, 0, str, (int)strlen(str), 0, 0); int buf_size = MultiByteToWideChar(CP_UTF8, 0, str, str_len, 0, 0);
if (buff_size == 0) cAudioString s(buf_size, L'\0');
return cAudioString(); MultiByteToWideChar(CP_UTF8, 0, str, str_len, &s[0], buf_size);
buffer = new wchar_t[buff_size + 1];
memset((void*)buffer, 0, sizeof(wchar_t) * (buff_size + 1));
MultiByteToWideChar(CP_UTF8, 0, str, (int)strlen(str), buffer, buff_size);
char* convert = new char[buff_size+1];
wcstombs(convert, buffer, sizeof(wchar_t) * (buff_size + 1));
cAudioString s(convert);
delete[] buffer;
return s; return s;
} }
#else #else
static const char* toWINSTR(const char* str) inline const char* toUTF8(const cAudioString& str)
{
return str;
}
static const char* toUTF8(const cAudioString& str)
{ {
return str.c_str(); return str.c_str();
} }
static cAudioString fromUTF8(const char* str) inline cAudioString fromUTF8(const char* str)
{ {
return cAudioString(str); return cAudioString(str);
} }

View File

@ -62,7 +62,7 @@ namespace cAudio
pointer allocate( size_type count, typename std::allocator<void>::const_pointer ptr = 0 ) pointer allocate( size_type count, typename std::allocator<void>::const_pointer ptr = 0 )
{ {
(void)ptr; (void)ptr;
register size_type size = count*sizeof( T ); size_type size = count*sizeof( T );
pointer p = static_cast<pointer>(CAUDIO_MALLOC(size)); pointer p = static_cast<pointer>(CAUDIO_MALLOC(size));
return p; return p;
} }

View File

@ -91,7 +91,7 @@ namespace cAudio
operator float*() { return &x; } operator float*() { return &x; }
const float operator[] ( int i ) const { return ( ( float* ) &x ) [i]; } float operator[] ( int i ) const { return ( ( float* ) &x ) [i]; }
float &operator[] ( int i ) { return ( ( float* ) &x ) [i]; } float &operator[] ( int i ) { return ( ( float* ) &x ) [i]; }
@ -151,4 +151,4 @@ namespace cAudio
output[2] = z; output[2] = z;
} }
}; };
}; };

View File

@ -91,9 +91,6 @@ namespace cAudio
} }
#endif #endif
manager->unRegisterAllAudioDecoders();
manager->unRegisterAllDataSources();
manager->unRegisterAllEventHandlers();
manager->shutDown(); manager->shutDown();
CAUDIO_DELETE manager; CAUDIO_DELETE manager;
@ -144,9 +141,6 @@ namespace cAudio
// Logger section // Logger section
//--------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------
static cLogger Logger;
static bool FirstTimeLogInit(false);
#if CAUDIO_COMPILE_WITH_CONSOLE_LOG_RECEIVER == 1 #if CAUDIO_COMPILE_WITH_CONSOLE_LOG_RECEIVER == 1
static cConsoleLogReceiver ConsoleLog; static cConsoleLogReceiver ConsoleLog;
#endif #endif
@ -157,17 +151,19 @@ namespace cAudio
CAUDIO_API ILogger* getLogger() CAUDIO_API ILogger* getLogger()
{ {
if(!FirstTimeLogInit) static cLogger* Logger = NULL;
if(!Logger)
{ {
FirstTimeLogInit = true; Logger = new cLogger;
#if CAUDIO_COMPILE_WITH_CONSOLE_LOG_RECEIVER == 1 #if CAUDIO_COMPILE_WITH_CONSOLE_LOG_RECEIVER == 1
Logger.registerLogReceiver(&ConsoleLog, "Console"); Logger->registerLogReceiver(&ConsoleLog, "Console");
#endif #endif
#if CAUDIO_COMPILE_WITH_FILE_LOG_RECEIVER == 1 #if CAUDIO_COMPILE_WITH_FILE_LOG_RECEIVER == 1
Logger.registerLogReceiver(&FileLog,"File"); Logger->registerLogReceiver(&FileLog,"File");
#endif #endif
} }
return &Logger; return Logger;
} }
//--------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------

View File

@ -14,15 +14,15 @@
namespace cAudio namespace cAudio
{ {
cAudioCapture::cAudioCapture() : Frequency(22050), Format(EAF_16BIT_MONO), InternalBufferSize(8192), cAudioCapture::cAudioCapture() : AudioThread(NULL), Frequency(22050), Format(EAF_16BIT_MONO),
SampleSize(2), Ready(false), Capturing(false), InternalBufferSize(8192), SampleSize(2), Ready(false),
CaptureDevice(NULL), AudioThread(NULL) Capturing(false), CaptureDevice(NULL)
{ {
} }
cAudioCapture::~cAudioCapture() cAudioCapture::~cAudioCapture()
{ {
shutdown(); cAudioCapture::shutdown();
} }
void cAudioCapture::run() void cAudioCapture::run()
@ -315,7 +315,7 @@ namespace cAudio
case ON_INIT: case ON_INIT:
for(it; it != eventHandlerList.end(); it++){ for(; it != eventHandlerList.end(); it++){
(*it)->onInit(); (*it)->onInit();
} }
@ -323,7 +323,7 @@ namespace cAudio
case ON_UPDATE: case ON_UPDATE:
for(it; it != eventHandlerList.end(); it++){ for(; it != eventHandlerList.end(); it++){
(*it)->onUpdate(); (*it)->onUpdate();
} }
@ -331,7 +331,7 @@ namespace cAudio
case ON_RELEASE: case ON_RELEASE:
for(it; it != eventHandlerList.end(); it++){ for(; it != eventHandlerList.end(); it++){
(*it)->onRelease(); (*it)->onRelease();
} }
@ -339,7 +339,7 @@ namespace cAudio
case ON_BEGINCAPTURE: case ON_BEGINCAPTURE:
for(it; it != eventHandlerList.end(); it++){ for(; it != eventHandlerList.end(); it++){
(*it)->onBeginCapture(); (*it)->onBeginCapture();
} }
@ -348,7 +348,7 @@ namespace cAudio
case ON_ENDCAPTURE: case ON_ENDCAPTURE:
for(it; it != eventHandlerList.end(); it++){ for(; it != eventHandlerList.end(); it++){
(*it)->onEndCapture(); (*it)->onEndCapture();
} }
@ -356,7 +356,7 @@ namespace cAudio
case ON_USERREQUESTEDBUFFER: case ON_USERREQUESTEDBUFFER:
for(it; it != eventHandlerList.end(); it++){ for(; it != eventHandlerList.end(); it++){
(*it)->onUserRequestBuffer(); (*it)->onUserRequestBuffer();
} }

View File

@ -5,6 +5,7 @@
#include "cAudioManager.h" #include "cAudioManager.h"
#include "cAudio.h" #include "cAudio.h"
#include "cAudioSource.h" #include "cAudioSource.h"
#include "cAudioStaticSource.h"
#include "cAudioPlatform.h" #include "cAudioPlatform.h"
#include "cAudioSleep.h" #include "cAudioSleep.h"
#include "cUtils.h" #include "cUtils.h"
@ -22,7 +23,7 @@ namespace cAudio
{ {
cAudioManager::~cAudioManager() cAudioManager::~cAudioManager()
{ {
shutDown(); cAudioManager::shutDown();
} }
bool cAudioManager::initialize(const char* deviceName, int outputFrequency, int eaxEffectSlots) bool cAudioManager::initialize(const char* deviceName, int outputFrequency, int eaxEffectSlots)
@ -60,6 +61,10 @@ namespace cAudio
} }
cAudioMutexBasicLock lock(Mutex); cAudioMutexBasicLock lock(Mutex);
unRegisterAllAudioDecoders();
unRegisterAllDataSources();
unRegisterAllEventHandlers();
releaseAllSources(); releaseAllSources();
@ -78,20 +83,35 @@ namespace cAudio
void cAudioManager::update() void cAudioManager::update()
{ {
cAudioMutexBasicLock lock(Mutex); updateSources.clear();
size_t count = audioSources.size();
for(size_t i=0; i<count; i++)
{
IAudioSource* source = audioSources[i];
if (source->isValid())
{
source->update();
}
}
{
cAudioMutexBasicLock lock(Mutex);
size_t count = audioSources.size();
for(size_t i=0; i<count; i++)
{
IAudioSource* source = audioSources[i];
if (source->isValid())
{
source->grab();
updateSources.push_back(source);
}
}
}
// not holding the mutex because this might take a while!
for (int i=0; i != updateSources.size(); i++)
{
IAudioSource *src = updateSources[i];
src->update();
src->drop();
}
cAudioMutexBasicLock lock(Mutex);
if (!managedAudioSources.empty()) if (!managedAudioSources.empty())
{ {
count = managedAudioSources.size(); size_t count = managedAudioSources.size();
for(size_t i=0; i<count; i++) for(size_t i=0; i<count; i++)
{ {
IAudioSource* source = managedAudioSources[i]; IAudioSource* source = managedAudioSources[i];
@ -148,6 +168,9 @@ namespace cAudio
{ {
cAudioMutexBasicLock lock(Mutex); cAudioMutexBasicLock lock(Mutex);
IAudioSource* pAudioSrc = create("", filename, true); IAudioSource* pAudioSrc = create("", filename, true);
if (!pAudioSrc)
return NULL;
if (!playLooped && !startPaused) if (!playLooped && !startPaused)
{ {
@ -212,6 +235,28 @@ namespace cAudio
return MasterVolume; return MasterVolume;
} }
void cAudioManager::setSpeedOfSound(float speed)
{
alSpeedOfSound(speed);
checkALError();
}
float cAudioManager::getSpeedOfSound() const
{
return alGetFloat(AL_SPEED_OF_SOUND);
}
void cAudioManager::setDopplerFactor(float factor) const
{
alDopplerFactor(factor);
checkALError();
}
float cAudioManager::getDopplerFactor() const
{
return alGetFloat(AL_DOPPLER_FACTOR);
}
void cAudioManager::stopAllSounds() void cAudioManager::stopAllSounds()
{ {
cAudioMutexBasicLock lock(Mutex); cAudioMutexBasicLock lock(Mutex);
@ -225,7 +270,10 @@ namespace cAudio
IAudioSource* cAudioManager::createAudioSource(IAudioDecoder* decoder, const cAudioString& audioName, const cAudioString& dataSource) IAudioSource* cAudioManager::createAudioSource(IAudioDecoder* decoder, const cAudioString& audioName, const cAudioString& dataSource)
{ {
if(decoder && decoder->isValid()) if (!decoder)
return NULL;
if(decoder->isValid())
{ {
#if CAUDIO_EFX_ENABLED == 1 #if CAUDIO_EFX_ENABLED == 1
IAudioSource* audio = CAUDIO_NEW cAudioSource(decoder, AudioContext, ((cAudioEffects*)getEffects())->getEFXInterface()); IAudioSource* audio = CAUDIO_NEW cAudioSource(decoder, AudioContext, ((cAudioEffects*)getEffects())->getEFXInterface());
@ -248,11 +296,13 @@ namespace cAudio
audio->drop(); audio->drop();
return NULL; return NULL;
} }
getLogger()->logError("AudioManager", "Failed to create Audio Source (%s): Audio data could not be decoded by (.%s) decoder.", toUTF8(audioName), toUTF8(decoder->getType())); getLogger()->logError("AudioManager", "Failed to create Audio Source (%s): Audio data could not be decoded by (.%s) decoder.",
toUTF8(audioName), toUTF8(decoder->getType()));
decoder->drop(); decoder->drop();
return NULL; return NULL;
} }
IAudioSource* cAudioManager::create(const char* name, const char* filename, bool stream) IAudioSource* cAudioManager::create(const char* name, const char* filename, bool stream)
{ {
if(!Initialized) return NULL; if(!Initialized) return NULL;
@ -284,8 +334,8 @@ namespace cAudio
if(audio != NULL) if(audio != NULL)
return audio; return audio;
if(source) //if(source)
source->drop(); // source->drop();
return NULL; return NULL;
} }
@ -358,6 +408,56 @@ namespace cAudio
return NULL; return NULL;
} }
IAudioBuffer* cAudioManager::createBuffer(const char* filename)
{
if(!Initialized) return NULL;
cAudioMutexBasicLock lock(Mutex);
cAudioString path = fromUTF8(filename);
cAudioString ext = getExt(path);
IAudioDecoderFactory* factory = getAudioDecoderFactory(toUTF8(ext));
if(!factory) {
getLogger()->logError("AudioManager", "Failed to create Audio Buffer: No decoder could be found for (.%s).", toUTF8(ext));
return NULL;
}
for(size_t i=0; i<dataSourcePriorityList.size(); ++i)
{
const cAudioString dataSourceName = dataSourcePriorityList[i].second;
IDataSourceFactory* dataFactory = datasourcemap[dataSourceName];
if(dataFactory)
{
IDataSource* source = dataFactory->CreateDataSource(filename, false);
if(source && source->isValid())
{
IAudioDecoder* decoder = factory->CreateAudioDecoder(source);
source->drop();
IAudioBuffer* buffer = CAUDIO_NEW cAudioBuffer(decoder);
if(buffer != NULL)
return buffer;
//if(source)
// source->drop();
return NULL;
}
}
}
return NULL;
}
IAudioSource* cAudioManager::createStatic(IAudioBuffer* buffer)
{
if(!Initialized) return NULL;
// FIXME save a reference?
IAudioSource *audio = CAUDIO_NEW cAudioStaticSource(buffer, AudioContext);
return audio;
}
bool cAudioManager::registerAudioDecoder(IAudioDecoderFactory* factory, const char* extension) bool cAudioManager::registerAudioDecoder(IAudioDecoderFactory* factory, const char* extension)
{ {
cAudioMutexBasicLock lock(Mutex); cAudioMutexBasicLock lock(Mutex);
@ -504,7 +604,7 @@ namespace cAudio
{ {
case ON_INIT: case ON_INIT:
for(it; it != eventHandlerList.end(); it++) for(; it != eventHandlerList.end(); it++)
{ {
(*it)->onInit(); (*it)->onInit();
} }
@ -513,7 +613,7 @@ namespace cAudio
case ON_UPDATE: case ON_UPDATE:
for(it; it != eventHandlerList.end(); it++) for(; it != eventHandlerList.end(); it++)
{ {
(*it)->onUpdate(); (*it)->onUpdate();
} }
@ -522,7 +622,7 @@ namespace cAudio
case ON_RELEASE: case ON_RELEASE:
for(it; it != eventHandlerList.end(); it++) for(; it != eventHandlerList.end(); it++)
{ {
(*it)->onRelease(); (*it)->onRelease();
} }
@ -531,7 +631,7 @@ namespace cAudio
case ON_SOURCECREATE: case ON_SOURCECREATE:
for(it; it != eventHandlerList.end(); it++) for(; it != eventHandlerList.end(); it++)
{ {
(*it)->onSourceCreate(); (*it)->onSourceCreate();
} }
@ -540,7 +640,7 @@ namespace cAudio
case ON_DECODERREGISTER: case ON_DECODERREGISTER:
for(it; it != eventHandlerList.end(); it++) for(; it != eventHandlerList.end(); it++)
{ {
(*it)->onDecoderRegister(); (*it)->onDecoderRegister();
} }
@ -549,7 +649,7 @@ namespace cAudio
case ON_DATASOURCEREGISTER: case ON_DATASOURCEREGISTER:
for(it; it != eventHandlerList.end(); it++) for(; it != eventHandlerList.end(); it++)
{ {
(*it)->onDataSourceRegister(); (*it)->onDataSourceRegister();
} }

View File

@ -1,12 +1,10 @@
// Copyright (c) 2008-2011 Raynaldo (Wildicv) Rivera, Joshua (Dark_Kilauea) Jones, Murat (wolfmanfx) Sari // Copyright (c) 2008-2011 Raynaldo (Wildicv) Rivera, Joshua (Dark_Kilauea) Jones, Murat (wolfmanfx) Sari
// This file is part of the "cAudio Engine" // This file is part of the "cAudio Engine"
// For conditions of distribution and use, see copyright notice in cAudio.h // For conditions of distribution and use, see copyright notice in cAudio.h
#include "cAudioPlatform.h" #include "cAudioPlatform.h"
#ifdef CAUDIO_PLATFORM_WIN #ifndef CAUDIO_PLATFORM_WIN
#include <windows.h> //Basic windows include for Sleep();
#else
#include <unistd.h> //Assumed linux system, include for usleep() #include <unistd.h> //Assumed linux system, include for usleep()
#include <time.h> #include <time.h>
#endif //If you need to support another platform, simply add a define for it #endif //If you need to support another platform, simply add a define for it

View File

@ -9,26 +9,56 @@
#include "cEffect.h" #include "cEffect.h"
#include "cAudioSleep.h" #include "cAudioSleep.h"
#include <string.h> #include <string.h>
#include <algorithm>
#if CAUDIO_EFX_ENABLED == 1 #if CAUDIO_EFX_ENABLED == 1
#include "cOpenALDeviceContext.h" #include "cOpenALDeviceContext.h"
#endif #endif
namespace
{
// return buffer length in seconds
ALfloat GetBufferLength(ALuint buffer)
{
ALint size, bits, channels, freq;
alGetBufferi(buffer, AL_SIZE, &size);
alGetBufferi(buffer, AL_BITS, &bits);
alGetBufferi(buffer, AL_CHANNELS, &channels);
alGetBufferi(buffer, AL_FREQUENCY, &freq);
if(alGetError() != AL_NO_ERROR || !bits || !channels || !freq)
return -1.0f;
return (ALfloat)((ALuint)size/channels/(bits/8)) / (ALfloat)freq;
}
ALint GetBufferSize(ALuint buffer)
{
ALint size;
alGetBufferi(buffer, AL_SIZE, &size);
return size;
}
}
namespace cAudio namespace cAudio
{ {
#if CAUDIO_EFX_ENABLED == 1 #if CAUDIO_EFX_ENABLED == 1
cAudioSource::cAudioSource(IAudioDecoder* decoder, IAudioDeviceContext* context, cEFXFunctions* oALFunctions) cAudioSource::cAudioSource(IAudioDecoder* decoder, IAudioDeviceContext* context, cEFXFunctions* oALFunctions)
: Context(context), Source(0), Volume(1.0), Decoder(decoder), Loop(false), Valid(false), : cAudioSourceBase(context), Decoder(decoder), Loop(false), Valid(false),
EFX(oALFunctions), Filter(NULL), EffectSlotsAvailable(0), LastFilterTimeStamp(0) EFX(oALFunctions), Filter(NULL), EffectSlotsAvailable(0), LastFilterTimeStamp(0)
#else #else
cAudioSource::cAudioSource(IAudioDecoder* decoder, IAudioDeviceContext* context) cAudioSource::cAudioSource(IAudioDecoder* decoder, IAudioDeviceContext* context)
: Context(context), Source(0), Volume(1.0), Decoder(decoder), Loop(false), Valid(false) : cAudioSourceBase(context), Decoder(decoder), Loop(false), Valid(false)
#endif #endif
{ {
cAudioMutexBasicLock lock(Mutex); cAudioMutexBasicLock lock(Mutex);
for(int i=0; i<CAUDIO_SOURCE_NUM_BUFFERS; ++i) BufferPosition = 0;
BufferTime = 0;
for(int i=0; i<CAUDIO_SOURCE_NUM_BUFFERS; ++i) {
Buffers[i] = 0; Buffers[i] = 0;
}
#if CAUDIO_EFX_ENABLED == 1 #if CAUDIO_EFX_ENABLED == 1
for(int i=0; i<CAUDIO_SOURCE_MAX_EFFECT_SLOTS; ++i) for(int i=0; i<CAUDIO_SOURCE_MAX_EFFECT_SLOTS; ++i)
@ -41,16 +71,14 @@ namespace cAudio
if(Decoder) if(Decoder)
Decoder->grab(); Decoder->grab();
//Generates 3 buffers for the ogg file ALboolean state = alIsSource(Source);
alGenBuffers(CAUDIO_SOURCE_NUM_BUFFERS, Buffers);
bool state = !checkError(); if (state)
if(state) {
{ //Generates 3 buffers for the ogg file
//Creates one source to be stored. alGenBuffers(CAUDIO_SOURCE_NUM_BUFFERS, Buffers);
alGenSources(1, &Source); state = !checkALError();
state = !checkError(); }
setVolume(Volume);
}
#if CAUDIO_EFX_ENABLED == 1 #if CAUDIO_EFX_ENABLED == 1
Valid = state && (Decoder != NULL) && (Context != NULL) && (EFX != NULL); Valid = state && (Decoder != NULL) && (Context != NULL) && (EFX != NULL);
@ -84,19 +112,36 @@ namespace cAudio
//Stops the audio Source //Stops the audio Source
alSourceStop(Source); alSourceStop(Source);
checkALError();
empty(); empty();
//Deletes the source alSourcei(Source, AL_BUFFER, 0);
alDeleteSources(1, &Source);
//deletes the last filled buffer //deletes the last filled buffer
alDeleteBuffers(CAUDIO_SOURCE_NUM_BUFFERS, Buffers); alDeleteBuffers(CAUDIO_SOURCE_NUM_BUFFERS, Buffers);
checkError(); checkALError();
if(Decoder) {
Decoder->drop();
Decoder = NULL;
}
}
cAudioSourceBase::cAudioSourceBase(IAudioDeviceContext* context) :
Context(context), Volume(1.f), Source(0)
{
alGenSources(1, &Source);
checkALError();
setVolume(Volume);
}
cAudioSourceBase::~cAudioSourceBase()
{
alSourceStop(Source);
checkALError();
alDeleteSources(1, &Source);
checkALError();
getLogger()->logDebug("Audio Source", "Audio source released."); getLogger()->logDebug("Audio Source", "Audio source released.");
signalEvent(ON_RELEASE); signalEvent(ON_RELEASE);
if(Decoder)
Decoder->drop();
unRegisterAllEventHandlers();
} }
@ -119,7 +164,9 @@ namespace cAudio
int queueSize = 0; int queueSize = 0;
//Purges all buffers from the source //Purges all buffers from the source
alSourcei(Source, AL_BUFFER, 0); alSourcei(Source, AL_BUFFER, 0);
checkError(); BufferPosition = Decoder->getCurrentPosition();
BufferTime = Decoder->getCurrentTime();
checkALError();
for(int u = 0; u < CAUDIO_SOURCE_NUM_BUFFERS; u++) for(int u = 0; u < CAUDIO_SOURCE_NUM_BUFFERS; u++)
{ {
int val = stream(Buffers[u]); int val = stream(Buffers[u]);
@ -133,7 +180,7 @@ namespace cAudio
} }
//Stores the sources 3 buffers to be used in the queue //Stores the sources 3 buffers to be used in the queue
alSourceQueueBuffers(Source, queueSize, Buffers); alSourceQueueBuffers(Source, queueSize, Buffers);
checkError(); checkALError();
} }
#if CAUDIO_EFX_ENABLED == 1 #if CAUDIO_EFX_ENABLED == 1
updateFilter(); updateFilter();
@ -141,7 +188,7 @@ namespace cAudio
updateEffect(i); updateEffect(i);
#endif #endif
alSourcePlay(Source); alSourcePlay(Source);
checkError(); checkALError();
getLogger()->logDebug("Audio Source", "Source playing."); getLogger()->logDebug("Audio Source", "Source playing.");
signalEvent(ON_PLAY); signalEvent(ON_PLAY);
oldState = AL_PLAYING; oldState = AL_PLAYING;
@ -154,7 +201,7 @@ namespace cAudio
alSourcei(Source, AL_SOURCE_RELATIVE, true); alSourcei(Source, AL_SOURCE_RELATIVE, true);
loop(toLoop); loop(toLoop);
bool state = play(); bool state = play();
checkError(); checkALError();
return state; return state;
} }
@ -166,7 +213,7 @@ namespace cAudio
setStrength(soundstr); setStrength(soundstr);
loop(toLoop); loop(toLoop);
bool state = play(); bool state = play();
checkError(); checkALError();
return state; return state;
} }
@ -174,7 +221,7 @@ namespace cAudio
{ {
cAudioMutexBasicLock lock(Mutex); cAudioMutexBasicLock lock(Mutex);
alSourcePause(Source); alSourcePause(Source);
checkError(); checkALError();
getLogger()->logDebug("Audio Source", "Source paused."); getLogger()->logDebug("Audio Source", "Source paused.");
signalEvent(ON_PAUSE); signalEvent(ON_PAUSE);
oldState = AL_PAUSED; oldState = AL_PAUSED;
@ -196,7 +243,7 @@ namespace cAudio
//Resets the audio to the beginning //Resets the audio to the beginning
Decoder->setPosition(0, false); Decoder->setPosition(0, false);
checkError(); checkALError();
getLogger()->logDebug("Audio Source", "Source stopped."); getLogger()->logDebug("Audio Source", "Source stopped.");
signalEvent(ON_STOP); signalEvent(ON_STOP);
oldState = AL_STOPPED; oldState = AL_STOPPED;
@ -215,6 +262,16 @@ namespace cAudio
if(Decoder->isSeekingSupported()) if(Decoder->isSeekingSupported())
{ {
state = Decoder->seek(seconds, relative); state = Decoder->seek(seconds, relative);
BufferPosition = Decoder->getCurrentPosition();
BufferTime = Decoder->getCurrentTime();
int queued = 0;
alGetSourcei(Source, AL_BUFFERS_QUEUED, &queued);
if (queued) {
BufferPosition -= queued * GetBufferSize(Buffers[0]);
BufferTime -= queued * GetBufferLength(Buffers[0]);
}
} }
return state; return state;
} }
@ -236,12 +293,16 @@ namespace cAudio
float cAudioSource::getCurrentAudioTime() float cAudioSource::getCurrentAudioTime()
{ {
return Decoder->getCurrentTime(); float time = -1;
alGetSourcef(Source, AL_SEC_OFFSET, &time);
return BufferTime + time;
} }
int cAudioSource::getCurrentAudioPosition() int cAudioSource::getCurrentAudioPosition()
{ {
return Decoder->getCurrentPosition(); int offset = -1;
alGetSourcei(Source, AL_BYTE_OFFSET, &offset);
return BufferPosition + offset;
} }
int cAudioSource::getCurrentCompressedAudioPosition() int cAudioSource::getCurrentCompressedAudioPosition()
@ -265,15 +326,17 @@ namespace cAudio
//gets the sound source processed buffers //gets the sound source processed buffers
alGetSourcei(Source, AL_BUFFERS_PROCESSED, &processed); alGetSourcei(Source, AL_BUFFERS_PROCESSED, &processed);
checkError(); checkALError();
//while there is more data refill buffers with audio data. //while there is more data refill buffers with audio data.
while (processed--) while (processed--)
{ {
ALuint buffer; ALuint buffer;
alSourceUnqueueBuffers(Source, 1, &buffer); alSourceUnqueueBuffers(Source, 1, &buffer);
BufferPosition += GetBufferSize(buffer);
BufferTime += GetBufferLength(buffer);
if (checkError()) if (checkALError())
{ {
processed++; processed++;
cAudioSleep(1); cAudioSleep(1);
@ -288,7 +351,7 @@ namespace cAudio
alSourceQueueBuffers(Source, 1, &buffer); alSourceQueueBuffers(Source, 1, &buffer);
} }
if (checkError()) if (checkALError())
{ {
processed++; processed++;
cAudioSleep(1); cAudioSleep(1);
@ -301,7 +364,7 @@ namespace cAudio
ALenum state; ALenum state;
alGetSourcei(Source, AL_SOURCE_STATE, &state); alGetSourcei(Source, AL_SOURCE_STATE, &state);
checkError(); checkALError();
if(state == AL_STOPPED && oldState != state) if(state == AL_STOPPED && oldState != state)
{ {
//Resets the audio to the beginning //Resets the audio to the beginning
@ -314,69 +377,69 @@ namespace cAudio
return active; return active;
} }
const bool cAudioSource::isValid() const bool cAudioSource::isValid() const
{ {
return Valid; return Valid;
} }
const bool cAudioSource::isPlaying() const bool cAudioSourceBase::isPlaying() const
{ {
ALenum state = 0; ALenum state = 0;
alGetSourcei(Source, AL_SOURCE_STATE, &state); alGetSourcei(Source, AL_SOURCE_STATE, &state);
checkError(); checkALError();
return (state == AL_PLAYING); return (state == AL_PLAYING);
} }
const bool cAudioSource::isPaused() const bool cAudioSourceBase::isPaused() const
{ {
ALenum state = 0; ALenum state = 0;
alGetSourcei(Source, AL_SOURCE_STATE, &state); alGetSourcei(Source, AL_SOURCE_STATE, &state);
checkError(); checkALError();
return (state == AL_PAUSED); return (state == AL_PAUSED);
} }
const bool cAudioSource::isStopped() const bool cAudioSourceBase::isStopped() const
{ {
ALenum state = 0; ALenum state = 0;
alGetSourcei(Source, AL_SOURCE_STATE, &state); alGetSourcei(Source, AL_SOURCE_STATE, &state);
checkError(); checkALError();
return (state == AL_STOPPED); return (state == AL_STOPPED);
} }
const bool cAudioSource::isLooping() const bool cAudioSource::isLooping() const
{ {
return Loop; return Loop;
} }
void cAudioSource::setPosition(const cVector3& position) void cAudioSourceBase::setPosition(const cVector3& position)
{ {
cAudioMutexBasicLock lock(Mutex); cAudioMutexBasicLock lock(Mutex);
alSource3f(Source, AL_POSITION, position.x, position.y, position.z); alSource3f(Source, AL_POSITION, position.x, position.y, position.z);
checkError(); checkALError();
} }
void cAudioSource::setVelocity(const cVector3& velocity) void cAudioSourceBase::setVelocity(const cVector3& velocity)
{ {
cAudioMutexBasicLock lock(Mutex); cAudioMutexBasicLock lock(Mutex);
alSource3f(Source, AL_VELOCITY, velocity.x, velocity.y, velocity.z); alSource3f(Source, AL_VELOCITY, velocity.x, velocity.y, velocity.z);
checkError(); checkALError();
} }
void cAudioSource::setDirection(const cVector3& direction) void cAudioSourceBase::setDirection(const cVector3& direction)
{ {
cAudioMutexBasicLock lock(Mutex); cAudioMutexBasicLock lock(Mutex);
alSource3f(Source, AL_DIRECTION, direction.x, direction.y, direction.z); alSource3f(Source, AL_DIRECTION, direction.x, direction.y, direction.z);
checkError(); checkALError();
} }
void cAudioSource::setRolloffFactor(const float& rolloff) void cAudioSourceBase::setRolloffFactor(const float& rolloff)
{ {
cAudioMutexBasicLock lock(Mutex); cAudioMutexBasicLock lock(Mutex);
alSourcef(Source, AL_ROLLOFF_FACTOR, rolloff); alSourcef(Source, AL_ROLLOFF_FACTOR, rolloff);
checkError(); checkALError();
} }
void cAudioSource::setStrength(const float& soundstrength) void cAudioSourceBase::setStrength(const float& soundstrength)
{ {
float inverseStrength = 0.0f; float inverseStrength = 0.0f;
if(soundstrength > 0.0f) if(soundstrength > 0.0f)
@ -384,88 +447,88 @@ namespace cAudio
cAudioMutexBasicLock lock(Mutex); cAudioMutexBasicLock lock(Mutex);
alSourcef(Source, AL_ROLLOFF_FACTOR, inverseStrength); alSourcef(Source, AL_ROLLOFF_FACTOR, inverseStrength);
checkError(); checkALError();
} }
void cAudioSource::setMinDistance(const float& minDistance) void cAudioSourceBase::setMinDistance(const float& minDistance)
{ {
cAudioMutexBasicLock lock(Mutex); cAudioMutexBasicLock lock(Mutex);
alSourcef(Source, AL_REFERENCE_DISTANCE, minDistance); alSourcef(Source, AL_REFERENCE_DISTANCE, minDistance);
checkError(); checkALError();
} }
void cAudioSource::setMaxAttenuationDistance(const float& maxDistance) void cAudioSourceBase::setMaxAttenuationDistance(const float& maxDistance)
{ {
cAudioMutexBasicLock lock(Mutex); cAudioMutexBasicLock lock(Mutex);
alSourcef(Source, AL_MAX_DISTANCE, maxDistance); alSourcef(Source, AL_MAX_DISTANCE, maxDistance);
checkError(); checkALError();
} }
void cAudioSource::setPitch(const float& pitch) void cAudioSourceBase::setPitch(const float& pitch)
{ {
cAudioMutexBasicLock lock(Mutex); cAudioMutexBasicLock lock(Mutex);
alSourcef (Source, AL_PITCH, pitch); alSourcef (Source, AL_PITCH, pitch);
checkError(); checkALError();
} }
void cAudioSource::setVolume(const float& volume) void cAudioSourceBase::setVolume(const float& volume)
{ {
cAudioMutexBasicLock lock(Mutex); cAudioMutexBasicLock lock(Mutex);
Volume = volume; Volume = volume;
alSourcef(Source, AL_GAIN, Volume * Context->getAudioManager()->getMasterVolume()); alSourcef(Source, AL_GAIN, Volume * Context->getAudioManager()->getMasterVolume());
checkError(); checkALError();
} }
void cAudioSource::setMinVolume(const float& minVolume) void cAudioSourceBase::setMinVolume(const float& minVolume)
{ {
cAudioMutexBasicLock lock(Mutex); cAudioMutexBasicLock lock(Mutex);
alSourcef(Source, AL_MIN_GAIN, minVolume); alSourcef(Source, AL_MIN_GAIN, minVolume);
checkError(); checkALError();
} }
void cAudioSource::setMaxVolume(const float& maxVolume) void cAudioSourceBase::setMaxVolume(const float& maxVolume)
{ {
cAudioMutexBasicLock lock(Mutex); cAudioMutexBasicLock lock(Mutex);
alSourcef(Source, AL_MAX_GAIN, maxVolume); alSourcef(Source, AL_MAX_GAIN, maxVolume);
checkError(); checkALError();
} }
void cAudioSource::setInnerConeAngle(const float& innerAngle) void cAudioSourceBase::setInnerConeAngle(const float& innerAngle)
{ {
cAudioMutexBasicLock lock(Mutex); cAudioMutexBasicLock lock(Mutex);
alSourcef(Source, AL_CONE_INNER_ANGLE, innerAngle); alSourcef(Source, AL_CONE_INNER_ANGLE, innerAngle);
checkError(); checkALError();
} }
void cAudioSource::setOuterConeAngle(const float& outerAngle) void cAudioSourceBase::setOuterConeAngle(const float& outerAngle)
{ {
cAudioMutexBasicLock lock(Mutex); cAudioMutexBasicLock lock(Mutex);
alSourcef(Source, AL_CONE_OUTER_ANGLE, outerAngle); alSourcef(Source, AL_CONE_OUTER_ANGLE, outerAngle);
checkError(); checkALError();
} }
void cAudioSource::setOuterConeVolume(const float& outerVolume) void cAudioSourceBase::setOuterConeVolume(const float& outerVolume)
{ {
cAudioMutexBasicLock lock(Mutex); cAudioMutexBasicLock lock(Mutex);
alSourcef(Source, AL_CONE_OUTER_GAIN, outerVolume); alSourcef(Source, AL_CONE_OUTER_GAIN, outerVolume);
checkError(); checkALError();
} }
void cAudioSource::setDopplerStrength(const float& dstrength) void cAudioSourceBase::setDopplerStrength(const float& dstrength)
{ {
cAudioMutexBasicLock lock(Mutex); cAudioMutexBasicLock lock(Mutex);
alSourcef(Source, AL_DOPPLER_FACTOR, dstrength); alSourcef(Source, AL_DOPPLER_FACTOR, dstrength);
checkError(); checkALError();
} }
void cAudioSource::setDopplerVelocity(const cVector3& dvelocity) void cAudioSourceBase::setDopplerVelocity(const cVector3& dvelocity)
{ {
cAudioMutexBasicLock lock(Mutex); cAudioMutexBasicLock lock(Mutex);
alSource3f(Source, AL_DOPPLER_VELOCITY, dvelocity.x, dvelocity.y, dvelocity.z); alSource3f(Source, AL_DOPPLER_VELOCITY, dvelocity.x, dvelocity.y, dvelocity.z);
checkError(); checkALError();
} }
void cAudioSource::move(const cVector3& position) void cAudioSourceBase::move(const cVector3& position)
{ {
cAudioMutexBasicLock lock(Mutex); cAudioMutexBasicLock lock(Mutex);
cVector3 oldPos = getPosition(); cVector3 oldPos = getPosition();
@ -473,45 +536,45 @@ namespace cAudio
alSource3f(Source, AL_VELOCITY, velocity.x, velocity.y, velocity.z); alSource3f(Source, AL_VELOCITY, velocity.x, velocity.y, velocity.z);
alSource3f(Source, AL_POSITION, position.x, position.y, position.z); alSource3f(Source, AL_POSITION, position.x, position.y, position.z);
checkError(); checkALError();
} }
const cVector3 cAudioSource::getPosition() const cVector3 cAudioSourceBase::getPosition() const
{ {
cVector3 position; cVector3 position;
alGetSourcefv(Source, AL_POSITION, &position.x); alGetSourcefv(Source, AL_POSITION, &position.x);
checkError(); checkALError();
return position; return position;
} }
const cVector3 cAudioSource::getVelocity() const cVector3 cAudioSourceBase::getVelocity() const
{ {
cVector3 velocity; cVector3 velocity;
alGetSourcefv(Source, AL_VELOCITY, &velocity.x); alGetSourcefv(Source, AL_VELOCITY, &velocity.x);
return velocity; return velocity;
} }
const cVector3 cAudioSource::getDirection() const cVector3 cAudioSourceBase::getDirection() const
{ {
cVector3 direction; cVector3 direction;
alGetSourcefv(Source, AL_DIRECTION, &direction.x); alGetSourcefv(Source, AL_DIRECTION, &direction.x);
checkError(); checkALError();
return direction; return direction;
} }
const float cAudioSource::getRolloffFactor() const float cAudioSourceBase::getRolloffFactor() const
{ {
float value = 0.0f; float value = 0.0f;
alGetSourcef(Source, AL_ROLLOFF_FACTOR, &value); alGetSourcef(Source, AL_ROLLOFF_FACTOR, &value);
checkError(); checkALError();
return value; return value;
} }
const float cAudioSource::getStrength() const float cAudioSourceBase::getStrength() const
{ {
float value = 0.0f; float value = 0.0f;
alGetSourcef(Source, AL_ROLLOFF_FACTOR, &value); alGetSourcef(Source, AL_ROLLOFF_FACTOR, &value);
checkError(); checkALError();
float inverseStrength = 0.0f; float inverseStrength = 0.0f;
if(value > 0.0f) if(value > 0.0f)
@ -520,88 +583,116 @@ namespace cAudio
return inverseStrength; return inverseStrength;
} }
const float cAudioSource::getMinDistance() const float cAudioSourceBase::getMinDistance() const
{ {
float value = 0.0f; float value = 0.0f;
alGetSourcef(Source, AL_REFERENCE_DISTANCE, &value); alGetSourcef(Source, AL_REFERENCE_DISTANCE, &value);
checkError(); checkALError();
return value; return value;
} }
const float cAudioSource::getMaxDistance() const float cAudioSourceBase::getMaxDistance() const
{ {
float value = 0.0f; float value = 0.0f;
alGetSourcef(Source, AL_MAX_DISTANCE, &value); alGetSourcef(Source, AL_MAX_DISTANCE, &value);
checkError(); checkALError();
return value; return value;
} }
const float cAudioSource::getPitch() const bool cAudioSourceBase::isRelative() const
{
int relative = 0;
alGetSourcei(Source, AL_SOURCE_RELATIVE, &relative);
return relative;
}
float cAudioSourceBase::calculateGain() const
{
// OpenAL Inverse Distance Clamped Model
// distance = max(distance,AL_REFERENCE_DISTANCE);
// distance = min(distance,AL_MAX_DISTANCE);
// gain = AL_REFERENCE_DISTANCE / (AL_REFERENCE_DISTANCE +
// AL_ROLLOFF_FACTOR *
// (distance AL_REFERENCE_DISTANCE));
cVector3 lpos = Context->getAudioManager()->getListener()->getPosition();
cVector3 pos = getPosition();
float refDist = getMinDistance();
float dist = 0.f;
dist = isRelative() ? pos.length() : (pos - lpos).length();
dist = std::max(dist, refDist);
dist = std::min(dist, getMaxDistance());
float gain = refDist / (refDist + getRolloffFactor() * (dist - refDist));
return gain * getVolume();
}
float cAudioSourceBase::getPitch() const
{ {
float value = 0.0f; float value = 0.0f;
alGetSourcef(Source, AL_PITCH, &value); alGetSourcef(Source, AL_PITCH, &value);
checkError(); checkALError();
return value; return value;
} }
const float cAudioSource::getVolume() const float cAudioSourceBase::getVolume() const
{ {
return Volume; return Volume;
} }
const float cAudioSource::getMinVolume() const float cAudioSourceBase::getMinVolume() const
{ {
float value = 0.0f; float value = 0.0f;
alGetSourcef(Source, AL_MIN_GAIN, &value); alGetSourcef(Source, AL_MIN_GAIN, &value);
checkError(); checkALError();
return value; return value;
} }
const float cAudioSource::getMaxVolume() const float cAudioSourceBase::getMaxVolume() const
{ {
float value = 0.0f; float value = 0.0f;
alGetSourcef(Source, AL_MAX_GAIN, &value); alGetSourcef(Source, AL_MAX_GAIN, &value);
checkError(); checkALError();
return value; return value;
} }
const float cAudioSource::getInnerConeAngle() const float cAudioSourceBase::getInnerConeAngle() const
{ {
float value = 0.0f; float value = 0.0f;
alGetSourcef(Source, AL_CONE_INNER_ANGLE, &value); alGetSourcef(Source, AL_CONE_INNER_ANGLE, &value);
checkError(); checkALError();
return value; return value;
} }
const float cAudioSource::getOuterConeAngle() const float cAudioSourceBase::getOuterConeAngle() const
{ {
float value = 0.0f; float value = 0.0f;
alGetSourcef(Source, AL_CONE_OUTER_ANGLE, &value); alGetSourcef(Source, AL_CONE_OUTER_ANGLE, &value);
checkError(); checkALError();
return value; return value;
} }
const float cAudioSource::getOuterConeVolume() const float cAudioSourceBase::getOuterConeVolume() const
{ {
float value = 0.0f; float value = 0.0f;
alGetSourcef(Source, AL_CONE_OUTER_GAIN, &value); alGetSourcef(Source, AL_CONE_OUTER_GAIN, &value);
checkError(); checkALError();
return value; return value;
} }
const float cAudioSource::getDopplerStrength() const float cAudioSourceBase::getDopplerStrength() const
{ {
float value = 0.0f; float value = 0.0f;
alGetSourcef(Source, AL_DOPPLER_FACTOR, &value); alGetSourcef(Source, AL_DOPPLER_FACTOR, &value);
checkError(); checkALError();
return value; return value;
} }
const cVector3 cAudioSource::getDopplerVelocity() const cVector3 cAudioSourceBase::getDopplerVelocity() const
{ {
cVector3 velocity; cVector3 velocity;
alGetSourcefv(Source, AL_DOPPLER_VELOCITY, &velocity.x); alGetSourcefv(Source, AL_DOPPLER_VELOCITY, &velocity.x);
checkError(); checkALError();
return velocity; return velocity;
} }
@ -668,100 +759,70 @@ namespace cAudio
{ {
int queued = 0; int queued = 0;
alGetSourcei(Source, AL_BUFFERS_QUEUED, &queued); alGetSourcei(Source, AL_BUFFERS_QUEUED, &queued);
checkError(); checkALError();
while (queued--) while (queued--)
{ {
ALuint buffer; ALuint buffer;
alSourceUnqueueBuffers(Source, 1, &buffer); alSourceUnqueueBuffers(Source, 1, &buffer);
checkError(); checkALError();
} }
} }
bool cAudioSource::checkError() const
{
int error = alGetError();
if (error != AL_NO_ERROR)
{
const char* errorString = alGetString(error);
if(error == AL_OUT_OF_MEMORY)
getLogger()->logCritical("Audio Source", "OpenAL Error: %s.", errorString);
else
getLogger()->logError("Audio Source", "OpenAL Error: %s.", errorString);
return true;
}
return false;
}
bool cAudioSource::stream(ALuint buffer) bool cAudioSource::stream(ALuint buffer)
{ {
if(Decoder) if(!Decoder)
return false;
//stores the calculated data into buffer that is passed to output.
size_t totalread = 0;
unsigned int errorcount = 0;
char tempbuffer[CAUDIO_SOURCE_BUFFER_SIZE];
while( totalread < CAUDIO_SOURCE_BUFFER_SIZE )
{ {
//stores the calculated data into buffer that is passed to output. char tempbuffer2[CAUDIO_SOURCE_BUFFER_SIZE];
size_t totalread = 0; Mutex.unlock(); // this can take a long time
unsigned int errorcount = 0; int actualread = Decoder->readAudioData(tempbuffer2, CAUDIO_SOURCE_BUFFER_SIZE-totalread);
char tempbuffer[CAUDIO_SOURCE_BUFFER_SIZE]; Mutex.lock();
while( totalread < CAUDIO_SOURCE_BUFFER_SIZE )
{ if(actualread > 0)
char tempbuffer2[CAUDIO_SOURCE_BUFFER_SIZE]; {
int actualread = Decoder->readAudioData(tempbuffer2, CAUDIO_SOURCE_BUFFER_SIZE-totalread); memcpy(tempbuffer+totalread,tempbuffer2,actualread);
if(actualread > 0) totalread += actualread;
{ }
memcpy(tempbuffer+totalread,tempbuffer2,actualread); if(actualread < 0)
totalread += actualread; {
} ++errorcount;
if(actualread < 0) getLogger()->logDebug("Audio Source", "Decoder returned an error: %i (%i of 3)", actualread, errorcount);
{ if(errorcount >= 3)
++errorcount; {
getLogger()->logDebug("Audio Source", "Decoder returned an error: %i (%i of 3)", actualread, errorcount); stop();
if(errorcount >= 3) break;
{ }
stop(); }
break; if(actualread == 0)
} {
} if(isLooping())
if(actualread == 0) {
{ //If we are to loop, set to the beginning and reload from the start
if(isLooping()) Decoder->setPosition(0, false);
{ getLogger()->logDebug("Audio Source", "Buffer looping.");
//If we are to loop, set to the beginning and reload from the start }
Decoder->setPosition(0, false); else
getLogger()->logDebug("Audio Source", "Buffer looping."); break;
} }
else
break;
}
}
//Second check, in case looping is not enabled, we will return false for end of stream
if(totalread == 0)
{
return false;
}
getLogger()->logDebug("Audio Source", "Buffered %i bytes of data into buffer %i at %i hz.", totalread, buffer, Decoder->getFrequency());
alBufferData(buffer, convertAudioFormatEnum(Decoder->getFormat()), tempbuffer, totalread, Decoder->getFrequency());
checkError();
return true;
} }
return false;
}
ALenum cAudioSource::convertAudioFormatEnum(AudioFormats format) //Second check, in case looping is not enabled, we will return false for end of stream
{ if(totalread == 0)
switch(format) {
{ return false;
case EAF_8BIT_MONO: }
return AL_FORMAT_MONO8; getLogger()->logDebug("Audio Source", "Buffered %i bytes of data into buffer %i at %i hz.", totalread, buffer, Decoder->getFrequency());
case EAF_16BIT_MONO: alBufferData(buffer, convertAudioFormatEnum(Decoder->getFormat()), tempbuffer, totalread, Decoder->getFrequency());
return AL_FORMAT_MONO16; checkALError();
case EAF_8BIT_STEREO: return true;
return AL_FORMAT_STEREO8; }
case EAF_16BIT_STEREO:
return AL_FORMAT_STEREO16;
default:
return AL_FORMAT_MONO8;
};
}
#if CAUDIO_EFX_ENABLED == 1 #if CAUDIO_EFX_ENABLED == 1
void cAudioSource::updateFilter(bool remove) void cAudioSource::updateFilter(bool remove)
@ -777,7 +838,7 @@ namespace cAudio
if(theFilter) if(theFilter)
{ {
alSourcei(Source, AL_DIRECT_FILTER, theFilter->getOpenALFilter()); alSourcei(Source, AL_DIRECT_FILTER, theFilter->getOpenALFilter());
checkError(); checkALError();
return; return;
} }
} }
@ -785,7 +846,7 @@ namespace cAudio
} }
} }
alSourcei(Source, AL_DIRECT_FILTER, AL_FILTER_NULL); alSourcei(Source, AL_DIRECT_FILTER, AL_FILTER_NULL);
checkError(); checkALError();
} }
void cAudioSource::updateEffect(unsigned int slot, bool remove) void cAudioSource::updateEffect(unsigned int slot, bool remove)
@ -809,7 +870,7 @@ namespace cAudio
filterID = theFilter->getOpenALFilter(); filterID = theFilter->getOpenALFilter();
} }
alSource3i(Source, AL_AUXILIARY_SEND_FILTER, theEffect->getOpenALEffectSlot(), slot, filterID); alSource3i(Source, AL_AUXILIARY_SEND_FILTER, theEffect->getOpenALEffectSlot(), slot, filterID);
checkError(); checkALError();
return; return;
} }
} }
@ -817,12 +878,12 @@ namespace cAudio
} }
} }
alSource3i(Source, AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, slot, AL_FILTER_NULL); alSource3i(Source, AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, slot, AL_FILTER_NULL);
checkError(); checkALError();
} }
} }
#endif #endif
void cAudioSource::registerEventHandler(ISourceEventHandler* handler) void cAudioSourceBase::registerEventHandler(ISourceEventHandler* handler)
{ {
if(handler) if(handler)
{ {
@ -831,71 +892,51 @@ namespace cAudio
} }
} }
void cAudioSource::unRegisterEventHandler(ISourceEventHandler* handler) void cAudioSourceBase::unRegisterEventHandler(ISourceEventHandler* handler)
{ {
if(handler) if(handler)
{ {
cAudioMutexBasicLock lock(Mutex); cAudioMutexBasicLock lock(Mutex);
eventHandlerList.remove(handler); for(int i=0; i<eventHandlerList.size(); i++) {
if(eventHandlerList[i] == handler)
eventHandlerList.erase(eventHandlerList.begin() + i);
}
} }
} }
void cAudioSource::unRegisterAllEventHandlers() void cAudioSourceBase::unRegisterAllEventHandlers()
{ {
cAudioMutexBasicLock lock(Mutex); cAudioMutexBasicLock lock(Mutex);
eventHandlerList.clear(); eventHandlerList.clear();
} }
void cAudioSource::signalEvent(Events sevent) void cAudioSourceBase::signalEvent(Events sevent)
{ {
cAudioMutexBasicLock lock(Mutex); cAudioMutexBasicLock lock(Mutex);
cAudioList<ISourceEventHandler*>::Type::iterator it = eventHandlerList.begin(); if(eventHandlerList.empty())
return;
if(it != eventHandlerList.end()){ size_t size = eventHandlerList.size();
switch(sevent){ for(int i=0; i<size; )
{
ISourceEventHandler *handler = eventHandlerList[i];
case ON_UPDATE: switch(sevent)
{
for( ; it != eventHandlerList.end(); it++){ case ON_UPDATE: handler->onUpdate(); break;
(*it)->onUpdate(); case ON_RELEASE: handler->onRelease(); break;
} case ON_PLAY: handler->onPlay(); break;
case ON_PAUSE: handler->onPause(); break;
break; case ON_STOP: handler->onStop(); break;
}
case ON_RELEASE:
// handler may have unregistered itself
for( ; it != eventHandlerList.end(); it++){ if(size == eventHandlerList.size()) {
(*it)->onRelease(); i++;
} } else {
size = eventHandlerList.size();
break; }
}
case ON_PLAY: }
for( ; it != eventHandlerList.end(); it++){
(*it)->onPlay();
}
break;
case ON_PAUSE:
for( ; it != eventHandlerList.end(); it++){
(*it)->onPause();
}
break;
case ON_STOP:
for( ; it != eventHandlerList.end(); it++){
(*it)->onStop();
}
break;
}
}
}
} }

View File

@ -11,8 +11,8 @@ namespace cAudio
{ {
bool cConsoleLogReceiver::OnLogMessage(const char* sender, const char* message, LogLevel level, float time) bool cConsoleLogReceiver::OnLogMessage(const char* sender, const char* message, LogLevel level, float time)
{ {
//std::cout << time << " " << sender << ": [" << LogLevelStrings[level] << "] " << message << std::endl; std::cout << sender << ": " << message << std::endl;
std::cout << "[" << LogLevelStrings[level] << "] " << message << std::endl; //std::cout << "[" << LogLevelStrings[level] << "] " << message << std::endl;
return true; return true;
} }
}; };

View File

@ -17,7 +17,7 @@ cFileSource::cFileSource(const char* filename) : pFile(NULL), Valid(false), File
cAudioString safeFilename = fromUTF8(filename); cAudioString safeFilename = fromUTF8(filename);
if(safeFilename.length() != 0) if(safeFilename.length() != 0)
{ {
pFile = fopen(toUTF8(safeFilename),"rb"); pFile = cfopen(safeFilename, "rb");
if(pFile) if(pFile)
Valid = true; Valid = true;
} }

View File

@ -1,10 +1,10 @@
// Copyright (c) 2008-2011 Raynaldo (Wildicv) Rivera, Joshua (Dark_Kilauea) Jones, Murat (wolfmanfx) Sari // Copyright (c) 2008-2011 Raynaldo (Wildicv) Rivera, Joshua (Dark_Kilauea) Jones, Murat (wolfmanfx) Sari
// This file is part of the "cAudio Engine" // This file is part of the "cAudio Engine"
// For conditions of distribution and use, see copyright notice in cAudio.h // For conditions of distribution and use, see copyright notice in cAudio.h
#include "cListener.h" #include "cListener.h"
#include "cEFXFunctions.h" #include "cEFXFunctions.h"
#include <al.h> #include "cOpenALUtil.h"
namespace cAudio namespace cAudio
{ {
@ -13,6 +13,7 @@ namespace cAudio
cAudioMutexBasicLock lock(Mutex); cAudioMutexBasicLock lock(Mutex);
Position = pos; Position = pos;
alListener3f(AL_POSITION, Position.x, Position.y, Position.z); alListener3f(AL_POSITION, Position.x, Position.y, Position.z);
checkALError();
} }
void cListener::setDirection(const cVector3& dir) void cListener::setDirection(const cVector3& dir)
{ {
@ -20,6 +21,7 @@ namespace cAudio
Direction = dir; Direction = dir;
float orient[6] = {Direction[0], Direction[1], Direction[2], UpVector[0], UpVector[1], UpVector[2]}; float orient[6] = {Direction[0], Direction[1], Direction[2], UpVector[0], UpVector[1], UpVector[2]};
alListenerfv(AL_ORIENTATION, orient); alListenerfv(AL_ORIENTATION, orient);
checkALError();
} }
void cListener::setUpVector(const cVector3& up) void cListener::setUpVector(const cVector3& up)
{ {
@ -27,18 +29,21 @@ namespace cAudio
UpVector = up; UpVector = up;
float orient[6] = {Direction[0], Direction[1], Direction[2], UpVector[0], UpVector[1], UpVector[2]}; float orient[6] = {Direction[0], Direction[1], Direction[2], UpVector[0], UpVector[1], UpVector[2]};
alListenerfv(AL_ORIENTATION, orient); alListenerfv(AL_ORIENTATION, orient);
checkALError();
} }
void cListener::setVelocity(const cVector3& vel) void cListener::setVelocity(const cVector3& vel)
{ {
cAudioMutexBasicLock lock(Mutex); cAudioMutexBasicLock lock(Mutex);
Velocity = vel; Velocity = vel;
alListener3f(AL_VELOCITY, Velocity.x, Velocity.y, Velocity.z); alListener3f(AL_VELOCITY, Velocity.x, Velocity.y, Velocity.z);
checkALError();
} }
void cListener::setMasterVolume(const float& volume) void cListener::setMasterVolume(const float& volume)
{ {
cAudioMutexBasicLock lock(Mutex); cAudioMutexBasicLock lock(Mutex);
MasterGain = volume; MasterGain = volume;
alListenerf(AL_GAIN, MasterGain); alListenerf(AL_GAIN, MasterGain);
checkALError();
} }
void cListener::move(const cVector3& pos) void cListener::move(const cVector3& pos)
{ {
@ -48,12 +53,14 @@ namespace cAudio
alListener3f(AL_POSITION, Position.x, Position.y, Position.z); alListener3f(AL_POSITION, Position.x, Position.y, Position.z);
alListener3f(AL_VELOCITY, Velocity.x, Velocity.y, Velocity.z); alListener3f(AL_VELOCITY, Velocity.x, Velocity.y, Velocity.z);
checkALError();
} }
#if CAUDIO_EFX_ENABLED == 1 #if CAUDIO_EFX_ENABLED == 1
void cListener::setMetersPerUnit(const float& meters) void cListener::setMetersPerUnit(const float& meters)
{ {
cAudioMutexBasicLock lock(Mutex); cAudioMutexBasicLock lock(Mutex);
alListenerf(AL_METERS_PER_UNIT, meters); alListenerf(AL_METERS_PER_UNIT, meters);
checkALError();
} }
float cListener::getMetersPerUnit(void) const float cListener::getMetersPerUnit(void) const
@ -63,4 +70,4 @@ namespace cAudio
return value; return value;
} }
#endif #endif
}; };

View File

@ -1,5 +1,5 @@
// Copyright (c) 2008-2011 Raynaldo (Wildicv) Rivera, Joshua (Dark_Kilauea) Jones, Murat (wolfmanfx) Sari // Copyright (c) 2008-2011 Raynaldo (Wildicv) Rivera, Joshua (Dark_Kilauea) Jones, Murat (wolfmanfx) Sari
// This file is part of the "cAudio Engine" // This file is part of the "cAudio Engine"
// For conditions of distribution and use, see copyright notice in cAudio.h // For conditions of distribution and use, see copyright notice in cAudio.h
#include "cMutex.h" #include "cMutex.h"
@ -30,7 +30,7 @@ namespace cAudio
#ifdef CAUDIO_PLATFORM_WIN #ifdef CAUDIO_PLATFORM_WIN
EnterCriticalSection(&criticalSection); EnterCriticalSection(&criticalSection);
#else #else
int error = pthread_mutex_lock(&Mutex); pthread_mutex_lock(&Mutex);
#endif #endif
} }
@ -41,7 +41,7 @@ namespace cAudio
#ifdef CAUDIO_PLATFORM_WIN #ifdef CAUDIO_PLATFORM_WIN
LeaveCriticalSection(&criticalSection); LeaveCriticalSection(&criticalSection);
#else #else
int error = pthread_mutex_unlock(&Mutex); pthread_mutex_unlock(&Mutex);
#endif #endif
} }
@ -51,10 +51,10 @@ namespace cAudio
InitializeCriticalSection(&criticalSection); InitializeCriticalSection(&criticalSection);
#else #else
pthread_mutexattr_t attr; pthread_mutexattr_t attr;
int error = pthread_mutexattr_init(&attr); pthread_mutexattr_init(&attr);
error = pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE); pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE);
error = pthread_mutex_init(&Mutex, &attr); pthread_mutex_init(&Mutex, &attr);
error = pthread_mutexattr_destroy(&attr); pthread_mutexattr_destroy(&attr);
#endif #endif
Initialized=true; Initialized=true;
} }

View File

@ -136,7 +136,7 @@ namespace cAudio
{ {
if(relative) if(relative)
{ {
float curtime = ov_time_tell(&oggStream); double curtime = ov_time_tell(&oggStream);
return (ov_time_seek(&oggStream,curtime+seconds)==0); return (ov_time_seek(&oggStream,curtime+seconds)==0);
} }
else else
@ -153,7 +153,8 @@ namespace cAudio
int cOggDecoder::getTotalSize() int cOggDecoder::getTotalSize()
{ {
return ov_pcm_total(&oggStream, -1) * vorbisInfo->channels; // ov_pcm_total is in samples
return ov_pcm_total(&oggStream, -1) * vorbisInfo->channels * 2;
} }
int cOggDecoder::getCompressedSize() int cOggDecoder::getCompressedSize()
@ -168,7 +169,8 @@ namespace cAudio
int cOggDecoder::getCurrentPosition() int cOggDecoder::getCurrentPosition()
{ {
return ov_pcm_tell(&oggStream) * vorbisInfo->channels; // ov_pcm_tell is in samples
return ov_pcm_tell(&oggStream) * vorbisInfo->channels * 2;
} }
int cOggDecoder::getCurrentCompressedPosition() int cOggDecoder::getCurrentCompressedPosition()

View File

@ -2,11 +2,8 @@
// This file is part of the "cAudio Engine" // This file is part of the "cAudio Engine"
// For conditions of distribution and use, see copyright notice in cAudio.h // For conditions of distribution and use, see copyright notice in cAudio.h
#pragma once
#include "cOpenALAudioDeviceList.h" #include "cOpenALAudioDeviceList.h"
#include <al.h> #include "cOpenALUtil.h"
#include <alc.h>
namespace cAudio namespace cAudio
{ {
@ -23,12 +20,15 @@ namespace cAudio
} }
else else
{ {
#if ALC_ENUMERATE_ALL_EXT
if( alcIsExtensionPresent(NULL, "ALC_ENUMERATE_ALL_EXT") == AL_TRUE ) if( alcIsExtensionPresent(NULL, "ALC_ENUMERATE_ALL_EXT") == AL_TRUE )
{ {
specifier = ALC_ALL_DEVICES_SPECIFIER; specifier = ALC_ALL_DEVICES_SPECIFIER;
defaultDevice = ALC_DEFAULT_ALL_DEVICES_SPECIFIER; defaultDevice = ALC_DEFAULT_ALL_DEVICES_SPECIFIER;
} }
else if( alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT") == AL_TRUE ) else
#endif
if( alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT") == AL_TRUE )
{ {
specifier = ALC_DEVICE_SPECIFIER; specifier = ALC_DEVICE_SPECIFIER;
defaultDevice = ALC_DEFAULT_DEVICE_SPECIFIER; defaultDevice = ALC_DEFAULT_DEVICE_SPECIFIER;
@ -87,4 +87,4 @@ namespace cAudio
} }
return AvailableDevices.size() > 0; return AvailableDevices.size() > 0;
} }
} }

View File

@ -84,9 +84,9 @@ namespace cAudio
return false; return false;
} }
getLogger()->logInfo("AudioManager", "OpenAL Version: %s", alGetString(AL_VERSION)); getLogger()->logWarning("AudioManager", "OpenAL Version: %s", alGetString(AL_VERSION));
getLogger()->logInfo("AudioManager", "Vendor: %s", alGetString(AL_VENDOR)); getLogger()->logWarning("AudioManager", "Vendor: %s", alGetString(AL_VENDOR));
getLogger()->logInfo("AudioManager", "Renderer: %s", alGetString(AL_RENDERER)); getLogger()->logWarning("AudioManager", "Renderer: %s", alGetString(AL_RENDERER));
#if CAUDIO_EFX_ENABLED == 1 #if CAUDIO_EFX_ENABLED == 1
initEffects.getEFXInterface()->Mutex.lock(); initEffects.getEFXInterface()->Mutex.lock();
@ -108,7 +108,8 @@ namespace cAudio
getLogger()->logWarning("AudioManager", "EFX is not supported, EFX disabled."); getLogger()->logWarning("AudioManager", "EFX is not supported, EFX disabled.");
} }
#endif #endif
getLogger()->logInfo("AudioManager", "Supported Extensions: %s", alGetString(AL_EXTENSIONS)); getLogger()->logWarning("AudioManager", "Supported Extensions: %s", alGetString(AL_EXTENSIONS));
Initialized = true;
return true; return true;
} }
@ -124,8 +125,8 @@ namespace cAudio
alcDestroyContext(Context); alcDestroyContext(Context);
Context = NULL; Context = NULL;
//Close the device //Close the device
alcCloseDevice(Device); if (!alcCloseDevice(Device))
checkError(); getLogger()->logError("AudioManager", "alcCloseDevice failed");
Device = NULL; Device = NULL;
Initialized = false; Initialized = false;
@ -169,16 +170,16 @@ namespace cAudio
return true; return true;
} }
if(Device) //if(Device)
{ {
error = alcGetError(Device); error = alcGetError(Device);
if (error != AL_NO_ERROR) if (error != AL_NO_ERROR)
{ {
errorString = alGetString(error); errorString = alcGetString(Device, error);
getLogger()->logError("AudioManager", "OpenAL Error: %s.", errorString); getLogger()->logError("AudioManager", "OpenAL Error: %s.", errorString);
return true; return true;
} }
} }
return false; return false;
} }
} }

View File

@ -13,8 +13,6 @@ namespace cAudio
cAudioThread::~cAudioThread() cAudioThread::~cAudioThread()
{ {
if(IsInit)
shutdown();
} }
bool cAudioThread::start() bool cAudioThread::start()
@ -28,8 +26,6 @@ namespace cAudio
#ifdef CAUDIO_PLATFORM_WIN #ifdef CAUDIO_PLATFORM_WIN
ThreadHandle = reinterpret_cast<HANDLE>(_beginthreadex(0, 0, threadFunc, this, 0, &ThreadID)); ThreadHandle = reinterpret_cast<HANDLE>(_beginthreadex(0, 0, threadFunc, this, 0, &ThreadID));
if(ThreadHandle == 0)
CloseHandle( ThreadHandle );
#else #else
pthread_create( &ThreadHandle, 0, threadFunc, this ); pthread_create( &ThreadHandle, 0, threadFunc, this );
#endif #endif
@ -79,9 +75,43 @@ namespace cAudio
} }
#ifdef CAUDIO_PLATFORM_WIN #ifdef CAUDIO_PLATFORM_WIN
//
// Usage: SetThreadName (-1, "MainThread");
//
const DWORD MS_VC_EXCEPTION = 0x406D1388;
#pragma pack(push,8)
typedef struct tagTHREADNAME_INFO
{
DWORD dwType; // Must be 0x1000.
LPCSTR szName; // Pointer to name (in user addr space).
DWORD dwThreadID; // Thread ID (-1=caller thread).
DWORD dwFlags; // Reserved for future use, must be zero.
} THREADNAME_INFO;
#pragma pack(pop)
inline void SetThreadName(DWORD dwThreadID, const char* threadName)
{
THREADNAME_INFO info;
info.dwType = 0x1000;
info.szName = threadName;
info.dwThreadID = dwThreadID;
info.dwFlags = 0;
__try
{
RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR*)&info);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
}
}
unsigned int __stdcall cAudioThread::threadFunc(void *args) unsigned int __stdcall cAudioThread::threadFunc(void *args)
{ {
cAudioThread* pThread = reinterpret_cast<cAudioThread*>(args); cAudioThread* pThread = reinterpret_cast<cAudioThread*>(args);
SetThreadName(GetCurrentThreadId(), "cAudio");
pThread->updateLoop(); pThread->updateLoop();
return 0; return 0;
} }
@ -89,8 +119,13 @@ namespace cAudio
void* cAudioThread::threadFunc(void* args) void* cAudioThread::threadFunc(void* args)
{ {
cAudioThread* pThread = reinterpret_cast<cAudioThread*>(args); cAudioThread* pThread = reinterpret_cast<cAudioThread*>(args);
#if defined(CAUDIO_PLATFORM_MAC) || defined(CAUDIO_PLATFORM_IPHONE)
pthread_setname_np("cAudio");
#else
pthread_setname_np(pthread_self(), "cAudio");
#endif
pThread->updateLoop(); pThread->updateLoop();
return 0; return 0;
} }
#endif #endif
}; };

View File

@ -19,7 +19,6 @@ namespace cAudio
char ident[4]; char ident[4];
int tempint32 = 0; int tempint32 = 0;
short tempint16 = 0; short tempint16 = 0;
char tempint8 = 0;
unsigned int startOffset = 0; unsigned int startOffset = 0;
@ -192,7 +191,7 @@ namespace cAudio
bool cWavDecoder::seek(float seconds,bool relative) bool cWavDecoder::seek(float seconds,bool relative)
{ {
int amountToSeek = seconds * (float)SampleRate * (float)Channels * (float)(BitsPerSample/8); int amountToSeek = (int) (seconds * (float)SampleRate * (float)Channels * (float)(BitsPerSample/8));
return setPosition(amountToSeek, relative); return setPosition(amountToSeek, relative);
} }