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
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/audaspace/OpenAL
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/audaspace/OpenAL')
-rw-r--r--intern/audaspace/OpenAL/AUD_OpenALDevice.cpp1620
-rw-r--r--intern/audaspace/OpenAL/AUD_OpenALDevice.h154
2 files changed, 862 insertions, 912 deletions
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