diff --git a/Examples/Tutorial4_AudioCapture/Tutorial4_AudioCapture.vcproj b/Examples/Tutorial4_AudioCapture/Tutorial4_AudioCapture.vcproj
new file mode 100644
index 0000000..6c10792
--- /dev/null
+++ b/Examples/Tutorial4_AudioCapture/Tutorial4_AudioCapture.vcproj
@@ -0,0 +1,186 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Examples/Tutorial4_AudioCapture/main.cpp b/Examples/Tutorial4_AudioCapture/main.cpp
new file mode 100644
index 0000000..7d190fb
--- /dev/null
+++ b/Examples/Tutorial4_AudioCapture/main.cpp
@@ -0,0 +1,103 @@
+#include
+#include
+//Include IAudioManager so we can easily work with cAudio
+#include "../../include/IAudioManager.h"
+//Include IAudio so we can create cAudio objects
+#include "../../include/IAudio.h"
+
+using namespace std;
+
+#define CAPTURE_FREQUENCY 22050
+#define CAPTURE_DURATION 10
+#define CAPTURE_FORMAT cAudio::EAF_16BIT_MONO
+
+int main(int argc, char* argv[])
+{
+ //To make visual studio happy
+ cAudio::IAudio* mysound = NULL;
+
+ //Some fancy text
+ cout << "cAudio 1.7.1 Tutorial 4: Capturing Audio \n \n";
+
+ std::string formatName;
+
+ if(CAPTURE_FORMAT == cAudio::EAF_8BIT_MONO)
+ formatName = "8 Bit Mono";
+ else if(CAPTURE_FORMAT == cAudio::EAF_8BIT_STEREO)
+ formatName = "8 Bit Stereo";
+ else if(CAPTURE_FORMAT == cAudio::EAF_16BIT_MONO)
+ formatName = "16 Bit Mono";
+ else
+ formatName = "16 Bit Stereo";
+
+ //Grap the cAudioManager
+ cAudio::IAudioManager* manager = cAudio::getAudioManager();
+ //Init the cAudio Engine
+ manager->init(argc,argv);
+
+ //! The capture interface should be grabbed after the manager has been initialized
+ cAudio::IAudioCapture* capture = manager->getAudioCapture();
+ bool captureReady = false;
+ cout << "Capturing Supported: " << std::boolalpha << capture->isSupported() << "\n";
+ if(capture->isSupported())
+ {
+ captureReady = capture->initialize(CAPTURE_FREQUENCY, CAPTURE_FORMAT);
+ cout << "Ready to capture audio: " << std::boolalpha << captureReady << "\n \n";
+
+ //Quick math to figure out how large our data should be for the duration of the record time
+ const int targetRecordSize = CAPTURE_FREQUENCY * CAPTURE_DURATION * capture->getSampleSize();
+ cout << "Capture Frequency: " << CAPTURE_FREQUENCY << "\n";
+ cout << "Capture Duration: " << CAPTURE_DURATION << "\n";
+ cout << "Capture Format: " << formatName << "\n";
+ cout << "Sample Size: " << capture->getSampleSize() << "\n";
+ cout << "Total size of audio: " << targetRecordSize << "\n";
+
+ cout << std::endl;
+
+ int currentsize = 0;
+ cout << "Starting capture... \n";
+ if(capture->beginCapture())
+ {
+ while(currentsize < targetRecordSize)
+ {
+ currentsize = capture->getCurrentCapturedAudioSize();
+ //Run the main update loop to keep audio data flowing in
+ manager->update();
+ }
+ }
+ capture->stopCapture();
+ cout << "Capture stopped... \n \n";
+
+ char* buffer = new char[currentsize];
+ capture->getCapturedAudio(buffer, currentsize);
+
+ //Create a IAudio object and load a sound from a file
+ mysound = manager->createFromRaw("sound1", buffer, currentsize, CAPTURE_FREQUENCY, CAPTURE_FORMAT);
+
+ delete buffer;
+
+ if(mysound)
+ {
+ cout << "Playing back captured audio... \n \n";
+ mysound->setVolume(1.0);
+ //Set the IAudio Sound to play2d and loop
+ mysound->play2d(false);
+
+ while(mysound->playing())
+ {
+ //Playback sound
+ manager->update();
+ }
+ }
+ }
+
+ //Delete all IAudio sounds
+ manager->release();
+ //Shutdown cAudio
+ manager->shutDown();
+
+ std::cout << "Press any key to quit \n";
+ std::cin.get();
+
+ return 0;
+}
diff --git a/Headers/cAudio.h b/Headers/cAudio.h
index 165f52f..9cfa62f 100644
--- a/Headers/cAudio.h
+++ b/Headers/cAudio.h
@@ -19,11 +19,12 @@ namespace cAudio
void play2d(bool loop = false);
//!plays the audio file and sets it to 3d
void play3d(bool loop = false, float x = 0.0, float y = 0.0, float z = 0.0, float soundstr = 1.0);
+
//!allows us to set the position or reset the position
void setPosition(float posx,float posy,float posz);
//!allows you to set the audio objects velocity
void setVelocity(float velx,float vely,float velz);
- //!allows us to set the direction the audio should play in / move
+ //!allows us to set the direction the audio should play in
void setDirection(float dirx,float diry,float dirz);
//! Sets the audios pitch level
void setPitch(float pitch);
@@ -35,6 +36,7 @@ namespace cAudio
void setDopplerStrength(float doop);
//!Set doppler velocity
void setDopplerVelocity(float doopx,float doopy,float doopz);
+
//!Seek the audio stream
void seek(float secs);
//!release the file handle
diff --git a/Headers/cAudioCapture.h b/Headers/cAudioCapture.h
new file mode 100644
index 0000000..d639024
--- /dev/null
+++ b/Headers/cAudioCapture.h
@@ -0,0 +1,93 @@
+#ifndef CAUDIOCAPTURE_H
+#define CAUDIOCAPTURE_H
+
+#include "../include/IAudioCapture.h"
+#include
+#include
+#include
+
+namespace cAudio
+{
+ class cAudioCapture : public IAudioCapture
+ {
+ public:
+ cAudioCapture();
+ ~cAudioCapture();
+
+ //! Checks to see if capturing audio is supported by OpenAL
+ //! Normally run automatically by cAudioManager::init()
+ bool checkCaptureExtension();
+
+ //! Grabs samples from the OpenAL buffer into the capture buffer. Should be run once every audio frame.
+ //! Normally run automatically by cAudioManager::update()
+ void updateCaptureBuffer(bool force = false);
+
+ //! Shuts down the capture device
+ //! Normally run automatically by cAudioManager::shutDown()
+ void shutdown();
+
+ //! Initializes the capture device to the selected settings
+ /** Note that calling this will cause the capture device to be reinitialized. Calling while in use may lead to a loss of audio data.
+ \param frequency: Frequency that the captured audio will be at
+ \param format: Format of the captured audio
+ \param internalBufferSize: Size of the internal OpenAL buffer used to store the captured audio until the next IAudioManager::update() in bytes
+ \return True on success, False if the capture device failed to initialize.
+ */
+ virtual bool initialize(unsigned int frequency = 22050, AudioFormats format = EAF_16BIT_MONO, unsigned int internalBufferSize = 8192);
+ //! Returns true if the current OpenAL implementation supports capturing audio
+ virtual bool isSupported() { return Supported; }
+ //! Returns true if the capture device is ready to be used. False may indicate an error with the current settings.
+ virtual bool isReady() { return Ready; }
+
+ //! Returns the frequency that the captured audio will be at
+ virtual unsigned int getFrequency() { return Frequency; }
+ //! Returns the format of the captured audio
+ virtual AudioFormats getFormat() { return Format; }
+ //! Returns the internal OpenAL buffer size in bytes
+ virtual unsigned int getInternalBufferSize() { return InternalBufferSize; }
+ //! Returns the size of a "sample" of audio data. Useful for making sure you grab audio data at sample boundaries
+ virtual unsigned int getSampleSize() { return SampleSize; }
+
+ //! Sets the frequency that the captured audio will be at. Will cause the capture device to be reinitialized. Calling while in use may lead to a loss of audio data.
+ /** \return True on success, False if the capture device failed to initialize. */
+ virtual bool setFrequency(unsigned int frequency);
+ //! Sets the format that the captured audio will be at. Will cause the capture device to be reinitialized. Calling while in use may lead to a loss of audio data.
+ /** \return True on success, False if the capture device failed to initialize. */
+ virtual bool setFormat(AudioFormats format);
+ //! Sets the internal buffer size that OpenAL will use to store captured audio between calls to IAudioManager::update() in bytes. Will cause the capture device to be reinitialized. Calling while in use may lead to a loss of audio data.
+ /** \return True on success, False if the capture device failed to initialize. */
+ virtual bool setInternalBufferSize(unsigned int internalBufferSize);
+
+ //! Starts capturing audio data to an internal buffer. Will clear any old data in the buffer.
+ /** \return True if capture was successfully started. */
+ virtual bool beginCapture();
+ //! Stops capturing audio data to an internal buffer. Will copy any remaining audio data to the capture buffer.
+ virtual void stopCapture();
+ //! Allows access to the audio data in the internal capture buffer
+ /** Can be called at any time to retrieve recorded audio. It is recommended that you call it every so often to prevent the internal buffer from growing too large.
+ Once successfully retrieved, the captured audio will be deleted from the internal buffer.
+ \param outputBuffer: Pointer to an output array to copy audio data to.
+ \param outputBufferSize: Size of the output array in bytes
+ */
+ virtual void getCapturedAudio(void* outputBuffer, unsigned int outputBufferSize);
+
+ //! Returns the current size of the internal audio buffer in bytes
+ virtual unsigned int getCurrentCapturedAudioSize();
+ protected:
+ bool initOpenALDevice();
+ void shutdownOpenALDevice();
+
+ unsigned int Frequency;
+ AudioFormats Format;
+ unsigned int InternalBufferSize;
+ std::vector CaptureBuffer;
+ bool Supported;
+ bool Ready;
+ bool Capturing;
+ int SampleSize;
+
+ ALCdevice* CaptureDevice;
+ };
+};
+
+#endif //! CAUDIOCAPTURE_H
\ No newline at end of file
diff --git a/Headers/cAudioManager.h b/Headers/cAudioManager.h
index f0fdd8a..ad8b158 100644
--- a/Headers/cAudioManager.h
+++ b/Headers/cAudioManager.h
@@ -6,6 +6,7 @@
#include "cAudio.h"
#include "../include/IAudioDecoderFactory.h"
#include "cListener.h"
+#include "cAudioCapture.h"
#include "../include/IAudioManager.h"
namespace cAudio
@@ -16,27 +17,40 @@ namespace cAudio
{
public:
//!Inits the audio manager calling the alut/etc start ups
- void init(int argc,char* argv[]);
+ virtual void init(int argc,char* argv[]);
//!Shuts everything down
- void shutDown();
+ virtual void shutDown();
//!Creates the cAudio object
- IAudio* createFromFile(const std::string& identifier,const std::string& file,bool stream = false);
+ virtual IAudio* createFromFile(const std::string& identifier,const std::string& file,bool stream = false);
//!Loads ogg from memory or virtual file system
- IAudio* createFromMemory(const std::string& identifier, const char* data, size_t length, std::string ext);
+ virtual IAudio* createFromMemory(const std::string& identifier, const char* data, size_t length, std::string ext);
+ //!Loads raw audio from memory.
+ virtual IAudio* createFromRaw(const std::string& identifier,const char* data, size_t length, unsigned int frequency, AudioFormats format);
+
//!Register Audio Codec
- void registerAudioDecoder(IAudioDecoderFactory* factory, std::string extension);
+ virtual bool registerAudioDecoder(IAudioDecoderFactory* factory, std::string extension);
+ //!Unregister Audio Codec (allows you to prevent an file type from being playable with new sound sources)
+ //!Note that all current sound sources will still continue to use any currently allocated decoders.
+ //!Will delete the factory instance
+ virtual void unRegisterAudioDecoder(std::string extension);
+ //!Returns whether an audio decoder is currently registered for this file type
+ virtual bool isAudioDecoderRegistered(std::string extension);
+ //!Returns a registered audio decoder factory
+ virtual IAudioDecoderFactory* getAudioDecoderFactory(std::string extension);
+
//!Allows you to set the listener position (DEPRECIATED! USE getListener() INSTEAD!)
- void setListenerPos(float x,float y,float z);
+ virtual void setListenerPos(float x,float y,float z);
//!Set Listener Orientation (DEPRECIATED! USE getListener() INSTEAD!)
- void setListenerOrientation(float ux,float uy,float uz);
+ virtual void setListenerOrientation(float ux,float uy,float uz);
//!Updates the cAudio playback
- void update();
+ virtual void update();
//!Gets you the cAudio object you want
- IAudio *getSound(std::string identifier);
+ virtual IAudio *getSound(std::string identifier);
//!Releases "ALL" cAudio objects
- void release();
+ virtual void release();
virtual IListener* getListener() { return &initlistener; }
+ virtual IAudioCapture* getAudioCapture() { return &initCapture; }
static cAudioManager* Instance()
{
@@ -55,6 +69,8 @@ namespace cAudio
std::map decodermap;
//!The listener object
cListener initlistener;
+ //!The audio capture instance
+ cAudioCapture initCapture;
};
}
diff --git a/Headers/cRawAudioDecoderFactory.h b/Headers/cRawAudioDecoderFactory.h
new file mode 100644
index 0000000..4c156a3
--- /dev/null
+++ b/Headers/cRawAudioDecoderFactory.h
@@ -0,0 +1,32 @@
+#ifndef CRAWAUDIODECODERFACOTRY_H_INCLUDED
+#define CRAWAUDIODECODERFACOTRY_H_INCLUDED
+
+#include "../include/IAudioDecoderFactory.h"
+#include "cRawDecoder.h"
+
+
+namespace cAudio
+{
+
+class cRawAudioDecoderFactory : public IAudioDecoderFactory
+{
+ public:
+ cRawAudioDecoderFactory() {}
+ ~cRawAudioDecoderFactory() {}
+
+ IAudioDecoder* CreateAudioDecoder(IDataSource* stream)
+ {
+ return new cRawDecoder(stream, 22050, EAF_16BIT_MONO);
+ }
+
+ IAudioDecoder* CreateAudioDecoder(IDataSource* stream, unsigned int frequency = 22050, AudioFormats format = EAF_16BIT_MONO)
+ {
+ return new cRawDecoder(stream, frequency, format);
+ }
+ protected:
+ private:
+};
+
+};
+
+#endif //! CRAWAUDIODECODERFACOTRY_H_INCLUDED
diff --git a/Headers/cRawDecoder.h b/Headers/cRawDecoder.h
new file mode 100644
index 0000000..7624bf1
--- /dev/null
+++ b/Headers/cRawDecoder.h
@@ -0,0 +1,41 @@
+#ifndef CRAWDECODER_H_INCLUDED
+#define CRAWDECODER_H_INCLUDED
+
+#include "../include/IAudioDecoder.h"
+
+namespace cAudio
+{
+
+ class cRawDecoder : public IAudioDecoder
+ {
+ public:
+
+ cRawDecoder(IDataSource* stream, unsigned int frequency, AudioFormats format);
+ ~cRawDecoder();
+
+ //!Retruns the format of the audio data
+ virtual AudioFormats getFormat();
+
+ //!Returns the frequency of the audio data
+ virtual int getFrequency();
+
+ //!Returns whether seeking is supported
+ virtual bool isSeekingSupported();
+
+ //!Reads a section of data out of the audio stream
+ virtual int readAudioData(void* output, int amount);
+
+ //!Sets the position to read data out of
+ virtual bool setPosition(int position, bool relative);
+
+ //!If seeking is supported, will seek the stream to seconds
+ virtual bool seek(float seconds,bool relative);
+
+ private:
+ unsigned int Frequency;
+ AudioFormats Format;
+ };
+
+}
+
+#endif //! CRAWDECODER_H_INCLUDED
\ No newline at end of file
diff --git a/Source/cAudio.cpp b/Source/cAudio.cpp
index 3255325..d61d1e2 100644
--- a/Source/cAudio.cpp
+++ b/Source/cAudio.cpp
@@ -27,13 +27,13 @@ namespace cAudio
//!Stops all playing sound sources and deletes the sources and buffers
void cAudio::release()
{
- //Stops the audio source
- alSourceStop(source);
- empty();
- //Deletes the source
- alDeleteSources(1, &source);
- //deletes the last filled buffer
- alDeleteBuffers(3, buffers);
+ //Stops the audio source
+ alSourceStop(source);
+ empty();
+ //Deletes the source
+ alDeleteSources(1, &source);
+ //deletes the last filled buffer
+ alDeleteBuffers(3, buffers);
}
//!Plays back sound source
@@ -69,10 +69,10 @@ namespace cAudio
int processed = 0;
bool active = true;
- //gets the sound source processed buffers/
+ //gets the sound source processed buffers/
alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed);
- //while there is more data refill buffers with audio data.
- while (processed--)
+ //while there is more data refill buffers with audio data.
+ while (processed--)
{
ALuint buffer;
@@ -80,13 +80,11 @@ namespace cAudio
active = stream(buffer);
- //if more in stream continue playing.
+ //if more in stream continue playing.
if(active)
alSourceQueueBuffers(source, 1, &buffer);
-
}
- return active;
-
+ return active;
}
//!The streaming function
@@ -95,58 +93,56 @@ namespace cAudio
if(Decoder)
{
//stores the caculated data into buffer that is passed to output.
- size_t totalread = 0;
+ size_t totalread = 0;
char tempbuffer[BUFFER_SIZE];
- while( totalread < BUFFER_SIZE )
- {
- char tempbuffer2[BUFFER_SIZE];
- int actualread = Decoder->readAudioData(tempbuffer2, BUFFER_SIZE-totalread);
- if(actualread > 0)
+ while( totalread < BUFFER_SIZE )
{
- memcpy(tempbuffer+totalread,tempbuffer2,actualread);
- totalread += actualread;
- }
- if(actualread < 0)
- {
- break;
- }
- if(actualread == 0)
- {
- if(toloop)
+ char tempbuffer2[BUFFER_SIZE];
+ int actualread = Decoder->readAudioData(tempbuffer2, BUFFER_SIZE-totalread);
+ if(actualread > 0)
{
- //If we are to loop, set to the beginning and reload from the start
- Decoder->setPosition(0,false);
+ memcpy(tempbuffer+totalread,tempbuffer2,actualread);
+ totalread += actualread;
}
- else
+ if(actualread < 0)
+ {
break;
- }
+ }
+ if(actualread == 0)
+ {
+ if(toloop)
+ {
+ //If we are to loop, set to the beginning and reload from the start
+ Decoder->setPosition(0,false);
+ }
+ else
+ break;
+ }
}
- //Second check, in case looping is not enabled, we will return false for end of stream
- if(totalread == 0)
- {
- return false;
- }
+ //Second check, in case looping is not enabled, we will return false for end of stream
+ if(totalread == 0)
+ {
+ return false;
+ }
//std::cout << buffer << std::endl;
-
- alBufferData(buffer, Decoder->getFormat(), tempbuffer, totalread, Decoder->getFrequency());
-
- return true;
- }
- return false;
+ alBufferData(buffer, Decoder->getFormat(), tempbuffer, totalread, Decoder->getFrequency());
+ return true;
+ }
+ return false;
}
//!clears the sound sources buffers and makes them free to be used by other sound sources.
void cAudio::empty()
{
int queued = 0;
- //grabs allt he sources buffers.
+ //grabs allt he sources buffers.
alGetSourcei(source, AL_BUFFERS_QUEUED, &queued);
while (queued--)
{
ALuint buffer;
- //unqueues sources buffers to be used for others.
+ //unqueues sources buffers to be used for others.
alSourceUnqueueBuffers(source, 1, &buffer);
}
}
@@ -158,16 +154,14 @@ namespace cAudio
if (error != AL_NO_ERROR)
{
- std::cout<<"OpenAL error was Raised.";
+ std::cout<< "OpenAL error was Raised.";
}
}
//!checks to see if the given ogg file is valid
bool cAudio::isvalid()
{
-
return (Decoder != 0);
-
}
//!Sets the sound source relativity to follow the listener to give the illusion of stereo 2d sound
@@ -176,14 +170,14 @@ namespace cAudio
alSourcei (source, AL_SOURCE_RELATIVE, true);
toloop = loop;
play();
- alSourcePlay(source);
+ alSourcePlay(source);
}
//!Plays the given audio file with 3d position
void cAudio::play3d(bool loop, float x, float y, float z,float soundstr)
{
alSourcei (source, AL_SOURCE_RELATIVE, false);
- alSource3f(source, AL_POSITION,x, y, z);
+ alSource3f(source, AL_POSITION, x, y, z);
alSourcef (source, AL_ROLLOFF_FACTOR, soundstr);
toloop = loop;
play();
@@ -199,49 +193,49 @@ namespace cAudio
//!Used to move the audio sources position after the initial creation
void cAudio::setPosition(float posx,float posy,float posz)
{
- alSource3f(source, AL_POSITION,posx, posy, posz);
+ alSource3f(source, AL_POSITION, posx, posy, posz);
}
//!Used to set the velocity of the audio source.
void cAudio::setVelocity(float velx,float vely, float velz)
{
- alSource3f(source, AL_VELOCITY,velx, vely, velz);
+ alSource3f(source, AL_VELOCITY, velx, vely, velz);
}
//!Used to set the direction of the audio source
void cAudio::setDirection(float dirx,float diry,float dirz)
{
- alSource3f(source, AL_DIRECTION,dirx, diry, dirz);
+ alSource3f(source, AL_DIRECTION, dirx, diry, dirz);
}
//!Used to set the sound strength or roll off factor
void cAudio::setStrength(float soundstrength)
{
- alSourcef (source, AL_ROLLOFF_FACTOR, soundstrength);
+ alSourcef(source, AL_ROLLOFF_FACTOR, soundstrength);
}
//!Used to set the pitch of the audio file
void cAudio::setPitch(float pitch)
{
- alSourcef (source, AL_PITCH,pitch);
+ alSourcef (source, AL_PITCH, pitch);
}
//!Used to set the volume of the audio source
void cAudio::setVolume(float volume)
{
- alSourcef(source,AL_GAIN,volume);
+ alSourcef(source, AL_GAIN, volume);
}
//!Used to set the doppler strength of the audio sources doppler effect
void cAudio::setDopplerStrength(float doop)
{
- alSourcef(source,AL_DOPPLER_FACTOR,doop);
+ alSourcef(source, AL_DOPPLER_FACTOR, doop);
}
//!Used to set the doppler velocity of the audio source
void cAudio::setDopplerVelocity(float doopx,float doopy,float doopz)
{
- alSource3f(source,AL_DOPPLER_VELOCITY,doopx,doopy,doopz);
+ alSource3f(source, AL_DOPPLER_VELOCITY, doopx, doopy, doopz);
}
//!Allows us to seek through a stream
@@ -257,13 +251,12 @@ namespace cAudio
bool cAudio::play()
{
playaudio = true;
- if (!this->paused())
+ if (!paused())
{
int queueSize = 0;
-
for(int u = 0; u < 3; u++)
{
- int val = this->stream(buffers[u]);
+ int val = stream(buffers[u]);
if(val < 0)
{
@@ -272,17 +265,13 @@ namespace cAudio
else if(val > 0)
++queueSize;
}
-
//Stores the sources 3 buffers to be used in the queue
alSourceQueueBuffers(source, queueSize, buffers);
- }
-
+ }
alSourcePlay(source);
-
return true;
}
-
//!Used to stop the audio source
void cAudio::stop()
{
diff --git a/Source/cAudioCapture.cpp b/Source/cAudioCapture.cpp
new file mode 100644
index 0000000..d6a948c
--- /dev/null
+++ b/Source/cAudioCapture.cpp
@@ -0,0 +1,177 @@
+#include "../Headers/cAudioCapture.h"
+#include
+
+namespace cAudio
+{
+ cAudioCapture::cAudioCapture() : Frequency(22050), Format(EAF_16BIT_MONO), InternalBufferSize(8192),
+ Supported(false), Ready(false), Capturing(false), SampleSize(2), CaptureDevice(NULL)
+ {
+
+ }
+ cAudioCapture::~cAudioCapture()
+ {
+
+ }
+
+ bool cAudioCapture::checkCaptureExtension()
+ {
+ // Check for Capture Extension support
+ ALCdevice* pDevice;
+ ALCcontext* pContext;
+ pContext = alcGetCurrentContext();
+ pDevice = alcGetContextsDevice(pContext);
+ Supported = ( alcIsExtensionPresent(pDevice, "ALC_EXT_CAPTURE") == AL_TRUE );
+ return Supported;
+ }
+
+ bool cAudioCapture::initOpenALDevice()
+ {
+ if(Supported)
+ {
+ if(CaptureDevice)
+ shutdownOpenALDevice();
+
+ CaptureDevice = alcCaptureOpenDevice(NULL, Frequency, Format, InternalBufferSize / SampleSize);
+ if(CaptureDevice)
+ {
+ Ready = true;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ void cAudioCapture::shutdownOpenALDevice()
+ {
+ if(Supported)
+ {
+ if(Capturing)
+ stopCapture();
+
+ if(CaptureDevice)
+ {
+ alcCaptureCloseDevice(CaptureDevice);
+ CaptureDevice = NULL;
+ Ready = false;
+ }
+ }
+ }
+
+ void cAudioCapture::shutdown()
+ {
+ shutdownOpenALDevice();
+ }
+
+ void cAudioCapture::updateCaptureBuffer(bool force)
+ {
+ if(Capturing && CaptureDevice && Ready)
+ {
+ int AvailableSamples = 0;
+ alcGetIntegerv(CaptureDevice, ALC_CAPTURE_SAMPLES, 1, &AvailableSamples);
+ const unsigned int availbuffersize = AvailableSamples * SampleSize;
+
+ //If the samples in the OpenAL buffer are more than half of its max size, grab them
+ if(availbuffersize > InternalBufferSize / 2 || force)
+ {
+ //Fixes a bug with the capture being forced, but no data being available
+ if(availbuffersize > 0)
+ {
+ const int oldBufferSize = CaptureBuffer.size();
+ CaptureBuffer.resize(oldBufferSize + availbuffersize, 0);
+ alcCaptureSamples(CaptureDevice, &CaptureBuffer[oldBufferSize], AvailableSamples);
+ }
+ }
+ }
+ }
+
+ bool cAudioCapture::beginCapture()
+ {
+ if(!Capturing)
+ {
+ CaptureBuffer.clear();
+ if(CaptureDevice && Ready)
+ {
+ alcCaptureStart(CaptureDevice);
+ Capturing = true;
+ }
+ return Capturing;
+ }
+ else
+ return false;
+ }
+
+ void cAudioCapture::stopCapture()
+ {
+ if(CaptureDevice && Ready)
+ {
+ alcCaptureStop(CaptureDevice);
+ updateCaptureBuffer(true);
+ }
+ Capturing = false;
+ }
+
+ void cAudioCapture::getCapturedAudio(void* outputBuffer, unsigned int outputBufferSize)
+ {
+ if(outputBuffer && outputBufferSize > 0)
+ {
+ int sizeToCopy = (outputBufferSize >= CaptureBuffer.size()) ? CaptureBuffer.size() : outputBufferSize;
+ memcpy(outputBuffer, &CaptureBuffer[0], sizeToCopy);
+ CaptureBuffer.erase(CaptureBuffer.begin(), CaptureBuffer.begin()+sizeToCopy);
+ }
+ }
+
+ unsigned int cAudioCapture::getCurrentCapturedAudioSize()
+ {
+ return CaptureBuffer.size();
+ }
+
+ bool cAudioCapture::setFrequency(unsigned int frequency)
+ {
+ Frequency = frequency;
+ shutdownOpenALDevice();
+ return initOpenALDevice();
+ }
+
+ bool cAudioCapture::setFormat(AudioFormats format)
+ {
+ Format = format;
+ if(Format == EAF_8BIT_MONO)
+ SampleSize = 1;
+ else if(Format == EAF_8BIT_STEREO)
+ SampleSize = 2;
+ else if(Format == EAF_16BIT_MONO)
+ SampleSize = 2;
+ else
+ SampleSize = 4;
+
+ shutdownOpenALDevice();
+ return initOpenALDevice();
+ }
+
+ bool cAudioCapture::setInternalBufferSize(unsigned int internalBufferSize)
+ {
+ InternalBufferSize = internalBufferSize;
+
+ shutdownOpenALDevice();
+ return initOpenALDevice();
+ }
+
+ bool cAudioCapture::initialize(unsigned int frequency, AudioFormats format, unsigned int internalBufferSize)
+ {
+ Frequency = frequency;
+ InternalBufferSize = internalBufferSize;
+
+ Format = format;
+ if(Format == EAF_8BIT_MONO)
+ SampleSize = 1;
+ else if(Format == EAF_8BIT_STEREO)
+ SampleSize = 2;
+ else if(Format == EAF_16BIT_MONO)
+ SampleSize = 2;
+ else
+ SampleSize = 4;
+
+ shutdownOpenALDevice();
+ return initOpenALDevice();
+ }
+};
diff --git a/Source/cAudioManager.cpp b/Source/cAudioManager.cpp
index 7c5a53d..e3ad8ab 100644
--- a/Source/cAudioManager.cpp
+++ b/Source/cAudioManager.cpp
@@ -4,8 +4,10 @@
#include "../Headers/cUtils.h"
#include "../Headers/cOggAudioDecoderFactory.h"
#include "../Headers/cWavAudioDecoderFacotry.h"
+#include "../Headers/cRawAudioDecoderFactory.h"
#include
+#include
#include
//!#include
//!#include
@@ -24,6 +26,7 @@ namespace cAudio
void cAudioManager::init(int argc,char* argv[])
{
alutInit(&argc,argv);
+
/*
ALCcontext *Context;
ALCdevice *Device;
@@ -64,8 +67,12 @@ namespace cAudio
LOAD_AL_FUNC(alIsEffect);
*/
+ initCapture.checkCaptureExtension();
+ initCapture.initialize();
+
registerAudioDecoder(new cOggAudioDecoderFactory, "ogg");
registerAudioDecoder(new cWavAudioDecoderFactory, "wav");
+ registerAudioDecoder(new cRawAudioDecoderFactory, "raw");
}
//!create a sound source
@@ -76,13 +83,13 @@ namespace cAudio
if(source->isValid())
{
std::string ext = getExt(file);
- std::map::iterator it = decodermap.find(ext);
- if(it == decodermap.end())
- {
+ IAudioDecoderFactory* factory = getAudioDecoderFactory(ext);
+ if(!factory)
+ {
delete source;
return NULL;
}
- IAudioDecoder* decoder = it->second->CreateAudioDecoder(source);
+ IAudioDecoder* decoder = factory->CreateAudioDecoder(source);
IAudio* audio = new cAudio(decoder);
audiomap[identifier] = audio;
return audio;
@@ -113,13 +120,13 @@ namespace cAudio
cMemorySource* source = new cMemorySource(data,length,true);
if(source->isValid())
{
- std::map::iterator it = decodermap.find(ext);
- if(it == decodermap.end())
+ IAudioDecoderFactory* factory = getAudioDecoderFactory(ext);
+ if(!factory)
{
delete source;
return NULL;
}
- IAudioDecoder* decoder = it->second->CreateAudioDecoder(source);
+ IAudioDecoder* decoder = factory->CreateAudioDecoder(source);
IAudio* audio = new cAudio(decoder);
audiomap[identifier] = audio;
return audio;
@@ -131,11 +138,61 @@ namespace cAudio
}
}
- void cAudioManager::registerAudioDecoder(IAudioDecoderFactory* factory, std::string extension)
+ IAudio* cAudioManager::createFromRaw(const std::string& identifier,const char* data, size_t length, unsigned int frequency, AudioFormats format)
+ {
+ cMemorySource* source = new cMemorySource(data,length,true);
+ if(source->isValid())
+ {
+ IAudioDecoderFactory* factory = getAudioDecoderFactory("raw");
+ if(!factory)
+ {
+ delete source;
+ return NULL;
+ }
+ IAudioDecoder* decoder = ((cRawAudioDecoderFactory*)factory)->CreateAudioDecoder(source, frequency, format);
+ IAudio* audio = new cAudio(decoder);
+ audiomap[identifier] = audio;
+ return audio;
+ }
+ else
+ {
+ delete source;
+ return NULL;
+ }
+ }
+
+ bool cAudioManager::registerAudioDecoder(IAudioDecoderFactory* factory, std::string extension)
{
decodermap[extension] = factory;
+ return true;
}
+ void cAudioManager::unRegisterAudioDecoder(std::string extension)
+ {
+ std::map::iterator it = decodermap.find(extension);
+ if(it != decodermap.end())
+ {
+ delete it->second;
+ decodermap.erase(it);
+ }
+ }
+
+ bool cAudioManager::isAudioDecoderRegistered(std::string extension)
+ {
+ std::map::iterator it = decodermap.find(extension);
+ return (it != decodermap.end());
+ }
+
+ IAudioDecoderFactory* cAudioManager::getAudioDecoderFactory(std::string extension)
+ {
+ std::map::iterator it = decodermap.find(extension);
+ if(it != decodermap.end())
+ {
+ return it->second;
+ }
+ return NULL;
+ }
+
//!grabs the selected audio file via the identifier
IAudio *cAudioManager::getSound(std::string identifier)
{
@@ -177,17 +234,19 @@ namespace cAudio
{
}
- if (i->second->playback())
+ /*if (i->second->playback())
{
- }
+ }*/
}
}
+ initCapture.updateCaptureBuffer();
}
//!Shuts down cAudio. Deletes all audio sources in process
void cAudioManager::shutDown()
{
+ initCapture.shutdown();
alutExit();
}
diff --git a/Source/cRawDecoder.cpp b/Source/cRawDecoder.cpp
new file mode 100644
index 0000000..0798c42
--- /dev/null
+++ b/Source/cRawDecoder.cpp
@@ -0,0 +1,53 @@
+#include "../Headers/cRawDecoder.h"
+
+namespace cAudio{
+
+ cRawDecoder::cRawDecoder(IDataSource* stream, unsigned int frequency, AudioFormats format) : IAudioDecoder(stream), Frequency(frequency), Format(format)
+ {
+
+ }
+
+ cRawDecoder::~cRawDecoder()
+ {
+
+ }
+
+ //!Returns wav channel format
+ AudioFormats cRawDecoder::getFormat()
+ {
+ return Format;
+ }
+
+ //!Returns wav data frequency
+ int cRawDecoder::getFrequency()
+ {
+ return Frequency;
+ }
+
+ //!Returns if seeking is supported
+ bool cRawDecoder::isSeekingSupported()
+ {
+ return false;
+ }
+
+ //!Reads wav data
+ int cRawDecoder::readAudioData(void* output, int amount)
+ {
+ return Stream->read(output,amount);
+ }
+
+ //!Sets data reader position
+ bool cRawDecoder::setPosition(int position, bool relative)
+ {
+ Stream->seek(position,relative);
+ return true;
+ }
+
+ //!Seeks wav data
+ bool cRawDecoder::seek(float seconds,bool relative)
+ {
+ return false;
+ }
+
+
+}
diff --git a/Source/cwavdecoder.cpp b/Source/cwavdecoder.cpp
index 3f387ad..c88f359 100644
--- a/Source/cwavdecoder.cpp
+++ b/Source/cwavdecoder.cpp
@@ -67,6 +67,10 @@ namespace cAudio{
//!Sets data reader position
bool cWavDecoder::setPosition(int position, bool relative)
{
+ //Safety to avoid reading the header as audio data
+ if(!relative && position < 44)
+ position = 44;
+
Stream->seek(position,relative);
return true;
}
diff --git a/cAudio.sln b/cAudio.sln
index 4c04313..aee351c 100644
--- a/cAudio.sln
+++ b/cAudio.sln
@@ -9,6 +9,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Tutorial2_3DSound", "Exampl
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Tutorial3_MemoryPlayback", "Examples\Tutorial3_MemoryPlayback\Tutorial3_MemoryPlayback.vcproj", "{FEA3B340-BBB2-4AFB-AF31-3962A0F3F2C6}"
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Tutorial4_AudioCapture", "Examples\Tutorial4_AudioCapture\Tutorial4_AudioCapture.vcproj", "{F04BE31E-E8CC-40C8-9C63-EEAE1BF84EB7}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@@ -31,6 +33,10 @@ Global
{FEA3B340-BBB2-4AFB-AF31-3962A0F3F2C6}.Debug|Win32.Build.0 = Debug|Win32
{FEA3B340-BBB2-4AFB-AF31-3962A0F3F2C6}.Release|Win32.ActiveCfg = Release|Win32
{FEA3B340-BBB2-4AFB-AF31-3962A0F3F2C6}.Release|Win32.Build.0 = Release|Win32
+ {F04BE31E-E8CC-40C8-9C63-EEAE1BF84EB7}.Debug|Win32.ActiveCfg = Debug|Win32
+ {F04BE31E-E8CC-40C8-9C63-EEAE1BF84EB7}.Debug|Win32.Build.0 = Debug|Win32
+ {F04BE31E-E8CC-40C8-9C63-EEAE1BF84EB7}.Release|Win32.ActiveCfg = Release|Win32
+ {F04BE31E-E8CC-40C8-9C63-EEAE1BF84EB7}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/cAudio.vcproj b/cAudio.vcproj
index 5354212..0f4b50e 100644
--- a/cAudio.vcproj
+++ b/cAudio.vcproj
@@ -178,6 +178,10 @@
RelativePath=".\Headers\cAudio.h"
>
+
+
@@ -202,12 +206,20 @@
RelativePath=".\Headers\cOggDecoder.h"
>
+
+
+
+
+
+
+
+
@@ -258,6 +278,10 @@
RelativePath=".\Source\cAudio.cpp"
>
+
+
@@ -282,6 +306,10 @@
RelativePath=".\Source\cOggDecoder.cpp"
>
+
+
diff --git a/include/IAudio.h b/include/IAudio.h
index 3f590da..6d6f792 100644
--- a/include/IAudio.h
+++ b/include/IAudio.h
@@ -21,7 +21,7 @@ namespace cAudio
virtual void setPosition(float posx,float posy,float posz) = 0;
//!allows you to set the audio objects velocity
virtual void setVelocity(float velx,float vely,float velz) = 0;
- //!allows us to set the direction the audio should play in / move
+ //!allows us to set the direction the audio should play in
virtual void setDirection(float dirx,float diry,float dirz) = 0;
//! Sets the audios pitch level
virtual void setPitch(float pitch) = 0;
diff --git a/include/IAudioCapture.h b/include/IAudioCapture.h
new file mode 100644
index 0000000..d799813
--- /dev/null
+++ b/include/IAudioCapture.h
@@ -0,0 +1,62 @@
+#ifndef IAUDIOCAPTURE_H
+#define IAUDIOCAPTURE_H
+
+#include "eAudioFormats.h"
+
+namespace cAudio
+{
+ class IAudioCapture
+ {
+ public:
+ //! Initializes the capture device to the selected settings
+ /** Note that calling this will cause the capture device to be reinitialized. Calling while in use may lead to a loss of audio data.
+ \param frequency: Frequency that the captured audio will be at
+ \param format: Format of the captured audio
+ \param internalBufferSize: Size of the internal OpenAL buffer used to store the captured audio until the next IAudioManager::update() in bytes
+ \return True on success, False if the capture device failed to initialize.
+ */
+ virtual bool initialize(unsigned int frequency = 22050, AudioFormats format = EAF_16BIT_MONO, unsigned int internalBufferSize = 8192) = 0;
+ //! Returns true if the current OpenAL implementation supports capturing audio
+ virtual bool isSupported() = 0;
+ //! Returns true if the capture device is ready to be used. False may indicate an error with the current settings.
+ virtual bool isReady() = 0;
+
+ //! Returns the frequency that the captured audio will be at
+ virtual unsigned int getFrequency() = 0;
+ //! Returns the format of the captured audio
+ virtual AudioFormats getFormat() = 0;
+ //! Returns the internal OpenAL buffer size in bytes
+ virtual unsigned int getInternalBufferSize() = 0;
+ //! Returns the size of a "sample" of audio data. Useful for making sure you grab audio data at sample boundaries
+ virtual unsigned int getSampleSize() = 0;
+
+ //! Sets the frequency that the captured audio will be at. Will cause the capture device to be reinitialized. Calling while in use may lead to a loss of audio data.
+ /** \return True on success, False if the capture device failed to initialize. */
+ virtual bool setFrequency(unsigned int frequency) = 0;
+ //! Sets the format that the captured audio will be at. Will cause the capture device to be reinitialized. Calling while in use may lead to a loss of audio data.
+ /** \return True on success, False if the capture device failed to initialize. */
+ virtual bool setFormat(AudioFormats format) = 0;
+ //! Sets the internal buffer size that OpenAL will use to store captured audio between calls to IAudioManager::update() in bytes. Will cause the capture device to be reinitialized. Calling while in use may lead to a loss of audio data.
+ /** \return True on success, False if the capture device failed to initialize. */
+ virtual bool setInternalBufferSize(unsigned int internalBufferSize) = 0;
+
+ //! Starts capturing audio data to an internal buffer. Will clear any old data in the buffer.
+ /** \return True if capture was successfully started. */
+ virtual bool beginCapture() = 0;
+ //! Stops capturing audio data to an internal buffer.
+ virtual void stopCapture() = 0;
+ //! Allows access to the audio data in the internal capture buffer
+ /** Can be called at any time to retrieve recorded audio. It is recommended that you call it every so often to prevent the internal buffer from growing too large.
+ Once successfully retrieved, the captured audio will be deleted from the internal buffer.
+ \param outputBuffer: Pointer to an output array to copy audio data to.
+ \param outputBufferSize: Size of the output array in bytes
+ */
+ virtual void getCapturedAudio(void* outputBuffer, unsigned int outputBufferSize) = 0;
+
+ //! Returns the current size of the internal audio buffer in bytes
+ virtual unsigned int getCurrentCapturedAudioSize() = 0;
+ protected:
+ };
+};
+
+#endif //! IAUDIOCAPTURE_H
\ No newline at end of file
diff --git a/include/IAudioDecoder.h b/include/IAudioDecoder.h
index 32a8c11..b7305ba 100644
--- a/include/IAudioDecoder.h
+++ b/include/IAudioDecoder.h
@@ -2,19 +2,11 @@
#define IAUDIODECODER_H
#include "IDataSource.h"
+#include "eAudioFormats.h"
namespace cAudio
{
-enum AudioFormats
-{
- EAF_8BIT_MONO = 0x1100,
- EAF_8BIT_STEREO = 0x1102,
- EAF_16BIT_MONO = 0x1101,
- EAF_16BIT_STEREO = 0x1103,
- EAF_COUNT
-};
-
class IAudioDecoder
{
public:
diff --git a/include/IAudioManager.h b/include/IAudioManager.h
index 8779701..64eb3d5 100644
--- a/include/IAudioManager.h
+++ b/include/IAudioManager.h
@@ -3,6 +3,7 @@
#define IAUDIOMANAGER_H
#include
#include "IListener.h"
+#include "IAudioCapture.h"
#ifndef CAUDIO_STATIC_LIB
@@ -28,24 +29,39 @@ namespace cAudio
virtual void init(int argc,char* argv[]) = 0;
//!Shuts everything down
virtual void shutDown() = 0;
+ //!Updates the cAudio playback
+ virtual void update() = 0;
+ //!Returns an IAudio object by its "name" and 0 if the name is not found
+ virtual IAudio *getSound(std::string identifier) = 0;
+ //!Releases "ALL" cAudio objects (but does not shutdown the manager)
+ virtual void release() = 0;
+
//!Creates the cAudio object
virtual IAudio* createFromFile(const std::string& identifier,const std::string& file,bool stream = false) = 0;
//!Loads audio from memory or virtual file system
virtual IAudio* createFromMemory(const std::string& identifier,const char* data, size_t length, std::string ext) = 0;
- //!Register Audio Codec
- virtual void registerAudioDecoder(IAudioDecoderFactory* factory, std::string extension) = 0;
- //!Allows you to set the listener position
- virtual void setListenerPos(float x,float y,float z) = 0;
- //!set the listeners orientation
- virtual void setListenerOrientation(float ux,float uy,float uz) = 0;
- //!Updates the cAudio playback
- virtual void update() = 0;
- //!Gets you the cAudio object you want
- virtual IAudio *getSound(std::string identifier) = 0;
- //!Releases "ALL" cAudio objects
- virtual void release() = 0;
+ //!Loads raw audio from memory.
+ virtual IAudio* createFromRaw(const std::string& identifier,const char* data, size_t length, unsigned int frequency, AudioFormats format) = 0;
+ //!Register Audio Codec
+ virtual bool registerAudioDecoder(IAudioDecoderFactory* factory, std::string extension) = 0;
+ //!Unregister Audio Codec (allows you to prevent an file type from being playable with new sound sources)
+ //!Note that all current sound sources will still continue to use any currently allocated decoders.
+ virtual void unRegisterAudioDecoder(std::string extension) = 0;
+ //!Returns whether an audio decoder is currently registered for this file type
+ virtual bool isAudioDecoderRegistered(std::string extension) = 0;
+ //!Returns a registered audio decoder factory
+ virtual IAudioDecoderFactory* getAudioDecoderFactory(std::string extension) = 0;
+
+ //!Allows you to set the listener position (DEPRECIATED! USE getListener() INSTEAD!)
+ virtual void setListenerPos(float x,float y,float z) = 0;
+ //!set the listeners orientation (DEPRECIATED! USE getListener() INSTEAD!)
+ virtual void setListenerOrientation(float ux,float uy,float uz) = 0;
+
+ //!Returns an interface for the listener
virtual IListener* getListener() = 0;
+ //!Returns an interface for audio capture
+ virtual IAudioCapture* getAudioCapture() = 0;
virtual ~IAudioManager() {}
protected:
diff --git a/include/IListener.h b/include/IListener.h
index 20e0da3..74b24b3 100644
--- a/include/IListener.h
+++ b/include/IListener.h
@@ -2,7 +2,7 @@
#ifndef ILISTENER_H
#define ILISTENER_H
-#include "../Headers/cVector3.h"
+#include "cVector3.h"
namespace cAudio
{
diff --git a/Headers/cVector3.h b/include/cVector3.h
similarity index 100%
rename from Headers/cVector3.h
rename to include/cVector3.h
diff --git a/include/eAudioFormats.h b/include/eAudioFormats.h
new file mode 100644
index 0000000..5903472
--- /dev/null
+++ b/include/eAudioFormats.h
@@ -0,0 +1,17 @@
+#ifndef EAUDIOFORMATS_H
+#define EAUDIOFORMATS_H
+
+namespace cAudio
+{
+
+enum AudioFormats
+{
+ EAF_8BIT_MONO = 0x1100,
+ EAF_8BIT_STEREO = 0x1102,
+ EAF_16BIT_MONO = 0x1101,
+ EAF_16BIT_STEREO = 0x1103
+};
+
+};
+
+#endif //! EAUDIOFORMATS_H
\ No newline at end of file