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:
Joerg Mueller
2011-02-18 23:50:27 +00:00
parent 020c03bc05
commit d36a89c8f4
8 changed files with 109 additions and 76 deletions

View File

@@ -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;

View File

@@ -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);

View File

@@ -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

View File

@@ -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.

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);