3D Audio GSoC:
[blender.git] / intern / audaspace / OpenAL / AUD_OpenALDevice.cpp
index 465ad5b5ae6f53fc28b606597f5ed6c7802ea7e8..f24d3aef4e2fa3d56f8d1012f50d8becb597ec84 100644 (file)
 #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);
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::pause()
+{
+       if(m_status)
+       {
+               m_device->lock();
 
-       /// The first buffer to be read next.
-       int current;
+               if(m_status == AUD_STATUS_PLAYING)
+               {
+                       m_device->m_playingSounds.remove(this);
+                       m_device->m_pausedSounds.push_back(this);
 
-       /// Whether the stream doesn't return any more data.
-       bool eos;
+                       alSourcePause(m_source);
 
-       /// The loop count of the source.
-       int loopcount;
+                       m_status = AUD_STATUS_PAUSED;
+                       m_device->unlock();
 
-       /// The stop callback.
-       stopCallback stop;
+                       return true;
+               }
 
-       /// Stop callback data.
-       void* stop_data;
-};
+               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();
+
+               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();
+
+       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();
 
-       /// The OpenAL buffer.
-       ALuint buffer;
-};
+       alSourcef(m_source, AL_CONE_OUTER_GAIN, volume);
 
-typedef std::list<AUD_OpenALHandle*>::iterator AUD_HandleIterator;
-typedef std::list<AUD_OpenALBufferedFactory*>::iterator AUD_BFIterator;
+       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;
@@ -702,373 +1267,40 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_Reference<AUD_IFactory> factory, bool kee
                        }
                }
        }
-       catch(AUD_Exception&)
-       {
-               unlock();
-               throw;
-       }
-
-       unlock();
-
-       if(sound)
-               return sound;*/
-
-       return play(factory->createReader(), keep);
-}
-
-bool AUD_OpenALDevice::pause(AUD_Handle* handle)
-{
-       bool result = false;
-
-       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);
-}
-
-void AUD_OpenALDevice::unlock()
-{
-       pthread_mutex_unlock(&m_mutex);
-}
-
-float AUD_OpenALDevice::getVolume() const
-{
-       float result;
-       alGetListenerf(AL_GAIN, &result);
-       return result;
-}
-
-void AUD_OpenALDevice::setVolume(float volume)
-{
-       alListenerf(AL_GAIN, volume);
-}
+       catch(AUD_Exception&)
+       {
+               unlock();
+               throw;
+       }
 
-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;
-}
+       if(sound)
+               return sound;*/
 
-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;
+       return play(factory->createReader(), keep);
 }
 
-bool AUD_OpenALDevice::setPitch(AUD_Handle* handle, float pitch)
+void AUD_OpenALDevice::lock()
 {
-       lock();
-       bool result = isValid(handle);
-       if(result)
-               alSourcef(((AUD_OpenALHandle*)handle)->source, AL_PITCH, pitch);
-       unlock();
-       return result;
+       pthread_mutex_lock(&m_mutex);
 }
 
-int AUD_OpenALDevice::getLoopCount(AUD_Handle* handle)
+void AUD_OpenALDevice::unlock()
 {
-       lock();
-       int result = 0;
-       if(isValid(handle))
-               result = ((AUD_OpenALHandle*)handle)->loopcount;
-       unlock();
-       return result;
+       pthread_mutex_unlock(&m_mutex);
 }
 
-bool AUD_OpenALDevice::setLoopCount(AUD_Handle* handle, int count)
+float AUD_OpenALDevice::getVolume() const
 {
-       lock();
-       bool result = isValid(handle);
-       if(result)
-       {
-               ((AUD_OpenALHandle*)handle)->loopcount = count;
-               ((AUD_OpenALHandle*)handle)->eos = false;
-       }
-       unlock();
+       float result;
+       alGetListenerf(AL_GAIN, &result);
        return result;
 }
 
-bool AUD_OpenALDevice::setStopCallback(AUD_Handle* handle, stopCallback callback, void* data)
+void AUD_OpenALDevice::setVolume(float volume)
 {
-       lock();
-       bool result = isValid(handle);
-       if(result)
-       {
-               AUD_OpenALHandle* h = (AUD_OpenALHandle*)handle;
-               h->stop = callback;
-               h->stop_data = data;
-       }
-       unlock();
-       return result;
+       alListenerf(AL_GAIN, volume);
 }
 
 /* AUD_XXX Temorary disabled
@@ -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;
-}