Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/intern
diff options
context:
space:
mode:
authorJoerg Mueller <nexyon@gmail.com>2011-06-22 00:21:43 +0400
committerJoerg Mueller <nexyon@gmail.com>2011-06-22 00:21:43 +0400
commit044887b5a4b1df57fce408f29f59bce1d7fa0085 (patch)
tree013c595e8bc737f5fd58a31a7c846f700a86ec58 /intern
parentcc71dcc218d9ee4612bfe955be6f00be521be5b1 (diff)
3D Audio GSoC:
- Created Handle classes - Changed Reference counting completely - Fixing some streaming bugs - Completely disabled OpenAL Buffered Factories (they were unused anyway)
Diffstat (limited to 'intern')
-rw-r--r--intern/audaspace/CMakeLists.txt3
-rw-r--r--intern/audaspace/FX/AUD_DoubleReader.cpp2
-rw-r--r--intern/audaspace/OpenAL/AUD_OpenALDevice.cpp1620
-rw-r--r--intern/audaspace/OpenAL/AUD_OpenALDevice.h154
-rw-r--r--intern/audaspace/Python/AUD_PyAPI.cpp255
-rw-r--r--intern/audaspace/Python/AUD_PyAPI.h7
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp2
-rw-r--r--intern/audaspace/intern/AUD_BufferReader.cpp2
-rw-r--r--intern/audaspace/intern/AUD_C-API.cpp212
-rw-r--r--intern/audaspace/intern/AUD_C-API.h13
-rw-r--r--intern/audaspace/intern/AUD_I3DDevice.h196
-rw-r--r--intern/audaspace/intern/AUD_I3DHandle.h213
-rw-r--r--intern/audaspace/intern/AUD_IDevice.h155
-rw-r--r--intern/audaspace/intern/AUD_IHandle.h181
-rw-r--r--intern/audaspace/intern/AUD_NULLDevice.cpp80
-rw-r--r--intern/audaspace/intern/AUD_NULLDevice.h19
-rw-r--r--intern/audaspace/intern/AUD_Reference.h113
-rw-r--r--intern/audaspace/intern/AUD_ReferenceHandler.cpp33
-rw-r--r--intern/audaspace/intern/AUD_SequencerFactory.cpp2
-rw-r--r--intern/audaspace/intern/AUD_SoftwareDevice.cpp535
-rw-r--r--intern/audaspace/intern/AUD_SoftwareDevice.h82
21 files changed, 1858 insertions, 2021 deletions
diff --git a/intern/audaspace/CMakeLists.txt b/intern/audaspace/CMakeLists.txt
index ab88c9ecabd..9c75cd67e6a 100644
--- a/intern/audaspace/CMakeLists.txt
+++ b/intern/audaspace/CMakeLists.txt
@@ -87,8 +87,10 @@ set(SRC
intern/AUD_FileFactory.cpp
intern/AUD_FileFactory.h
intern/AUD_I3DDevice.h
+ intern/AUD_I3DHandle.h
intern/AUD_IDevice.h
intern/AUD_IFactory.h
+ intern/AUD_IHandle.h
intern/AUD_IReader.h
intern/AUD_LinearResampleFactory.cpp
intern/AUD_LinearResampleFactory.h
@@ -104,6 +106,7 @@ set(SRC
intern/AUD_ReadDevice.cpp
intern/AUD_ReadDevice.h
intern/AUD_Reference.h
+ intern/AUD_ReferenceHandler.cpp
intern/AUD_ResampleFactory.h
intern/AUD_SequencerFactory.cpp
intern/AUD_SequencerFactory.h
diff --git a/intern/audaspace/FX/AUD_DoubleReader.cpp b/intern/audaspace/FX/AUD_DoubleReader.cpp
index 5d9ebbd6187..2c39d193f67 100644
--- a/intern/audaspace/FX/AUD_DoubleReader.cpp
+++ b/intern/audaspace/FX/AUD_DoubleReader.cpp
@@ -91,6 +91,8 @@ AUD_Specs AUD_DoubleReader::getSpecs() const
void AUD_DoubleReader::read(int& length, bool& eos, sample_t* buffer)
{
+ eos = false;
+
if(!m_finished1)
{
int len = length;
diff --git a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp b/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
index 465ad5b5ae6..f24d3aef4e2 100644
--- a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
+++ b/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
@@ -43,56 +43,723 @@
#include <unistd.h>
#endif
-#define AUD_OPENAL_CYCLE_BUFFERS 3
+/*struct AUD_OpenALBufferedFactory
+{
+ /// The factory.
+ AUD_IFactory* factory;
+
+ /// The OpenAL buffer.
+ ALuint buffer;
+};*/
+
+typedef std::list<AUD_Reference<AUD_OpenALDevice::AUD_OpenALHandle> >::iterator AUD_HandleIterator;
+//typedef std::list<AUD_OpenALBufferedFactory*>::iterator AUD_BFIterator;
+
+
+/******************************************************************************/
+/*********************** AUD_OpenALHandle Handle Code *************************/
+/******************************************************************************/
+
+static const char* genbuffer_error = "AUD_OpenALDevice: Buffer couldn't be "
+ "generated.";
+static const char* gensource_error = "AUD_OpenALDevice: Source couldn't be "
+ "generated.";
+static const char* queue_error = "AUD_OpenALDevice: Buffer couldn't be "
+ "queued to the source.";
+static const char* bufferdata_error = "AUD_OpenALDevice: Buffer couldn't be "
+ "filled with data.";
-/// Saves the data for playback.
-struct AUD_OpenALHandle : AUD_Handle
+AUD_OpenALDevice::AUD_OpenALHandle::AUD_OpenALHandle(AUD_OpenALDevice* device, ALenum format, AUD_Reference<AUD_IReader> reader, bool keep) :
+ m_isBuffered(false), m_reader(reader), m_keep(keep), m_format(format), m_current(0),
+ m_eos(false), m_loopcount(0), m_stop(NULL), m_stop_data(NULL), m_status(AUD_STATUS_PLAYING),
+ m_device(device)
{
- /// Whether it's a buffered or a streamed source.
- bool isBuffered;
+ AUD_DeviceSpecs specs = m_device->m_specs;
+ specs.specs = m_reader->getSpecs();
- /// The reader source.
- AUD_Reference<AUD_IReader> reader;
+ // OpenAL playback code
+ alGenBuffers(CYCLE_BUFFERS, m_buffers);
+ if(alGetError() != AL_NO_ERROR)
+ AUD_THROW(AUD_ERROR_OPENAL, genbuffer_error);
- /// Whether to keep the source if end of it is reached.
- bool keep;
+ try
+ {
+ m_device->m_buffer.assureSize(m_device->m_buffersize * AUD_DEVICE_SAMPLE_SIZE(specs));
+ int length;
+ bool eos;
- /// OpenAL sample format.
- ALenum format;
+ for(int i = 0; i < CYCLE_BUFFERS; i++)
+ {
+ length = m_device->m_buffersize;
+ reader->read(length, eos, m_device->m_buffer.getBuffer());
+ alBufferData(m_buffers[i], m_format, m_device->m_buffer.getBuffer(),
+ length * AUD_DEVICE_SAMPLE_SIZE(specs),
+ specs.rate);
+ if(alGetError() != AL_NO_ERROR)
+ AUD_THROW(AUD_ERROR_OPENAL, bufferdata_error);
+ }
- /// OpenAL source.
- ALuint source;
+ alGenSources(1, &m_source);
+ if(alGetError() != AL_NO_ERROR)
+ AUD_THROW(AUD_ERROR_OPENAL, gensource_error);
- /// OpenAL buffers.
- ALuint buffers[AUD_OPENAL_CYCLE_BUFFERS];
+ try
+ {
+ alSourceQueueBuffers(m_source, CYCLE_BUFFERS,
+ m_buffers);
+ if(alGetError() != AL_NO_ERROR)
+ AUD_THROW(AUD_ERROR_OPENAL, queue_error);
+ }
+ catch(AUD_Exception&)
+ {
+ alDeleteSources(1, &m_source);
+ throw;
+ }
+ }
+ catch(AUD_Exception&)
+ {
+ alDeleteBuffers(CYCLE_BUFFERS, m_buffers);
+ throw;
+ }
+ alSourcei(m_source, AL_SOURCE_RELATIVE, 1);
+}
- /// The first buffer to be read next.
- int current;
+bool AUD_OpenALDevice::AUD_OpenALHandle::pause()
+{
+ if(m_status)
+ {
+ m_device->lock();
- /// Whether the stream doesn't return any more data.
- bool eos;
+ if(m_status == AUD_STATUS_PLAYING)
+ {
+ m_device->m_playingSounds.remove(this);
+ m_device->m_pausedSounds.push_back(this);
- /// The loop count of the source.
- int loopcount;
+ alSourcePause(m_source);
- /// The stop callback.
- stopCallback stop;
+ m_status = AUD_STATUS_PAUSED;
+ m_device->unlock();
- /// Stop callback data.
- void* stop_data;
-};
+ return true;
+ }
+
+ m_device->unlock();
+ }
-struct AUD_OpenALBufferedFactory
+ return false;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::resume()
{
- /// The factory.
- AUD_IFactory* factory;
+ if(m_status)
+ {
+ m_device->lock();
- /// The OpenAL buffer.
- ALuint buffer;
-};
+ if(m_status == AUD_STATUS_PAUSED)
+ {
+ m_device->m_pausedSounds.remove(this);
+ m_device->m_playingSounds.push_back(this);
+
+ m_device->start();
+ m_status = AUD_STATUS_PLAYING;
+ m_device->unlock();
+ return true;
+ }
+
+ m_device->unlock();
+ }
+
+ return false;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::stop()
+{
+ if(!m_status)
+ return false;
+
+ m_device->lock();
+
+ if(m_status == AUD_STATUS_PLAYING)
+ m_device->m_playingSounds.remove(this);
+ else
+ m_device->m_pausedSounds.remove(this);
+
+ m_device->unlock();
+
+ alDeleteSources(1, &m_source);
+ if(!m_isBuffered)
+ alDeleteBuffers(CYCLE_BUFFERS, m_buffers);
+
+ m_status = AUD_STATUS_INVALID;
+ return true;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::getKeep()
+{
+ if(m_status)
+ return m_keep;
+
+ return false;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::setKeep(bool keep)
+{
+ if(!m_status)
+ return false;
+
+ m_device->lock();
+
+ m_keep = keep;
+
+ m_device->unlock();
+
+ return true;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::seek(float position)
+{
+ if(!m_status)
+ return false;
+
+ m_device->lock();
+
+ if(m_isBuffered)
+ alSourcef(m_source, AL_SEC_OFFSET, position);
+ else
+ {
+ m_reader->seek((int)(position * m_reader->getSpecs().rate));
+ m_eos = false;
+
+ ALint info;
+
+ alGetSourcei(m_source, AL_SOURCE_STATE, &info);
+
+ if(info != AL_PLAYING)
+ {
+ if(info == AL_PAUSED)
+ alSourceStop(m_source);
+
+ alSourcei(m_source, AL_BUFFER, 0);
+ m_current = 0;
+
+ ALenum err;
+ if((err = alGetError()) == AL_NO_ERROR)
+ {
+ int length;
+ AUD_DeviceSpecs specs = m_device->m_specs;
+ specs.specs = m_reader->getSpecs();
+ m_device->m_buffer.assureSize(m_device->m_buffersize * AUD_DEVICE_SAMPLE_SIZE(specs));
+
+ for(int i = 0; i < CYCLE_BUFFERS; i++)
+ {
+ length = m_device->m_buffersize;
+ m_reader->read(length, m_eos, m_device->m_buffer.getBuffer());
+ alBufferData(m_buffers[i], m_format, m_device->m_buffer.getBuffer(),
+ length * AUD_DEVICE_SAMPLE_SIZE(specs), specs.rate);
+
+ if(alGetError() != AL_NO_ERROR)
+ break;
+ }
+
+ if(m_loopcount != 0)
+ m_eos = false;
+
+ alSourceQueueBuffers(m_source, CYCLE_BUFFERS, m_buffers);
+ }
+
+ alSourceRewind(m_source);
+ }
+ }
+
+ m_device->unlock();
+
+ return true;
+}
+
+float AUD_OpenALDevice::AUD_OpenALHandle::getPosition()
+{
+ if(!m_status)
+ return 0.0f;
+
+ m_device->lock();
+
+ float position = 0.0f;
+
+ alGetSourcef(m_source, AL_SEC_OFFSET, &position);
+
+ if(!m_isBuffered)
+ {
+ AUD_Specs specs = m_reader->getSpecs();
+ position += (m_reader->getPosition() - m_device->m_buffersize *
+ CYCLE_BUFFERS) / (float)specs.rate;
+ }
+
+ m_device->unlock();
+
+ return position;
+}
+
+AUD_Status AUD_OpenALDevice::AUD_OpenALHandle::getStatus()
+{
+ return m_status;
+}
+
+float AUD_OpenALDevice::AUD_OpenALHandle::getVolume()
+{
+ float result = std::numeric_limits<float>::quiet_NaN();
+
+ if(!m_status)
+ return result;
+
+ m_device->lock();
+
+ alGetSourcef(m_source, AL_GAIN, &result);
+
+ m_device->unlock();
+
+ return result;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::setVolume(float volume)
+{
+ if(!m_status)
+ return false;
+
+ m_device->lock();
+
+ alSourcef(m_source, AL_GAIN, volume);
+
+ m_device->unlock();
+
+ return true;
+}
+
+float AUD_OpenALDevice::AUD_OpenALHandle::getPitch()
+{
+ float result = std::numeric_limits<float>::quiet_NaN();
+
+ if(!m_status)
+ return result;
+
+ m_device->lock();
+
+ alGetSourcef(m_source, AL_PITCH, &result);
+
+ m_device->unlock();
+
+ return result;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::setPitch(float pitch)
+{
+ if(!m_status)
+ return false;
+
+ m_device->lock();
+
+ alSourcef(m_source, AL_PITCH, pitch);
+
+ m_device->unlock();
+
+ return true;
+}
+
+int AUD_OpenALDevice::AUD_OpenALHandle::getLoopCount()
+{
+ if(!m_status)
+ return 0;
+ return m_loopcount;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::setLoopCount(int count)
+{
+ if(!m_status)
+ return false;
+ m_loopcount = count;
+ return true;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::setStopCallback(stopCallback callback, void* data)
+{
+ if(!m_status)
+ return false;
+
+ m_device->lock();
+
+ m_stop = callback;
+ m_stop_data = data;
+
+ m_device->unlock();
+
+ return true;
+}
+
+/******************************************************************************/
+/********************* AUD_OpenALHandle 3DHandle Code *************************/
+/******************************************************************************/
+
+AUD_Vector3 AUD_OpenALDevice::AUD_OpenALHandle::getSourceLocation()
+{
+ AUD_Vector3 result = AUD_Vector3(0, 0, 0);
+
+ if(!m_status)
+ return result;
+
+ m_device->lock();
+
+ ALfloat p[3];
+ alGetSourcefv(m_source, AL_POSITION, p);
+
+ m_device->unlock();
+
+ result = AUD_Vector3(p[0], p[1], p[2]);
+
+ return result;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::setSourceLocation(const AUD_Vector3& location)
+{
+ if(!m_status)
+ return false;
+
+ m_device->lock();
+
+ alSourcefv(m_source, AL_POSITION, (ALfloat*)location.get());
+
+ m_device->unlock();
+
+ return true;
+}
+
+AUD_Vector3 AUD_OpenALDevice::AUD_OpenALHandle::getSourceVelocity()
+{
+ AUD_Vector3 result = AUD_Vector3(0, 0, 0);
+
+ if(!m_status)
+ return result;
+
+ m_device->lock();
+
+ ALfloat v[3];
+ alGetSourcefv(m_source, AL_VELOCITY, v);
+
+ m_device->unlock();
+
+ result = AUD_Vector3(v[0], v[1], v[2]);
+
+ return result;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::setSourceVelocity(const AUD_Vector3& velocity)
+{
+ if(!m_status)
+ return false;
+
+ m_device->lock();
+
+ alSourcefv(m_source, AL_VELOCITY, (ALfloat*)velocity.get());
+
+ m_device->unlock();
+
+ return true;
+}
+
+AUD_Quaternion AUD_OpenALDevice::AUD_OpenALHandle::getSourceOrientation()
+{
+ // AUD_XXX not implemented yet
+ return AUD_Quaternion(0, 0, 0, 0);
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::setSourceOrientation(const AUD_Quaternion& orientation)
+{
+ if(!m_status)
+ return false;
+
+ ALfloat direction[3];
+ direction[0] = -2 * (orientation.w() * orientation.y() +
+ orientation.x() * orientation.z());
+ direction[1] = 2 * (orientation.x() * orientation.w() -
+ orientation.z() * orientation.y());
+ direction[2] = 2 * (orientation.x() * orientation.x() +
+ orientation.y() * orientation.y()) - 1;
+ m_device->lock();
+
+ alSourcefv(m_source, AL_DIRECTION, direction);
+
+ m_device->unlock();
+
+ return true;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::isRelative()
+{
+ int result = std::numeric_limits<float>::quiet_NaN();
+
+ if(!m_status)
+ return result;
+
+ m_device->lock();
+
+ alGetSourcei(m_source, AL_SOURCE_RELATIVE, &result);
+
+ m_device->unlock();
+
+ return result;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::setRelative(bool relative)
+{
+ if(!m_status)
+ return false;
+
+ m_device->lock();
+
+ alSourcei(m_source, AL_SOURCE_RELATIVE, relative);
+
+ m_device->unlock();
+
+ return true;
+}
+
+float AUD_OpenALDevice::AUD_OpenALHandle::getVolumeMaximum()
+{
+ float result = std::numeric_limits<float>::quiet_NaN();
+
+ if(!m_status)
+ return result;
+
+ m_device->lock();
+
+ alGetSourcef(m_source, AL_MAX_GAIN, &result);
+
+ m_device->unlock();
+
+ return result;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::setVolumeMaximum(float volume)
+{
+ if(!m_status)
+ return false;
+
+ m_device->lock();
+
+ alSourcef(m_source, AL_MAX_GAIN, volume);
+
+ m_device->unlock();
+
+ return true;
+}
+
+float AUD_OpenALDevice::AUD_OpenALHandle::getVolumeMinimum()
+{
+ float result = std::numeric_limits<float>::quiet_NaN();
+
+ if(!m_status)
+ return result;
+
+ m_device->lock();
+
+ alGetSourcef(m_source, AL_MIN_GAIN, &result);
+
+ m_device->unlock();
+
+ return result;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::setVolumeMinimum(float volume)
+{
+ if(!m_status)
+ return false;
+
+ m_device->lock();
+
+ alSourcef(m_source, AL_MIN_GAIN, volume);
+
+ m_device->unlock();
+
+ return true;
+}
+
+float AUD_OpenALDevice::AUD_OpenALHandle::getDistanceMaximum()
+{
+ float result = std::numeric_limits<float>::quiet_NaN();
+
+ if(!m_status)
+ return result;
+
+ m_device->lock();
+
+ alGetSourcef(m_source, AL_MAX_DISTANCE, &result);
+
+ m_device->unlock();
+
+ return result;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::setDistanceMaximum(float distance)
+{
+ if(!m_status)
+ return false;
+
+ m_device->lock();
+
+ alSourcef(m_source, AL_MAX_DISTANCE, distance);
+
+ m_device->unlock();
+
+ return true;
+}
+
+float AUD_OpenALDevice::AUD_OpenALHandle::getDistanceReference()
+{
+ float result = std::numeric_limits<float>::quiet_NaN();
+
+ if(!m_status)
+ return result;
+
+ m_device->lock();
+
+ alGetSourcef(m_source, AL_REFERENCE_DISTANCE, &result);
+
+ m_device->unlock();
+
+ return result;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::setDistanceReference(float distance)
+{
+ if(!m_status)
+ return false;
+
+ m_device->lock();
-typedef std::list<AUD_OpenALHandle*>::iterator AUD_HandleIterator;
-typedef std::list<AUD_OpenALBufferedFactory*>::iterator AUD_BFIterator;
+ alSourcef(m_source, AL_REFERENCE_DISTANCE, distance);
+
+ m_device->unlock();
+
+ return true;
+}
+
+float AUD_OpenALDevice::AUD_OpenALHandle::getAttenuation()
+{
+ float result = std::numeric_limits<float>::quiet_NaN();
+
+ if(!m_status)
+ return result;
+
+ m_device->lock();
+
+ alGetSourcef(m_source, AL_ROLLOFF_FACTOR, &result);
+
+ m_device->unlock();
+
+ return result;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::setAttenuation(float factor)
+{
+ if(!m_status)
+ return false;
+
+ m_device->lock();
+
+ alSourcef(m_source, AL_ROLLOFF_FACTOR, factor);
+
+ m_device->unlock();
+
+ return true;
+}
+
+float AUD_OpenALDevice::AUD_OpenALHandle::getConeAngleOuter()
+{
+ float result = std::numeric_limits<float>::quiet_NaN();
+
+ if(!m_status)
+ return result;
+
+ m_device->lock();
+
+ alGetSourcef(m_source, AL_CONE_OUTER_ANGLE, &result);
+
+ m_device->unlock();
+
+ return result;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::setConeAngleOuter(float angle)
+{
+ if(!m_status)
+ return false;
+
+ m_device->lock();
+
+ alSourcef(m_source, AL_CONE_OUTER_ANGLE, angle);
+
+ m_device->unlock();
+
+ return true;
+}
+
+float AUD_OpenALDevice::AUD_OpenALHandle::getConeAngleInner()
+{
+ float result = std::numeric_limits<float>::quiet_NaN();
+
+ if(!m_status)
+ return result;
+
+ m_device->lock();
+
+ alGetSourcef(m_source, AL_CONE_INNER_ANGLE, &result);
+
+ m_device->unlock();
+
+ return result;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::setConeAngleInner(float angle)
+{
+ if(!m_status)
+ return false;
+
+ m_device->lock();
+
+ alSourcef(m_source, AL_CONE_INNER_ANGLE, angle);
+
+ m_device->unlock();
+
+ return true;
+}
+
+float AUD_OpenALDevice::AUD_OpenALHandle::getConeVolumeOuter()
+{
+ float result = std::numeric_limits<float>::quiet_NaN();
+
+ if(!m_status)
+ return result;
+
+ m_device->lock();
+
+ alGetSourcef(m_source, AL_CONE_OUTER_GAIN, &result);
+
+ m_device->unlock();
+
+ return result;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::setConeVolumeOuter(float volume)
+{
+ if(!m_status)
+ return false;
+
+ m_device->lock();
+
+ alSourcef(m_source, AL_CONE_OUTER_GAIN, volume);
+
+ m_device->unlock();
+
+ return true;
+}
/******************************************************************************/
/**************************** Threading Code **********************************/
@@ -127,15 +794,15 @@ void AUD_OpenALDevice::start()
void AUD_OpenALDevice::updateStreams()
{
- AUD_OpenALHandle* sound;
+ AUD_Reference<AUD_OpenALHandle> sound;
int length;
ALint info;
AUD_DeviceSpecs specs = m_specs;
ALCenum cerr;
- std::list<AUD_OpenALHandle*> stopSounds;
- std::list<AUD_OpenALHandle*> pauseSounds;
+ std::list<AUD_Reference<AUD_OpenALHandle> > stopSounds;
+ std::list<AUD_Reference<AUD_OpenALHandle> > pauseSounds;
AUD_HandleIterator it;
while(1)
@@ -147,45 +814,45 @@ void AUD_OpenALDevice::updateStreams()
if(cerr == ALC_NO_ERROR)
{
// for all sounds
- for(it = m_playingSounds->begin(); it != m_playingSounds->end(); it++)
+ for(it = m_playingSounds.begin(); it != m_playingSounds.end(); it++)
{
sound = *it;
// is it a streamed sound?
- if(!sound->isBuffered)
+ if(!sound->m_isBuffered)
{
// check for buffer refilling
- alGetSourcei(sound->source, AL_BUFFERS_PROCESSED, &info);
+ alGetSourcei(sound->m_source, AL_BUFFERS_PROCESSED, &info);
if(info)
{
- specs.specs = sound->reader->getSpecs();
+ specs.specs = sound->m_reader->getSpecs();
m_buffer.assureSize(m_buffersize * AUD_DEVICE_SAMPLE_SIZE(specs));
// for all empty buffers
while(info--)
{
// if there's still data to play back
- if(!sound->eos)
+ if(!sound->m_eos)
{
// read data
length = m_buffersize;
- sound->reader->read(length, sound->eos, m_buffer.getBuffer());
+ sound->m_reader->read(length, sound->m_eos, m_buffer.getBuffer());
// looping necessary?
- if(length == 0 && sound->loopcount)
+ if(length == 0 && sound->m_loopcount)
{
- if(sound->loopcount > 0)
- sound->loopcount--;
+ if(sound->m_loopcount > 0)
+ sound->m_loopcount--;
- sound->reader->seek(0);
+ sound->m_reader->seek(0);
length = m_buffersize;
- sound->reader->read(length, sound->eos, m_buffer.getBuffer());
+ sound->m_reader->read(length, sound->m_eos, m_buffer.getBuffer());
}
- if(sound->loopcount != 0)
- sound->eos = false;
+ if(sound->m_loopcount != 0)
+ sound->m_eos = false;
// read nothing?
if(length == 0)
@@ -194,39 +861,39 @@ void AUD_OpenALDevice::updateStreams()
}
// unqueue buffer
- alSourceUnqueueBuffers(sound->source, 1,
- &sound->buffers[sound->current]);
+ alSourceUnqueueBuffers(sound->m_source, 1,
+ &sound->m_buffers[sound->m_current]);
ALenum err;
if((err = alGetError()) != AL_NO_ERROR)
{
- sound->eos = true;
+ sound->m_eos = true;
break;
}
// fill with new data
- alBufferData(sound->buffers[sound->current],
- sound->format,
+ alBufferData(sound->m_buffers[sound->m_current],
+ sound->m_format,
m_buffer.getBuffer(), length *
AUD_DEVICE_SAMPLE_SIZE(specs),
specs.rate);
if((err = alGetError()) != AL_NO_ERROR)
{
- sound->eos = true;
+ sound->m_eos = true;
break;
}
// and queue again
- alSourceQueueBuffers(sound->source, 1,
- &sound->buffers[sound->current]);
+ alSourceQueueBuffers(sound->m_source, 1,
+ &sound->m_buffers[sound->m_current]);
if(alGetError() != AL_NO_ERROR)
{
- sound->eos = true;
+ sound->m_eos = true;
break;
}
- sound->current = (sound->current+1) %
- AUD_OPENAL_CYCLE_BUFFERS;
+ sound->m_current = (sound->m_current+1) %
+ AUD_OpenALHandle::CYCLE_BUFFERS;
}
else
break;
@@ -235,18 +902,18 @@ void AUD_OpenALDevice::updateStreams()
}
// check if the sound has been stopped
- alGetSourcei(sound->source, AL_SOURCE_STATE, &info);
+ alGetSourcei(sound->m_source, AL_SOURCE_STATE, &info);
if(info != AL_PLAYING)
{
// if it really stopped
- if(sound->eos)
+ if(sound->m_eos)
{
- if(sound->stop)
- sound->stop(sound->stop_data);
+ if(sound->m_stop)
+ sound->m_stop(sound->m_stop_data);
// pause or
- if(sound->keep)
+ if(sound->m_keep)
pauseSounds.push_back(sound);
// stop
else
@@ -254,15 +921,15 @@ void AUD_OpenALDevice::updateStreams()
}
// continue playing
else
- alSourcePlay(sound->source);
+ alSourcePlay(sound->m_source);
}
}
for(it = pauseSounds.begin(); it != pauseSounds.end(); it++)
- pause(*it);
+ (*it)->pause();
for(it = stopSounds.begin(); it != stopSounds.end(); it++)
- stop(*it);
+ (*it)->stop();
pauseSounds.clear();
stopSounds.clear();
@@ -271,7 +938,7 @@ void AUD_OpenALDevice::updateStreams()
}
// stop thread
- if(m_playingSounds->empty() || (cerr != ALC_NO_ERROR))
+ if(m_playingSounds.empty() || (cerr != ALC_NO_ERROR))
{
unlock();
m_playing = false;
@@ -292,19 +959,6 @@ void AUD_OpenALDevice::updateStreams()
/**************************** IDevice Code ************************************/
/******************************************************************************/
-bool AUD_OpenALDevice::isValid(AUD_Handle* handle)
-{
- for(AUD_HandleIterator i = m_playingSounds->begin();
- i != m_playingSounds->end(); i++)
- if(*i == handle)
- return true;
- for(AUD_HandleIterator i = m_pausedSounds->begin();
- i != m_pausedSounds->end(); i++)
- if(*i == handle)
- return true;
- return false;
-}
-
static const char* open_error = "AUD_OpenALDevice: Device couldn't be opened.";
AUD_OpenALDevice::AUD_OpenALDevice(AUD_DeviceSpecs specs, int buffersize)
@@ -357,9 +1011,7 @@ AUD_OpenALDevice::AUD_OpenALDevice(AUD_DeviceSpecs specs, int buffersize)
m_buffersize = buffersize;
m_playing = false;
- m_playingSounds = new std::list<AUD_OpenALHandle*>();
- m_pausedSounds = new std::list<AUD_OpenALHandle*>();
- m_bufferedFactories = new std::list<AUD_OpenALBufferedFactory*>();
+// m_bufferedFactories = new std::list<AUD_OpenALBufferedFactory*>();
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
@@ -372,44 +1024,23 @@ AUD_OpenALDevice::AUD_OpenALDevice(AUD_DeviceSpecs specs, int buffersize)
AUD_OpenALDevice::~AUD_OpenALDevice()
{
- AUD_OpenALHandle* sound;
-
lock();
alcSuspendContext(m_context);
- // delete all playing sounds
- while(!m_playingSounds->empty())
- {
- sound = *(m_playingSounds->begin());
- alDeleteSources(1, &sound->source);
- if(!sound->isBuffered)
- {
- alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
- }
- delete sound;
- m_playingSounds->erase(m_playingSounds->begin());
- }
+ while(!m_playingSounds.empty())
+ m_playingSounds.front()->stop();
+
+ while(!m_pausedSounds.empty())
+ m_pausedSounds.front()->stop();
- // delete all paused sounds
- while(!m_pausedSounds->empty())
- {
- sound = *(m_pausedSounds->begin());
- alDeleteSources(1, &sound->source);
- if(!sound->isBuffered)
- {
- alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
- }
- delete sound;
- m_pausedSounds->erase(m_pausedSounds->begin());
- }
// delete all buffered factories
- while(!m_bufferedFactories->empty())
+ /*while(!m_bufferedFactories->empty())
{
alDeleteBuffers(1, &(*(m_bufferedFactories->begin()))->buffer);
delete *m_bufferedFactories->begin();
m_bufferedFactories->erase(m_bufferedFactories->begin());
- }
+ }*/
alcProcessContext(m_context);
@@ -422,9 +1053,7 @@ AUD_OpenALDevice::~AUD_OpenALDevice()
else
unlock();
- delete m_playingSounds;
- delete m_pausedSounds;
- delete m_bufferedFactories;
+ //delete m_bufferedFactories;
// quit OpenAL
alcMakeContextCurrent(NULL);
@@ -530,116 +1159,52 @@ bool AUD_OpenALDevice::getFormat(ALenum &format, AUD_Specs specs)
return valid;
}
-static const char* genbuffer_error = "AUD_OpenALDevice: Buffer couldn't be "
- "generated.";
-static const char* gensource_error = "AUD_OpenALDevice: Source couldn't be "
- "generated.";
-static const char* queue_error = "AUD_OpenALDevice: Buffer couldn't be "
- "queued to the source.";
-static const char* bufferdata_error = "AUD_OpenALDevice: Buffer couldn't be "
- "filled with data.";
-
-AUD_Handle* AUD_OpenALDevice::play(AUD_Reference<AUD_IReader> reader, bool keep)
+AUD_Reference<AUD_IHandle> AUD_OpenALDevice::play(AUD_Reference<AUD_IReader> reader, bool keep)
{
- AUD_OpenALHandle* sound = NULL;
-
- AUD_DeviceSpecs specs = m_specs;
- specs.specs = reader->getSpecs();
+ AUD_Specs specs = reader->getSpecs();
// check format
- bool valid = specs.channels != AUD_CHANNELS_INVALID;
+ if(specs.channels == AUD_CHANNELS_INVALID)
+ return NULL;
if(m_specs.format != AUD_FORMAT_FLOAT32)
reader = new AUD_ConverterReader(reader, m_specs);
- // create the handle
- sound = new AUD_OpenALHandle;
- sound->keep = keep;
- sound->reader = reader;
- sound->current = 0;
- sound->isBuffered = false;
- sound->loopcount = 0;
- sound->stop = NULL;
- sound->stop_data = NULL;
-
- valid &= getFormat(sound->format, specs.specs);
+ ALenum format;
- if(!valid)
- {
- delete sound;
+ if(!getFormat(format, specs))
return NULL;
- }
lock();
alcSuspendContext(m_context);
- // OpenAL playback code
+ AUD_Reference<AUD_OpenALDevice::AUD_OpenALHandle> sound;
+
try
{
- alGenBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
- if(alGetError() != AL_NO_ERROR)
- AUD_THROW(AUD_ERROR_OPENAL, genbuffer_error);
-
- try
- {
- m_buffer.assureSize(m_buffersize * AUD_DEVICE_SAMPLE_SIZE(specs));
- int length;
-
- for(int i = 0; i < AUD_OPENAL_CYCLE_BUFFERS; i++)
- {
- length = m_buffersize;
- reader->read(length,sound->eos, m_buffer.getBuffer());
- alBufferData(sound->buffers[i], sound->format, m_buffer.getBuffer(),
- length * AUD_DEVICE_SAMPLE_SIZE(specs),
- specs.rate);
- if(alGetError() != AL_NO_ERROR)
- AUD_THROW(AUD_ERROR_OPENAL, bufferdata_error);
- }
-
- alGenSources(1, &sound->source);
- if(alGetError() != AL_NO_ERROR)
- AUD_THROW(AUD_ERROR_OPENAL, gensource_error);
-
- try
- {
- alSourceQueueBuffers(sound->source, AUD_OPENAL_CYCLE_BUFFERS,
- sound->buffers);
- if(alGetError() != AL_NO_ERROR)
- AUD_THROW(AUD_ERROR_OPENAL, queue_error);
- }
- catch(AUD_Exception&)
- {
- alDeleteSources(1, &sound->source);
- throw;
- }
- }
- catch(AUD_Exception&)
- {
- alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
- throw;
- }
+ // create the handle
+ sound = new AUD_OpenALDevice::AUD_OpenALHandle(this, format, reader, keep);
}
catch(AUD_Exception&)
{
- delete sound;
alcProcessContext(m_context);
unlock();
throw;
}
+ alcProcessContext(m_context);
+
// play sound
- m_playingSounds->push_back(sound);
- alSourcei(sound->source, AL_SOURCE_RELATIVE, 1);
+ m_playingSounds.push_back(sound);
start();
- alcProcessContext(m_context);
unlock();
- return sound;
+ return AUD_Reference<AUD_IHandle>(sound);
}
-AUD_Handle* AUD_OpenALDevice::play(AUD_Reference<AUD_IFactory> factory, bool keep)
+AUD_Reference<AUD_IHandle> AUD_OpenALDevice::play(AUD_Reference<AUD_IFactory> factory, bool keep)
{
/* AUD_XXX disabled
AUD_OpenALHandle* sound = NULL;
@@ -716,262 +1281,6 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_Reference<AUD_IFactory> factory, bool kee
return play(factory->createReader(), keep);
}
-bool AUD_OpenALDevice::pause(AUD_Handle* handle)
-{
- bool result = false;
-
- lock();
-
- // only songs that are played can be paused
- for(AUD_HandleIterator i = m_playingSounds->begin();
- i != m_playingSounds->end(); i++)
- {
- if(*i == handle)
- {
- m_pausedSounds->push_back(*i);
- alSourcePause((*i)->source);
- m_playingSounds->erase(i);
- result = true;
- break;
- }
- }
-
- unlock();
-
- return result;
-}
-
-bool AUD_OpenALDevice::resume(AUD_Handle* handle)
-{
- bool result = false;
-
- lock();
-
- // only songs that are paused can be resumed
- for(AUD_HandleIterator i = m_pausedSounds->begin();
- i != m_pausedSounds->end(); i++)
- {
- if(*i == handle)
- {
- m_playingSounds->push_back(*i);
- start();
- m_pausedSounds->erase(i);
- result = true;
- break;
- }
- }
-
- unlock();
-
- return result;
-}
-
-bool AUD_OpenALDevice::stop(AUD_Handle* handle)
-{
- AUD_OpenALHandle* sound;
-
- bool result = false;
-
- lock();
-
- for(AUD_HandleIterator i = m_playingSounds->begin();
- i != m_playingSounds->end(); i++)
- {
- if(*i == handle)
- {
- sound = *i;
- alDeleteSources(1, &sound->source);
- if(!sound->isBuffered)
- {
- alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
- }
- delete *i;
- m_playingSounds->erase(i);
- result = true;
- break;
- }
- }
- if(!result)
- {
- for(AUD_HandleIterator i = m_pausedSounds->begin();
- i != m_pausedSounds->end(); i++)
- {
- if(*i == handle)
- {
- sound = *i;
- alDeleteSources(1, &sound->source);
- if(!sound->isBuffered)
- {
- alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
- }
- delete *i;
- m_pausedSounds->erase(i);
- result = true;
- break;
- }
- }
- }
-
- unlock();
-
- return result;
-}
-
-bool AUD_OpenALDevice::getKeep(AUD_Handle* handle)
-{
- bool result = false;
-
- lock();
-
- if(isValid(handle))
- result = ((AUD_OpenALHandle*)handle)->keep;
-
- unlock();
-
- return result;
-}
-
-bool AUD_OpenALDevice::setKeep(AUD_Handle* handle, bool keep)
-{
- bool result = false;
-
- lock();
-
- if(isValid(handle))
- {
- ((AUD_OpenALHandle*)handle)->keep = keep;
- result = true;
- }
-
- unlock();
-
- return result;
-}
-
-bool AUD_OpenALDevice::seek(AUD_Handle* handle, float position)
-{
- bool result = false;
-
- lock();
-
- if(isValid(handle))
- {
- AUD_OpenALHandle* alhandle = (AUD_OpenALHandle*)handle;
- if(alhandle->isBuffered)
- alSourcef(alhandle->source, AL_SEC_OFFSET, position);
- else
- {
- alhandle->reader->seek((int)(position *
- alhandle->reader->getSpecs().rate));
- alhandle->eos = false;
-
- ALint info;
-
- alGetSourcei(alhandle->source, AL_SOURCE_STATE, &info);
-
- if(info != AL_PLAYING)
- {
- if(info == AL_PAUSED)
- alSourceStop(alhandle->source);
-
- alSourcei(alhandle->source, AL_BUFFER, 0);
- alhandle->current = 0;
-
- ALenum err;
- if((err = alGetError()) == AL_NO_ERROR)
- {
- int length;
- AUD_DeviceSpecs specs = m_specs;
- specs.specs = alhandle->reader->getSpecs();
- m_buffer.assureSize(m_buffersize * AUD_DEVICE_SAMPLE_SIZE(specs));
-
- for(int i = 0; i < AUD_OPENAL_CYCLE_BUFFERS; i++)
- {
- length = m_buffersize;
- alhandle->reader->read(length, alhandle->eos, m_buffer.getBuffer());
- alBufferData(alhandle->buffers[i], alhandle->format,
- m_buffer.getBuffer(),
- length * AUD_DEVICE_SAMPLE_SIZE(specs),
- specs.rate);
-
- if(alGetError() != AL_NO_ERROR)
- break;
- }
-
- if(alhandle->loopcount != 0)
- alhandle->eos = false;
-
- alSourceQueueBuffers(alhandle->source,
- AUD_OPENAL_CYCLE_BUFFERS,
- alhandle->buffers);
- }
-
- alSourceRewind(alhandle->source);
- }
- }
- result = true;
- }
-
- unlock();
- return result;
-}
-
-float AUD_OpenALDevice::getPosition(AUD_Handle* handle)
-{
- float position = 0.0f;
-
- lock();
-
- if(isValid(handle))
- {
- AUD_OpenALHandle* h = (AUD_OpenALHandle*)handle;
- alGetSourcef(h->source, AL_SEC_OFFSET, &position);
- if(!h->isBuffered)
- {
- AUD_Specs specs = h->reader->getSpecs();
- position += (h->reader->getPosition() - m_buffersize *
- AUD_OPENAL_CYCLE_BUFFERS) /
- (float)specs.rate;
- }
- }
-
- unlock();
- return position;
-}
-
-AUD_Status AUD_OpenALDevice::getStatus(AUD_Handle* handle)
-{
- AUD_Status status = AUD_STATUS_INVALID;
-
- lock();
-
- for(AUD_HandleIterator i = m_playingSounds->begin();
- i != m_playingSounds->end(); i++)
- {
- if(*i == handle)
- {
- status = AUD_STATUS_PLAYING;
- break;
- }
- }
- if(status == AUD_STATUS_INVALID)
- {
- for(AUD_HandleIterator i = m_pausedSounds->begin();
- i != m_pausedSounds->end(); i++)
- {
- if(*i == handle)
- {
- status = AUD_STATUS_PAUSED;
- break;
- }
- }
- }
-
- unlock();
-
- return status;
-}
-
void AUD_OpenALDevice::lock()
{
pthread_mutex_lock(&m_mutex);
@@ -994,83 +1303,6 @@ void AUD_OpenALDevice::setVolume(float volume)
alListenerf(AL_GAIN, volume);
}
-float AUD_OpenALDevice::getVolume(AUD_Handle* handle)
-{
- lock();
- float result = std::numeric_limits<float>::quiet_NaN();
- if(isValid(handle))
- alGetSourcef(((AUD_OpenALHandle*)handle)->source,AL_GAIN, &result);
- unlock();
- return result;
-}
-
-bool AUD_OpenALDevice::setVolume(AUD_Handle* handle, float volume)
-{
- lock();
- bool result = isValid(handle);
- if(result)
- alSourcef(((AUD_OpenALHandle*)handle)->source, AL_GAIN, volume);
- unlock();
- return result;
-}
-
-float AUD_OpenALDevice::getPitch(AUD_Handle* handle)
-{
- lock();
- float result = std::numeric_limits<float>::quiet_NaN();
- if(isValid(handle))
- alGetSourcef(((AUD_OpenALHandle*)handle)->source,AL_PITCH, &result);
- unlock();
- return result;
-}
-
-bool AUD_OpenALDevice::setPitch(AUD_Handle* handle, float pitch)
-{
- lock();
- bool result = isValid(handle);
- if(result)
- alSourcef(((AUD_OpenALHandle*)handle)->source, AL_PITCH, pitch);
- unlock();
- return result;
-}
-
-int AUD_OpenALDevice::getLoopCount(AUD_Handle* handle)
-{
- lock();
- int result = 0;
- if(isValid(handle))
- result = ((AUD_OpenALHandle*)handle)->loopcount;
- unlock();
- return result;
-}
-
-bool AUD_OpenALDevice::setLoopCount(AUD_Handle* handle, int count)
-{
- lock();
- bool result = isValid(handle);
- if(result)
- {
- ((AUD_OpenALHandle*)handle)->loopcount = count;
- ((AUD_OpenALHandle*)handle)->eos = false;
- }
- unlock();
- return result;
-}
-
-bool AUD_OpenALDevice::setStopCallback(AUD_Handle* handle, stopCallback callback, void* data)
-{
- lock();
- bool result = isValid(handle);
- if(result)
- {
- AUD_OpenALHandle* h = (AUD_OpenALHandle*)handle;
- h->stop = callback;
- h->stop_data = data;
- }
- unlock();
- return result;
-}
-
/* AUD_XXX Temorary disabled
bool AUD_OpenALDevice::bufferFactory(void *value)
@@ -1308,333 +1540,3 @@ void AUD_OpenALDevice::setDistanceModel(AUD_DistanceModel model)
alDistanceModel(AL_NONE);
}
}
-
-AUD_Vector3 AUD_OpenALDevice::getSourceLocation(AUD_Handle* handle)
-{
- AUD_Vector3 result = AUD_Vector3(0, 0, 0);
- ALfloat p[3];
- lock();
-
- if(isValid(handle))
- {
- alGetSourcefv(((AUD_OpenALHandle*)handle)->source, AL_POSITION, p);
- result = AUD_Vector3(p[0], p[1], p[2]);
- }
-
- unlock();
- return result;
-}
-
-bool AUD_OpenALDevice::setSourceLocation(AUD_Handle* handle, const AUD_Vector3& location)
-{
- lock();
- bool result = isValid(handle);
-
- if(result)
- alSourcefv(((AUD_OpenALHandle*)handle)->source, AL_POSITION,
- (ALfloat*)location.get());
-
- unlock();
- return result;
-}
-
-AUD_Vector3 AUD_OpenALDevice::getSourceVelocity(AUD_Handle* handle)
-{
- AUD_Vector3 result = AUD_Vector3(0, 0, 0);
- ALfloat v[3];
- lock();
-
- if(isValid(handle))
- {
- alGetSourcefv(((AUD_OpenALHandle*)handle)->source, AL_VELOCITY, v);
- result = AUD_Vector3(v[0], v[1], v[2]);
- }
-
- unlock();
- return result;
-}
-
-bool AUD_OpenALDevice::setSourceVelocity(AUD_Handle* handle, const AUD_Vector3& velocity)
-{
- lock();
- bool result = isValid(handle);
-
- if(result)
- alSourcefv(((AUD_OpenALHandle*)handle)->source, AL_VELOCITY,
- (ALfloat*)velocity.get());
-
- unlock();
- return result;
-}
-
-AUD_Quaternion AUD_OpenALDevice::getSourceOrientation(AUD_Handle* handle)
-{
- // AUD_XXX not implemented yet
- return AUD_Quaternion(0, 0, 0, 0);
-}
-
-bool AUD_OpenALDevice::setSourceOrientation(AUD_Handle* handle, const AUD_Quaternion& orientation)
-{
- lock();
- bool result = isValid(handle);
-
- if(result)
- {
- ALfloat direction[3];
- direction[0] = -2 * (orientation.w() * orientation.y() +
- orientation.x() * orientation.z());
- direction[1] = 2 * (orientation.x() * orientation.w() -
- orientation.z() * orientation.y());
- direction[2] = 2 * (orientation.x() * orientation.x() +
- orientation.y() * orientation.y()) - 1;
- alSourcefv(((AUD_OpenALHandle*)handle)->source, AL_DIRECTION,
- direction);
- }
-
- unlock();
- return result;
-}
-
-bool AUD_OpenALDevice::isRelative(AUD_Handle* handle)
-{
- int result = std::numeric_limits<float>::quiet_NaN();;
-
- lock();
-
- if(isValid(handle))
- alGetSourcei(((AUD_OpenALHandle*)handle)->source, AL_SOURCE_RELATIVE,
- &result);
-
- unlock();
- return result;
-}
-
-bool AUD_OpenALDevice::setRelative(AUD_Handle* handle, bool relative)
-{
- lock();
- bool result = isValid(handle);
-
- if(result)
- alSourcei(((AUD_OpenALHandle*)handle)->source, AL_SOURCE_RELATIVE,
- relative);
-
- unlock();
- return result;
-}
-
-float AUD_OpenALDevice::getVolumeMaximum(AUD_Handle* handle)
-{
- float result = std::numeric_limits<float>::quiet_NaN();;
-
- lock();
-
- if(isValid(handle))
- alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_MAX_GAIN,
- &result);
-
- unlock();
- return result;
-}
-
-bool AUD_OpenALDevice::setVolumeMaximum(AUD_Handle* handle, float volume)
-{
- lock();
- bool result = isValid(handle);
-
- if(result)
-
- alSourcef(((AUD_OpenALHandle*)handle)->source, AL_MAX_GAIN,
- volume);
-
- unlock();
- return result;
-}
-
-float AUD_OpenALDevice::getVolumeMinimum(AUD_Handle* handle)
-{
- float result = std::numeric_limits<float>::quiet_NaN();;
-
- lock();
-
- if(isValid(handle))
- alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_MIN_GAIN,
- &result);
-
- unlock();
- return result;
-}
-
-bool AUD_OpenALDevice::setVolumeMinimum(AUD_Handle* handle, float volume)
-{
- lock();
- bool result = isValid(handle);
-
- if(result)
- alSourcef(((AUD_OpenALHandle*)handle)->source, AL_MIN_GAIN,
- volume);
-
- unlock();
- return result;
-}
-
-float AUD_OpenALDevice::getDistanceMaximum(AUD_Handle* handle)
-{
- float result = std::numeric_limits<float>::quiet_NaN();;
-
- lock();
-
- if(isValid(handle))
- alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_MAX_DISTANCE,
- &result);
-
- unlock();
- return result;
-}
-
-bool AUD_OpenALDevice::setDistanceMaximum(AUD_Handle* handle, float distance)
-{
- lock();
- bool result = isValid(handle);
-
- if(result)
- alSourcef(((AUD_OpenALHandle*)handle)->source, AL_MAX_DISTANCE,
- distance);
-
- unlock();
- return result;
-}
-
-float AUD_OpenALDevice::getDistanceReference(AUD_Handle* handle)
-{
- float result = std::numeric_limits<float>::quiet_NaN();;
-
- lock();
-
- if(isValid(handle))
- alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_REFERENCE_DISTANCE,
- &result);
-
- unlock();
- return result;
-}
-
-bool AUD_OpenALDevice::setDistanceReference(AUD_Handle* handle, float distance)
-{
- lock();
- bool result = isValid(handle);
-
- if(result)
- alSourcef(((AUD_OpenALHandle*)handle)->source, AL_REFERENCE_DISTANCE,
- distance);
-
- unlock();
- return result;
-}
-
-float AUD_OpenALDevice::getAttenuation(AUD_Handle* handle)
-{
- float result = std::numeric_limits<float>::quiet_NaN();;
-
- lock();
-
- if(isValid(handle))
- alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_ROLLOFF_FACTOR,
- &result);
-
- unlock();
- return result;
-}
-
-bool AUD_OpenALDevice::setAttenuation(AUD_Handle* handle, float factor)
-{
- lock();
- bool result = isValid(handle);
-
- if(result)
- alSourcef(((AUD_OpenALHandle*)handle)->source, AL_ROLLOFF_FACTOR,
- factor);
-
- unlock();
- return result;
-}
-
-float AUD_OpenALDevice::getConeAngleOuter(AUD_Handle* handle)
-{
- float result = std::numeric_limits<float>::quiet_NaN();;
-
- lock();
-
- if(isValid(handle))
- alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_CONE_OUTER_ANGLE,
- &result);
-
- unlock();
- return result;
-}
-
-bool AUD_OpenALDevice::setConeAngleOuter(AUD_Handle* handle, float angle)
-{
- lock();
- bool result = isValid(handle);
-
- if(result)
- alSourcef(((AUD_OpenALHandle*)handle)->source, AL_CONE_OUTER_ANGLE,
- angle);
-
- unlock();
- return result;
-}
-
-float AUD_OpenALDevice::getConeAngleInner(AUD_Handle* handle)
-{
- float result = std::numeric_limits<float>::quiet_NaN();;
-
- lock();
-
- if(isValid(handle))
- alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_CONE_INNER_ANGLE,
- &result);
-
- unlock();
- return result;
-}
-
-bool AUD_OpenALDevice::setConeAngleInner(AUD_Handle* handle, float angle)
-{
- lock();
- bool result = isValid(handle);
-
- if(result)
- alSourcef(((AUD_OpenALHandle*)handle)->source, AL_CONE_INNER_ANGLE,
- angle);
-
- unlock();
- return result;
-}
-
-float AUD_OpenALDevice::getConeVolumeOuter(AUD_Handle* handle)
-{
- float result = std::numeric_limits<float>::quiet_NaN();;
-
- lock();
-
- if(isValid(handle))
- alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_CONE_OUTER_GAIN,
- &result);
-
- unlock();
- return result;
-}
-
-bool AUD_OpenALDevice::setConeVolumeOuter(AUD_Handle* handle, float volume)
-{
- lock();
- bool result = isValid(handle);
-
- if(result)
- alSourcef(((AUD_OpenALHandle*)handle)->source, AL_CONE_OUTER_GAIN,
- volume);
-
- unlock();
- return result;
-}
diff --git a/intern/audaspace/OpenAL/AUD_OpenALDevice.h b/intern/audaspace/OpenAL/AUD_OpenALDevice.h
index d5db5989fe7..6bf04a36329 100644
--- a/intern/audaspace/OpenAL/AUD_OpenALDevice.h
+++ b/intern/audaspace/OpenAL/AUD_OpenALDevice.h
@@ -33,10 +33,11 @@
#define AUD_OPENALDEVICE
#include "AUD_IDevice.h"
+#include "AUD_IHandle.h"
#include "AUD_I3DDevice.h"
+#include "AUD_I3DHandle.h"
#include "AUD_Buffer.h"
-struct AUD_OpenALHandle;
-struct AUD_OpenALBufferedFactory;
+//struct AUD_OpenALBufferedFactory;
#include <AL/al.h>
#include <AL/alc.h>
@@ -49,6 +50,99 @@ struct AUD_OpenALBufferedFactory;
class AUD_OpenALDevice : public AUD_IDevice, public AUD_I3DDevice
{
private:
+ /// Saves the data for playback.
+ class AUD_OpenALHandle : public AUD_IHandle, public AUD_I3DHandle
+ {
+ public:
+ static const int CYCLE_BUFFERS = 3;
+
+ /// Whether it's a buffered or a streamed source.
+ bool m_isBuffered;
+
+ /// The reader source.
+ AUD_Reference<AUD_IReader> m_reader;
+
+ /// Whether to keep the source if end of it is reached.
+ bool m_keep;
+
+ /// OpenAL sample format.
+ ALenum m_format;
+
+ /// OpenAL source.
+ ALuint m_source;
+
+ /// OpenAL buffers.
+ ALuint m_buffers[CYCLE_BUFFERS];
+
+ /// The first buffer to be read next.
+ int m_current;
+
+ /// Whether the stream doesn't return any more data.
+ bool m_eos;
+
+ /// The loop count of the source.
+ int m_loopcount;
+
+ /// The stop callback.
+ stopCallback m_stop;
+
+ /// Stop callback data.
+ void* m_stop_data;
+
+ /// Current status of the handle
+ AUD_Status m_status;
+
+ /// Own device.
+ AUD_OpenALDevice* m_device;
+
+ public:
+
+ AUD_OpenALHandle(AUD_OpenALDevice* device, ALenum format, AUD_Reference<AUD_IReader> reader, bool keep);
+
+ virtual ~AUD_OpenALHandle() {}
+ virtual bool pause();
+ virtual bool resume();
+ virtual bool stop();
+ virtual bool getKeep();
+ virtual bool setKeep(bool keep);
+ virtual bool seek(float position);
+ virtual float getPosition();
+ virtual AUD_Status getStatus();
+ virtual float getVolume();
+ virtual bool setVolume(float volume);
+ virtual float getPitch();
+ virtual bool setPitch(float pitch);
+ virtual int getLoopCount();
+ virtual bool setLoopCount(int count);
+ virtual bool setStopCallback(stopCallback callback = 0, void* data = 0);
+
+ virtual AUD_Vector3 getSourceLocation();
+ virtual bool setSourceLocation(const AUD_Vector3& location);
+ virtual AUD_Vector3 getSourceVelocity();
+ virtual bool setSourceVelocity(const AUD_Vector3& velocity);
+ virtual AUD_Quaternion getSourceOrientation();
+ virtual bool setSourceOrientation(const AUD_Quaternion& orientation);
+ virtual bool isRelative();
+ virtual bool setRelative(bool relative);
+ virtual float getVolumeMaximum();
+ virtual bool setVolumeMaximum(float volume);
+ virtual float getVolumeMinimum();
+ virtual bool setVolumeMinimum(float volume);
+ virtual float getDistanceMaximum();
+ virtual bool setDistanceMaximum(float distance);
+ virtual float getDistanceReference();
+ virtual bool setDistanceReference(float distance);
+ virtual float getAttenuation();
+ virtual bool setAttenuation(float factor);
+ virtual float getConeAngleOuter();
+ virtual bool setConeAngleOuter(float angle);
+ virtual float getConeAngleInner();
+ virtual bool setConeAngleInner(float angle);
+ virtual float getConeVolumeOuter();
+ virtual bool setConeVolumeOuter(float volume);
+ };
+
+
/**
* The OpenAL device handle.
*/
@@ -72,17 +166,17 @@ private:
/**
* The list of sounds that are currently playing.
*/
- std::list<AUD_OpenALHandle*>* m_playingSounds;
+ std::list<AUD_Reference<AUD_OpenALHandle> > m_playingSounds;
/**
* The list of sounds that are currently paused.
*/
- std::list<AUD_OpenALHandle*>* m_pausedSounds;
+ std::list<AUD_Reference<AUD_OpenALHandle> > m_pausedSounds;
/**
* The list of buffered factories.
*/
- std::list<AUD_OpenALBufferedFactory*>* m_bufferedFactories;
+ //std::list<AUD_OpenALBufferedFactory*>* m_bufferedFactories;
/**
* The mutex for locking.
@@ -115,13 +209,6 @@ private:
void start();
/**
- * Checks if a handle is valid.
- * \param handle The handle to check.
- * \return Whether the handle is valid.
- */
- bool isValid(AUD_Handle* handle);
-
- /**
* Gets the format according to the specs.
* \param format The variable to put the format into.
* \param specs The specs to read the channel count from.
@@ -153,27 +240,12 @@ public:
virtual ~AUD_OpenALDevice();
virtual AUD_DeviceSpecs getSpecs() const;
- virtual AUD_Handle* play(AUD_Reference<AUD_IReader> reader, bool keep = false);
- virtual AUD_Handle* play(AUD_Reference<AUD_IFactory> factory, bool keep = false);
- virtual bool pause(AUD_Handle* handle);
- virtual bool resume(AUD_Handle* handle);
- virtual bool stop(AUD_Handle* handle);
- virtual bool getKeep(AUD_Handle* handle);
- virtual bool setKeep(AUD_Handle* handle, bool keep);
- virtual bool seek(AUD_Handle* handle, float position);
- virtual float getPosition(AUD_Handle* handle);
- virtual AUD_Status getStatus(AUD_Handle* handle);
+ virtual AUD_Reference<AUD_IHandle> play(AUD_Reference<AUD_IReader> reader, bool keep = false);
+ virtual AUD_Reference<AUD_IHandle> play(AUD_Reference<AUD_IFactory> factory, bool keep = false);
virtual void lock();
virtual void unlock();
virtual float getVolume() const;
virtual void setVolume(float volume);
- virtual float getVolume(AUD_Handle* handle);
- virtual bool setVolume(AUD_Handle* handle, float volume);
- virtual float getPitch(AUD_Handle* handle);
- virtual bool setPitch(AUD_Handle* handle, float pitch);
- virtual int getLoopCount(AUD_Handle* handle);
- virtual bool setLoopCount(AUD_Handle* handle, int count);
- virtual bool setStopCallback(AUD_Handle* handle, stopCallback callback = NULL, void* data = NULL);
virtual AUD_Vector3 getListenerLocation() const;
virtual void setListenerLocation(const AUD_Vector3& location);
@@ -187,30 +259,6 @@ public:
virtual void setDopplerFactor(float factor);
virtual AUD_DistanceModel getDistanceModel() const;
virtual void setDistanceModel(AUD_DistanceModel model);
- virtual AUD_Vector3 getSourceLocation(AUD_Handle* handle);
- virtual bool setSourceLocation(AUD_Handle* handle, const AUD_Vector3& location);
- virtual AUD_Vector3 getSourceVelocity(AUD_Handle* handle);
- virtual bool setSourceVelocity(AUD_Handle* handle, const AUD_Vector3& velocity);
- virtual AUD_Quaternion getSourceOrientation(AUD_Handle* handle);
- virtual bool setSourceOrientation(AUD_Handle* handle, const AUD_Quaternion& orientation);
- virtual bool isRelative(AUD_Handle* handle);
- virtual bool setRelative(AUD_Handle* handle, bool relative);
- virtual float getVolumeMaximum(AUD_Handle* handle);
- virtual bool setVolumeMaximum(AUD_Handle* handle, float volume);
- virtual float getVolumeMinimum(AUD_Handle* handle);
- virtual bool setVolumeMinimum(AUD_Handle* handle, float volume);
- virtual float getDistanceMaximum(AUD_Handle* handle);
- virtual bool setDistanceMaximum(AUD_Handle* handle, float distance);
- virtual float getDistanceReference(AUD_Handle* handle);
- virtual bool setDistanceReference(AUD_Handle* handle, float distance);
- virtual float getAttenuation(AUD_Handle* handle);
- virtual bool setAttenuation(AUD_Handle* handle, float factor);
- virtual float getConeAngleOuter(AUD_Handle* handle);
- virtual bool setConeAngleOuter(AUD_Handle* handle, float angle);
- virtual float getConeAngleInner(AUD_Handle* handle);
- virtual bool setConeAngleInner(AUD_Handle* handle, float angle);
- virtual float getConeVolumeOuter(AUD_Handle* handle);
- virtual bool setConeVolumeOuter(AUD_Handle* handle, float volume);
};
#endif //AUD_OPENALDEVICE
diff --git a/intern/audaspace/Python/AUD_PyAPI.cpp b/intern/audaspace/Python/AUD_PyAPI.cpp
index b6e336eb329..2a4cee4dd0e 100644
--- a/intern/audaspace/Python/AUD_PyAPI.cpp
+++ b/intern/audaspace/Python/AUD_PyAPI.cpp
@@ -33,6 +33,7 @@
#include "structmember.h"
#include "AUD_I3DDevice.h"
+#include "AUD_I3DHandle.h"
#include "AUD_NULLDevice.h"
#include "AUD_DelayFactory.h"
#include "AUD_DoubleFactory.h"
@@ -1033,7 +1034,8 @@ static PyTypeObject FactoryType = {
static void
Handle_dealloc(Handle* self)
{
- Py_XDECREF(self->device);
+ if(self->handle)
+ delete reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle);
Py_TYPE(self)->tp_free((PyObject*)self);
}
@@ -1046,11 +1048,9 @@ PyDoc_STRVAR(M_aud_Handle_pause_doc,
static PyObject *
Handle_pause(Handle *self)
{
- Device* device = (Device*)self->device;
-
try
{
- return PyBool_FromLong((long)(*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(device->device))->pause(self->handle));
+ return PyBool_FromLong((long)(*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->pause());
}
catch(AUD_Exception& e)
{
@@ -1068,11 +1068,9 @@ PyDoc_STRVAR(M_aud_Handle_resume_doc,
static PyObject *
Handle_resume(Handle *self)
{
- Device* device = (Device*)self->device;
-
try
{
- return PyBool_FromLong((long)(*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(device->device))->resume(self->handle));
+ return PyBool_FromLong((long)(*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->resume());
}
catch(AUD_Exception& e)
{
@@ -1091,11 +1089,9 @@ PyDoc_STRVAR(M_aud_Handle_stop_doc,
static PyObject *
Handle_stop(Handle *self)
{
- Device* device = (Device*)self->device;
-
try
{
- return PyBool_FromLong((long)(*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(device->device))->stop(self->handle));
+ return PyBool_FromLong((long)(*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->stop());
}
catch(AUD_Exception& e)
{
@@ -1123,11 +1119,9 @@ PyDoc_STRVAR(M_aud_Handle_position_doc,
static PyObject *
Handle_get_position(Handle *self, void* nothing)
{
- Device* device = (Device*)self->device;
-
try
{
- return Py_BuildValue("f", (*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(device->device))->getPosition(self->handle));
+ return Py_BuildValue("f", (*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->getPosition());
}
catch(AUD_Exception& e)
{
@@ -1144,11 +1138,9 @@ Handle_set_position(Handle *self, PyObject* args, void* nothing)
if(!PyArg_Parse(args, "f:position", &position))
return -1;
- Device* device = (Device*)self->device;
-
try
{
- if((*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(device->device))->seek(self->handle, position))
+ if((*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->seek(position))
return 0;
PyErr_SetString(AUDError, "Couldn't seek the sound!");
}
@@ -1172,11 +1164,9 @@ PyDoc_STRVAR(M_aud_Handle_keep_doc,
static PyObject *
Handle_get_keep(Handle *self, void* nothing)
{
- Device* device = (Device*)self->device;
-
try
{
- return PyBool_FromLong((long)(*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(device->device))->getKeep(self->handle));
+ return PyBool_FromLong((long)(*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->getKeep());
}
catch(AUD_Exception& e)
{
@@ -1195,11 +1185,10 @@ Handle_set_keep(Handle *self, PyObject* args, void* nothing)
}
bool keep = args == Py_True;
- Device* device = (Device*)self->device;
try
{
- if((*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(device->device))->setKeep(self->handle, keep))
+ if((*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->setKeep(keep))
return 0;
PyErr_SetString(AUDError, "Couldn't set keep of the sound!");
}
@@ -1217,11 +1206,9 @@ PyDoc_STRVAR(M_aud_Handle_status_doc,
static PyObject *
Handle_get_status(Handle *self, void* nothing)
{
- Device* device = (Device*)self->device;
-
try
{
- return PyBool_FromLong((long)(*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(device->device))->getStatus(self->handle));
+ return PyBool_FromLong((long)(*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->getStatus());
}
catch(AUD_Exception& e)
{
@@ -1236,11 +1223,9 @@ PyDoc_STRVAR(M_aud_Handle_volume_doc,
static PyObject *
Handle_get_volume(Handle *self, void* nothing)
{
- Device* device = (Device*)self->device;
-
try
{
- return Py_BuildValue("f", (*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(device->device))->getVolume(self->handle));
+ return Py_BuildValue("f", (*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->getVolume());
}
catch(AUD_Exception& e)
{
@@ -1257,11 +1242,9 @@ Handle_set_volume(Handle *self, PyObject* args, void* nothing)
if(!PyArg_Parse(args, "f:volume", &volume))
return -1;
- Device* device = (Device*)self->device;
-
try
{
- if((*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(device->device))->setVolume(self->handle, volume))
+ if((*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->setVolume(volume))
return 0;
PyErr_SetString(AUDError, "Couldn't set the sound volume!");
}
@@ -1279,11 +1262,9 @@ PyDoc_STRVAR(M_aud_Handle_pitch_doc,
static PyObject *
Handle_get_pitch(Handle *self, void* nothing)
{
- Device* device = (Device*)self->device;
-
try
{
- return Py_BuildValue("f", (*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(device->device))->getPitch(self->handle));
+ return Py_BuildValue("f", (*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->getPitch());
}
catch(AUD_Exception& e)
{
@@ -1300,11 +1281,9 @@ Handle_set_pitch(Handle *self, PyObject* args, void* nothing)
if(!PyArg_Parse(args, "f:pitch", &pitch))
return -1;
- Device* device = (Device*)self->device;
-
try
{
- if((*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(device->device))->setPitch(self->handle, pitch))
+ if((*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->setPitch(pitch))
return 0;
PyErr_SetString(AUDError, "Couldn't set the sound pitch!");
}
@@ -1322,11 +1301,9 @@ PyDoc_STRVAR(M_aud_Handle_loop_count_doc,
static PyObject *
Handle_get_loop_count(Handle *self, void* nothing)
{
- Device* device = (Device*)self->device;
-
try
{
- return Py_BuildValue("i", (*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(device->device))->getLoopCount(self->handle));
+ return Py_BuildValue("i", (*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->getLoopCount());
}
catch(AUD_Exception& e)
{
@@ -1343,11 +1320,9 @@ Handle_set_loop_count(Handle *self, PyObject* args, void* nothing)
if(!PyArg_Parse(args, "i:loop_count", &loops))
return -1;
- Device* device = (Device*)self->device;
-
try
{
- if((*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(device->device))->setLoopCount(self->handle, loops))
+ if((*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->setLoopCount(loops))
return 0;
PyErr_SetString(AUDError, "Couldn't set the loop count!");
}
@@ -1365,14 +1340,12 @@ PyDoc_STRVAR(M_aud_Handle_location_doc,
static PyObject *
Handle_get_location(Handle *self, void* nothing)
{
- Device* dev = (Device*)self->device;
-
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
- AUD_Vector3 v = device->getSourceLocation(self->handle);
+ AUD_Vector3 v = handle->getSourceLocation();
return Py_BuildValue("(fff)", v.x(), v.y(), v.z());
}
else
@@ -1396,15 +1369,13 @@ Handle_set_location(Handle *self, PyObject* args, void* nothing)
if(!PyArg_Parse(args, "(fff):location", &x, &y, &z))
return -1;
- Device* dev = (Device*)self->device;
-
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
AUD_Vector3 location(x, y, z);
- if(device->setSourceLocation(self->handle, location))
+ if(handle->setSourceLocation(location))
return 0;
PyErr_SetString(AUDError, "Location couldn't be set!");
}
@@ -1425,14 +1396,12 @@ PyDoc_STRVAR(M_aud_Handle_velocity_doc,
static PyObject *
Handle_get_velocity(Handle *self, void* nothing)
{
- Device* dev = (Device*)self->device;
-
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
- AUD_Vector3 v = device->getSourceVelocity(self->handle);
+ AUD_Vector3 v = handle->getSourceVelocity();
return Py_BuildValue("(fff)", v.x(), v.y(), v.z());
}
else
@@ -1456,15 +1425,13 @@ Handle_set_velocity(Handle *self, PyObject* args, void* nothing)
if(!PyArg_Parse(args, "(fff):velocity", &x, &y, &z))
return -1;
- Device* dev = (Device*)self->device;
-
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
AUD_Vector3 velocity(x, y, z);
- if(device->setSourceVelocity(self->handle, velocity))
+ if(handle->setSourceVelocity(velocity))
return 0;
PyErr_SetString(AUDError, "Couldn't set the velocity!");
}
@@ -1485,14 +1452,12 @@ PyDoc_STRVAR(M_aud_Handle_orientation_doc,
static PyObject *
Handle_get_orientation(Handle *self, void* nothing)
{
- Device* dev = (Device*)self->device;
-
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
- AUD_Quaternion o = device->getSourceOrientation(self->handle);
+ AUD_Quaternion o = handle->getSourceOrientation();
return Py_BuildValue("(ffff)", o.w(), o.x(), o.y(), o.z());
}
else
@@ -1516,15 +1481,13 @@ Handle_set_orientation(Handle *self, PyObject* args, void* nothing)
if(!PyArg_Parse(args, "(ffff):orientation", &w, &x, &y, &z))
return -1;
- Device* dev = (Device*)self->device;
-
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
AUD_Quaternion orientation(w, x, y, z);
- if(device->setSourceOrientation(self->handle, orientation))
+ if(handle->setSourceOrientation(orientation))
return 0;
PyErr_SetString(AUDError, "Couldn't set the orientation!");
}
@@ -1545,14 +1508,12 @@ PyDoc_STRVAR(M_aud_Handle_relative_doc,
static PyObject *
Handle_get_relative(Handle *self, void* nothing)
{
- Device* dev = (Device*)self->device;
-
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
- return PyBool_FromLong((long)device->isRelative(self->handle));
+ return PyBool_FromLong((long)handle->isRelative());
}
else
{
@@ -1577,14 +1538,13 @@ Handle_set_relative(Handle *self, PyObject* args, void* nothing)
}
bool relative = (args == Py_True);
- Device* dev = (Device*)self->device;
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
- if(device->setRelative(self->handle, relative))
+ if(handle->setRelative(relative))
return 0;
PyErr_SetString(AUDError, "Couldn't set the relativeness!");
}
@@ -1606,14 +1566,12 @@ PyDoc_STRVAR(M_aud_Handle_volume_minimum_doc,
static PyObject *
Handle_get_volume_minimum(Handle *self, void* nothing)
{
- Device* dev = (Device*)self->device;
-
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
- return Py_BuildValue("f", device->getVolumeMinimum(self->handle));
+ return Py_BuildValue("f", handle->getVolumeMinimum());
}
else
{
@@ -1636,14 +1594,12 @@ Handle_set_volume_minimum(Handle *self, PyObject* args, void* nothing)
if(!PyArg_Parse(args, "f:volume_minimum", &volume))
return -1;
- Device* dev = (Device*)self->device;
-
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
- if(device->setVolumeMinimum(self->handle, volume))
+ if(handle->setVolumeMinimum(volume))
return 0;
PyErr_SetString(AUDError, "Couldn't set the minimum volume!");
}
@@ -1665,14 +1621,12 @@ PyDoc_STRVAR(M_aud_Handle_volume_maximum_doc,
static PyObject *
Handle_get_volume_maximum(Handle *self, void* nothing)
{
- Device* dev = (Device*)self->device;
-
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
- return Py_BuildValue("f", device->getVolumeMaximum(self->handle));
+ return Py_BuildValue("f", handle->getVolumeMaximum());
}
else
{
@@ -1695,14 +1649,12 @@ Handle_set_volume_maximum(Handle *self, PyObject* args, void* nothing)
if(!PyArg_Parse(args, "f:volume_maximum", &volume))
return -1;
- Device* dev = (Device*)self->device;
-
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
- if(device->setVolumeMaximum(self->handle, volume))
+ if(handle->setVolumeMaximum(volume))
return 0;
PyErr_SetString(AUDError, "Couldn't set the maximum volume!");
}
@@ -1725,14 +1677,12 @@ PyDoc_STRVAR(M_aud_Handle_distance_reference_doc,
static PyObject *
Handle_get_distance_reference(Handle *self, void* nothing)
{
- Device* dev = (Device*)self->device;
-
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
- return Py_BuildValue("f", device->getDistanceReference(self->handle));
+ return Py_BuildValue("f", handle->getDistanceReference());
}
else
{
@@ -1755,14 +1705,12 @@ Handle_set_distance_reference(Handle *self, PyObject* args, void* nothing)
if(!PyArg_Parse(args, "f:distance_reference", &distance))
return -1;
- Device* dev = (Device*)self->device;
-
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
- if(device->setDistanceReference(self->handle, distance))
+ if(handle->setDistanceReference(distance))
return 0;
PyErr_SetString(AUDError, "Couldn't set the reference distance!");
}
@@ -1785,14 +1733,12 @@ PyDoc_STRVAR(M_aud_Handle_distance_maximum_doc,
static PyObject *
Handle_get_distance_maximum(Handle *self, void* nothing)
{
- Device* dev = (Device*)self->device;
-
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
- return Py_BuildValue("f", device->getDistanceMaximum(self->handle));
+ return Py_BuildValue("f", handle->getDistanceMaximum());
}
else
{
@@ -1815,14 +1761,12 @@ Handle_set_distance_maximum(Handle *self, PyObject* args, void* nothing)
if(!PyArg_Parse(args, "f:distance_maximum", &distance))
return -1;
- Device* dev = (Device*)self->device;
-
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
- if(device->setDistanceMaximum(self->handle, distance))
+ if(handle->setDistanceMaximum(distance))
return 0;
PyErr_SetString(AUDError, "Couldn't set the maximum distance!");
}
@@ -1845,14 +1789,12 @@ PyDoc_STRVAR(M_aud_Handle_attenuation_doc,
static PyObject *
Handle_get_attenuation(Handle *self, void* nothing)
{
- Device* dev = (Device*)self->device;
-
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
- return Py_BuildValue("f", device->getAttenuation(self->handle));
+ return Py_BuildValue("f", handle->getAttenuation());
}
else
{
@@ -1875,14 +1817,12 @@ Handle_set_attenuation(Handle *self, PyObject* args, void* nothing)
if(!PyArg_Parse(args, "f:attenuation", &factor))
return -1;
- Device* dev = (Device*)self->device;
-
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
- if(device->setAttenuation(self->handle, factor))
+ if(handle->setAttenuation(factor))
return 0;
PyErr_SetString(AUDError, "Couldn't set the attenuation!");
}
@@ -1910,14 +1850,12 @@ PyDoc_STRVAR(M_aud_Handle_cone_angle_inner_doc,
static PyObject *
Handle_get_cone_angle_inner(Handle *self, void* nothing)
{
- Device* dev = (Device*)self->device;
-
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
- return Py_BuildValue("f", device->getConeAngleInner(self->handle));
+ return Py_BuildValue("f", handle->getConeAngleInner());
}
else
{
@@ -1940,14 +1878,12 @@ Handle_set_cone_angle_inner(Handle *self, PyObject* args, void* nothing)
if(!PyArg_Parse(args, "f:cone_angle_inner", &angle))
return -1;
- Device* dev = (Device*)self->device;
-
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
- if(device->setConeAngleInner(self->handle, angle))
+ if(handle->setConeAngleInner(angle))
return 0;
PyErr_SetString(AUDError, "Couldn't set the cone inner angle!");
}
@@ -1969,14 +1905,12 @@ PyDoc_STRVAR(M_aud_Handle_cone_angle_outer_doc,
static PyObject *
Handle_get_cone_angle_outer(Handle *self, void* nothing)
{
- Device* dev = (Device*)self->device;
-
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
- return Py_BuildValue("f", device->getConeAngleOuter(self->handle));
+ return Py_BuildValue("f", handle->getConeAngleOuter());
}
else
{
@@ -1999,14 +1933,12 @@ Handle_set_cone_angle_outer(Handle *self, PyObject* args, void* nothing)
if(!PyArg_Parse(args, "f:cone_angle_outer", &angle))
return -1;
- Device* dev = (Device*)self->device;
-
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
- if(device->setConeAngleOuter(self->handle, angle))
+ if(handle->setConeAngleOuter(angle))
return 0;
PyErr_SetString(AUDError, "Couldn't set the cone outer angle!");
}
@@ -2028,14 +1960,12 @@ PyDoc_STRVAR(M_aud_Handle_cone_volume_outer_doc,
static PyObject *
Handle_get_cone_volume_outer(Handle *self, void* nothing)
{
- Device* dev = (Device*)self->device;
-
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
- return Py_BuildValue("f", device->getConeVolumeOuter(self->handle));
+ return Py_BuildValue("f", handle->getConeVolumeOuter());
}
else
{
@@ -2058,14 +1988,12 @@ Handle_set_cone_volume_outer(Handle *self, PyObject* args, void* nothing)
if(!PyArg_Parse(args, "f:cone_volume_outer", &volume))
return -1;
- Device* dev = (Device*)self->device;
-
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
- if(device->setConeVolumeOuter(self->handle, volume))
+ if(handle->setConeVolumeOuter(volume))
return 0;
PyErr_SetString(AUDError, "Couldn't set the cone outer volume!");
}
@@ -2302,12 +2230,9 @@ Device_play(Device *self, PyObject *args, PyObject *kwds)
handle = (Handle*)HandleType.tp_alloc(&HandleType, 0);
if(handle != NULL)
{
- handle->device = (PyObject*)self;
- Py_INCREF(self);
-
try
{
- handle->handle = (*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device))->play(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(sound->factory), keep);
+ handle->handle = new AUD_Reference<AUD_IHandle>((*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device))->play(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(sound->factory), keep));
}
catch(AUD_Exception& e)
{
diff --git a/intern/audaspace/Python/AUD_PyAPI.h b/intern/audaspace/Python/AUD_PyAPI.h
index 822aec06976..e234ad4dded 100644
--- a/intern/audaspace/Python/AUD_PyAPI.h
+++ b/intern/audaspace/Python/AUD_PyAPI.h
@@ -36,15 +36,15 @@
#ifdef __cplusplus
extern "C" {
-struct AUD_Handle;
#else
typedef void AUD_IFactory;
typedef void AUD_IDevice;
-typedef void AUD_Handle;
+typedef void AUD_IHandle;
#endif
typedef void AUD_Reference_AUD_IFactory;
typedef void AUD_Reference_AUD_IDevice;
+typedef void AUD_Reference_AUD_IHandle;
typedef struct {
PyObject_HEAD
@@ -54,8 +54,7 @@ typedef struct {
typedef struct {
PyObject_HEAD
- AUD_Handle* handle;
- PyObject* device;
+ AUD_Reference_AUD_IHandle* handle;
} Handle;
typedef struct {
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
index 852b93d24a8..b7690d55383 100644
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
+++ b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
@@ -432,7 +432,7 @@ void AUD_FFMPEGReader::read(int& length, bool& eos, sample_t* buffer)
pkgbuf_pos-data_size);
}
- if(eos = (left > 0))
+ if((eos = (left > 0)))
length -= left;
m_position += length;
diff --git a/intern/audaspace/intern/AUD_BufferReader.cpp b/intern/audaspace/intern/AUD_BufferReader.cpp
index 3ab226558ac..99a99069378 100644
--- a/intern/audaspace/intern/AUD_BufferReader.cpp
+++ b/intern/audaspace/intern/AUD_BufferReader.cpp
@@ -68,6 +68,8 @@ AUD_Specs AUD_BufferReader::getSpecs() const
void AUD_BufferReader::read(int& length, bool& eos, sample_t* buffer)
{
+ eos = false;
+
int sample_size = AUD_SAMPLE_SIZE(m_specs);
sample_t* buf = m_buffer->getBuffer() + m_position * m_specs.channels;
diff --git a/intern/audaspace/intern/AUD_C-API.cpp b/intern/audaspace/intern/AUD_C-API.cpp
index 0b2e782925c..fc693be12d5 100644
--- a/intern/audaspace/intern/AUD_C-API.cpp
+++ b/intern/audaspace/intern/AUD_C-API.cpp
@@ -45,6 +45,7 @@
#include "AUD_NULLDevice.h"
#include "AUD_I3DDevice.h"
+#include "AUD_I3DHandle.h"
#include "AUD_FileFactory.h"
#include "AUD_StreamBufferFactory.h"
#include "AUD_DelayFactory.h"
@@ -89,7 +90,7 @@ extern "C" {
typedef AUD_Reference<AUD_IFactory> AUD_Sound;
typedef AUD_Reference<AUD_ReadDevice> AUD_Device;
-typedef AUD_Handle AUD_Channel;
+typedef AUD_Reference<AUD_IHandle> AUD_Channel;
typedef AUD_Reference<AUD_SequencerEntry> AUD_SEntry;
#define AUD_CAPI_IMPLEMENTATION
@@ -375,16 +376,16 @@ AUD_Sound* AUD_loopSound(AUD_Sound* sound)
int AUD_setLoop(AUD_Channel* handle, int loops)
{
- if(handle)
+ assert(handle);
+
+ try
+ {
+ return (*handle)->setLoopCount(loops);
+ }
+ catch(AUD_Exception&)
{
- try
- {
- return AUD_device->setLoopCount(handle, loops);
- }
- catch(AUD_Exception&)
- {
- }
}
+
return false;
}
@@ -413,49 +414,58 @@ AUD_Channel* AUD_play(AUD_Sound* sound, int keep)
assert(sound);
try
{
- return AUD_device->play(*sound, keep);
+ AUD_Channel channel = AUD_device->play(*sound, keep);
+ if(!channel.isNull())
+ return new AUD_Channel(channel);
}
catch(AUD_Exception&)
{
- return NULL;
}
+ return NULL;
}
int AUD_pause(AUD_Channel* handle)
{
- return AUD_device->pause(handle);
+ assert(handle);
+ return (*handle)->pause();
}
int AUD_resume(AUD_Channel* handle)
{
- return AUD_device->resume(handle);
+ assert(handle);
+ return (*handle)->resume();
}
int AUD_stop(AUD_Channel* handle)
{
- if(!AUD_device.isNull())
- return AUD_device->stop(handle);
- return false;
+ assert(handle);
+ int result = (*handle)->stop();
+ delete handle;
+ return result;
}
int AUD_setKeep(AUD_Channel* handle, int keep)
{
- return AUD_device->setKeep(handle, keep);
+ assert(handle);
+ return (*handle)->setKeep(keep);
}
int AUD_seek(AUD_Channel* handle, float seekTo)
{
- return AUD_device->seek(handle, seekTo);
+ assert(handle);
+ return (*handle)->seek(seekTo);
}
float AUD_getPosition(AUD_Channel* handle)
{
- return AUD_device->getPosition(handle);
+ assert(handle);
+ return (*handle)->getPosition();
}
AUD_Status AUD_getStatus(AUD_Channel* handle)
{
- return AUD_device->getStatus(handle);
+ assert(handle);
+ return (*handle)->getStatus();
}
int AUD_setListenerLocation(const float* location)
@@ -529,10 +539,13 @@ int AUD_setDistanceModel(AUD_DistanceModel model)
int AUD_setSourceLocation(AUD_Channel* handle, const float* location)
{
- if(AUD_3ddevice)
+ assert(handle);
+ AUD_Reference<AUD_I3DHandle> h(*handle);
+
+ if(!h.isNull())
{
AUD_Vector3 v(location[0], location[1], location[2]);
- return AUD_3ddevice->setSourceLocation(handle, v);
+ return h->setSourceLocation(v);
}
return false;
@@ -540,10 +553,13 @@ int AUD_setSourceLocation(AUD_Channel* handle, const float* location)
int AUD_setSourceVelocity(AUD_Channel* handle, const float* velocity)
{
- if(AUD_3ddevice)
+ assert(handle);
+ AUD_Reference<AUD_I3DHandle> h(*handle);
+
+ if(!h.isNull())
{
AUD_Vector3 v(velocity[0], velocity[1], velocity[2]);
- return AUD_3ddevice->setSourceVelocity(handle, v);
+ return h->setSourceVelocity(v);
}
return false;
@@ -551,10 +567,13 @@ int AUD_setSourceVelocity(AUD_Channel* handle, const float* velocity)
int AUD_setSourceOrientation(AUD_Channel* handle, const float* orientation)
{
- if(AUD_3ddevice)
+ assert(handle);
+ AUD_Reference<AUD_I3DHandle> h(*handle);
+
+ if(!h.isNull())
{
AUD_Quaternion q(orientation[3], orientation[0], orientation[1], orientation[2]);
- return AUD_3ddevice->setSourceOrientation(handle, q);
+ return h->setSourceOrientation(q);
}
return false;
@@ -562,9 +581,12 @@ int AUD_setSourceOrientation(AUD_Channel* handle, const float* orientation)
int AUD_setRelative(AUD_Channel* handle, int relative)
{
- if(AUD_3ddevice)
+ assert(handle);
+ AUD_Reference<AUD_I3DHandle> h(*handle);
+
+ if(!h.isNull())
{
- return AUD_3ddevice->setRelative(handle, relative);
+ return h->setRelative(relative);
}
return false;
@@ -572,9 +594,12 @@ int AUD_setRelative(AUD_Channel* handle, int relative)
int AUD_setVolumeMaximum(AUD_Channel* handle, float volume)
{
- if(AUD_3ddevice)
+ assert(handle);
+ AUD_Reference<AUD_I3DHandle> h(*handle);
+
+ if(!h.isNull())
{
- return AUD_3ddevice->setVolumeMaximum(handle, volume);
+ return h->setVolumeMaximum(volume);
}
return false;
@@ -582,9 +607,12 @@ int AUD_setVolumeMaximum(AUD_Channel* handle, float volume)
int AUD_setVolumeMinimum(AUD_Channel* handle, float volume)
{
- if(AUD_3ddevice)
+ assert(handle);
+ AUD_Reference<AUD_I3DHandle> h(*handle);
+
+ if(!h.isNull())
{
- return AUD_3ddevice->setVolumeMinimum(handle, volume);
+ return h->setVolumeMinimum(volume);
}
return false;
@@ -592,9 +620,12 @@ int AUD_setVolumeMinimum(AUD_Channel* handle, float volume)
int AUD_setDistanceMaximum(AUD_Channel* handle, float distance)
{
- if(AUD_3ddevice)
+ assert(handle);
+ AUD_Reference<AUD_I3DHandle> h(*handle);
+
+ if(!h.isNull())
{
- return AUD_3ddevice->setDistanceMaximum(handle, distance);
+ return h->setDistanceMaximum(distance);
}
return false;
@@ -602,9 +633,12 @@ int AUD_setDistanceMaximum(AUD_Channel* handle, float distance)
int AUD_setDistanceReference(AUD_Channel* handle, float distance)
{
- if(AUD_3ddevice)
+ assert(handle);
+ AUD_Reference<AUD_I3DHandle> h(*handle);
+
+ if(!h.isNull())
{
- return AUD_3ddevice->setDistanceReference(handle, distance);
+ return h->setDistanceReference(distance);
}
return false;
@@ -612,9 +646,12 @@ int AUD_setDistanceReference(AUD_Channel* handle, float distance)
int AUD_setAttenuation(AUD_Channel* handle, float factor)
{
- if(AUD_3ddevice)
+ assert(handle);
+ AUD_Reference<AUD_I3DHandle> h(*handle);
+
+ if(!h.isNull())
{
- return AUD_3ddevice->setAttenuation(handle, factor);
+ return h->setAttenuation(factor);
}
return false;
@@ -622,9 +659,12 @@ int AUD_setAttenuation(AUD_Channel* handle, float factor)
int AUD_setConeAngleOuter(AUD_Channel* handle, float angle)
{
- if(AUD_3ddevice)
+ assert(handle);
+ AUD_Reference<AUD_I3DHandle> h(*handle);
+
+ if(!h.isNull())
{
- return AUD_3ddevice->setConeAngleOuter(handle, angle);
+ return h->setConeAngleOuter(angle);
}
return false;
@@ -632,9 +672,12 @@ int AUD_setConeAngleOuter(AUD_Channel* handle, float angle)
int AUD_setConeAngleInner(AUD_Channel* handle, float angle)
{
- if(AUD_3ddevice)
+ assert(handle);
+ AUD_Reference<AUD_I3DHandle> h(*handle);
+
+ if(!h.isNull())
{
- return AUD_3ddevice->setConeAngleInner(handle, angle);
+ return h->setConeAngleInner(angle);
}
return false;
@@ -642,9 +685,12 @@ int AUD_setConeAngleInner(AUD_Channel* handle, float angle)
int AUD_setConeVolumeOuter(AUD_Channel* handle, float volume)
{
- if(AUD_3ddevice)
+ assert(handle);
+ AUD_Reference<AUD_I3DHandle> h(*handle);
+
+ if(!h.isNull())
{
- return AUD_3ddevice->setConeVolumeOuter(handle, volume);
+ return h->setConeVolumeOuter(volume);
}
return false;
@@ -652,27 +698,23 @@ int AUD_setConeVolumeOuter(AUD_Channel* handle, float volume)
int AUD_setSoundVolume(AUD_Channel* handle, float volume)
{
- if(handle)
+ assert(handle);
+ try
{
- try
- {
- return AUD_device->setVolume(handle, volume);
- }
- catch(AUD_Exception&) {}
+ return (*handle)->setVolume(volume);
}
+ catch(AUD_Exception&) {}
return false;
}
int AUD_setSoundPitch(AUD_Channel* handle, float pitch)
{
- if(handle)
+ assert(handle);
+ try
{
- try
- {
- return AUD_device->setPitch(handle, pitch);
- }
- catch(AUD_Exception&) {}
+ return (*handle)->setPitch(pitch);
}
+ catch(AUD_Exception&) {}
return false;
}
@@ -695,14 +737,17 @@ AUD_Channel* AUD_playDevice(AUD_Device* device, AUD_Sound* sound, float seek)
try
{
- AUD_Channel* handle = (*device)->play(*sound);
- (*device)->seek(handle, seek);
- return handle;
+ AUD_Channel channel = (*device)->play(*sound);
+ if(!channel.isNull())
+ {
+ channel->seek(seek);
+ return new AUD_Channel(channel);
+ }
}
catch(AUD_Exception&)
{
- return NULL;
}
+ return NULL;
}
int AUD_setDeviceVolume(AUD_Device* device, float volume)
@@ -719,22 +764,6 @@ int AUD_setDeviceVolume(AUD_Device* device, float volume)
return false;
}
-int AUD_setDeviceSoundVolume(AUD_Device* device, AUD_Channel* handle,
- float volume)
-{
- if(handle)
- {
- assert(device);
-
- try
- {
- return (*device)->setVolume(handle, volume);
- }
- catch(AUD_Exception&) {}
- }
- return false;
-}
-
int AUD_readDevice(AUD_Device* device, data_t* buffer, int length)
{
assert(device);
@@ -821,7 +850,8 @@ float* AUD_readSoundBuffer(const char* filename, float low, float high,
static void pauseSound(AUD_Channel* handle)
{
- AUD_device->pause(handle);
+ assert(handle);
+ (*handle)->pause();
}
AUD_Channel* AUD_pauseAfter(AUD_Channel* handle, float seconds)
@@ -829,16 +859,25 @@ AUD_Channel* AUD_pauseAfter(AUD_Channel* handle, float seconds)
AUD_Reference<AUD_IFactory> silence = new AUD_SilenceFactory;
AUD_Reference<AUD_IFactory> limiter = new AUD_LimiterFactory(silence, 0, seconds);
+ AUD_device->lock();
+
try
{
- AUD_Channel* channel = AUD_device->play(limiter);
- AUD_device->setStopCallback(channel, (stopCallback)pauseSound, handle);
- return channel;
+ AUD_Channel channel = AUD_device->play(limiter);
+ if(!channel.isNull())
+ {
+ channel->setStopCallback((stopCallback)pauseSound, handle);
+ AUD_device->unlock();
+ return new AUD_Channel(channel);
+ }
}
catch(AUD_Exception&)
{
- return NULL;
}
+
+ AUD_device->unlock();
+
+ return NULL;
}
AUD_Sound* AUD_createSequencer(int muted, void* data, AUD_volumeFunction volume)
@@ -966,7 +1005,8 @@ void AUD_seekSequencer(AUD_Channel* handle, float time)
else
#endif
{
- AUD_device->seek(handle, time);
+ assert(handle);
+ (*handle)->seek(time);
}
}
@@ -979,7 +1019,8 @@ float AUD_getSequencerPosition(AUD_Channel* handle)
else
#endif
{
- return AUD_device->getPosition(handle);
+ assert(handle);
+ return (*handle)->getPosition();
}
}
@@ -1006,3 +1047,8 @@ AUD_Sound* AUD_copy(AUD_Sound* sound)
{
return new AUD_Reference<AUD_IFactory>(*sound);
}
+
+void AUD_freeChannel(AUD_Channel* channel)
+{
+ delete channel;
+}
diff --git a/intern/audaspace/intern/AUD_C-API.h b/intern/audaspace/intern/AUD_C-API.h
index 3fdb9e7bca3..945faa50070 100644
--- a/intern/audaspace/intern/AUD_C-API.h
+++ b/intern/audaspace/intern/AUD_C-API.h
@@ -418,17 +418,6 @@ extern int AUD_setDeviceVolume(AUD_Device* device, float volume);
extern AUD_Channel* AUD_playDevice(AUD_Device* device, AUD_Sound* sound, float seek);
/**
- * Sets the volume of a played back sound of a read device.
- * \param device The read device.
- * \param handle The handle to the sound.
- * \param volume The new volume, must be between 0.0 and 1.0.
- * \return Whether the action succeeded.
- */
-extern int AUD_setDeviceSoundVolume(AUD_Device* device,
- AUD_Channel* handle,
- float volume);
-
-/**
* Reads the next samples into the supplied buffer.
* \param device The read device.
* \param buffer The target buffer.
@@ -498,6 +487,8 @@ extern int AUD_doesPlayback(void);
extern AUD_Sound* AUD_copy(AUD_Sound* sound);
+extern void AUD_freeChannel(AUD_Channel* channel);
+
#ifdef WITH_PYTHON
extern PyObject* AUD_getPythonFactory(AUD_Sound* sound);
diff --git a/intern/audaspace/intern/AUD_I3DDevice.h b/intern/audaspace/intern/AUD_I3DDevice.h
index df341dbb319..036f7b1fa94 100644
--- a/intern/audaspace/intern/AUD_I3DDevice.h
+++ b/intern/audaspace/intern/AUD_I3DDevice.h
@@ -35,8 +35,6 @@
#include "AUD_Space.h"
#include "AUD_3DMath.h"
-struct AUD_Handle;
-
/**
* This class represents an output device for 3D sound.
*/
@@ -121,200 +119,6 @@ public:
* \param model distance model.
*/
virtual void setDistanceModel(AUD_DistanceModel model)=0;
-
-
-
- /**
- * Retrieves the location of a source.
- * \param handle The handle of the source.
- * \return The location.
- */
- virtual AUD_Vector3 getSourceLocation(AUD_Handle* handle)=0;
-
- /**
- * Sets the location of a source.
- * \param handle The handle of the source.
- * \param location The new location.
- * \return Whether the action succeeded.
- */
- virtual bool setSourceLocation(AUD_Handle* handle, const AUD_Vector3& location)=0;
-
- /**
- * Retrieves the velocity of a source.
- * \param handle The handle of the source.
- * \return The velocity.
- */
- virtual AUD_Vector3 getSourceVelocity(AUD_Handle* handle)=0;
-
- /**
- * Sets the velocity of a source.
- * \param handle The handle of the source.
- * \param velocity The new velocity.
- * \return Whether the action succeeded.
- */
- virtual bool setSourceVelocity(AUD_Handle* handle, const AUD_Vector3& velocity)=0;
-
- /**
- * Retrieves the orientation of a source.
- * \param handle The handle of the source.
- * \return The orientation as quaternion.
- */
- virtual AUD_Quaternion getSourceOrientation(AUD_Handle* handle)=0;
-
- /**
- * Sets the orientation of a source.
- * \param handle The handle of the source.
- * \param orientation The new orientation as quaternion.
- * \return Whether the action succeeded.
- */
- virtual bool setSourceOrientation(AUD_Handle* handle, const AUD_Quaternion& orientation)=0;
-
-
- /**
- * Checks whether the source location, velocity and orientation are relative
- * to the listener.
- * \param handle The handle of the source.
- * \return Whether the source is relative.
- */
- virtual bool isRelative(AUD_Handle* handle)=0;
-
- /**
- * Sets whether the source location, velocity and orientation are relative
- * to the listener.
- * \param handle The handle of the source.
- * \param relative Whether the source is relative.
- * \return Whether the action succeeded.
- */
- virtual bool setRelative(AUD_Handle* handle, bool relative)=0;
-
- /**
- * Retrieves the maximum volume of a source.
- * \param handle The handle of the source.
- * \return The maximum volume.
- */
- virtual float getVolumeMaximum(AUD_Handle* handle)=0;
-
- /**
- * Sets the maximum volume of a source.
- * \param handle The handle of the source.
- * \param volume The new maximum volume.
- * \return Whether the action succeeded.
- */
- virtual bool setVolumeMaximum(AUD_Handle* handle, float volume)=0;
-
- /**
- * Retrieves the minimum volume of a source.
- * \param handle The handle of the source.
- * \return The minimum volume.
- */
- virtual float getVolumeMinimum(AUD_Handle* handle)=0;
-
- /**
- * Sets the minimum volume of a source.
- * \param handle The handle of the source.
- * \param volume The new minimum volume.
- * \return Whether the action succeeded.
- */
- virtual bool setVolumeMinimum(AUD_Handle* handle, float volume)=0;
-
- /**
- * Retrieves the maximum distance of a source.
- * If a source is further away from the reader than this distance, the
- * volume will automatically be set to 0.
- * \param handle The handle of the source.
- * \return The maximum distance.
- */
- virtual float getDistanceMaximum(AUD_Handle* handle)=0;
-
- /**
- * Sets the maximum distance of a source.
- * If a source is further away from the reader than this distance, the
- * volume will automatically be set to 0.
- * \param handle The handle of the source.
- * \param distance The new maximum distance.
- * \return Whether the action succeeded.
- */
- virtual bool setDistanceMaximum(AUD_Handle* handle, float distance)=0;
-
- /**
- * Retrieves the reference distance of a source.
- * \param handle The handle of the source.
- * \return The reference distance.
- */
- virtual float getDistanceReference(AUD_Handle* handle)=0;
-
- /**
- * Sets the reference distance of a source.
- * \param handle The handle of the source.
- * \param distance The new reference distance.
- * \return Whether the action succeeded.
- */
- virtual bool setDistanceReference(AUD_Handle* handle, float distance)=0;
-
- /**
- * Retrieves the attenuation of a source.
- * \param handle The handle of the source.
- * \return The attenuation.
- */
- virtual float getAttenuation(AUD_Handle* handle)=0;
-
- /**
- * Sets the attenuation of a source.
- * This value is used for distance calculation.
- * \param handle The handle of the source.
- * \param factor The new attenuation.
- * \return Whether the action succeeded.
- */
- virtual bool setAttenuation(AUD_Handle* handle, float factor)=0;
-
- /**
- * Retrieves the outer angle of the cone of a source.
- * \param handle The handle of the source.
- * \return The outer angle of the cone.
- */
- virtual float getConeAngleOuter(AUD_Handle* handle)=0;
-
- /**
- * Sets the outer angle of the cone of a source.
- * \param handle The handle of the source.
- * \param angle The new outer angle of the cone.
- * \return Whether the action succeeded.
- */
- virtual bool setConeAngleOuter(AUD_Handle* handle, float angle)=0;
-
- /**
- * Retrieves the inner angle of the cone of a source.
- * \param handle The handle of the source.
- * \return The inner angle of the cone.
- */
- virtual float getConeAngleInner(AUD_Handle* handle)=0;
-
- /**
- * Sets the inner angle of the cone of a source.
- * \param handle The handle of the source.
- * \param angle The new inner angle of the cone.
- * \return Whether the action succeeded.
- */
- virtual bool setConeAngleInner(AUD_Handle* handle, float angle)=0;
-
- /**
- * Retrieves the outer volume of the cone of a source.
- * The volume between inner and outer angle is interpolated between inner
- * volume and this value.
- * \param handle The handle of the source.
- * \return The outer volume of the cone.
- */
- virtual float getConeVolumeOuter(AUD_Handle* handle)=0;
-
- /**
- * Sets the outer volume of the cone of a source.
- * The volume between inner and outer angle is interpolated between inner
- * volume and this value.
- * \param handle The handle of the source.
- * \param volume The new outer volume of the cone.
- * \return Whether the action succeeded.
- */
- virtual bool setConeVolumeOuter(AUD_Handle* handle, float volume)=0;
};
#endif //AUD_I3DDEVICE
diff --git a/intern/audaspace/intern/AUD_I3DHandle.h b/intern/audaspace/intern/AUD_I3DHandle.h
new file mode 100644
index 00000000000..259c702bf86
--- /dev/null
+++ b/intern/audaspace/intern/AUD_I3DHandle.h
@@ -0,0 +1,213 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * Copyright 2009-2011 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * Audaspace is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Audaspace; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file audaspace/intern/AUD_I3DHandle.h
+ * \ingroup audaspaceintern
+ */
+
+
+#ifndef AUD_I3DHANDLE
+#define AUD_I3DHANDLE
+
+#include "AUD_Space.h"
+#include "AUD_3DMath.h"
+
+/**
+ * This class represents an output device for 3D sound.
+ */
+class AUD_I3DHandle
+{
+public:
+ /**
+ * Retrieves the location of a source.
+ * \return The location.
+ */
+ virtual AUD_Vector3 getSourceLocation()=0;
+
+ /**
+ * Sets the location of a source.
+ * \param location The new location.
+ * \return Whether the action succeeded.
+ */
+ virtual bool setSourceLocation(const AUD_Vector3& location)=0;
+
+ /**
+ * Retrieves the velocity of a source.
+ * \return The velocity.
+ */
+ virtual AUD_Vector3 getSourceVelocity()=0;
+
+ /**
+ * Sets the velocity of a source.
+ * \param velocity The new velocity.
+ * \return Whether the action succeeded.
+ */
+ virtual bool setSourceVelocity(const AUD_Vector3& velocity)=0;
+
+ /**
+ * Retrieves the orientation of a source.
+ * \return The orientation as quaternion.
+ */
+ virtual AUD_Quaternion getSourceOrientation()=0;
+
+ /**
+ * Sets the orientation of a source.
+ * \param orientation The new orientation as quaternion.
+ * \return Whether the action succeeded.
+ */
+ virtual bool setSourceOrientation(const AUD_Quaternion& orientation)=0;
+
+
+ /**
+ * Checks whether the source location, velocity and orientation are relative
+ * to the listener.
+ * \return Whether the source is relative.
+ */
+ virtual bool isRelative()=0;
+
+ /**
+ * Sets whether the source location, velocity and orientation are relative
+ * to the listener.
+ * \param relative Whether the source is relative.
+ * \return Whether the action succeeded.
+ */
+ virtual bool setRelative(bool relative)=0;
+
+ /**
+ * Retrieves the maximum volume of a source.
+ * \return The maximum volume.
+ */
+ virtual float getVolumeMaximum()=0;
+
+ /**
+ * Sets the maximum volume of a source.
+ * \param volume The new maximum volume.
+ * \return Whether the action succeeded.
+ */
+ virtual bool setVolumeMaximum(float volume)=0;
+
+ /**
+ * Retrieves the minimum volume of a source.
+ * \return The minimum volume.
+ */
+ virtual float getVolumeMinimum()=0;
+
+ /**
+ * Sets the minimum volume of a source.
+ * \param volume The new minimum volume.
+ * \return Whether the action succeeded.
+ */
+ virtual bool setVolumeMinimum(float volume)=0;
+
+ /**
+ * Retrieves the maximum distance of a source.
+ * If a source is further away from the reader than this distance, the
+ * volume will automatically be set to 0.
+ * \return The maximum distance.
+ */
+ virtual float getDistanceMaximum()=0;
+
+ /**
+ * Sets the maximum distance of a source.
+ * If a source is further away from the reader than this distance, the
+ * volume will automatically be set to 0.
+ * \param distance The new maximum distance.
+ * \return Whether the action succeeded.
+ */
+ virtual bool setDistanceMaximum(float distance)=0;
+
+ /**
+ * Retrieves the reference distance of a source.
+ * \return The reference distance.
+ */
+ virtual float getDistanceReference()=0;
+
+ /**
+ * Sets the reference distance of a source.
+ * \param distance The new reference distance.
+ * \return Whether the action succeeded.
+ */
+ virtual bool setDistanceReference(float distance)=0;
+
+ /**
+ * Retrieves the attenuation of a source.
+ * \return The attenuation.
+ */
+ virtual float getAttenuation()=0;
+
+ /**
+ * Sets the attenuation of a source.
+ * This value is used for distance calculation.
+ * \param factor The new attenuation.
+ * \return Whether the action succeeded.
+ */
+ virtual bool setAttenuation(float factor)=0;
+
+ /**
+ * Retrieves the outer angle of the cone of a source.
+ * \return The outer angle of the cone.
+ */
+ virtual float getConeAngleOuter()=0;
+
+ /**
+ * Sets the outer angle of the cone of a source.
+ * \param angle The new outer angle of the cone.
+ * \return Whether the action succeeded.
+ */
+ virtual bool setConeAngleOuter(float angle)=0;
+
+ /**
+ * Retrieves the inner angle of the cone of a source.
+ * \return The inner angle of the cone.
+ */
+ virtual float getConeAngleInner()=0;
+
+ /**
+ * Sets the inner angle of the cone of a source.
+ * \param angle The new inner angle of the cone.
+ * \return Whether the action succeeded.
+ */
+ virtual bool setConeAngleInner(float angle)=0;
+
+ /**
+ * Retrieves the outer volume of the cone of a source.
+ * The volume between inner and outer angle is interpolated between inner
+ * volume and this value.
+ * \return The outer volume of the cone.
+ */
+ virtual float getConeVolumeOuter()=0;
+
+ /**
+ * Sets the outer volume of the cone of a source.
+ * The volume between inner and outer angle is interpolated between inner
+ * volume and this value.
+ * \param volume The new outer volume of the cone.
+ * \return Whether the action succeeded.
+ */
+ virtual bool setConeVolumeOuter(float volume)=0;
+};
+
+#endif //AUD_I3DHANDLE
diff --git a/intern/audaspace/intern/AUD_IDevice.h b/intern/audaspace/intern/AUD_IDevice.h
index 88c9aa5e8d9..992e3347366 100644
--- a/intern/audaspace/intern/AUD_IDevice.h
+++ b/intern/audaspace/intern/AUD_IDevice.h
@@ -36,13 +36,7 @@
#include "AUD_Reference.h"
class AUD_IFactory;
class AUD_IReader;
-
-/// Handle structure, for inherition.
-struct AUD_Handle
-{
-};
-
-typedef void (*stopCallback)(void*);
+class AUD_IHandle;
/**
* This class represents an output device for sound sources.
@@ -75,7 +69,7 @@ public:
* \exception AUD_Exception Thrown if there's an unexpected (from the
* device side) error during creation of the reader.
*/
- virtual AUD_Handle* play(AUD_Reference<AUD_IReader> reader, bool keep = false)=0;
+ virtual AUD_Reference<AUD_IHandle> play(AUD_Reference<AUD_IReader> reader, bool keep = false)=0;
/**
* Plays a sound source.
@@ -87,87 +81,7 @@ public:
* \exception AUD_Exception Thrown if there's an unexpected (from the
* device side) error during creation of the reader.
*/
- virtual AUD_Handle* play(AUD_Reference<AUD_IFactory> factory, bool keep = false)=0;
-
- /**
- * Pauses a played back sound.
- * \param handle The handle returned by the play function.
- * \return
- * - true if the sound has been paused.
- * - false if the sound isn't playing back or the handle is invalid.
- */
- virtual bool pause(AUD_Handle* handle)=0;
-
- /**
- * Resumes a paused sound.
- * \param handle The handle returned by the play function.
- * \return
- * - true if the sound has been resumed.
- * - false if the sound isn't paused or the handle is invalid.
- */
- virtual bool resume(AUD_Handle* handle)=0;
-
- /**
- * Stops a played back or paused sound. The handle is definitely invalid
- * afterwards.
- * \param handle The handle returned by the play function.
- * \return
- * - true if the sound has been stopped.
- * - false if the handle is invalid.
- */
- virtual bool stop(AUD_Handle* handle)=0;
-
- /**
- * Gets the behaviour of the device for a played back sound when the sound
- * doesn't return any more samples.
- * \param handle The handle returned by the play function.
- * \return
- * - true if the source will be paused when it's end is reached
- * - false if the handle won't kept or is invalid.
- */
- virtual bool getKeep(AUD_Handle* handle)=0;
-
- /**
- * Sets the behaviour of the device for a played back sound when the sound
- * doesn't return any more samples.
- * \param handle The handle returned by the play function.
- * \param keep True when the source should be paused and not deleted.
- * \return
- * - true if the behaviour has been changed.
- * - false if the handle is invalid.
- */
- virtual bool setKeep(AUD_Handle* handle, bool keep)=0;
-
- /**
- * Seeks in a played back sound.
- * \param handle The handle returned by the play function.
- * \param position The new position from where to play back, in seconds.
- * \return
- * - true if the handle is valid.
- * - false if the handle is invalid.
- * \warning Whether the seek works or not depends on the sound source.
- */
- virtual bool seek(AUD_Handle* handle, float position)=0;
-
- /**
- * Retrieves the current playback position of a sound.
- * \param handle The handle returned by the play function.
- * \return The playback position in seconds, or 0.0 if the handle is
- * invalid.
- */
- virtual float getPosition(AUD_Handle* handle)=0;
-
- /**
- * Returns the status of a played back sound.
- * \param handle The handle returned by the play function.
- * \return
- * - AUD_STATUS_INVALID if the sound has stopped or the handle is
- *. invalid
- * - AUD_STATUS_PLAYING if the sound is currently played back.
- * - AUD_STATUS_PAUSED if the sound is currently paused.
- * \see AUD_Status
- */
- virtual AUD_Status getStatus(AUD_Handle* handle)=0;
+ virtual AUD_Reference<AUD_IHandle> play(AUD_Reference<AUD_IFactory> factory, bool keep = false)=0;
/**
* Locks the device.
@@ -196,69 +110,6 @@ public:
* \param volume The overall device volume.
*/
virtual void setVolume(float volume)=0;
-
- /**
- * Retrieves the volume of a playing sound.
- * \param handle The sound handle.
- * \return The volume.
- */
- virtual float getVolume(AUD_Handle* handle)=0;
-
- /**
- * Sets the volume of a playing sound.
- * \param handle The sound handle.
- * \param volume The volume.
- * \return
- * - true if the handle is valid.
- * - false if the handle is invalid.
- */
- virtual bool setVolume(AUD_Handle* handle, float volume)=0;
-
- /**
- * Retrieves the pitch of a playing sound.
- * \return The pitch.
- */
- virtual float getPitch(AUD_Handle* handle)=0;
-
- /**
- * Sets the pitch of a playing sound.
- * \param handle The sound handle.
- * \param pitch The pitch.
- * \return
- * - true if the handle is valid.
- * - false if the handle is invalid.
- */
- virtual bool setPitch(AUD_Handle* handle, float pitch)=0;
-
- /**
- * Retrieves the loop count of a playing sound.
- * A negative value indicates infinity.
- * \return The remaining loop count.
- */
- virtual int getLoopCount(AUD_Handle* handle)=0;
-
- /**
- * Sets the loop count of a playing sound.
- * A negative value indicates infinity.
- * \param handle The sound handle.
- * \param count The new loop count.
- * \return
- * - true if the handle is valid.
- * - false if the handle is invalid.
- */
- virtual bool setLoopCount(AUD_Handle* handle, int count)=0;
-
- /**
- * Sets the callback function that's called when the end of a playing sound
- * is reached.
- * \param handle The sound handle.
- * \param callback The callback function.
- * \param data The data that should be passed to the callback function.
- * \return
- * - true if the handle is valid.
- * - false if the handle is invalid.
- */
- virtual bool setStopCallback(AUD_Handle* handle, stopCallback callback = 0, void* data = 0)=0;
};
#endif //AUD_IDevice
diff --git a/intern/audaspace/intern/AUD_IHandle.h b/intern/audaspace/intern/AUD_IHandle.h
new file mode 100644
index 00000000000..51d8e0ca2e5
--- /dev/null
+++ b/intern/audaspace/intern/AUD_IHandle.h
@@ -0,0 +1,181 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * Copyright 2009-2011 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * Audaspace is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Audaspace; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file audaspace/intern/AUD_IHandle.h
+ * \ingroup audaspaceintern
+ */
+
+#ifndef AUD_IHANDLE
+#define AUD_IHANDLE
+
+//#include "AUD_Space.h"
+//#include "AUD_Reference.h"
+
+typedef void (*stopCallback)(void*);
+
+/**
+ * This class represents a playback handles for specific devices.
+ */
+class AUD_IHandle
+{
+public:
+ /**
+ * Destroys the device.
+ */
+ virtual ~AUD_IHandle() {}
+
+ /**
+ * Pauses a played back sound.
+ * \return
+ * - true if the sound has been paused.
+ * - false if the sound isn't playing back or the handle is invalid.
+ */
+ virtual bool pause()=0;
+
+ /**
+ * Resumes a paused sound.
+ * \return
+ * - true if the sound has been resumed.
+ * - false if the sound isn't paused or the handle is invalid.
+ */
+ virtual bool resume()=0;
+
+ /**
+ * Stops a played back or paused sound. The handle is definitely invalid
+ * afterwards.
+ * \return
+ * - true if the sound has been stopped.
+ * - false if the handle is invalid.
+ */
+ virtual bool stop()=0;
+
+ /**
+ * Gets the behaviour of the device for a played back sound when the sound
+ * doesn't return any more samples.
+ * \return
+ * - true if the source will be paused when it's end is reached
+ * - false if the handle won't kept or is invalid.
+ */
+ virtual bool getKeep()=0;
+
+ /**
+ * Sets the behaviour of the device for a played back sound when the sound
+ * doesn't return any more samples.
+ * \param keep True when the source should be paused and not deleted.
+ * \return
+ * - true if the behaviour has been changed.
+ * - false if the handle is invalid.
+ */
+ virtual bool setKeep(bool keep)=0;
+
+ /**
+ * Seeks in a played back sound.
+ * \param position The new position from where to play back, in seconds.
+ * \return
+ * - true if the handle is valid.
+ * - false if the handle is invalid.
+ * \warning Whether the seek works or not depends on the sound source.
+ */
+ virtual bool seek(float position)=0;
+
+ /**
+ * Retrieves the current playback position of a sound.
+ * \return The playback position in seconds, or 0.0 if the handle is
+ * invalid.
+ */
+ virtual float getPosition()=0;
+
+ /**
+ * Returns the status of a played back sound.
+ * \return
+ * - AUD_STATUS_INVALID if the sound has stopped or the handle is
+ *. invalid
+ * - AUD_STATUS_PLAYING if the sound is currently played back.
+ * - AUD_STATUS_PAUSED if the sound is currently paused.
+ * \see AUD_Status
+ */
+ virtual AUD_Status getStatus()=0;
+
+ /**
+ * Retrieves the volume of a playing sound.
+ * \return The volume.
+ */
+ virtual float getVolume()=0;
+
+ /**
+ * Sets the volume of a playing sound.
+ * \param volume The volume.
+ * \return
+ * - true if the handle is valid.
+ * - false if the handle is invalid.
+ */
+ virtual bool setVolume(float volume)=0;
+
+ /**
+ * Retrieves the pitch of a playing sound.
+ * \return The pitch.
+ */
+ virtual float getPitch()=0;
+
+ /**
+ * Sets the pitch of a playing sound.
+ * \param pitch The pitch.
+ * \return
+ * - true if the handle is valid.
+ * - false if the handle is invalid.
+ */
+ virtual bool setPitch(float pitch)=0;
+
+ /**
+ * Retrieves the loop count of a playing sound.
+ * A negative value indicates infinity.
+ * \return The remaining loop count.
+ */
+ virtual int getLoopCount()=0;
+
+ /**
+ * Sets the loop count of a playing sound.
+ * A negative value indicates infinity.
+ * \param count The new loop count.
+ * \return
+ * - true if the handle is valid.
+ * - false if the handle is invalid.
+ */
+ virtual bool setLoopCount(int count)=0;
+
+ /**
+ * Sets the callback function that's called when the end of a playing sound
+ * is reached.
+ * \param callback The callback function.
+ * \param data The data that should be passed to the callback function.
+ * \return
+ * - true if the handle is valid.
+ * - false if the handle is invalid.
+ */
+ virtual bool setStopCallback(stopCallback callback = 0, void* data = 0)=0;
+};
+
+#endif //AUD_IHandle
diff --git a/intern/audaspace/intern/AUD_NULLDevice.cpp b/intern/audaspace/intern/AUD_NULLDevice.cpp
index 09fc4835978..6cb13111a43 100644
--- a/intern/audaspace/intern/AUD_NULLDevice.cpp
+++ b/intern/audaspace/intern/AUD_NULLDevice.cpp
@@ -34,6 +34,7 @@
#include "AUD_NULLDevice.h"
#include "AUD_IReader.h"
#include "AUD_IFactory.h"
+#include "AUD_IHandle.h"
AUD_NULLDevice::AUD_NULLDevice()
{
@@ -48,56 +49,16 @@ AUD_DeviceSpecs AUD_NULLDevice::getSpecs() const
return specs;
}
-AUD_Handle* AUD_NULLDevice::play(AUD_Reference<AUD_IReader> reader, bool keep)
+AUD_Reference<AUD_IHandle> AUD_NULLDevice::play(AUD_Reference<AUD_IReader> reader, bool keep)
{
return 0;
}
-AUD_Handle* AUD_NULLDevice::play(AUD_Reference<AUD_IFactory> factory, bool keep)
+AUD_Reference<AUD_IHandle> AUD_NULLDevice::play(AUD_Reference<AUD_IFactory> factory, bool keep)
{
return 0;
}
-bool AUD_NULLDevice::pause(AUD_Handle* handle)
-{
- return false;
-}
-
-bool AUD_NULLDevice::resume(AUD_Handle* handle)
-{
- return false;
-}
-
-bool AUD_NULLDevice::stop(AUD_Handle* handle)
-{
- return false;
-}
-
-bool AUD_NULLDevice::getKeep(AUD_Handle* handle)
-{
- return false;
-}
-
-bool AUD_NULLDevice::setKeep(AUD_Handle* handle, bool keep)
-{
- return false;
-}
-
-bool AUD_NULLDevice::seek(AUD_Handle* handle, float position)
-{
- return false;
-}
-
-float AUD_NULLDevice::getPosition(AUD_Handle* handle)
-{
- return std::numeric_limits<float>::quiet_NaN();
-}
-
-AUD_Status AUD_NULLDevice::getStatus(AUD_Handle* handle)
-{
- return AUD_STATUS_INVALID;
-}
-
void AUD_NULLDevice::lock()
{
}
@@ -114,38 +75,3 @@ float AUD_NULLDevice::getVolume() const
void AUD_NULLDevice::setVolume(float volume)
{
}
-
-float AUD_NULLDevice::getVolume(AUD_Handle* handle)
-{
- return std::numeric_limits<float>::quiet_NaN();
-}
-
-bool AUD_NULLDevice::setVolume(AUD_Handle* handle, float volume)
-{
- return false;
-}
-
-float AUD_NULLDevice::getPitch(AUD_Handle* handle)
-{
- return std::numeric_limits<float>::quiet_NaN();
-}
-
-bool AUD_NULLDevice::setPitch(AUD_Handle* handle, float pitch)
-{
- return false;
-}
-
-int AUD_NULLDevice::getLoopCount(AUD_Handle* handle)
-{
- return 0;
-}
-
-bool AUD_NULLDevice::setLoopCount(AUD_Handle* handle, int count)
-{
- return false;
-}
-
-bool AUD_NULLDevice::setStopCallback(AUD_Handle* handle, stopCallback callback, void* data)
-{
- return false;
-}
diff --git a/intern/audaspace/intern/AUD_NULLDevice.h b/intern/audaspace/intern/AUD_NULLDevice.h
index 6a10267bbe0..69ca5b74f3b 100644
--- a/intern/audaspace/intern/AUD_NULLDevice.h
+++ b/intern/audaspace/intern/AUD_NULLDevice.h
@@ -47,27 +47,12 @@ public:
AUD_NULLDevice();
virtual AUD_DeviceSpecs getSpecs() const;
- virtual AUD_Handle* play(AUD_Reference<AUD_IReader> reader, bool keep = false);
- virtual AUD_Handle* play(AUD_Reference<AUD_IFactory> factory, bool keep = false);
- virtual bool pause(AUD_Handle* handle);
- virtual bool resume(AUD_Handle* handle);
- virtual bool stop(AUD_Handle* handle);
- virtual bool getKeep(AUD_Handle* handle);
- virtual bool setKeep(AUD_Handle* handle, bool keep);
- virtual bool seek(AUD_Handle* handle, float position);
- virtual float getPosition(AUD_Handle* handle);
- virtual AUD_Status getStatus(AUD_Handle* handle);
+ virtual AUD_Reference<AUD_IHandle> play(AUD_Reference<AUD_IReader> reader, bool keep = false);
+ virtual AUD_Reference<AUD_IHandle> play(AUD_Reference<AUD_IFactory> factory, bool keep = false);
virtual void lock();
virtual void unlock();
virtual float getVolume() const;
virtual void setVolume(float volume);
- virtual float getVolume(AUD_Handle* handle);
- virtual bool setVolume(AUD_Handle* handle, float volume);
- virtual float getPitch(AUD_Handle* handle);
- virtual bool setPitch(AUD_Handle* handle, float pitch);
- virtual int getLoopCount(AUD_Handle* handle);
- virtual bool setLoopCount(AUD_Handle* handle, int count);
- virtual bool setStopCallback(AUD_Handle* handle, stopCallback callback = 0, void* data = 0);
};
#endif //AUD_NULLDEVICE
diff --git a/intern/audaspace/intern/AUD_Reference.h b/intern/audaspace/intern/AUD_Reference.h
index 22abb29bdbb..4cc5c51d24d 100644
--- a/intern/audaspace/intern/AUD_Reference.h
+++ b/intern/audaspace/intern/AUD_Reference.h
@@ -28,10 +28,41 @@
* \ingroup audaspaceintern
*/
-
#ifndef AUD_REFERENCE
#define AUD_REFERENCE
+#include <map>
+
+class AUD_ReferenceHandler
+{
+private:
+ static std::map<void*, int> m_references;
+
+public:
+ static inline void incref(void* reference)
+ {
+ std::map<void*, int>::iterator result = m_references.find(reference);
+ if(result != m_references.end())
+ {
+ m_references[reference]++;
+ }
+ else
+ {
+ m_references[reference] = 1;
+ }
+ }
+
+ static inline bool decref(void* reference)
+ {
+ if(!--m_references[reference])
+ {
+ m_references.erase(reference);
+ return true;
+ }
+ return false;
+ }
+};
+
template <class T>
/**
* This class provides reference counting functionality.
@@ -41,8 +72,7 @@ class AUD_Reference
private:
/// The reference.
T* m_reference;
- /// The reference counter.
- int* m_refcount;
+ void* m_original;
public:
/**
* Creates a new reference counter.
@@ -50,9 +80,8 @@ public:
*/
AUD_Reference(T* reference = 0)
{
- m_reference = reference;
- m_refcount = new int;
- *m_refcount = 1;
+ m_original = m_reference = reference;
+ AUD_ReferenceHandler::incref(reference);
}
/**
@@ -61,9 +90,16 @@ public:
*/
AUD_Reference(const AUD_Reference& ref)
{
- m_reference = ref.m_reference;
- m_refcount = ref.m_refcount;
- (*m_refcount)++;
+ m_original = m_reference = ref.m_reference;
+ AUD_ReferenceHandler::incref(m_reference);
+ }
+
+ template <class U>
+ explicit AUD_Reference(const AUD_Reference<U>& ref)
+ {
+ m_original = ref.get();
+ m_reference = dynamic_cast<T*>(ref.get());
+ AUD_ReferenceHandler::incref(m_original);
}
/**
@@ -72,12 +108,8 @@ public:
*/
~AUD_Reference()
{
- (*m_refcount)--;
- if(*m_refcount == 0)
- {
+ if(AUD_ReferenceHandler::decref(m_original))
delete m_reference;
- delete m_refcount;
- }
}
/**
@@ -89,16 +121,12 @@ public:
if(&ref == this)
return *this;
- (*m_refcount)--;
- if(*m_refcount == 0)
- {
+ if(AUD_ReferenceHandler::decref(m_original))
delete m_reference;
- delete m_refcount;
- }
+ m_original = ref.m_original;
m_reference = ref.m_reference;
- m_refcount = ref.m_refcount;
- (*m_refcount)++;
+ AUD_ReferenceHandler::incref(m_original);
return *this;
}
@@ -106,7 +134,7 @@ public:
/**
* Returns whether the reference is NULL.
*/
- bool isNull() const
+ inline bool isNull() const
{
return m_reference == 0;
}
@@ -114,15 +142,20 @@ public:
/**
* Returns the reference.
*/
- T* get() const
+ inline T* get() const
{
return m_reference;
}
+ inline void* getOriginal() const
+ {
+ return m_original;
+ }
+
/**
* Returns the reference.
*/
- T& operator*() const
+ inline T& operator*() const
{
return *m_reference;
}
@@ -130,44 +163,22 @@ public:
/**
* Returns the reference.
*/
- T* operator->() const
+ inline T* operator->() const
{
return m_reference;
}
-
- template <class U>
- explicit AUD_Reference(U* reference, int* refcount)
- {
- m_reference = dynamic_cast<T*>(reference);
- if(m_reference)
- {
- m_refcount = refcount;
- (*m_refcount)++;
- }
- else
- {
- m_refcount = new int;
- *m_refcount = 1;
- }
- }
-
- template <class U>
- AUD_Reference<U> convert()
- {
- return AUD_Reference<U>(m_reference, m_refcount);
- }
};
template<class T, class U>
-bool operator==(const AUD_Reference<T>& a, const AUD_Reference<U>& b)
+inline bool operator==(const AUD_Reference<T>& a, const AUD_Reference<U>& b)
{
- return a.get() == b.get();
+ return a.getOriginal() == b.getOriginal();
}
template<class T, class U>
-bool operator!=(const AUD_Reference<T>& a, const AUD_Reference<U>& b)
+inline bool operator!=(const AUD_Reference<T>& a, const AUD_Reference<U>& b)
{
- return a.get() == b.get();
+ return a.getOriginal() != b.getOriginal();
}
#endif // AUD_REFERENCE
diff --git a/intern/audaspace/intern/AUD_ReferenceHandler.cpp b/intern/audaspace/intern/AUD_ReferenceHandler.cpp
new file mode 100644
index 00000000000..cfc3c9441a8
--- /dev/null
+++ b/intern/audaspace/intern/AUD_ReferenceHandler.cpp
@@ -0,0 +1,33 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * Copyright 2009-2011 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * Audaspace is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Audaspace; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file audaspace/intern/AUD_Reference.cpp
+ * \ingroup audaspaceintern
+ */
+
+#include "AUD_Reference.h"
+
+std::map<void*, int> AUD_ReferenceHandler::m_references;
diff --git a/intern/audaspace/intern/AUD_SequencerFactory.cpp b/intern/audaspace/intern/AUD_SequencerFactory.cpp
index 47d5243c04e..1787dea0ebb 100644
--- a/intern/audaspace/intern/AUD_SequencerFactory.cpp
+++ b/intern/audaspace/intern/AUD_SequencerFactory.cpp
@@ -108,7 +108,7 @@ AUD_Reference<AUD_IReader> AUD_SequencerFactory::createReader()
m_volume);
m_readers.push_front(reader);
- return reader.convert<AUD_IReader>();
+ return AUD_Reference<AUD_IReader>(reader);
}
void AUD_SequencerFactory::removeReader(AUD_Reference<AUD_SequencerReader> reader)
diff --git a/intern/audaspace/intern/AUD_SoftwareDevice.cpp b/intern/audaspace/intern/AUD_SoftwareDevice.cpp
index f522772fc61..8ca735e9ad9 100644
--- a/intern/audaspace/intern/AUD_SoftwareDevice.cpp
+++ b/intern/audaspace/intern/AUD_SoftwareDevice.cpp
@@ -37,29 +37,202 @@
#include <cstring>
#include <limits>
-/// Saves the data for playback.
-struct AUD_SoftwareHandle : AUD_Handle
+typedef std::list<AUD_Reference<AUD_SoftwareDevice::AUD_SoftwareHandle> >::iterator AUD_HandleIterator;
+
+AUD_SoftwareDevice::AUD_SoftwareHandle::AUD_SoftwareHandle(AUD_SoftwareDevice* device, AUD_Reference<AUD_IReader> reader, bool keep) :
+ m_reader(reader), m_keep(keep), m_volume(1.0f), m_loopcount(0),
+ m_stop(NULL), m_stop_data(NULL), m_status(AUD_STATUS_PLAYING), m_device(device)
+{
+}
+
+bool AUD_SoftwareDevice::AUD_SoftwareHandle::pause()
+{
+ if(m_status)
+ {
+ m_device->lock();
+
+ if(m_status == AUD_STATUS_PLAYING)
+ {
+ m_device->m_playingSounds.remove(this);
+ m_device->m_pausedSounds.push_back(this);
+
+ if(m_device->m_playingSounds.empty())
+ m_device->playing(m_device->m_playback = false);
+ m_status = AUD_STATUS_PAUSED;
+ m_device->unlock();
+
+ return true;
+ }
+
+ m_device->unlock();
+ }
+
+ return false;
+}
+
+bool AUD_SoftwareDevice::AUD_SoftwareHandle::resume()
+{
+ if(m_status)
+ {
+ m_device->lock();
+
+ if(m_status == AUD_STATUS_PAUSED)
+ {
+ m_device->m_pausedSounds.remove(this);
+ m_device->m_playingSounds.push_back(this);
+
+ if(!m_device->m_playback)
+ m_device->playing(m_device->m_playback = true);
+ m_status = AUD_STATUS_PLAYING;
+ m_device->unlock();
+ return true;
+ }
+
+ m_device->unlock();
+ }
+
+ return false;
+}
+
+bool AUD_SoftwareDevice::AUD_SoftwareHandle::stop()
+{
+ if(!m_status)
+ return false;
+
+ m_device->lock();
+
+ if(m_status == AUD_STATUS_PLAYING)
+ {
+ m_device->m_playingSounds.remove(this);
+
+ if(m_device->m_playingSounds.empty())
+ m_device->playing(m_device->m_playback = false);
+ }
+ else
+ m_device->m_pausedSounds.remove(this);
+
+ m_device->unlock();
+ m_status = AUD_STATUS_INVALID;
+ return true;
+}
+
+bool AUD_SoftwareDevice::AUD_SoftwareHandle::getKeep()
+{
+ if(m_status)
+ return m_keep;
+
+ return false;
+}
+
+bool AUD_SoftwareDevice::AUD_SoftwareHandle::setKeep(bool keep)
+{
+ if(!m_status)
+ return false;
+
+ m_device->lock();
+
+ m_keep = keep;
+
+ m_device->unlock();
+
+ return true;
+}
+
+bool AUD_SoftwareDevice::AUD_SoftwareHandle::seek(float position)
{
- /// The reader source.
- AUD_Reference<AUD_IReader> reader;
+ if(!m_status)
+ return false;
+
+ m_device->lock();
+
+ m_reader->seek((int)(position * m_reader->getSpecs().rate));
+
+ m_device->unlock();
+
+ return true;
+}
+
+float AUD_SoftwareDevice::AUD_SoftwareHandle::getPosition()
+{
+ if(!m_status)
+ return 0.0f;
+
+ m_device->lock();
+
+ float position = m_reader->getPosition() / (float)m_device->m_specs.rate;
+
+ m_device->unlock();
+
+ return position;
+}
+
+AUD_Status AUD_SoftwareDevice::AUD_SoftwareHandle::getStatus()
+{
+ return m_status;
+}
+
+float AUD_SoftwareDevice::AUD_SoftwareHandle::getVolume()
+{
+ return m_volume;
+}
+
+bool AUD_SoftwareDevice::AUD_SoftwareHandle::setVolume(float volume)
+{
+ if(!m_status)
+ return false;
+ m_volume = volume;
+ return true;
+}
+
+float AUD_SoftwareDevice::AUD_SoftwareHandle::getPitch()
+{
+ return std::numeric_limits<float>::quiet_NaN();
+}
+
+bool AUD_SoftwareDevice::AUD_SoftwareHandle::setPitch(float pitch)
+{
+ return false;
+}
+
+int AUD_SoftwareDevice::AUD_SoftwareHandle::getLoopCount()
+{
+ if(!m_status)
+ return 0;
+ return m_loopcount;
+}
+
+bool AUD_SoftwareDevice::AUD_SoftwareHandle::setLoopCount(int count)
+{
+ if(!m_status)
+ return false;
+ m_loopcount = count;
+ return true;
+}
+
+bool AUD_SoftwareDevice::AUD_SoftwareHandle::setStopCallback(stopCallback callback, void* data)
+{
+ if(!m_status)
+ return false;
+
+ m_device->lock();
+
+ m_stop = callback;
+ m_stop_data = data;
+
+ m_device->unlock();
+
+ return true;
+}
+
+
+
+
- /// Whether to keep the source if end of it is reached.
- bool keep;
- /// The volume of the source.
- float volume;
- /// The loop count of the source.
- int loopcount;
- /// The stop callback.
- stopCallback stop;
- /// Stop callback data.
- void* stop_data;
-};
-typedef std::list<AUD_SoftwareHandle*>::iterator AUD_HandleIterator;
void AUD_SoftwareDevice::create()
{
@@ -81,23 +254,11 @@ void AUD_SoftwareDevice::destroy()
if(m_playback)
playing(m_playback = false);
- AUD_SoftwareHandle* handle;
-
- // delete all playing sounds
while(!m_playingSounds.empty())
- {
- handle = m_playingSounds.front();
- m_playingSounds.pop_front();
- delete handle;
- }
+ m_playingSounds.front()->stop();
- // delete all paused sounds
while(!m_pausedSounds.empty())
- {
- handle = m_pausedSounds.front();
- m_pausedSounds.pop_front();
- delete handle;
- }
+ m_pausedSounds.front()->stop();
pthread_mutex_destroy(&m_mutex);
}
@@ -109,11 +270,11 @@ void AUD_SoftwareDevice::mix(data_t* buffer, int length)
lock();
{
- AUD_SoftwareHandle* sound;
+ AUD_Reference<AUD_SoftwareDevice::AUD_SoftwareHandle> sound;
int len;
int pos;
bool eos;
- std::list<AUD_SoftwareHandle*> stopSounds;
+ std::list<AUD_Reference<AUD_SoftwareDevice::AUD_SoftwareHandle> > stopSounds;
sample_t* buf = m_buffer.getBuffer();
m_mixer->clear(length);
@@ -131,39 +292,38 @@ void AUD_SoftwareDevice::mix(data_t* buffer, int length)
pos = 0;
len = length;
- sound->reader->read(len, eos, buf);
+ sound->m_reader->read(len, eos, buf);
// in case of looping
- while(pos + len < length && sound->loopcount && eos)
+ while(pos + len < length && sound->m_loopcount && eos)
{
- m_mixer->mix(buf, pos, len, sound->volume);
+ m_mixer->mix(buf, pos, len, sound->m_volume);
pos += len;
- if(sound->loopcount > 0)
- sound->loopcount--;
+ if(sound->m_loopcount > 0)
+ sound->m_loopcount--;
- sound->reader->seek(0);
+ sound->m_reader->seek(0);
len = length - pos;
- sound->reader->read(len, eos, buf);
+ sound->m_reader->read(len, eos, buf);
// prevent endless loop
if(!len)
break;
}
- m_mixer->mix(buf, pos, len, sound->volume);
- pos += len;
+ m_mixer->mix(buf, pos, len, sound->m_volume);
// in case the end of the sound is reached
- if(eos && !sound->loopcount)
+ if(eos && !sound->m_loopcount)
{
- if(sound->stop)
- sound->stop(sound->stop_data);
+ if(sound->m_stop)
+ sound->m_stop(sound->m_stop_data);
- if(sound->keep)
- pause(sound);
+ if(sound->m_keep)
+ sound->pause();
else
stopSounds.push_back(sound);
}
@@ -177,32 +337,19 @@ void AUD_SoftwareDevice::mix(data_t* buffer, int length)
{
sound = stopSounds.front();
stopSounds.pop_front();
- stop(sound);
+ sound->stop();
}
}
unlock();
}
-bool AUD_SoftwareDevice::isValid(AUD_Handle* handle)
-{
- for(AUD_HandleIterator i = m_playingSounds.begin();
- i != m_playingSounds.end(); i++)
- if(*i == handle)
- return true;
- for(AUD_HandleIterator i = m_pausedSounds.begin();
- i != m_pausedSounds.end(); i++)
- if(*i == handle)
- return true;
- return false;
-}
-
AUD_DeviceSpecs AUD_SoftwareDevice::getSpecs() const
{
return m_specs;
}
-AUD_Handle* AUD_SoftwareDevice::play(AUD_Reference<AUD_IReader> reader, bool keep)
+AUD_Reference<AUD_IHandle> AUD_SoftwareDevice::play(AUD_Reference<AUD_IReader> reader, bool keep)
{
// prepare the reader
reader = m_mixer->prepare(reader);
@@ -210,13 +357,7 @@ AUD_Handle* AUD_SoftwareDevice::play(AUD_Reference<AUD_IReader> reader, bool kee
return NULL;
// play sound
- AUD_SoftwareHandle* sound = new AUD_SoftwareHandle;
- sound->keep = keep;
- sound->reader = reader;
- sound->volume = 1.0f;
- sound->loopcount = 0;
- sound->stop = NULL;
- sound->stop_data = NULL;
+ AUD_Reference<AUD_SoftwareDevice::AUD_SoftwareHandle> sound = new AUD_SoftwareDevice::AUD_SoftwareHandle(this, reader, keep);
lock();
m_playingSounds.push_back(sound);
@@ -225,204 +366,14 @@ AUD_Handle* AUD_SoftwareDevice::play(AUD_Reference<AUD_IReader> reader, bool kee
playing(m_playback = true);
unlock();
- return sound;
+ return AUD_Reference<AUD_IHandle>(sound);
}
-AUD_Handle* AUD_SoftwareDevice::play(AUD_Reference<AUD_IFactory> factory, bool keep)
+AUD_Reference<AUD_IHandle> AUD_SoftwareDevice::play(AUD_Reference<AUD_IFactory> factory, bool keep)
{
return play(factory->createReader(), keep);
}
-bool AUD_SoftwareDevice::pause(AUD_Handle* handle)
-{
- bool result = false;
-
- lock();
-
- // only songs that are played can be paused
- for(AUD_HandleIterator i = m_playingSounds.begin();
- i != m_playingSounds.end(); i++)
- {
- if(*i == handle)
- {
- m_pausedSounds.push_back(*i);
- m_playingSounds.erase(i);
- if(m_playingSounds.empty())
- playing(m_playback = false);
- result = true;
- break;
- }
- }
-
- unlock();
-
- return result;
-}
-
-bool AUD_SoftwareDevice::resume(AUD_Handle* handle)
-{
- bool result = false;
-
- lock();
-
- // only songs that are paused can be resumed
- for(AUD_HandleIterator i = m_pausedSounds.begin();
- i != m_pausedSounds.end(); i++)
- {
- if(*i == handle)
- {
- m_playingSounds.push_back(*i);
- m_pausedSounds.erase(i);
- if(!m_playback)
- playing(m_playback = true);
- result = true;
- break;
- }
- }
-
- unlock();
-
- return result;
-}
-
-bool AUD_SoftwareDevice::stop(AUD_Handle* handle)
-{
- bool result = false;
-
- lock();
-
- for(AUD_HandleIterator i = m_playingSounds.begin();
- i != m_playingSounds.end(); i++)
- {
- if(*i == handle)
- {
- delete *i;
- m_playingSounds.erase(i);
- if(m_playingSounds.empty())
- playing(m_playback = false);
- result = true;
- break;
- }
- }
- if(!result)
- {
- for(AUD_HandleIterator i = m_pausedSounds.begin();
- i != m_pausedSounds.end(); i++)
- {
- if(*i == handle)
- {
- delete *i;
- m_pausedSounds.erase(i);
- result = true;
- break;
- }
- }
- }
-
- unlock();
-
- return result;
-}
-
-bool AUD_SoftwareDevice::getKeep(AUD_Handle* handle)
-{
- bool result = false;
-
- lock();
-
- if(isValid(handle))
- result = ((AUD_SoftwareHandle*)handle)->keep;
-
- unlock();
-
- return result;
-}
-
-bool AUD_SoftwareDevice::setKeep(AUD_Handle* handle, bool keep)
-{
- bool result = false;
-
- lock();
-
- if(isValid(handle))
- {
- ((AUD_SoftwareHandle*)handle)->keep = keep;
- result = true;
- }
-
- unlock();
-
- return result;
-}
-
-bool AUD_SoftwareDevice::seek(AUD_Handle* handle, float position)
-{
- lock();
-
- bool result = false;
-
- if(isValid(handle))
- {
- AUD_Reference<AUD_IReader> reader = ((AUD_SoftwareHandle*)handle)->reader;
- reader->seek((int)(position * reader->getSpecs().rate));
- result = true;
- }
-
- unlock();
-
- return result;
-}
-
-float AUD_SoftwareDevice::getPosition(AUD_Handle* handle)
-{
- lock();
-
- float position = 0.0f;
-
- if(isValid(handle))
- {
- AUD_SoftwareHandle* h = (AUD_SoftwareHandle*)handle;
- position = h->reader->getPosition() / (float)m_specs.rate;
- }
-
- unlock();
-
- return position;
-}
-
-AUD_Status AUD_SoftwareDevice::getStatus(AUD_Handle* handle)
-{
- AUD_Status status = AUD_STATUS_INVALID;
-
- lock();
-
- for(AUD_HandleIterator i = m_playingSounds.begin();
- i != m_playingSounds.end(); i++)
- {
- if(*i == handle)
- {
- status = AUD_STATUS_PLAYING;
- break;
- }
- }
- if(status == AUD_STATUS_INVALID)
- {
- for(AUD_HandleIterator i = m_pausedSounds.begin();
- i != m_pausedSounds.end(); i++)
- {
- if(*i == handle)
- {
- status = AUD_STATUS_PAUSED;
- break;
- }
- }
- }
-
- unlock();
-
- return status;
-}
-
void AUD_SoftwareDevice::lock()
{
pthread_mutex_lock(&m_mutex);
@@ -442,67 +393,3 @@ void AUD_SoftwareDevice::setVolume(float volume)
{
m_volume = volume;
}
-
-float AUD_SoftwareDevice::getVolume(AUD_Handle* handle)
-{
- lock();
- float result = std::numeric_limits<float>::quiet_NaN();
- if(isValid(handle))
- result = ((AUD_SoftwareHandle*)handle)->volume;
- unlock();
- return result;
-}
-
-bool AUD_SoftwareDevice::setVolume(AUD_Handle* handle, float volume)
-{
- lock();
- bool result = isValid(handle);
- if(result)
- ((AUD_SoftwareHandle*)handle)->volume = volume;
- unlock();
- return result;
-}
-
-float AUD_SoftwareDevice::getPitch(AUD_Handle* handle)
-{
- return std::numeric_limits<float>::quiet_NaN();
-}
-
-bool AUD_SoftwareDevice::setPitch(AUD_Handle* handle, float pitch)
-{
- return false;
-}
-
-int AUD_SoftwareDevice::getLoopCount(AUD_Handle* handle)
-{
- lock();
- int result = 0;
- if(isValid(handle))
- result = ((AUD_SoftwareHandle*)handle)->loopcount;
- unlock();
- return result;
-}
-
-bool AUD_SoftwareDevice::setLoopCount(AUD_Handle* handle, int count)
-{
- lock();
- bool result = isValid(handle);
- if(result)
- ((AUD_SoftwareHandle*)handle)->loopcount = count;
- unlock();
- return result;
-}
-
-bool AUD_SoftwareDevice::setStopCallback(AUD_Handle* handle, stopCallback callback, void* data)
-{
- lock();
- bool result = isValid(handle);
- if(result)
- {
- AUD_SoftwareHandle* h = (AUD_SoftwareHandle*)handle;
- h->stop = callback;
- h->stop_data = data;
- }
- unlock();
- return result;
-}
diff --git a/intern/audaspace/intern/AUD_SoftwareDevice.h b/intern/audaspace/intern/AUD_SoftwareDevice.h
index 6518afe6737..45df48d12be 100644
--- a/intern/audaspace/intern/AUD_SoftwareDevice.h
+++ b/intern/audaspace/intern/AUD_SoftwareDevice.h
@@ -33,9 +33,9 @@
#define AUD_SOFTWAREDEVICE
#include "AUD_IDevice.h"
+#include "AUD_IHandle.h"
#include "AUD_Mixer.h"
#include "AUD_Buffer.h"
-struct AUD_SoftwareHandle;
#include <list>
#include <pthread.h>
@@ -51,6 +51,56 @@ struct AUD_SoftwareHandle;
class AUD_SoftwareDevice : public AUD_IDevice
{
protected:
+ /// Saves the data for playback.
+ class AUD_SoftwareHandle : public AUD_IHandle
+ {
+ public:
+ /// The reader source.
+ AUD_Reference<AUD_IReader> m_reader;
+
+ /// Whether to keep the source if end of it is reached.
+ bool m_keep;
+
+ /// The volume of the source.
+ float m_volume;
+
+ /// The loop count of the source.
+ int m_loopcount;
+
+ /// The stop callback.
+ stopCallback m_stop;
+
+ /// Stop callback data.
+ void* m_stop_data;
+
+ /// Current status of the handle
+ AUD_Status m_status;
+
+ /// Own device.
+ AUD_SoftwareDevice* m_device;
+
+ public:
+
+ AUD_SoftwareHandle(AUD_SoftwareDevice* device, AUD_Reference<AUD_IReader> reader, bool keep);
+
+ virtual ~AUD_SoftwareHandle() {}
+ virtual bool pause();
+ virtual bool resume();
+ virtual bool stop();
+ virtual bool getKeep();
+ virtual bool setKeep(bool keep);
+ virtual bool seek(float position);
+ virtual float getPosition();
+ virtual AUD_Status getStatus();
+ virtual float getVolume();
+ virtual bool setVolume(float volume);
+ virtual float getPitch();
+ virtual bool setPitch(float pitch);
+ virtual int getLoopCount();
+ virtual bool setLoopCount(int count);
+ virtual bool setStopCallback(stopCallback callback = 0, void* data = 0);
+ };
+
/**
* The specification of the device.
*/
@@ -93,12 +143,12 @@ private:
/**
* The list of sounds that are currently playing.
*/
- std::list<AUD_SoftwareHandle*> m_playingSounds;
+ std::list<AUD_Reference<AUD_SoftwareHandle> > m_playingSounds;
/**
* The list of sounds that are currently paused.
*/
- std::list<AUD_SoftwareHandle*> m_pausedSounds;
+ std::list<AUD_Reference<AUD_SoftwareHandle> > m_pausedSounds;
/**
* Whether there is currently playback.
@@ -115,36 +165,14 @@ private:
*/
float m_volume;
- /**
- * Checks if a handle is valid.
- * \param handle The handle to check.
- * \return Whether the handle is valid.
- */
- bool isValid(AUD_Handle* handle);
-
public:
virtual AUD_DeviceSpecs getSpecs() const;
- virtual AUD_Handle* play(AUD_Reference<AUD_IReader> reader, bool keep = false);
- virtual AUD_Handle* play(AUD_Reference<AUD_IFactory> factory, bool keep = false);
- virtual bool pause(AUD_Handle* handle);
- virtual bool resume(AUD_Handle* handle);
- virtual bool stop(AUD_Handle* handle);
- virtual bool getKeep(AUD_Handle* handle);
- virtual bool setKeep(AUD_Handle* handle, bool keep);
- virtual bool seek(AUD_Handle* handle, float position);
- virtual float getPosition(AUD_Handle* handle);
- virtual AUD_Status getStatus(AUD_Handle* handle);
+ virtual AUD_Reference<AUD_IHandle> play(AUD_Reference<AUD_IReader> reader, bool keep = false);
+ virtual AUD_Reference<AUD_IHandle> play(AUD_Reference<AUD_IFactory> factory, bool keep = false);
virtual void lock();
virtual void unlock();
virtual float getVolume() const;
virtual void setVolume(float volume);
- virtual float getVolume(AUD_Handle* handle);
- virtual bool setVolume(AUD_Handle* handle, float volume);
- virtual float getPitch(AUD_Handle* handle);
- virtual bool setPitch(AUD_Handle* handle, float pitch);
- virtual int getLoopCount(AUD_Handle* handle);
- virtual bool setLoopCount(AUD_Handle* handle, int count);
- virtual bool setStopCallback(AUD_Handle* handle, stopCallback callback = NULL, void* data = NULL);
};
#endif //AUD_SOFTWAREDEVICE