From d36a89c8f41f455895b6e52ce798c36c9debb967 Mon Sep 17 00:00:00 2001 From: Joerg Mueller Date: Fri, 18 Feb 2011 23:50:27 +0000 Subject: Audaspace: * Adding play method to the device classes to play back a reader (not used yet, preparation for a later feature). * Using a linear resampler in case SRC is disabled. --- intern/audaspace/OpenAL/AUD_OpenALDevice.cpp | 149 +++++++++++++------------ intern/audaspace/OpenAL/AUD_OpenALDevice.h | 1 + intern/audaspace/intern/AUD_DefaultMixer.cpp | 6 +- intern/audaspace/intern/AUD_IDevice.h | 13 +++ intern/audaspace/intern/AUD_NULLDevice.cpp | 5 + intern/audaspace/intern/AUD_NULLDevice.h | 1 + intern/audaspace/intern/AUD_SoftwareDevice.cpp | 9 +- intern/audaspace/intern/AUD_SoftwareDevice.h | 1 + 8 files changed, 109 insertions(+), 76 deletions(-) (limited to 'intern/audaspace') diff --git a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp b/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp index 2873b68ce47..94cac65d1fb 100644 --- a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp +++ b/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp @@ -534,81 +534,10 @@ static const char* queue_error = "AUD_OpenALDevice: Buffer couldn't be " static const char* bufferdata_error = "AUD_OpenALDevice: Buffer couldn't be " "filled with data."; -AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep) +AUD_Handle* AUD_OpenALDevice::play(AUD_IReader* reader, bool keep) { - lock(); - AUD_OpenALHandle* sound = NULL; - try - { - // check if it is a buffered factory - for(AUD_BFIterator i = m_bufferedFactories->begin(); - i != m_bufferedFactories->end(); i++) - { - if((*i)->factory == factory) - { - // create the handle - sound = new AUD_OpenALHandle; - sound->keep = keep; - sound->current = -1; - sound->isBuffered = true; - sound->data_end = true; - sound->loopcount = 0; - sound->stop = NULL; - sound->stop_data = NULL; - - alcSuspendContext(m_context); - - // OpenAL playback code - try - { - alGenSources(1, &sound->source); - if(alGetError() != AL_NO_ERROR) - AUD_THROW(AUD_ERROR_OPENAL, gensource_error); - - try - { - alSourcei(sound->source, AL_BUFFER, (*i)->buffer); - if(alGetError() != AL_NO_ERROR) - AUD_THROW(AUD_ERROR_OPENAL, queue_error); - } - catch(AUD_Exception&) - { - alDeleteSources(1, &sound->source); - throw; - } - } - catch(AUD_Exception&) - { - delete sound; - alcProcessContext(m_context); - throw; - } - - // play sound - m_playingSounds->push_back(sound); - - alSourcei(sound->source, AL_SOURCE_RELATIVE, 1); - start(); - - alcProcessContext(m_context); - } - } - } - catch(AUD_Exception&) - { - unlock(); - throw; - } - - unlock(); - - if(sound) - return sound; - - AUD_IReader* reader = factory->createReader(); - AUD_DeviceSpecs specs = m_specs; specs.specs = reader->getSpecs(); @@ -708,6 +637,82 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep) return sound; } +AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep) +{ + AUD_OpenALHandle* sound = NULL; + + lock(); + + try + { + // check if it is a buffered factory + for(AUD_BFIterator i = m_bufferedFactories->begin(); + i != m_bufferedFactories->end(); i++) + { + if((*i)->factory == factory) + { + // create the handle + sound = new AUD_OpenALHandle; + sound->keep = keep; + sound->current = -1; + sound->isBuffered = true; + sound->data_end = true; + sound->loopcount = 0; + sound->stop = NULL; + sound->stop_data = NULL; + + alcSuspendContext(m_context); + + // OpenAL playback code + try + { + alGenSources(1, &sound->source); + if(alGetError() != AL_NO_ERROR) + AUD_THROW(AUD_ERROR_OPENAL, gensource_error); + + try + { + alSourcei(sound->source, AL_BUFFER, (*i)->buffer); + if(alGetError() != AL_NO_ERROR) + AUD_THROW(AUD_ERROR_OPENAL, queue_error); + } + catch(AUD_Exception&) + { + alDeleteSources(1, &sound->source); + throw; + } + } + catch(AUD_Exception&) + { + delete sound; + alcProcessContext(m_context); + throw; + } + + // play sound + m_playingSounds->push_back(sound); + + alSourcei(sound->source, AL_SOURCE_RELATIVE, 1); + start(); + + alcProcessContext(m_context); + } + } + } + catch(AUD_Exception&) + { + unlock(); + throw; + } + + unlock(); + + if(sound) + return sound; + + return play(factory->createReader(), keep); +} + bool AUD_OpenALDevice::pause(AUD_Handle* handle) { bool result = false; diff --git a/intern/audaspace/OpenAL/AUD_OpenALDevice.h b/intern/audaspace/OpenAL/AUD_OpenALDevice.h index e997c9df5ad..3965ff03533 100644 --- a/intern/audaspace/OpenAL/AUD_OpenALDevice.h +++ b/intern/audaspace/OpenAL/AUD_OpenALDevice.h @@ -142,6 +142,7 @@ public: virtual ~AUD_OpenALDevice(); virtual AUD_DeviceSpecs getSpecs() const; + virtual AUD_Handle* play(AUD_IReader* reader, bool keep = false); virtual AUD_Handle* play(AUD_IFactory* factory, bool keep = false); virtual bool pause(AUD_Handle* handle); virtual bool resume(AUD_Handle* handle); diff --git a/intern/audaspace/intern/AUD_DefaultMixer.cpp b/intern/audaspace/intern/AUD_DefaultMixer.cpp index 495bdd7694e..d1b22df6f62 100644 --- a/intern/audaspace/intern/AUD_DefaultMixer.cpp +++ b/intern/audaspace/intern/AUD_DefaultMixer.cpp @@ -27,6 +27,8 @@ #include "AUD_DefaultMixer.h" #ifdef WITH_SAMPLERATE #include "AUD_SRCResampleReader.h" +#else +#include "AUD_LinearResampleReader.h" #endif #include "AUD_ChannelMapperReader.h" #include "AUD_ChannelMapperFactory.h" @@ -53,10 +55,12 @@ AUD_IReader* AUD_DefaultMixer::prepare(AUD_IReader* reader) specs.channels = m_specs.channels; } -#ifdef WITH_SAMPLERATE // resample if(specs.rate != m_specs.rate) +#ifdef WITH_SAMPLERATE reader = new AUD_SRCResampleReader(reader, m_specs.specs); +#else + reader = new AUD_LinearResampleReader(reader, m_specs.specs); #endif // rechannel diff --git a/intern/audaspace/intern/AUD_IDevice.h b/intern/audaspace/intern/AUD_IDevice.h index 56e874019b2..81a4653c7e9 100644 --- a/intern/audaspace/intern/AUD_IDevice.h +++ b/intern/audaspace/intern/AUD_IDevice.h @@ -29,6 +29,7 @@ #include "AUD_Space.h" class AUD_IFactory; +class AUD_IReader; /// Handle structure, for inherition. struct AUD_Handle @@ -58,6 +59,18 @@ public: */ virtual AUD_DeviceSpecs getSpecs() const=0; + /** + * Plays a sound source. + * \param reader The reader to play. + * \param keep When keep is true the sound source will not be deleted but + * set to paused when its end has been reached. + * \return Returns a handle with which the playback can be controlled. + * This is NULL if the sound couldn't be played back. + * \exception AUD_Exception Thrown if there's an unexpected (from the + * device side) error during creation of the reader. + */ + virtual AUD_Handle* play(AUD_IReader* reader, bool keep = false)=0; + /** * Plays a sound source. * \param factory The factory to create the reader for the sound source. diff --git a/intern/audaspace/intern/AUD_NULLDevice.cpp b/intern/audaspace/intern/AUD_NULLDevice.cpp index ecd40e126fb..2a8565054c6 100644 --- a/intern/audaspace/intern/AUD_NULLDevice.cpp +++ b/intern/audaspace/intern/AUD_NULLDevice.cpp @@ -43,6 +43,11 @@ AUD_DeviceSpecs AUD_NULLDevice::getSpecs() const return specs; } +AUD_Handle* AUD_NULLDevice::play(AUD_IReader* reader, bool keep) +{ + return 0; +} + AUD_Handle* AUD_NULLDevice::play(AUD_IFactory* factory, bool keep) { return 0; diff --git a/intern/audaspace/intern/AUD_NULLDevice.h b/intern/audaspace/intern/AUD_NULLDevice.h index 41a95f8feaa..c093a7a681e 100644 --- a/intern/audaspace/intern/AUD_NULLDevice.h +++ b/intern/audaspace/intern/AUD_NULLDevice.h @@ -41,6 +41,7 @@ public: AUD_NULLDevice(); virtual AUD_DeviceSpecs getSpecs() const; + virtual AUD_Handle* play(AUD_IReader* reader, bool keep = false); virtual AUD_Handle* play(AUD_IFactory* factory, bool keep = false); virtual bool pause(AUD_Handle* handle); virtual bool resume(AUD_Handle* handle); diff --git a/intern/audaspace/intern/AUD_SoftwareDevice.cpp b/intern/audaspace/intern/AUD_SoftwareDevice.cpp index 9feaf169d8b..02579719ffb 100644 --- a/intern/audaspace/intern/AUD_SoftwareDevice.cpp +++ b/intern/audaspace/intern/AUD_SoftwareDevice.cpp @@ -208,10 +208,8 @@ AUD_DeviceSpecs AUD_SoftwareDevice::getSpecs() const return m_specs; } -AUD_Handle* AUD_SoftwareDevice::play(AUD_IFactory* factory, bool keep) +AUD_Handle* AUD_SoftwareDevice::play(AUD_IReader* reader, bool keep) { - AUD_IReader* reader = factory->createReader(); - // prepare the reader reader = m_mixer->prepare(reader); if(reader == NULL) @@ -236,6 +234,11 @@ AUD_Handle* AUD_SoftwareDevice::play(AUD_IFactory* factory, bool keep) return sound; } +AUD_Handle* AUD_SoftwareDevice::play(AUD_IFactory* factory, bool keep) +{ + return play(factory->createReader(), keep); +} + bool AUD_SoftwareDevice::pause(AUD_Handle* handle) { bool result = false; diff --git a/intern/audaspace/intern/AUD_SoftwareDevice.h b/intern/audaspace/intern/AUD_SoftwareDevice.h index 90da9aca0b4..af0861b353a 100644 --- a/intern/audaspace/intern/AUD_SoftwareDevice.h +++ b/intern/audaspace/intern/AUD_SoftwareDevice.h @@ -114,6 +114,7 @@ private: public: virtual AUD_DeviceSpecs getSpecs() const; + virtual AUD_Handle* play(AUD_IReader* reader, bool keep = false); virtual AUD_Handle* play(AUD_IFactory* factory, bool keep = false); virtual bool pause(AUD_Handle* handle); virtual bool resume(AUD_Handle* handle); -- cgit v1.2.3