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.
This commit is contained in:
@@ -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;
|
||||
|
@@ -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);
|
||||
|
@@ -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
|
||||
|
@@ -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.
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
Reference in New Issue
Block a user