Audaspace: Refactored the complete 3D Device code giving a nicer API.
authorJoerg Mueller <nexyon@gmail.com>
Fri, 30 Jul 2010 22:20:08 +0000 (22:20 +0000)
committerJoerg Mueller <nexyon@gmail.com>
Fri, 30 Jul 2010 22:20:08 +0000 (22:20 +0000)
12 files changed:
intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
intern/audaspace/OpenAL/AUD_OpenALDevice.h
intern/audaspace/Python/AUD_PyAPI.cpp
intern/audaspace/intern/AUD_3DMath.h [new file with mode: 0644]
intern/audaspace/intern/AUD_C-API.cpp
intern/audaspace/intern/AUD_C-API.h
intern/audaspace/intern/AUD_I3DDevice.h
intern/audaspace/intern/AUD_IDevice.h
intern/audaspace/intern/AUD_Space.h
source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
source/gameengine/Ketsji/KX_KetsjiEngine.cpp
source/gameengine/Ketsji/KX_SoundActuator.cpp

index 4d908261ae8eac292c039b91d0e0364ee731a4be..6d1f9a5527b27e8d43247f76afd89e1477113629 100644 (file)
@@ -1099,214 +1099,447 @@ bool AUD_OpenALDevice::bufferFactory(void *value)
 /**************************** 3D Device Code **********************************/
 /******************************************************************************/
 
-AUD_Handle* AUD_OpenALDevice::play3D(AUD_IFactory* factory, bool keep)
+AUD_Vector3 AUD_OpenALDevice::getListenerLocation() const
 {
-       AUD_OpenALHandle* handle = (AUD_OpenALHandle*)play(factory, keep);
-       if(handle)
-               alSourcei(handle->source, AL_SOURCE_RELATIVE, 0);
-       return handle;
+       ALfloat p[3];
+       alGetListenerfv(AL_POSITION, p);
+       return AUD_Vector3(p[0], p[1], p[2]);
 }
 
-bool AUD_OpenALDevice::updateListener(AUD_3DData &data)
+void AUD_OpenALDevice::setListenerLocation(const AUD_Vector3& location)
 {
-       alListenerfv(AL_POSITION, (ALfloat*)data.position);
-       alListenerfv(AL_VELOCITY, (ALfloat*)data.velocity);
-       alListenerfv(AL_ORIENTATION, (ALfloat*)&(data.orientation[3]));
+       alListenerfv(AL_POSITION, (ALfloat*)location.get());
+}
 
-       return true;
+AUD_Vector3 AUD_OpenALDevice::getListenerVelocity() const
+{
+       ALfloat v[3];
+       alGetListenerfv(AL_VELOCITY, v);
+       return AUD_Vector3(v[0], v[1], v[2]);
+}
+
+void AUD_OpenALDevice::setListenerVelocity(const AUD_Vector3& velocity)
+{
+       alListenerfv(AL_VELOCITY, (ALfloat*)velocity.get());
+}
+
+AUD_Quaternion AUD_OpenALDevice::getListenerOrientation() const
+{
+       // AUD_XXX not implemented yet
+       return AUD_Quaternion(0, 0, 0, 0);
+}
+
+void AUD_OpenALDevice::setListenerOrientation(const AUD_Quaternion& orientation)
+{
+       ALfloat direction[6];
+       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;
+       direction[3] = 2 * (orientation.x() * orientation.y() -
+                                               orientation.w() * orientation.z());
+       direction[4] = 1 - 2 * (orientation.x() * orientation.x() +
+                                                       orientation.z() * orientation.z());
+       direction[5] = 2 * (orientation.w() * orientation.x() +
+                                               orientation.y() * orientation.z());
+       alListenerfv(AL_ORIENTATION, direction);
+}
+
+float AUD_OpenALDevice::getSpeedOfSound() const
+{
+       return alGetFloat(AL_SPEED_OF_SOUND);
+}
+
+void AUD_OpenALDevice::setSpeedOfSound(float speed)
+{
+       alSpeedOfSound(speed);
 }
 
-bool AUD_OpenALDevice::setSetting(AUD_3DSetting setting, float value)
+float AUD_OpenALDevice::getDopplerFactor() const
 {
-       switch(setting)
+       return alGetFloat(AL_DOPPLER_FACTOR);
+}
+
+void AUD_OpenALDevice::setDopplerFactor(float factor)
+{
+       alDopplerFactor(factor);
+}
+
+AUD_DistanceModel AUD_OpenALDevice::getDistanceModel() const
+{
+       switch(alGetInteger(AL_DISTANCE_MODEL))
        {
-       case AUD_3DS_DISTANCE_MODEL:
-               if(value == AUD_DISTANCE_MODEL_NONE)
-                       alDistanceModel(AL_NONE);
-               else if(value == AUD_DISTANCE_MODEL_INVERSE)
-                       alDistanceModel(AL_INVERSE_DISTANCE);
-               else if(value == AUD_DISTANCE_MODEL_INVERSE_CLAMPED)
-                       alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
-               else if(value == AUD_DISTANCE_MODEL_LINEAR)
-                       alDistanceModel(AL_LINEAR_DISTANCE);
-               else if(value == AUD_DISTANCE_MODEL_LINEAR_CLAMPED)
-                       alDistanceModel(AL_LINEAR_DISTANCE_CLAMPED);
-               else if(value == AUD_DISTANCE_MODEL_EXPONENT)
-                       alDistanceModel(AL_EXPONENT_DISTANCE);
-               else if(value == AUD_DISTANCE_MODEL_EXPONENT_CLAMPED)
-                       alDistanceModel(AL_EXPONENT_DISTANCE_CLAMPED);
-               else
-                       return false;
-               return true;
-       case AUD_3DS_DOPPLER_FACTOR:
-               alDopplerFactor(value);
-               return true;
-       case AUD_3DS_SPEED_OF_SOUND:
-               alSpeedOfSound(value);
-               return true;
+       case AL_INVERSE_DISTANCE:
+               return AUD_DISTANCE_MODEL_INVERSE;
+       case AL_INVERSE_DISTANCE_CLAMPED:
+               return AUD_DISTANCE_MODEL_INVERSE_CLAMPED;
+       case AL_LINEAR_DISTANCE:
+               return AUD_DISTANCE_MODEL_LINEAR;
+       case AL_LINEAR_DISTANCE_CLAMPED:
+               return AUD_DISTANCE_MODEL_LINEAR_CLAMPED;
+       case AL_EXPONENT_DISTANCE:
+               return AUD_DISTANCE_MODEL_EXPONENT;
+       case AL_EXPONENT_DISTANCE_CLAMPED:
+               return AUD_DISTANCE_MODEL_EXPONENT_CLAMPED;
        default:
-               return false;
+               return AUD_DISTANCE_MODEL_INVALID;
        }
 }
 
-float AUD_OpenALDevice::getSetting(AUD_3DSetting setting)
+void AUD_OpenALDevice::setDistanceModel(AUD_DistanceModel model)
 {
-       switch(setting)
+       switch(model)
        {
-       case AUD_3DS_DISTANCE_MODEL:
-               switch(alGetInteger(AL_DISTANCE_MODEL))
-               {
-                       case AL_NONE:
-                               return AUD_DISTANCE_MODEL_NONE;
-                       case AL_INVERSE_DISTANCE:
-                               return AUD_DISTANCE_MODEL_INVERSE;
-                       case AL_INVERSE_DISTANCE_CLAMPED:
-                               return AUD_DISTANCE_MODEL_INVERSE_CLAMPED;
-                       case AL_LINEAR_DISTANCE:
-                               return AUD_DISTANCE_MODEL_LINEAR;
-                       case AL_LINEAR_DISTANCE_CLAMPED:
-                               return AUD_DISTANCE_MODEL_LINEAR_CLAMPED;
-                       case AL_EXPONENT_DISTANCE:
-                               return AUD_DISTANCE_MODEL_EXPONENT;
-                       case AL_EXPONENT_DISTANCE_CLAMPED:
-                               return AUD_DISTANCE_MODEL_EXPONENT_CLAMPED;
-               }
-       case AUD_3DS_DOPPLER_FACTOR:
-               return alGetFloat(AL_DOPPLER_FACTOR);
-       case AUD_3DS_SPEED_OF_SOUND:
-               return alGetFloat(AL_SPEED_OF_SOUND);
+       case AUD_DISTANCE_MODEL_INVERSE:
+               alDistanceModel(AL_INVERSE_DISTANCE);
+               break;
+       case AUD_DISTANCE_MODEL_INVERSE_CLAMPED:
+               alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
+               break;
+       case AUD_DISTANCE_MODEL_LINEAR:
+               alDistanceModel(AL_LINEAR_DISTANCE);
+               break;
+       case AUD_DISTANCE_MODEL_LINEAR_CLAMPED:
+               alDistanceModel(AL_LINEAR_DISTANCE_CLAMPED);
+               break;
+       case AUD_DISTANCE_MODEL_EXPONENT:
+               alDistanceModel(AL_EXPONENT_DISTANCE);
+               break;
+       case AUD_DISTANCE_MODEL_EXPONENT_CLAMPED:
+               alDistanceModel(AL_EXPONENT_DISTANCE_CLAMPED);
+               break;
        default:
-               return std::numeric_limits<float>::quiet_NaN();
+               alDistanceModel(AL_NONE);
        }
 }
 
-bool AUD_OpenALDevice::updateSource(AUD_Handle* handle, AUD_3DData &data)
+AUD_Vector3 AUD_OpenALDevice::getSourceLocation(AUD_Handle* handle)
 {
-       bool result = false;
-
+       AUD_Vector3 result = AUD_Vector3(0, 0, 0);
+       ALfloat p[3];
        lock();
 
        if(isValid(handle))
        {
-               int source = ((AUD_OpenALHandle*)handle)->source;
-               alSourcefv(source, AL_POSITION, (ALfloat*)data.position);
-               alSourcefv(source, AL_VELOCITY, (ALfloat*)data.velocity);
-               alSourcefv(source, AL_DIRECTION, (ALfloat*)&(data.orientation[3]));
-               result = true;
+               alGetSourcefv(((AUD_OpenALHandle*)handle)->source, AL_POSITION, p);
+               result = AUD_Vector3(p[0], p[1], p[2]);
        }
 
        unlock();
-
        return result;
 }
 
-bool AUD_OpenALDevice::setSourceSetting(AUD_Handle* handle,
-                                                                               AUD_3DSourceSetting setting,
-                                                                               float value)
+bool AUD_OpenALDevice::setSourceLocation(AUD_Handle* handle, const AUD_Vector3& location)
 {
        lock();
+       bool result = isValid(handle);
 
-       bool result = false;
+       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))
        {
-               int source = ((AUD_OpenALHandle*)handle)->source;
+               alGetSourcefv(((AUD_OpenALHandle*)handle)->source, AL_VELOCITY, v);
+               result = AUD_Vector3(v[0], v[1], v[2]);
+       }
 
-               switch(setting)
-               {
-               case AUD_3DSS_CONE_INNER_ANGLE:
-                       alSourcef(source, AL_CONE_INNER_ANGLE, value);
-                       result = true;
-                       break;
-               case AUD_3DSS_CONE_OUTER_ANGLE:
-                       alSourcef(source, AL_CONE_OUTER_ANGLE, value);
-                       result = true;
-                       break;
-               case AUD_3DSS_CONE_OUTER_GAIN:
-                       alSourcef(source, AL_CONE_OUTER_GAIN, value);
-                       result = true;
-                       break;
-               case AUD_3DSS_IS_RELATIVE:
-                       alSourcei(source, AL_SOURCE_RELATIVE, value > 0.0f);
-                       result = true;
-                       break;
-               case AUD_3DSS_MAX_DISTANCE:
-                       alSourcef(source, AL_MAX_DISTANCE, value);
-                       result = true;
-                       break;
-               case AUD_3DSS_MAX_GAIN:
-                       alSourcef(source, AL_MAX_GAIN, value);
-                       result = true;
-                       break;
-               case AUD_3DSS_MIN_GAIN:
-                       alSourcef(source, AL_MIN_GAIN, value);
-                       result = true;
-                       break;
-               case AUD_3DSS_REFERENCE_DISTANCE:
-                       alSourcef(source, AL_REFERENCE_DISTANCE, value);
-                       result = true;
-                       break;
-               case AUD_3DSS_ROLLOFF_FACTOR:
-                       alSourcef(source, AL_ROLLOFF_FACTOR, value);
-                       result = true;
-                       break;
-               default:
-                       break;
-               }
+       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;
 }
 
-float AUD_OpenALDevice::getSourceSetting(AUD_Handle* handle,
-                                                                                AUD_3DSourceSetting setting)
+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))
-       {
-               int source = ((AUD_OpenALHandle*)handle)->source;
+               alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_MAX_GAIN,
+                                        &result);
 
-               switch(setting)
-               {
-               case AUD_3DSS_CONE_INNER_ANGLE:
-                       alGetSourcef(source, AL_CONE_INNER_ANGLE, &result);
-                       break;
-               case AUD_3DSS_CONE_OUTER_ANGLE:
-                       alGetSourcef(source, AL_CONE_OUTER_ANGLE, &result);
-                       break;
-               case AUD_3DSS_CONE_OUTER_GAIN:
-                       alGetSourcef(source, AL_CONE_OUTER_GAIN, &result);
-                       break;
-               case AUD_3DSS_IS_RELATIVE:
-                       {
-                               ALint i;
-                               alGetSourcei(source, AL_SOURCE_RELATIVE, &i);
-                               result = i ? 1.0f : 0.0f;
-                               break;
-                       }
-               case AUD_3DSS_MAX_DISTANCE:
-                       alGetSourcef(source, AL_MAX_DISTANCE, &result);
-                       break;
-               case AUD_3DSS_MAX_GAIN:
-                       alGetSourcef(source, AL_MAX_GAIN, &result);
-                       break;
-               case AUD_3DSS_MIN_GAIN:
-                       alGetSourcef(source, AL_MIN_GAIN, &result);
-                       break;
-               case AUD_3DSS_REFERENCE_DISTANCE:
-                       alGetSourcef(source, AL_REFERENCE_DISTANCE, &result);
-                       break;
-               case AUD_3DSS_ROLLOFF_FACTOR:
-                       alGetSourcef(source, AL_ROLLOFF_FACTOR, &result);
-                       break;
-               default:
-                       break;
-               }
-       }
+       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;
index fa8f7c55134edd109aaaf0c1d1ca10773470ca61..cba031f25f96a8f1dd3a296d9779cb23391d9244 100644 (file)
@@ -159,15 +159,42 @@ public:
        virtual float getPitch(AUD_Handle* handle);
        virtual bool setPitch(AUD_Handle* handle, float pitch);
 
-       virtual AUD_Handle* play3D(AUD_IFactory* factory, bool keep = false);
-       virtual bool updateListener(AUD_3DData &data);
-       virtual bool setSetting(AUD_3DSetting setting, float value);
-       virtual float getSetting(AUD_3DSetting setting);
-       virtual bool updateSource(AUD_Handle* handle, AUD_3DData &data);
-       virtual bool setSourceSetting(AUD_Handle* handle,
-                                                                 AUD_3DSourceSetting setting, float value);
-       virtual float getSourceSetting(AUD_Handle* handle,
-                                                                  AUD_3DSourceSetting setting);
+       virtual AUD_Vector3 getListenerLocation() const;
+       virtual void setListenerLocation(const AUD_Vector3& location);
+       virtual AUD_Vector3 getListenerVelocity() const;
+       virtual void setListenerVelocity(const AUD_Vector3& velocity);
+       virtual AUD_Quaternion getListenerOrientation() const;
+       virtual void setListenerOrientation(const AUD_Quaternion& orientation);
+       virtual float getSpeedOfSound() const;
+       virtual void setSpeedOfSound(float speed);
+       virtual float getDopplerFactor() const;
+       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
index b26abee26e47c403e633ed43cfc02c76b5db8f0d..13617283a1ea0ac9ccec387523b7568d3d6055a8 100644 (file)
@@ -26,6 +26,7 @@
 #include "AUD_PyAPI.h"
 #include "structmember.h"
 
+#include "AUD_I3DDevice.h"
 #include "AUD_NULLDevice.h"
 #include "AUD_DelayFactory.h"
 #include "AUD_DoubleFactory.h"
@@ -1008,55 +1009,6 @@ Handle_stop(Handle *self)
        Py_RETURN_FALSE;
 }
 
-PyDoc_STRVAR(M_aud_Handle_update_doc,
-                        "update(info)\n\n"
-                        "Updates the 3D information of the source.\n\n"
-                        ":arg info: The 3D info in the format (fff)(fff)((fff)(fff)(fff))."
-                        " Position, velocity and a 3x3 orientation matrix.\n"
-                        ":type info: float tuple\n"
-                        ":return: Whether the action succeeded.\n"
-                        ":rtype: boolean");
-
-static PyObject *
-Handle_update(Handle *self, PyObject *args)
-{
-       AUD_3DData data;
-
-       if(!PyArg_Parse(args, "(fff)(fff)((fff)(fff)(fff))",
-                                       &data.position[0], &data.position[1], &data.position[2],
-                                       &data.velocity[0], &data.velocity[1], &data.velocity[2],
-                                       &data.orientation[0], &data.orientation[1], &data.orientation[2],
-                                       &data.orientation[3], &data.orientation[4], &data.orientation[5],
-                                       &data.orientation[6], &data.orientation[7], &data.orientation[8]))
-               return NULL;
-
-       Device* dev = (Device*)self->device;
-
-       try
-       {
-               AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
-               if(device)
-               {
-                       if(device->updateSource(self->handle, data))
-                       {
-                               Py_RETURN_TRUE;
-                       }
-               }
-               else
-               {
-                       PyErr_SetString(AUDError, "Device is not a 3D device!");
-                       return NULL;
-               }
-       }
-       catch(AUD_Exception&)
-       {
-               PyErr_SetString(AUDError, "Couldn't update the source!");
-               return NULL;
-       }
-
-       Py_RETURN_FALSE;
-}
-
 static PyMethodDef Handle_methods[] = {
        {"pause", (PyCFunction)Handle_pause, METH_NOARGS,
         M_aud_Handle_pause_doc
@@ -1067,9 +1019,6 @@ static PyMethodDef Handle_methods[] = {
        {"stop", (PyCFunction)Handle_stop, METH_NOARGS,
         M_aud_Handle_stop_doc
        },
-       {"update", (PyCFunction)Handle_update, METH_O,
-        M_aud_Handle_update_doc
-       },
        {NULL}  /* Sentinel */
 };
 
@@ -1318,8 +1267,185 @@ Handle_set_loop_count(Handle *self, PyObject* args, void* nothing)
        return -1;
 }
 
+PyDoc_STRVAR(M_aud_Handle_location_doc,
+                        "The source's location in 3D space, a 3D tuple of floats.");
+
+static PyObject *
+Handle_get_location(Handle *self, void* nothing)
+{
+       Device* dev = (Device*)self->device;
+
+       try
+       {
+               AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
+               if(device)
+               {
+                       AUD_Vector3 v = device->getSourceLocation(self->handle);
+                       return Py_BuildValue("(fff)", v.x(), v.y(), v.z());
+               }
+               else
+               {
+                       PyErr_SetString(AUDError, "Device is not a 3D device!");
+               }
+       }
+       catch(AUD_Exception&)
+       {
+               PyErr_SetString(AUDError, "Couldn't retrieve the location!");
+       }
+
+       return NULL;
+}
+
+static int
+Handle_set_location(Handle *self, PyObject* args, void* nothing)
+{
+       float x, y, z;
+
+       if(!PyArg_Parse(args, "(fff)", &x, &y, &z))
+               return NULL;
+
+       Device* dev = (Device*)self->device;
+
+       try
+       {
+               AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
+               if(device)
+               {
+                       AUD_Vector3 location(x, y, z);
+                       device->setSourceLocation(self->handle, location);
+                       return 0;
+               }
+               else
+                       PyErr_SetString(AUDError, "Device is not a 3D device!");
+       }
+       catch(AUD_Exception&)
+       {
+               PyErr_SetString(AUDError, "Couldn't set the location!");
+       }
+
+       return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_velocity_doc,
+                        "The source's velocity in 3D space, a 3D tuple of floats.");
+
+static PyObject *
+Handle_get_velocity(Handle *self, void* nothing)
+{
+       Device* dev = (Device*)self->device;
+
+       try
+       {
+               AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
+               if(device)
+               {
+                       AUD_Vector3 v = device->getSourceVelocity(self->handle);
+                       return Py_BuildValue("(fff)", v.x(), v.y(), v.z());
+               }
+               else
+               {
+                       PyErr_SetString(AUDError, "Device is not a 3D device!");
+               }
+       }
+       catch(AUD_Exception&)
+       {
+               PyErr_SetString(AUDError, "Couldn't retrieve the velocity!");
+       }
+
+       return NULL;
+}
+
+static int
+Handle_set_velocity(Handle *self, PyObject* args, void* nothing)
+{
+       float x, y, z;
+
+       if(!PyArg_Parse(args, "(fff)", &x, &y, &z))
+               return NULL;
+
+       Device* dev = (Device*)self->device;
+
+       try
+       {
+               AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
+               if(device)
+               {
+                       AUD_Vector3 velocity(x, y, z);
+                       device->setSourceVelocity(self->handle, velocity);
+                       return 0;
+               }
+               else
+                       PyErr_SetString(AUDError, "Device is not a 3D device!");
+       }
+       catch(AUD_Exception&)
+       {
+               PyErr_SetString(AUDError, "Couldn't set the velocity!");
+       }
+
+       return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_orientation_doc,
+                        "The source's orientation in 3D space as quaternion, a 4 float tuple.");
+
+static PyObject *
+Handle_get_orientation(Handle *self, void* nothing)
+{
+       Device* dev = (Device*)self->device;
+
+       try
+       {
+               AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
+               if(device)
+               {
+                       AUD_Quaternion o = device->getSourceOrientation(self->handle);
+                       return Py_BuildValue("(ffff)", o.w(), o.x(), o.y(), o.z());
+               }
+               else
+               {
+                       PyErr_SetString(AUDError, "Device is not a 3D device!");
+               }
+       }
+       catch(AUD_Exception&)
+       {
+               PyErr_SetString(AUDError, "Couldn't retrieve the orientation!");
+       }
+
+       return NULL;
+}
+
+static int
+Handle_set_orientation(Handle *self, PyObject* args, void* nothing)
+{
+       float w, x, y, z;
+
+       if(!PyArg_Parse(args, "(ffff)", &w, &x, &y, &z))
+               return NULL;
+
+       Device* dev = (Device*)self->device;
+
+       try
+       {
+               AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
+               if(device)
+               {
+                       AUD_Quaternion orientation(w, x, y, z);
+                       device->setSourceOrientation(self->handle, orientation);
+                       return 0;
+               }
+               else
+                       PyErr_SetString(AUDError, "Device is not a 3D device!");
+       }
+       catch(AUD_Exception&)
+       {
+               PyErr_SetString(AUDError, "Couldn't set the orientation!");
+       }
+
+       return -1;
+}
+
 PyDoc_STRVAR(M_aud_Handle_relative_doc,
-                        "Whether the source's position is relative or absolute to the listener.");
+                        "Whether the source's location, velocity and orientation is relative or absolute to the listener.");
 
 static PyObject *
 Handle_get_relative(Handle *self, void* nothing)
@@ -1331,7 +1457,7 @@ Handle_get_relative(Handle *self, void* nothing)
                AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
                if(device)
                {
-                       if(device->getSourceSetting(self->handle, AUD_3DSS_IS_RELATIVE) > 0)
+                       if(device->isRelative(self->handle))
                        {
                                Py_RETURN_TRUE;
                        }
@@ -1362,7 +1488,7 @@ Handle_set_relative(Handle *self, PyObject* args, void* nothing)
                return -1;
        }
 
-       float relative = (args == Py_True);
+       bool relative = (args == Py_True);
        Device* dev = (Device*)self->device;
 
        try
@@ -1370,7 +1496,7 @@ Handle_set_relative(Handle *self, PyObject* args, void* nothing)
                AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
                if(device)
                {
-                       device->setSourceSetting(self->handle, AUD_3DSS_IS_RELATIVE, relative);
+                       device->setRelative(self->handle, relative);
                        return 0;
                }
                else
@@ -1384,11 +1510,11 @@ Handle_set_relative(Handle *self, PyObject* args, void* nothing)
        return -1;
 }
 
-PyDoc_STRVAR(M_aud_Handle_min_gain_doc,
-                        "The minimum gain of the source.");
+PyDoc_STRVAR(M_aud_Handle_volume_minimum_doc,
+                        "The minimum volume of the source.");
 
 static PyObject *
-Handle_get_min_gain(Handle *self, void* nothing)
+Handle_get_volume_minimum(Handle *self, void* nothing)
 {
        Device* dev = (Device*)self->device;
 
@@ -1397,7 +1523,7 @@ Handle_get_min_gain(Handle *self, void* nothing)
                AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
                if(device)
                {
-                       return Py_BuildValue("f", device->getSourceSetting(self->handle, AUD_3DSS_MIN_GAIN));
+                       return Py_BuildValue("f", device->getVolumeMinimum(self->handle));
                }
                else
                {
@@ -1407,17 +1533,17 @@ Handle_get_min_gain(Handle *self, void* nothing)
        }
        catch(AUD_Exception&)
        {
-               PyErr_SetString(AUDError, "Couldn't retrieve the minimum gain of the sound!");
+               PyErr_SetString(AUDError, "Couldn't retrieve the minimum volume of the sound!");
                return NULL;
        }
 }
 
 static int
-Handle_set_min_gain(Handle *self, PyObject* args, void* nothing)
+Handle_set_volume_minimum(Handle *self, PyObject* args, void* nothing)
 {
-       float gain;
+       float volume;
 
-       if(!PyArg_Parse(args, "f", &gain))
+       if(!PyArg_Parse(args, "f", &volume))
                return -1;
 
        Device* dev = (Device*)self->device;
@@ -1427,7 +1553,7 @@ Handle_set_min_gain(Handle *self, PyObject* args, void* nothing)
                AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
                if(device)
                {
-                       device->setSourceSetting(self->handle, AUD_3DSS_MIN_GAIN, gain);
+                       device->setVolumeMinimum(self->handle, volume);
                        return 0;
                }
                else
@@ -1435,17 +1561,17 @@ Handle_set_min_gain(Handle *self, PyObject* args, void* nothing)
        }
        catch(AUD_Exception&)
        {
-               PyErr_SetString(AUDError, "Couldn't set the minimum source gain!");
+               PyErr_SetString(AUDError, "Couldn't set the minimum source volume!");
        }
 
        return -1;
 }
 
-PyDoc_STRVAR(M_aud_Handle_max_gain_doc,
-                        "The maximum gain of the source.");
+PyDoc_STRVAR(M_aud_Handle_volume_maximum_doc,
+                        "The maximum volume of the source.");
 
 static PyObject *
-Handle_get_max_gain(Handle *self, void* nothing)
+Handle_get_volume_maximum(Handle *self, void* nothing)
 {
        Device* dev = (Device*)self->device;
 
@@ -1454,7 +1580,7 @@ Handle_get_max_gain(Handle *self, void* nothing)
                AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
                if(device)
                {
-                       return Py_BuildValue("f", device->getSourceSetting(self->handle, AUD_3DSS_MAX_GAIN));
+                       return Py_BuildValue("f", device->getVolumeMaximum(self->handle));
                }
                else
                {
@@ -1464,17 +1590,17 @@ Handle_get_max_gain(Handle *self, void* nothing)
        }
        catch(AUD_Exception&)
        {
-               PyErr_SetString(AUDError, "Couldn't retrieve the maximum gain of the sound!");
+               PyErr_SetString(AUDError, "Couldn't retrieve the maximum volume of the sound!");
                return NULL;
        }
 }
 
 static int
-Handle_set_max_gain(Handle *self, PyObject* args, void* nothing)
+Handle_set_volume_maximum(Handle *self, PyObject* args, void* nothing)
 {
-       float gain;
+       float volume;
 
-       if(!PyArg_Parse(args, "f", &gain))
+       if(!PyArg_Parse(args, "f", &volume))
                return -1;
 
        Device* dev = (Device*)self->device;
@@ -1484,7 +1610,7 @@ Handle_set_max_gain(Handle *self, PyObject* args, void* nothing)
                AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
                if(device)
                {
-                       device->setSourceSetting(self->handle, AUD_3DSS_MAX_GAIN, gain);
+                       device->setVolumeMaximum(self->handle, volume);
                        return 0;
                }
                else
@@ -1492,17 +1618,17 @@ Handle_set_max_gain(Handle *self, PyObject* args, void* nothing)
        }
        catch(AUD_Exception&)
        {
-               PyErr_SetString(AUDError, "Couldn't set the maximum source gain!");
+               PyErr_SetString(AUDError, "Couldn't set the maximum source volume!");
        }
 
        return -1;
 }
 
-PyDoc_STRVAR(M_aud_Handle_reference_distance_doc,
+PyDoc_STRVAR(M_aud_Handle_distance_reference_doc,
                         "The reference distance of the source.");
 
 static PyObject *
-Handle_get_reference_distance(Handle *self, void* nothing)
+Handle_get_distance_reference(Handle *self, void* nothing)
 {
        Device* dev = (Device*)self->device;
 
@@ -1511,7 +1637,7 @@ Handle_get_reference_distance(Handle *self, void* nothing)
                AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
                if(device)
                {
-                       return Py_BuildValue("f", device->getSourceSetting(self->handle, AUD_3DSS_REFERENCE_DISTANCE));
+                       return Py_BuildValue("f", device->getDistanceReference(self->handle));
                }
                else
                {
@@ -1527,7 +1653,7 @@ Handle_get_reference_distance(Handle *self, void* nothing)
 }
 
 static int
-Handle_set_reference_distance(Handle *self, PyObject* args, void* nothing)
+Handle_set_distance_reference(Handle *self, PyObject* args, void* nothing)
 {
        float distance;
 
@@ -1541,7 +1667,7 @@ Handle_set_reference_distance(Handle *self, PyObject* args, void* nothing)
                AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
                if(device)
                {
-                       device->setSourceSetting(self->handle, AUD_3DSS_REFERENCE_DISTANCE, distance);
+                       device->setDistanceReference(self->handle, distance);
                        return 0;
                }
                else
@@ -1555,11 +1681,11 @@ Handle_set_reference_distance(Handle *self, PyObject* args, void* nothing)
        return -1;
 }
 
-PyDoc_STRVAR(M_aud_Handle_max_distance_doc,
+PyDoc_STRVAR(M_aud_Handle_distance_maximum_doc,
                         "The maximum distance of the source.");
 
 static PyObject *
-Handle_get_max_distance(Handle *self, void* nothing)
+Handle_get_distance_maximum(Handle *self, void* nothing)
 {
        Device* dev = (Device*)self->device;
 
@@ -1568,7 +1694,7 @@ Handle_get_max_distance(Handle *self, void* nothing)
                AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
                if(device)
                {
-                       return Py_BuildValue("f", device->getSourceSetting(self->handle, AUD_3DSS_MAX_DISTANCE));
+                       return Py_BuildValue("f", device->getDistanceMaximum(self->handle));
                }
                else
                {
@@ -1584,7 +1710,7 @@ Handle_get_max_distance(Handle *self, void* nothing)
 }
 
 static int
-Handle_set_max_distance(Handle *self, PyObject* args, void* nothing)
+Handle_set_distance_maximum(Handle *self, PyObject* args, void* nothing)
 {
        float distance;
 
@@ -1598,7 +1724,7 @@ Handle_set_max_distance(Handle *self, PyObject* args, void* nothing)
                AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
                if(device)
                {
-                       device->setSourceSetting(self->handle, AUD_3DSS_MAX_DISTANCE, distance);
+                       device->setDistanceMaximum(self->handle, distance);
                        return 0;
                }
                else
@@ -1612,11 +1738,11 @@ Handle_set_max_distance(Handle *self, PyObject* args, void* nothing)
        return -1;
 }
 
-PyDoc_STRVAR(M_aud_Handle_rolloff_factor_doc,
-                        "The rolloff factor of the source.");
+PyDoc_STRVAR(M_aud_Handle_attenuation_doc,
+                        "The attenuation of the source.");
 
 static PyObject *
-Handle_get_rolloff_factor(Handle *self, void* nothing)
+Handle_get_attenuation(Handle *self, void* nothing)
 {
        Device* dev = (Device*)self->device;
 
@@ -1625,7 +1751,7 @@ Handle_get_rolloff_factor(Handle *self, void* nothing)
                AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
                if(device)
                {
-                       return Py_BuildValue("f", device->getSourceSetting(self->handle, AUD_3DSS_ROLLOFF_FACTOR));
+                       return Py_BuildValue("f", device->getAttenuation(self->handle));
                }
                else
                {
@@ -1635,13 +1761,13 @@ Handle_get_rolloff_factor(Handle *self, void* nothing)
        }
        catch(AUD_Exception&)
        {
-               PyErr_SetString(AUDError, "Couldn't retrieve the rolloff factor of the sound!");
+               PyErr_SetString(AUDError, "Couldn't retrieve the attenuation of the sound!");
                return NULL;
        }
 }
 
 static int
-Handle_set_rolloff_factor(Handle *self, PyObject* args, void* nothing)
+Handle_set_attenuation(Handle *self, PyObject* args, void* nothing)
 {
        float factor;
 
@@ -1655,7 +1781,7 @@ Handle_set_rolloff_factor(Handle *self, PyObject* args, void* nothing)
                AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
                if(device)
                {
-                       device->setSourceSetting(self->handle, AUD_3DSS_ROLLOFF_FACTOR, factor);
+                       device->setAttenuation(self->handle, factor);
                        return 0;
                }
                else
@@ -1663,17 +1789,17 @@ Handle_set_rolloff_factor(Handle *self, PyObject* args, void* nothing)
        }
        catch(AUD_Exception&)
        {
-               PyErr_SetString(AUDError, "Couldn't set the rolloff factor!");
+               PyErr_SetString(AUDError, "Couldn't set the attenuation!");
        }
 
        return -1;
 }
 
-PyDoc_STRVAR(M_aud_Handle_cone_inner_angle_doc,
+PyDoc_STRVAR(M_aud_Handle_cone_angle_inner_doc,
                         "The cone inner angle of the source.");
 
 static PyObject *
-Handle_get_cone_inner_angle(Handle *self, void* nothing)
+Handle_get_cone_angle_inner(Handle *self, void* nothing)
 {
        Device* dev = (Device*)self->device;
 
@@ -1682,7 +1808,7 @@ Handle_get_cone_inner_angle(Handle *self, void* nothing)
                AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
                if(device)
                {
-                       return Py_BuildValue("f", device->getSourceSetting(self->handle, AUD_3DSS_CONE_INNER_ANGLE));
+                       return Py_BuildValue("f", device->getConeAngleInner(self->handle));
                }
                else
                {
@@ -1698,7 +1824,7 @@ Handle_get_cone_inner_angle(Handle *self, void* nothing)
 }
 
 static int
-Handle_set_cone_inner_angle(Handle *self, PyObject* args, void* nothing)
+Handle_set_cone_angle_inner(Handle *self, PyObject* args, void* nothing)
 {
        float angle;
 
@@ -1712,7 +1838,7 @@ Handle_set_cone_inner_angle(Handle *self, PyObject* args, void* nothing)
                AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
                if(device)
                {
-                       device->setSourceSetting(self->handle, AUD_3DSS_CONE_INNER_ANGLE, angle);
+                       device->setConeAngleInner(self->handle, angle);
                        return 0;
                }
                else
@@ -1726,11 +1852,11 @@ Handle_set_cone_inner_angle(Handle *self, PyObject* args, void* nothing)
        return -1;
 }
 
-PyDoc_STRVAR(M_aud_Handle_cone_outer_angle_doc,
+PyDoc_STRVAR(M_aud_Handle_cone_angle_outer_doc,
                         "The cone outer angle of the source.");
 
 static PyObject *
-Handle_get_cone_outer_angle(Handle *self, void* nothing)
+Handle_get_cone_angle_outer(Handle *self, void* nothing)
 {
        Device* dev = (Device*)self->device;
 
@@ -1739,7 +1865,7 @@ Handle_get_cone_outer_angle(Handle *self, void* nothing)
                AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
                if(device)
                {
-                       return Py_BuildValue("f", device->getSourceSetting(self->handle, AUD_3DSS_CONE_OUTER_ANGLE));
+                       return Py_BuildValue("f", device->getConeAngleOuter(self->handle));
                }
                else
                {
@@ -1755,7 +1881,7 @@ Handle_get_cone_outer_angle(Handle *self, void* nothing)
 }
 
 static int
-Handle_set_cone_outer_angle(Handle *self, PyObject* args, void* nothing)
+Handle_set_cone_angle_outer(Handle *self, PyObject* args, void* nothing)
 {
        float angle;
 
@@ -1769,7 +1895,7 @@ Handle_set_cone_outer_angle(Handle *self, PyObject* args, void* nothing)
                AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
                if(device)
                {
-                       device->setSourceSetting(self->handle, AUD_3DSS_CONE_OUTER_ANGLE, angle);
+                       device->setConeAngleOuter(self->handle, angle);
                        return 0;
                }
                else
@@ -1783,11 +1909,11 @@ Handle_set_cone_outer_angle(Handle *self, PyObject* args, void* nothing)
        return -1;
 }
 
-PyDoc_STRVAR(M_aud_Handle_cone_outer_gain_doc,
-                        "The cone outer gain of the source.");
+PyDoc_STRVAR(M_aud_Handle_cone_volume_outer_doc,
+                        "The cone outer volume of the source.");
 
 static PyObject *
-Handle_get_cone_outer_gain(Handle *self, void* nothing)
+Handle_get_cone_volume_outer(Handle *self, void* nothing)
 {
        Device* dev = (Device*)self->device;
 
@@ -1796,7 +1922,7 @@ Handle_get_cone_outer_gain(Handle *self, void* nothing)
                AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
                if(device)
                {
-                       return Py_BuildValue("f", device->getSourceSetting(self->handle, AUD_3DSS_CONE_OUTER_GAIN));
+                       return Py_BuildValue("f", device->getConeVolumeOuter(self->handle));
                }
                else
                {
@@ -1806,17 +1932,17 @@ Handle_get_cone_outer_gain(Handle *self, void* nothing)
        }
        catch(AUD_Exception&)
        {
-               PyErr_SetString(AUDError, "Couldn't retrieve the cone outer gain of the sound!");
+               PyErr_SetString(AUDError, "Couldn't retrieve the cone outer volume of the sound!");
                return NULL;
        }
 }
 
 static int
-Handle_set_cone_outer_gain(Handle *self, PyObject* args, void* nothing)
+Handle_set_cone_volume_outer(Handle *self, PyObject* args, void* nothing)
 {
-       float gain;
+       float volume;
 
-       if(!PyArg_Parse(args, "f", &gain))
+       if(!PyArg_Parse(args, "f", &volume))
                return -1;
 
        Device* dev = (Device*)self->device;
@@ -1826,7 +1952,7 @@ Handle_set_cone_outer_gain(Handle *self, PyObject* args, void* nothing)
                AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
                if(device)
                {
-                       device->setSourceSetting(self->handle, AUD_3DSS_CONE_OUTER_GAIN, gain);
+                       device->setConeVolumeOuter(self->handle, volume);
                        return 0;
                }
                else
@@ -1834,7 +1960,7 @@ Handle_set_cone_outer_gain(Handle *self, PyObject* args, void* nothing)
        }
        catch(AUD_Exception&)
        {
-               PyErr_SetString(AUDError, "Couldn't set the cone outer gain!");
+               PyErr_SetString(AUDError, "Couldn't set the cone outer volume!");
        }
 
        return -1;
@@ -1853,24 +1979,30 @@ static PyGetSetDef Handle_properties[] = {
         M_aud_Handle_pitch_doc, NULL },
        {(char*)"loop_count", (getter)Handle_get_loop_count, (setter)Handle_set_loop_count,
         M_aud_Handle_loop_count_doc, NULL },
+       {(char*)"location", (getter)Handle_get_location, (setter)Handle_set_location,
+        M_aud_Handle_location_doc, NULL },
+       {(char*)"velocity", (getter)Handle_get_velocity, (setter)Handle_set_velocity,
+        M_aud_Handle_velocity_doc, NULL },
+       {(char*)"orientation", (getter)Handle_get_orientation, (setter)Handle_set_orientation,
+        M_aud_Handle_orientation_doc, NULL },
        {(char*)"relative", (getter)Handle_get_relative, (setter)Handle_set_relative,
         M_aud_Handle_relative_doc, NULL },
-       {(char*)"min_gain", (getter)Handle_get_min_gain, (setter)Handle_set_min_gain,
-        M_aud_Handle_min_gain_doc, NULL },
-       {(char*)"max_gain", (getter)Handle_get_max_gain, (setter)Handle_set_max_gain,
-        M_aud_Handle_max_gain_doc, NULL },
-       {(char*)"reference_distance", (getter)Handle_get_reference_distance, (setter)Handle_set_reference_distance,
-        M_aud_Handle_reference_distance_doc, NULL },
-       {(char*)"max_distance", (getter)Handle_get_max_distance, (setter)Handle_set_max_distance,
-        M_aud_Handle_max_distance_doc, NULL },
-       {(char*)"rolloff_factor", (getter)Handle_get_rolloff_factor, (setter)Handle_set_rolloff_factor,
-        M_aud_Handle_rolloff_factor_doc, NULL },
-       {(char*)"cone_inner_angle", (getter)Handle_get_cone_inner_angle, (setter)Handle_set_cone_inner_angle,
-        M_aud_Handle_cone_inner_angle_doc, NULL },
-       {(char*)"cone_outer_angle", (getter)Handle_get_cone_outer_angle, (setter)Handle_set_cone_outer_angle,
-        M_aud_Handle_cone_outer_angle_doc, NULL },
-       {(char*)"cone_outer_gain", (getter)Handle_get_cone_outer_gain, (setter)Handle_set_cone_outer_gain,
-        M_aud_Handle_cone_outer_gain_doc, NULL },
+       {(char*)"volume_minimum", (getter)Handle_get_volume_minimum, (setter)Handle_set_volume_minimum,
+        M_aud_Handle_volume_minimum_doc, NULL },
+       {(char*)"volume_maximum", (getter)Handle_get_volume_maximum, (setter)Handle_set_volume_maximum,
+        M_aud_Handle_volume_maximum_doc, NULL },
+       {(char*)"distance_reference", (getter)Handle_get_distance_reference, (setter)Handle_set_distance_reference,
+        M_aud_Handle_distance_reference_doc, NULL },
+       {(char*)"distance_maximum", (getter)Handle_get_distance_maximum, (setter)Handle_set_distance_maximum,
+        M_aud_Handle_distance_maximum_doc, NULL },
+       {(char*)"attenuation", (getter)Handle_get_attenuation, (setter)Handle_set_attenuation,
+        M_aud_Handle_attenuation_doc, NULL },
+       {(char*)"cone_angle_inner", (getter)Handle_get_cone_angle_inner, (setter)Handle_set_cone_angle_inner,
+        M_aud_Handle_cone_angle_inner_doc, NULL },
+       {(char*)"cone_angle_outer", (getter)Handle_get_cone_angle_outer, (setter)Handle_set_cone_angle_outer,
+        M_aud_Handle_cone_angle_outer_doc, NULL },
+       {(char*)"cone_volume_outer", (getter)Handle_get_cone_volume_outer, (setter)Handle_set_cone_volume_outer,
+        M_aud_Handle_cone_volume_outer_doc, NULL },
        {NULL}  /* Sentinel */
 };
 
@@ -2036,122 +2168,6 @@ Device_unlock(Device *self)
        }
 }
 
-PyDoc_STRVAR(M_aud_Device_play3D_doc,
-                        "play3d(sound[, keep])\n\n"
-                        "Plays a sound 3 dimensional if possible.\n\n"
-                        ":arg sound: The sound to play.\n"
-                        ":type sound: aud.Sound\n"
-                        ":arg keep: Whether the sound should be kept paused in the device when its end is reached.\n"
-                        ":type keep: boolean\n"
-                        ":return: The playback handle.\n"
-                        ":rtype: aud.Handle");
-
-static PyObject *
-Device_play3D(Device *self, PyObject *args, PyObject *kwds)
-{
-       PyObject* object;
-       PyObject* keepo = NULL;
-
-       bool keep = false;
-
-       static const char *kwlist[] = {"sound", "keep", NULL};
-
-       if(!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", const_cast<char**>(kwlist), &object, &keepo))
-               return NULL;
-
-       if(!PyObject_TypeCheck(object, &SoundType))
-       {
-               PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Sound!");
-               return NULL;
-       }
-
-       if(keepo != NULL)
-       {
-               if(!PyBool_Check(keepo))
-               {
-                       PyErr_SetString(PyExc_TypeError, "keep is not a boolean!");
-                       return NULL;
-               }
-
-               keep = keepo == Py_True;
-       }
-
-       Sound* sound = (Sound*)object;
-       Handle *handle;
-
-       handle = (Handle*)HandleType.tp_alloc(&HandleType, 0);
-       if(handle != NULL)
-       {
-               handle->device = (PyObject*)self;
-               Py_INCREF(self);
-
-               try
-               {
-                       AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
-                       if(device)
-                       {
-                               handle->handle = device->play3D(sound->factory, keep);
-                       }
-                       else
-                       {
-                               Py_DECREF(handle);
-                               PyErr_SetString(AUDError, "Device is not a 3D device!");
-                               return NULL;
-                       }
-               }
-               catch(AUD_Exception&)
-               {
-                       Py_DECREF(handle);
-                       PyErr_SetString(AUDError, "Couldn't play the sound!");
-                       return NULL;
-               }
-       }
-
-       return (PyObject *)handle;
-}
-
-PyDoc_STRVAR(M_aud_Device_update_listener_doc,
-                        "update_listener(info)\n\n"
-                        "Updates the 3D information of the listener.\n\n"
-                        ":arg info: The 3D info in the format (fff)(fff)((fff)(fff)(fff))."
-                        " Position, velocity and a 3x3 orientation matrix.\n"
-                        ":type info: float tuple");
-
-static PyObject *
-Device_update_listener(Device *self, PyObject *args)
-{
-       AUD_3DData data;
-
-       if(!PyArg_ParseTuple(args, "(fff)(fff)((fff)(fff)(fff))",
-                                                &data.position[0], &data.position[1], &data.position[2],
-                                                &data.velocity[0], &data.velocity[1], &data.velocity[2],
-                                                &data.orientation[0], &data.orientation[1], &data.orientation[2],
-                                                &data.orientation[3], &data.orientation[4], &data.orientation[5],
-                                                &data.orientation[6], &data.orientation[7], &data.orientation[8]))
-               return NULL;
-
-       try
-       {
-               AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
-               if(device)
-               {
-                       device->updateListener(data);
-               }
-               else
-               {
-                       PyErr_SetString(AUDError, "Device is not a 3D device!");
-                       return NULL;
-               }
-       }
-       catch(AUD_Exception&)
-       {
-               PyErr_SetString(AUDError, "Couldn't update the listener!");
-               return NULL;
-       }
-
-       Py_RETURN_NONE;
-}
-
 PyDoc_STRVAR(M_aud_Device_OpenAL_doc,
                         "OpenAL([frequency[, buffer_size]])\n\n"
                         "Creates an OpenAL device.\n\n"
@@ -2213,12 +2229,6 @@ static PyMethodDef Device_methods[] = {
        {"unlock", (PyCFunction)Device_unlock, METH_NOARGS,
         M_aud_Device_unlock_doc
        },
-       {"play3D", (PyCFunction)Device_play3D, METH_VARARGS | METH_KEYWORDS,
-        M_aud_Device_play3D_doc
-       },
-       {"update_listener", (PyCFunction)Device_update_listener, METH_VARARGS,
-        M_aud_Device_update_listener_doc
-       },
        {"OpenAL", (PyCFunction)Device_OpenAL, METH_VARARGS | METH_STATIC | METH_KEYWORDS,
         M_aud_Device_OpenAL_doc
        },
@@ -2325,6 +2335,171 @@ Device_set_volume(Device *self, PyObject* args, void* nothing)
        }
 }
 
+PyDoc_STRVAR(M_aud_Device_listener_location_doc,
+                        "The listeners's location in 3D space, a 3D tuple of floats.");
+
+static PyObject *
+Device_get_listener_location(Device *self, void* nothing)
+{
+       try
+       {
+               AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+               if(device)
+               {
+                       AUD_Vector3 v = device->getListenerLocation();
+                       return Py_BuildValue("(fff)", v.x(), v.y(), v.z());
+               }
+               else
+               {
+                       PyErr_SetString(AUDError, "Device is not a 3D device!");
+               }
+       }
+       catch(AUD_Exception&)
+       {
+               PyErr_SetString(AUDError, "Couldn't retrieve the location!");
+       }
+
+       return NULL;
+}
+
+static int
+Device_set_listener_location(Device *self, PyObject* args, void* nothing)
+{
+       float x, y, z;
+
+       if(!PyArg_Parse(args, "(fff)", &x, &y, &z))
+               return NULL;
+
+       try
+       {
+               AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+               if(device)
+               {
+                       AUD_Vector3 location(x, y, z);
+                       device->setListenerLocation(location);
+                       return 0;
+               }
+               else
+                       PyErr_SetString(AUDError, "Device is not a 3D device!");
+       }
+       catch(AUD_Exception&)
+       {
+               PyErr_SetString(AUDError, "Couldn't set the location!");
+       }
+
+       return -1;
+}
+
+PyDoc_STRVAR(M_aud_Device_listener_velocity_doc,
+                        "The listener's velocity in 3D space, a 3D tuple of floats.");
+
+static PyObject *
+Device_get_listener_velocity(Device *self, void* nothing)
+{
+       try
+       {
+               AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+               if(device)
+               {
+                       AUD_Vector3 v = device->getListenerVelocity();
+                       return Py_BuildValue("(fff)", v.x(), v.y(), v.z());
+               }
+               else
+               {
+                       PyErr_SetString(AUDError, "Device is not a 3D device!");
+               }
+       }
+       catch(AUD_Exception&)
+       {
+               PyErr_SetString(AUDError, "Couldn't retrieve the velocity!");
+       }
+
+       return NULL;
+}
+
+static int
+Device_set_listener_velocity(Device *self, PyObject* args, void* nothing)
+{
+       float x, y, z;
+
+       if(!PyArg_Parse(args, "(fff)", &x, &y, &z))
+               return NULL;
+
+       try
+       {
+               AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+               if(device)
+               {
+                       AUD_Vector3 velocity(x, y, z);
+                       device->setListenerVelocity(velocity);
+                       return 0;
+               }
+               else
+                       PyErr_SetString(AUDError, "Device is not a 3D device!");
+       }
+       catch(AUD_Exception&)
+       {
+               PyErr_SetString(AUDError, "Couldn't set the velocity!");
+       }
+
+       return -1;
+}
+
+PyDoc_STRVAR(M_aud_Device_listener_orientation_doc,
+                        "The listener's orientation in 3D space as quaternion, a 4 float tuple.");
+
+static PyObject *
+Device_get_listener_orientation(Device *self, void* nothing)
+{
+       try
+       {
+               AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+               if(device)
+               {
+                       AUD_Quaternion o = device->getListenerOrientation();
+                       return Py_BuildValue("(ffff)", o.w(), o.x(), o.y(), o.z());
+               }
+               else
+               {
+                       PyErr_SetString(AUDError, "Device is not a 3D device!");
+               }
+       }
+       catch(AUD_Exception&)
+       {
+               PyErr_SetString(AUDError, "Couldn't retrieve the orientation!");
+       }
+
+       return NULL;
+}
+
+static int
+Device_set_listener_orientation(Device *self, PyObject* args, void* nothing)
+{
+       float w, x, y, z;
+
+       if(!PyArg_Parse(args, "(ffff)", &w, &x, &y, &z))
+               return NULL;
+
+       try
+       {
+               AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+               if(device)
+               {
+                       AUD_Quaternion orientation(w, x, y, z);
+                       device->setListenerOrientation(orientation);
+                       return 0;
+               }
+               else
+                       PyErr_SetString(AUDError, "Device is not a 3D device!");
+       }
+       catch(AUD_Exception&)
+       {
+               PyErr_SetString(AUDError, "Couldn't set the orientation!");
+       }
+
+       return -1;
+}
+
 PyDoc_STRVAR(M_aud_Device_speed_of_sound_doc,
                         "The speed of sound of the device.");
 
@@ -2336,7 +2511,7 @@ Device_get_speed_of_sound(Device *self, void* nothing)
                AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
                if(device)
                {
-                       return Py_BuildValue("f", device->getSetting(AUD_3DS_SPEED_OF_SOUND));
+                       return Py_BuildValue("f", device->getSpeedOfSound());
                }
                else
                {
@@ -2364,7 +2539,7 @@ Device_set_speed_of_sound(Device *self, PyObject* args, void* nothing)
                AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
                if(device)
                {
-                       device->setSetting(AUD_3DS_SPEED_OF_SOUND, speed);
+                       device->setSpeedOfSound(speed);
                        return 0;
                }
                else
@@ -2389,7 +2564,7 @@ Device_get_doppler_factor(Device *self, void* nothing)
                AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
                if(device)
                {
-                       return Py_BuildValue("f", device->getSetting(AUD_3DS_DOPPLER_FACTOR));
+                       return Py_BuildValue("f", device->getDopplerFactor());
                }
                else
                {
@@ -2417,7 +2592,7 @@ Device_set_doppler_factor(Device *self, PyObject* args, void* nothing)
                AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
                if(device)
                {
-                       device->setSetting(AUD_3DS_DOPPLER_FACTOR, factor);
+                       device->setDopplerFactor(factor);
                        return 0;
                }
                else
@@ -2442,7 +2617,7 @@ Device_get_distance_model(Device *self, void* nothing)
                AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
                if(device)
                {
-                       return Py_BuildValue("i", int(device->getSetting(AUD_3DS_DISTANCE_MODEL)));
+                       return Py_BuildValue("i", int(device->getDistanceModel()));
                }
                else
                {
@@ -2470,7 +2645,7 @@ Device_set_distance_model(Device *self, PyObject* args, void* nothing)
                AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
                if(device)
                {
-                       device->setSetting(AUD_3DS_DISTANCE_MODEL, model);
+                       device->setDistanceModel(AUD_DistanceModel(model));
                        return 0;
                }
                else
@@ -2493,6 +2668,12 @@ static PyGetSetDef Device_properties[] = {
         M_aud_Device_channels_doc, NULL },
        {(char*)"volume", (getter)Device_get_volume, (setter)Device_set_volume,
         M_aud_Device_volume_doc, NULL },
+       {(char*)"listener_location", (getter)Device_get_listener_location, (setter)Device_set_listener_location,
+        M_aud_Device_listener_location_doc, NULL },
+       {(char*)"listener_velocity", (getter)Device_get_listener_velocity, (setter)Device_set_listener_velocity,
+        M_aud_Device_listener_velocity_doc, NULL },
+       {(char*)"listener_orientation", (getter)Device_get_listener_orientation, (setter)Device_set_listener_orientation,
+        M_aud_Device_listener_orientation_doc, NULL },
        {(char*)"speed_of_sound", (getter)Device_get_speed_of_sound, (setter)Device_set_speed_of_sound,
         M_aud_Device_speed_of_sound_doc, NULL },
        {(char*)"doppler_factor", (getter)Device_get_doppler_factor, (setter)Device_set_doppler_factor,
@@ -2779,7 +2960,7 @@ PyInit_aud(void)
        PY_MODULE_ADD_CONSTANT(m, AUD_DISTANCE_MODEL_INVERSE_CLAMPED);
        PY_MODULE_ADD_CONSTANT(m, AUD_DISTANCE_MODEL_LINEAR);
        PY_MODULE_ADD_CONSTANT(m, AUD_DISTANCE_MODEL_LINEAR_CLAMPED);
-       PY_MODULE_ADD_CONSTANT(m, AUD_DISTANCE_MODEL_NONE);
+       PY_MODULE_ADD_CONSTANT(m, AUD_DISTANCE_MODEL_INVALID);
 
        return m;
 }
diff --git a/intern/audaspace/intern/AUD_3DMath.h b/intern/audaspace/intern/AUD_3DMath.h
new file mode 100644 (file)
index 0000000..a3405bf
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_3DMATH
+#define AUD_3DMATH
+
+class AUD_Quaternion
+{
+private:
+       union
+       {
+               float m_v[4];
+               struct
+               {
+                       const float m_w;
+                       const float m_x;
+                       const float m_y;
+                       const float m_z;
+               };
+       };
+
+public:
+       /**
+        * Creates a new quaternion.
+        * \param w The w component.
+        * \param x The x component.
+        * \param y The y component.
+        * \param z The z component.
+        */
+       inline AUD_Quaternion(float w, float x, float y, float z) :
+               m_w(w), m_x(x), m_y(y), m_z(z)
+       {
+       }
+
+       /**
+        * Retrieves the w component of the quarternion.
+        * \return The w component.
+        */
+       inline const float& w() const
+       {
+               return m_w;
+       }
+
+       /**
+        * Retrieves the x component of the quarternion.
+        * \return The x component.
+        */
+       inline const float& x() const
+       {
+               return m_x;
+       }
+
+       /**
+        * Retrieves the y component of the quarternion.
+        * \return The y component.
+        */
+       inline const float& y() const
+       {
+               return m_y;
+       }
+
+       /**
+        * Retrieves the z component of the quarternion.
+        * \return The z component.
+        */
+       inline const float& z() const
+       {
+               return m_z;
+       }
+
+       /**
+        * Retrieves the components of the vector.
+        * \param destination Where the 4 float values should be saved to.
+        */
+       inline void get(float* destination) const
+       {
+               destination[0] = m_w;
+               destination[1] = m_x;
+               destination[2] = m_y;
+               destination[3] = m_z;
+       }
+
+       /**
+        * Retrieves the components of the vector.
+        * \return The components as float[4].
+        */
+       inline const float* get() const
+       {
+               return m_v;
+       }
+};
+
+class AUD_Vector3
+{
+private:
+       union
+       {
+               float m_v[3];
+               struct
+               {
+                       const float m_x;
+                       const float m_y;
+                       const float m_z;
+               };
+       };
+
+public:
+       /**
+        * Creates a new 3 dimensional vector.
+        * \param x The x component.
+        * \param y The y component.
+        * \param z The z component.
+        */
+       inline AUD_Vector3(float x, float y, float z) :
+               m_x(x), m_y(y), m_z(z)
+       {
+       }
+
+       /**
+        * Retrieves the x component of the vector.
+        * \return The x component.
+        */
+       inline const float& x() const
+       {
+               return m_x;
+       }
+
+       /**
+        * Retrieves the y component of the vector.
+        * \return The y component.
+        */
+       inline const float& y() const
+       {
+               return m_y;
+       }
+
+       /**
+        * Retrieves the z component of the vector.
+        * \return The z component.
+        */
+       inline const float& z() const
+       {
+               return m_z;
+       }
+
+       /**
+        * Retrieves the components of the vector.
+        * \param destination Where the 3 float values should be saved to.
+        */
+       inline void get(float* destination) const
+       {
+               destination[0] = m_x;
+               destination[1] = m_y;
+               destination[2] = m_z;
+       }
+
+       /**
+        * Retrieves the components of the vector.
+        * \return The components as float[3].
+        */
+       inline const float* get() const
+       {
+               return m_v;
+       }
+};
+
+#endif //AUD_3DMATH
index 2236af099042151cbb95c7f439134dbf8e3c6f74..1f9e76c4535a04690c92d9138fc6b2c3564f7cc0 100644 (file)
@@ -443,124 +443,244 @@ AUD_Status AUD_getStatus(AUD_Channel* handle)
        return AUD_device->getStatus(handle);
 }
 
-AUD_Channel* AUD_play3D(AUD_Sound* sound, int keep)
+int AUD_setListenerLocation(const float* location)
 {
        assert(AUD_device);
-       assert(sound);
 
-       try
+       if(AUD_3ddevice)
        {
-               if(AUD_3ddevice)
-                       return AUD_3ddevice->play3D(sound, keep);
-               else
-                       return AUD_device->play(sound, keep);
+               AUD_Vector3 v(location[0], location[1], location[2]);
+               AUD_3ddevice->setListenerLocation(v);
+               return true;
        }
-       catch(AUD_Exception&)
+
+       return false;
+}
+
+int AUD_setListenerVelocity(const float* velocity)
+{
+       assert(AUD_device);
+
+       if(AUD_3ddevice)
        {
-               return NULL;
+               AUD_Vector3 v(velocity[0], velocity[1], velocity[2]);
+               AUD_3ddevice->setListenerVelocity(v);
+               return true;
        }
+
+       return false;
 }
 
-int AUD_updateListener(AUD_3DData* data)
+int AUD_setListenerOrientation(const float* orientation)
 {
        assert(AUD_device);
-       assert(data);
 
-       try
+       if(AUD_3ddevice)
        {
-               if(AUD_3ddevice)
-                       return AUD_3ddevice->updateListener(*data);
+               AUD_Quaternion q(orientation[0], orientation[1], orientation[2], orientation[3]);
+               AUD_3ddevice->setListenerOrientation(q);
+               return true;
        }
-       catch(AUD_Exception&)
+
+       return false;
+}
+
+int AUD_setSpeedOfSound(float speed)
+{
+       assert(AUD_device);
+
+       if(AUD_3ddevice)
        {
+               AUD_3ddevice->setSpeedOfSound(speed);
+               return true;
        }
+
        return false;
 }
 
-int AUD_set3DSetting(AUD_3DSetting setting, float value)
+int AUD_setDopplerFactor(float factor)
 {
        assert(AUD_device);
 
-       try
+       if(AUD_3ddevice)
        {
-               if(AUD_3ddevice)
-                       return AUD_3ddevice->setSetting(setting, value);
+               AUD_3ddevice->setDopplerFactor(factor);
+               return true;
        }
-       catch(AUD_Exception&)
+
+       return false;
+}
+
+int AUD_setDistanceModel(AUD_DistanceModel model)
+{
+       assert(AUD_device);
+
+       if(AUD_3ddevice)
        {
+               AUD_3ddevice->setDistanceModel(model);
+               return true;
        }
+
        return false;
 }
 
-float AUD_get3DSetting(AUD_3DSetting setting)
+int AUD_setSourceLocation(AUD_Channel* handle, const float* location)
 {
        assert(AUD_device);
+       assert(handle);
 
-       try
+       if(AUD_3ddevice)
        {
-               if(AUD_3ddevice)
-                       return AUD_3ddevice->getSetting(setting);
+               AUD_Vector3 v(location[0], location[1], location[2]);
+               return AUD_3ddevice->setSourceLocation(handle, v);
        }
-       catch(AUD_Exception&)
+
+       return false;
+}
+
+int AUD_setSourceVelocity(AUD_Channel* handle, const float* velocity)
+{
+       assert(AUD_device);
+       assert(handle);
+
+       if(AUD_3ddevice)
        {
+               AUD_Vector3 v(velocity[0], velocity[1], velocity[2]);
+               return AUD_3ddevice->setSourceVelocity(handle, v);
        }
-       return 0.0f;
+
+       return false;
 }
 
-int AUD_update3DSource(AUD_Channel* handle, AUD_3DData* data)
+int AUD_setSourceOrientation(AUD_Channel* handle, const float* orientation)
 {
-       if(handle)
+       assert(AUD_device);
+       assert(handle);
+
+       if(AUD_3ddevice)
        {
-               assert(AUD_device);
-               assert(data);
+               AUD_Quaternion q(orientation[0], orientation[1], orientation[2], orientation[3]);
+               return AUD_3ddevice->setSourceOrientation(handle, q);
+       }
 
-               try
-               {
-                       if(AUD_3ddevice)
-                               return AUD_3ddevice->updateSource(handle, *data);
-               }
-               catch(AUD_Exception&)
-               {
-               }
+       return false;
+}
+
+int AUD_setRelative(AUD_Channel* handle, int relative)
+{
+       assert(AUD_device);
+       assert(handle);
+
+       if(AUD_3ddevice)
+       {
+               return AUD_3ddevice->setRelative(handle, relative);
        }
+
        return false;
 }
 
-int AUD_set3DSourceSetting(AUD_Channel* handle,
-                                                  AUD_3DSourceSetting setting, float value)
+int AUD_setVolumeMaximum(AUD_Channel* handle, float volume)
 {
-       if(handle)
+       assert(AUD_device);
+       assert(handle);
+
+       if(AUD_3ddevice)
        {
-               assert(AUD_device);
+               return AUD_3ddevice->setVolumeMaximum(handle, volume);
+       }
 
-               try
-               {
-                       if(AUD_3ddevice)
-                               return AUD_3ddevice->setSourceSetting(handle, setting, value);
-               }
-               catch(AUD_Exception&)
-               {
-               }
+       return false;
+}
+
+int AUD_setVolumeMinimum(AUD_Channel* handle, float volume)
+{
+       assert(AUD_device);
+       assert(handle);
+
+       if(AUD_3ddevice)
+       {
+               return AUD_3ddevice->setVolumeMinimum(handle, volume);
        }
+
        return false;
 }
 
-float AUD_get3DSourceSetting(AUD_Channel* handle, AUD_3DSourceSetting setting)
+int AUD_setDistanceMaximum(AUD_Channel* handle, float distance)
 {
-       if(handle)
+       assert(AUD_device);
+       assert(handle);
+
+       if(AUD_3ddevice)
        {
-               assert(AUD_device);
+               return AUD_3ddevice->setDistanceMaximum(handle, distance);
+       }
 
-               try
-               {
-                       if(AUD_3ddevice)
-                               return AUD_3ddevice->getSourceSetting(handle, setting);
-               }
-               catch(AUD_Exception&)
-               {
-               }
+       return false;
+}
+
+int AUD_setDistanceReference(AUD_Channel* handle, float distance)
+{
+       assert(AUD_device);
+       assert(handle);
+
+       if(AUD_3ddevice)
+       {
+               return AUD_3ddevice->setDistanceReference(handle, distance);
+       }
+
+       return false;
+}
+
+int AUD_setAttenuation(AUD_Channel* handle, float factor)
+{
+       assert(AUD_device);
+       assert(handle);
+
+       if(AUD_3ddevice)
+       {
+               return AUD_3ddevice->setAttenuation(handle, factor);
+       }
+
+       return false;
+}
+
+int AUD_setConeAngleOuter(AUD_Channel* handle, float angle)
+{
+       assert(AUD_device);
+       assert(handle);
+
+       if(AUD_3ddevice)
+       {
+               return AUD_3ddevice->setConeAngleOuter(handle, angle);
+       }
+
+       return false;
+}
+
+int AUD_setConeAngleInner(AUD_Channel* handle, float angle)
+{
+       assert(AUD_device);
+       assert(handle);
+
+       if(AUD_3ddevice)
+       {
+               return AUD_3ddevice->setConeAngleInner(handle, angle);
+       }
+
+       return false;
+}
+
+int AUD_setConeVolumeOuter(AUD_Channel* handle, float volume)
+{
+       assert(AUD_device);
+       assert(handle);
+
+       if(AUD_3ddevice)
+       {
+               return AUD_3ddevice->setConeVolumeOuter(handle, volume);
        }
-       return 0.0f;
+
+       return false;
 }
 
 int AUD_setSoundVolume(AUD_Channel* handle, float volume)
index 83feb234a6ebc749a206064fbf68305e44b8c9b0..6b7f7c1a2ea89b51952c0466c334b293ff74e26a 100644 (file)
@@ -246,64 +246,145 @@ extern float AUD_getPosition(AUD_Channel* handle);
 extern AUD_Status AUD_getStatus(AUD_Channel* handle);
 
 /**
- * Plays a 3D sound.
- * \param sound The handle of the sound file.
- * \param keep When keep is true the sound source will not be deleted but set to
- *             paused when its end has been reached.
- * \return A handle to the played back sound.
- * \note The factory must provide a mono (single channel) source and the device
- *       must support 3D audio, otherwise the sound is played back normally.
+ * Sets the listener location.
+ * \param location The new location.
+ */
+extern int AUD_setListenerLocation(const float* location);
+
+/**
+ * Sets the listener velocity.
+ * \param velocity The new velocity.
+ */
+extern int AUD_setListenerVelocity(const float* velocity);
+
+/**
+ * Sets the listener orientation.
+ * \param orientation The new orientation as quaternion.
  */
-extern AUD_Channel* AUD_play3D(AUD_Sound* sound, int keep);
+extern int AUD_setListenerOrientation(const float* orientation);
 
 /**
- * Updates the listener 3D data.
- * \param data The 3D data.
+ * Sets the speed of sound.
+ * This value is needed for doppler effect calculation.
+ * \param speed The new speed of sound.
+ */
+extern int AUD_setSpeedOfSound(float speed);
+
+/**
+ * Sets the doppler factor.
+ * This value is a scaling factor for the velocity vectors of sources and
+ * listener which is used while calculating the doppler effect.
+ * \param factor The new doppler factor.
+ */
+extern int AUD_setDopplerFactor(float factor);
+
+/**
+ * Sets the distance model.
+ * \param model distance model.
+ */
+extern int AUD_setDistanceModel(AUD_DistanceModel model);
+
+/**
+ * Sets the location of a source.
+ * \param handle The handle of the source.
+ * \param location The new location.
  * \return Whether the action succeeded.
  */
-extern int AUD_updateListener(AUD_3DData* data);
+extern int AUD_setSourceLocation(AUD_Channel* handle, const float* location);
 
 /**
- * Sets a 3D device setting.
- * \param setting The setting type.
- * \param value The new setting value.
+ * Sets the velocity of a source.
+ * \param handle The handle of the source.
+ * \param velocity The new velocity.
  * \return Whether the action succeeded.
  */
-extern int AUD_set3DSetting(AUD_3DSetting setting, float value);
+extern int AUD_setSourceVelocity(AUD_Channel* handle, const float* velocity);
 
 /**
- * Retrieves a 3D device setting.
- * \param setting The setting type.
- * \return The setting value.
+ * Sets the orientation of a source.
+ * \param handle The handle of the source.
+ * \param orientation The new orientation as quaternion.
+ * \return Whether the action succeeded.
  */
-extern float AUD_get3DSetting(AUD_3DSetting setting);
+extern int AUD_setSourceOrientation(AUD_Channel* handle, const float* orientation);
 
 /**
- * Updates a listeners 3D data.
- * \param handle The source handle.
- * \param data The 3D data.
+ * Sets whether the source location, velocity and orientation are relative
+ * to the listener.
+ * \param handle The handle of the source.
+ * \param relative Whether the source is relative.
  * \return Whether the action succeeded.
  */
-extern int AUD_update3DSource(AUD_Channel* handle, AUD_3DData* data);
+extern int AUD_setRelative(AUD_Channel* handle, int relative);
 
 /**
- * Sets a 3D source setting.
- * \param handle The source handle.
- * \param setting The setting type.
- * \param value The new setting value.
+ * Sets the maximum volume of a source.
+ * \param handle The handle of the source.
+ * \param volume The new maximum volume.
  * \return Whether the action succeeded.
  */
-extern int AUD_set3DSourceSetting(AUD_Channel* handle,
-                                                                 AUD_3DSourceSetting setting, float value);
+extern int AUD_setVolumeMaximum(AUD_Channel* handle, float volume);
 
 /**
- * Retrieves a 3D source setting.
- * \param handle The source handle.
- * \param setting The setting type.
- * \return The setting value.
+ * Sets the minimum volume of a source.
+ * \param handle The handle of the source.
+ * \param volume The new minimum volume.
+ * \return Whether the action succeeded.
+ */
+extern int AUD_setVolumeMinimum(AUD_Channel* handle, float volume);
+
+/**
+ * Sets the maximum distance of a source.
+ * If a source is further away from the reader than this distance, the
+ * volume will automatically be set to 0.
+ * \param handle The handle of the source.
+ * \param distance The new maximum distance.
+ * \return Whether the action succeeded.
+ */
+extern int AUD_setDistanceMaximum(AUD_Channel* handle, float distance);
+
+/**
+ * Sets the reference distance of a source.
+ * \param handle The handle of the source.
+ * \param distance The new reference distance.
+ * \return Whether the action succeeded.
+ */
+extern int AUD_setDistanceReference(AUD_Channel* handle, float distance);
+
+/**
+ * Sets the attenuation of a source.
+ * This value is used for distance calculation.
+ * \param handle The handle of the source.
+ * \param factor The new attenuation.
+ * \return Whether the action succeeded.
+ */
+extern int AUD_setAttenuation(AUD_Channel* handle, float factor);
+
+/**
+ * Sets the outer angle of the cone of a source.
+ * \param handle The handle of the source.
+ * \param angle The new outer angle of the cone.
+ * \return Whether the action succeeded.
+ */
+extern int AUD_setConeAngleOuter(AUD_Channel* handle, float angle);
+
+/**
+ * Sets the inner angle of the cone of a source.
+ * \param handle The handle of the source.
+ * \param angle The new inner angle of the cone.
+ * \return Whether the action succeeded.
+ */
+extern int AUD_setConeAngleInner(AUD_Channel* handle, float angle);
+
+/**
+ * Sets the outer volume of the cone of a source.
+ * The volume between inner and outer angle is interpolated between inner
+ * volume and this value.
+ * \param handle The handle of the source.
+ * \param volume The new outer volume of the cone.
+ * \return Whether the action succeeded.
  */
-extern float AUD_get3DSourceSetting(AUD_Channel* handle,
-                                                                       AUD_3DSourceSetting setting);
+extern int AUD_setConeVolumeOuter(AUD_Channel* handle, float volume);
 
 /**
  * Sets the volume of a played back sound.
index 8e3f2e5958ad82917d23c96e970d8e8fe069d94d..629b0997d4d5da1888a6e9a7859b3c4395d1c35f 100644 (file)
@@ -27,6 +27,9 @@
 #define AUD_I3DDEVICE
 
 #include "AUD_Space.h"
+#include "AUD_3DMath.h"
+
+struct AUD_Handle;
 
 /**
  * This class represents an output device for 3D sound.
@@ -35,67 +38,277 @@ class AUD_I3DDevice
 {
 public:
        /**
-        * Plays a 3D sound source.
-        * \param factory The factory to create the reader for the sound source.
-        * \param keep When keep is true the sound source will not be deleted but
-        *             set to paused when its end has been reached.
-        * \return Returns a handle with which the playback can be controlled.
-        *         This is NULL if the sound couldn't be played back.
-        * \exception AUD_Exception Thrown if there's an unexpected (from the
-        *            device side) error during creation of the reader.
-        * \note The factory must provide a mono (single channel) source otherwise
-        *       the sound is played back normally.
+        * Retrieves the listener location.
+        * \return The listener location.
+        */
+       virtual AUD_Vector3 getListenerLocation() const=0;
+
+       /**
+        * Sets the listener location.
+        * \param location The new location.
+        */
+       virtual void setListenerLocation(const AUD_Vector3& location)=0;
+
+       /**
+        * Retrieves the listener velocity.
+        * \return The listener velocity.
+        */
+       virtual AUD_Vector3 getListenerVelocity() const=0;
+
+       /**
+        * Sets the listener velocity.
+        * \param velocity The new velocity.
+        */
+       virtual void setListenerVelocity(const AUD_Vector3& velocity)=0;
+
+       /**
+        * Retrieves the listener orientation.
+        * \return The listener orientation as quaternion.
+        */
+       virtual AUD_Quaternion getListenerOrientation() const=0;
+
+       /**
+        * Sets the listener orientation.
+        * \param orientation The new orientation as quaternion.
+        */
+       virtual void setListenerOrientation(const AUD_Quaternion& orientation)=0;
+
+
+       /**
+        * Retrieves the speed of sound.
+        * This value is needed for doppler effect calculation.
+        * \return The speed of sound.
+        */
+       virtual float getSpeedOfSound() const=0;
+
+       /**
+        * Sets the speed of sound.
+        * This value is needed for doppler effect calculation.
+        * \param speed The new speed of sound.
+        */
+       virtual void setSpeedOfSound(float speed)=0;
+
+       /**
+        * Retrieves the doppler factor.
+        * This value is a scaling factor for the velocity vectors of sources and
+        * listener which is used while calculating the doppler effect.
+        * \return The doppler factor.
+        */
+       virtual float getDopplerFactor() const=0;
+
+       /**
+        * Sets the doppler factor.
+        * This value is a scaling factor for the velocity vectors of sources and
+        * listener which is used while calculating the doppler effect.
+        * \param factor The new doppler factor.
+        */
+       virtual void setDopplerFactor(float factor)=0;
+
+       /**
+        * Retrieves the distance model.
+        * \return The distance model.
+        */
+       virtual AUD_DistanceModel getDistanceModel() const=0;
+
+       /**
+        * Sets the distance model.
+        * \param model distance model.
+        */
+       virtual void setDistanceModel(AUD_DistanceModel model)=0;
+
+
+
+       /**
+        * Retrieves the location of a source.
+        * \param handle The handle of the source.
+        * \return The location.
+        */
+       virtual AUD_Vector3 getSourceLocation(AUD_Handle* handle)=0;
+
+       /**
+        * Sets the location of a source.
+        * \param handle The handle of the source.
+        * \param location The new location.
+        * \return Whether the action succeeded.
+        */
+       virtual bool setSourceLocation(AUD_Handle* handle, const AUD_Vector3& location)=0;
+
+       /**
+        * Retrieves the velocity of a source.
+        * \param handle The handle of the source.
+        * \return The velocity.
+        */
+       virtual AUD_Vector3 getSourceVelocity(AUD_Handle* handle)=0;
+
+       /**
+        * Sets the velocity of a source.
+        * \param handle The handle of the source.
+        * \param velocity The new velocity.
+        * \return Whether the action succeeded.
+        */
+       virtual bool setSourceVelocity(AUD_Handle* handle, const AUD_Vector3& velocity)=0;
+
+       /**
+        * Retrieves the orientation of a source.
+        * \param handle The handle of the source.
+        * \return The orientation as quaternion.
+        */
+       virtual AUD_Quaternion getSourceOrientation(AUD_Handle* handle)=0;
+
+       /**
+        * Sets the orientation of a source.
+        * \param handle The handle of the source.
+        * \param orientation The new orientation as quaternion.
+        * \return Whether the action succeeded.
+        */
+       virtual bool setSourceOrientation(AUD_Handle* handle, const AUD_Quaternion& orientation)=0;
+
+
+       /**
+        * Checks whether the source location, velocity and orientation are relative
+        * to the listener.
+        * \param handle The handle of the source.
+        * \return Whether the source is relative.
+        */
+       virtual bool isRelative(AUD_Handle* handle)=0;
+
+       /**
+        * Sets whether the source location, velocity and orientation are relative
+        * to the listener.
+        * \param handle The handle of the source.
+        * \param relative Whether the source is relative.
+        * \return Whether the action succeeded.
+        */
+       virtual bool setRelative(AUD_Handle* handle, bool relative)=0;
+
+       /**
+        * Retrieves the maximum volume of a source.
+        * \param handle The handle of the source.
+        * \return The maximum volume.
+        */
+       virtual float getVolumeMaximum(AUD_Handle* handle)=0;
+
+       /**
+        * Sets the maximum volume of a source.
+        * \param handle The handle of the source.
+        * \param volume The new maximum volume.
+        * \return Whether the action succeeded.
+        */
+       virtual bool setVolumeMaximum(AUD_Handle* handle, float volume)=0;
+
+       /**
+        * Retrieves the minimum volume of a source.
+        * \param handle The handle of the source.
+        * \return The minimum volume.
         */
-       virtual AUD_Handle* play3D(AUD_IFactory* factory, bool keep = false)=0;
+       virtual float getVolumeMinimum(AUD_Handle* handle)=0;
 
        /**
-        * Updates a listeners 3D data.
-        * \param data The 3D data.
+        * Sets the minimum volume of a source.
+        * \param handle The handle of the source.
+        * \param volume The new minimum volume.
         * \return Whether the action succeeded.
         */
-       virtual bool updateListener(AUD_3DData &data)=0;
+       virtual bool setVolumeMinimum(AUD_Handle* handle, float volume)=0;
+
+       /**
+        * Retrieves the maximum distance of a source.
+        * If a source is further away from the reader than this distance, the
+        * volume will automatically be set to 0.
+        * \param handle The handle of the source.
+        * \return The maximum distance.
+        */
+       virtual float getDistanceMaximum(AUD_Handle* handle)=0;
 
        /**
-        * Sets a 3D device setting.
-        * \param setting The setting type.
-        * \param value The new setting value.
+        * Sets the maximum distance of a source.
+        * If a source is further away from the reader than this distance, the
+        * volume will automatically be set to 0.
+        * \param handle The handle of the source.
+        * \param distance The new maximum distance.
         * \return Whether the action succeeded.
         */
-       virtual bool setSetting(AUD_3DSetting setting, float value)=0;
+       virtual bool setDistanceMaximum(AUD_Handle* handle, float distance)=0;
 
        /**
-        * Retrieves a 3D device setting.
-        * \param setting The setting type.
-        * \return The setting value.
+        * Retrieves the reference distance of a source.
+        * \param handle The handle of the source.
+        * \return The reference distance.
         */
-       virtual float getSetting(AUD_3DSetting setting)=0;
+       virtual float getDistanceReference(AUD_Handle* handle)=0;
 
        /**
-        * Updates a listeners 3D data.
-        * \param handle The source handle.
-        * \param data The 3D data.
+        * Sets the reference distance of a source.
+        * \param handle The handle of the source.
+        * \param distance The new reference distance.
         * \return Whether the action succeeded.
         */
-       virtual bool updateSource(AUD_Handle* handle, AUD_3DData &data)=0;
+       virtual bool setDistanceReference(AUD_Handle* handle, float distance)=0;
+
+       /**
+        * Retrieves the attenuation of a source.
+        * \param handle The handle of the source.
+        * \return The attenuation.
+        */
+       virtual float getAttenuation(AUD_Handle* handle)=0;
 
        /**
-        * Sets a 3D source setting.
-        * \param handle The source handle.
-        * \param setting The setting type.
-        * \param value The new setting value.
+        * Sets the attenuation of a source.
+        * This value is used for distance calculation.
+        * \param handle The handle of the source.
+        * \param factor The new attenuation.
         * \return Whether the action succeeded.
         */
-       virtual bool setSourceSetting(AUD_Handle* handle,
-                                                                 AUD_3DSourceSetting setting, float value)=0;
+       virtual bool setAttenuation(AUD_Handle* handle, float factor)=0;
 
        /**
-        * Retrieves a 3D source setting.
-        * \param handle The source handle.
-        * \param setting The setting type.
-        * \return The setting value.
+        * Retrieves the outer angle of the cone of a source.
+        * \param handle The handle of the source.
+        * \return The outer angle of the cone.
+        */
+       virtual float getConeAngleOuter(AUD_Handle* handle)=0;
+
+       /**
+        * Sets the outer angle of the cone of a source.
+        * \param handle The handle of the source.
+        * \param angle The new outer angle of the cone.
+        * \return Whether the action succeeded.
+        */
+       virtual bool setConeAngleOuter(AUD_Handle* handle, float angle)=0;
+
+       /**
+        * Retrieves the inner angle of the cone of a source.
+        * \param handle The handle of the source.
+        * \return The inner angle of the cone.
+        */
+       virtual float getConeAngleInner(AUD_Handle* handle)=0;
+
+       /**
+        * Sets the inner angle of the cone of a source.
+        * \param handle The handle of the source.
+        * \param angle The new inner angle of the cone.
+        * \return Whether the action succeeded.
+        */
+       virtual bool setConeAngleInner(AUD_Handle* handle, float angle)=0;
+
+       /**
+        * Retrieves the outer volume of the cone of a source.
+        * The volume between inner and outer angle is interpolated between inner
+        * volume and this value.
+        * \param handle The handle of the source.
+        * \return The outer volume of the cone.
+        */
+       virtual float getConeVolumeOuter(AUD_Handle* handle)=0;
+
+       /**
+        * Sets the outer volume of the cone of a source.
+        * The volume between inner and outer angle is interpolated between inner
+        * volume and this value.
+        * \param handle The handle of the source.
+        * \param volume The new outer volume of the cone.
+        * \return Whether the action succeeded.
         */
-       virtual float getSourceSetting(AUD_Handle* handle,
-                                                                  AUD_3DSourceSetting setting)=0;
+       virtual bool setConeVolumeOuter(AUD_Handle* handle, float volume)=0;
 };
 
 #endif //AUD_I3DDEVICE
index dfafb6713b0ebb5e8f2f7ff300e890e9abe92cc4..4170e27457462d12ae7f04db125c4fe52bb45552 100644 (file)
@@ -30,9 +30,9 @@
 class AUD_IFactory;
 
 /// Handle structure, for inherition.
-typedef struct
+struct AUD_Handle
 {
-} AUD_Handle;
+};
 
 /**
  * This class represents an output device for sound sources.
index 1c3a018daa904e301ec77d384b446831e6bd184c..5c0350fed15bac105abb3846720aa71774a354d1 100644 (file)
@@ -124,39 +124,17 @@ typedef enum
        AUD_FADE_OUT
 } AUD_FadeType;
 
-/// 3D device settings.
-typedef enum
-{
-       AUD_3DS_NONE,                                   /// No setting.
-       AUD_3DS_SPEED_OF_SOUND,                 /// Speed of sound.
-       AUD_3DS_DOPPLER_FACTOR,                 /// Doppler factor.
-       AUD_3DS_DISTANCE_MODEL                  /// Distance model.
-} AUD_3DSetting;
-
 /// Possible distance models for the 3D device.
-#define AUD_DISTANCE_MODEL_NONE                                        0.0f
-#define AUD_DISTANCE_MODEL_INVERSE                             1.0f
-#define AUD_DISTANCE_MODEL_INVERSE_CLAMPED             2.0f
-#define AUD_DISTANCE_MODEL_LINEAR                              3.0f
-#define AUD_DISTANCE_MODEL_LINEAR_CLAMPED              4.0f
-#define AUD_DISTANCE_MODEL_EXPONENT                            5.0f
-#define AUD_DISTANCE_MODEL_EXPONENT_CLAMPED            6.0f
-
-/// 3D source settings.
 typedef enum
 {
-       AUD_3DSS_NONE,                                  /// No setting.
-       AUD_3DSS_IS_RELATIVE,                   /// > 0 tells that the sound source is
-                                                                       /// relative to the listener
-       AUD_3DSS_MIN_GAIN,                              /// Minimum gain.
-       AUD_3DSS_MAX_GAIN,                              /// Maximum gain.
-       AUD_3DSS_REFERENCE_DISTANCE,    /// Reference distance.
-       AUD_3DSS_MAX_DISTANCE,                  /// Maximum distance.
-       AUD_3DSS_ROLLOFF_FACTOR,                /// Rolloff factor.
-       AUD_3DSS_CONE_INNER_ANGLE,              /// Cone inner angle.
-       AUD_3DSS_CONE_OUTER_ANGLE,              /// Cone outer angle.
-       AUD_3DSS_CONE_OUTER_GAIN                /// Cone outer gain.
-} AUD_3DSourceSetting;
+       AUD_DISTANCE_MODEL_INVALID = 0,
+       AUD_DISTANCE_MODEL_INVERSE,
+       AUD_DISTANCE_MODEL_INVERSE_CLAMPED,
+       AUD_DISTANCE_MODEL_LINEAR,
+       AUD_DISTANCE_MODEL_LINEAR_CLAMPED,
+       AUD_DISTANCE_MODEL_EXPONENT,
+       AUD_DISTANCE_MODEL_EXPONENT_CLAMPED,
+} AUD_DistanceModel;
 
 /// Sample type.(float samples)
 typedef float sample_t;
@@ -206,17 +184,4 @@ typedef struct
        // void* userData; - for the case it is needed someday
 } AUD_Exception;
 
-/// Handle structure, for inherition.
-typedef struct
-{
-       /// x, y and z coordinates of the object.
-       float position[3];
-
-       /// x, y and z coordinates telling the velocity and direction of the object.
-       float velocity[3];
-
-       /// 3x3 matrix telling the orientation of the object.
-       float orientation[9];
-} AUD_3DData;
-
 #endif //AUD_SPACE
index c4375ea2a30382de123a2aed0460f76898d05ba0..b5b9c96a7ffad1aec94b36c1e85790b56f42bcb3 100644 (file)
@@ -388,9 +388,9 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c
                                ketsjiengine->InitDome(scene->gm.dome.res, scene->gm.dome.mode, scene->gm.dome.angle, scene->gm.dome.resbuf, scene->gm.dome.tilt, scene->gm.dome.warptext);
 
                        // initialize 3D Audio Settings
-                       AUD_set3DSetting(AUD_3DS_SPEED_OF_SOUND, scene->audio.speed_of_sound);
-                       AUD_set3DSetting(AUD_3DS_DOPPLER_FACTOR, scene->audio.doppler_factor);
-                       AUD_set3DSetting(AUD_3DS_DISTANCE_MODEL, scene->audio.distance_model);
+                       AUD_setSpeedOfSound(scene->audio.speed_of_sound);
+                       AUD_setDopplerFactor(scene->audio.doppler_factor);
+                       AUD_setDistanceModel(AUD_DistanceModel(scene->audio.distance_model));
 
                        // from see blender.c:
                        // FIXME: this version patching should really be part of the file-reading code,
index 71cd8b36045d8be824aff61a9a698d02a48ce3a9..f1a0a495db6939b07b51b77e096c04d3cffd5cbb 100644 (file)
@@ -966,44 +966,17 @@ void KX_KetsjiEngine::DoSound(KX_Scene* scene)
        KX_Camera* cam = scene->GetActiveCamera();
        if (!cam)
                return;
-       MT_Point3 listenerposition = cam->NodeGetWorldPosition();
-       MT_Vector3 listenervelocity = cam->GetLinearVelocity();
-       MT_Matrix3x3 listenerorientation = cam->NodeGetWorldOrientation();
 
-       {
-               AUD_3DData data;
-               float f;
-
-               listenerorientation.getValue3x3(data.orientation);
-               listenerposition.getValue(data.position);
-               listenervelocity.getValue(data.velocity);
-
-               f = data.position[1];
-               data.position[1] = data.position[2];
-               data.position[2] = -f;
-
-               f = data.velocity[1];
-               data.velocity[1] = data.velocity[2];
-               data.velocity[2] = -f;
+       float f[4];
 
-               f = data.orientation[1];
-               data.orientation[1] = data.orientation[2];
-               data.orientation[2] = -f;
+       cam->NodeGetWorldPosition().getValue(f);
+       AUD_setListenerLocation(f);
 
-               f = data.orientation[3];
-               data.orientation[3] = -data.orientation[6];
-               data.orientation[6] = f;
+       cam->GetLinearVelocity().getValue(f);
+       AUD_setListenerVelocity(f);
 
-               f = data.orientation[4];
-               data.orientation[4] = -data.orientation[8];
-               data.orientation[8] = -f;
-
-               f = data.orientation[5];
-               data.orientation[5] = data.orientation[7];
-               data.orientation[7] = f;
-
-               AUD_updateListener(&data);
-       }
+       cam->NodeGetWorldOrientation().getRotation().getValue(f);
+       AUD_setListenerOrientation(f);
 }
 
 
index 7f9b090d680d6c2f8b4059cd26686a31daba8432..c3ef36dfe11a8c42472f89599f5deb939b09f1fe 100644 (file)
@@ -31,6 +31,7 @@
  */
 
 #include "KX_SoundActuator.h"
+#include "AUD_C-API.h"
 #include "KX_GameObject.h"
 #include "KX_PyMath.h" // needed for PyObjectFrom()
 #include <iostream>
@@ -102,16 +103,17 @@ void KX_SoundActuator::play()
        if(m_is3d)
        {
                // sound shall be played 3D
-               m_handle = AUD_play3D(sound, 0);
-
-               AUD_set3DSourceSetting(m_handle, AUD_3DSS_MAX_GAIN, m_3d.max_gain);
-               AUD_set3DSourceSetting(m_handle, AUD_3DSS_MIN_GAIN, m_3d.min_gain);
-               AUD_set3DSourceSetting(m_handle, AUD_3DSS_REFERENCE_DISTANCE, m_3d.reference_distance);
-               AUD_set3DSourceSetting(m_handle, AUD_3DSS_MAX_DISTANCE, m_3d.max_distance);
-               AUD_set3DSourceSetting(m_handle, AUD_3DSS_ROLLOFF_FACTOR, m_3d.rolloff_factor);
-               AUD_set3DSourceSetting(m_handle, AUD_3DSS_CONE_INNER_ANGLE, m_3d.cone_inner_angle);
-               AUD_set3DSourceSetting(m_handle, AUD_3DSS_CONE_OUTER_ANGLE, m_3d.cone_outer_angle);
-               AUD_set3DSourceSetting(m_handle, AUD_3DSS_CONE_OUTER_GAIN, m_3d.cone_outer_gain);
+               m_handle = AUD_play(sound, 0);
+
+               AUD_setRelative(m_handle, true);
+               AUD_setVolumeMaximum(m_handle, m_3d.max_gain);
+               AUD_setVolumeMinimum(m_handle, m_3d.min_gain);
+               AUD_setDistanceReference(m_handle, m_3d.reference_distance);
+               AUD_setDistanceMaximum(m_handle, m_3d.max_distance);
+               AUD_setAttenuation(m_handle, m_3d.rolloff_factor);
+               AUD_setConeAngleInner(m_handle, m_3d.cone_inner_angle);
+               AUD_setConeAngleOuter(m_handle, m_3d.cone_outer_angle);
+               AUD_setConeVolumeOuter(m_handle, m_3d.cone_outer_gain);
        }
        else
                m_handle = AUD_play(sound, 0);
@@ -215,39 +217,15 @@ bool KX_SoundActuator::Update(double curtime, bool frame)
        {
                if(m_is3d)
                {
-                       AUD_3DData data;
-                       float f;
-                       ((KX_GameObject*)this->GetParent())->NodeGetWorldPosition().getValue(data.position);
-                       ((KX_GameObject*)this->GetParent())->GetLinearVelocity().getValue(data.velocity);
-                       ((KX_GameObject*)this->GetParent())->NodeGetWorldOrientation().getValue3x3(data.orientation);
-
-                       /*
-                        * The 3D data from blender has to be transformed for OpenAL:
-                        *  - In blender z is up and y is forwards
-                        *  - In OpenAL y is up and z is backwards
-                        * We have to do that for all 5 vectors.
-                        */
-                       f = data.position[1];
-                       data.position[1] = data.position[2];
-                       data.position[2] = -f;
-
-                       f = data.velocity[1];
-                       data.velocity[1] = data.velocity[2];
-                       data.velocity[2] = -f;
-
-                       f = data.orientation[1];
-                       data.orientation[1] = data.orientation[2];
-                       data.orientation[2] = -f;
-
-                       f = data.orientation[4];
-                       data.orientation[4] = data.orientation[5];
-                       data.orientation[5] = -f;
-
-                       f = data.orientation[7];
-                       data.orientation[7] = data.orientation[8];
-                       data.orientation[8] = -f;
-
-                       AUD_update3DSource(m_handle, &data);
+                       KX_GameObject* obj = (KX_GameObject*)this->GetParent();
+                       float f[4];
+
+                       obj->NodeGetWorldPosition().getValue(f);
+                       AUD_setSourceLocation(m_handle, f);
+                       obj->GetLinearVelocity().getValue(f);
+                       AUD_setSourceVelocity(m_handle, f);
+                       obj->NodeGetWorldOrientation().getRotation().getValue(f);
+                       AUD_setSourceOrientation(m_handle, f);
                }
                result = true;
        }
@@ -300,19 +278,18 @@ PyMethodDef KX_SoundActuator::Methods[] = {
 
 PyAttributeDef KX_SoundActuator::Attributes[] = {
        KX_PYATTRIBUTE_BOOL_RO("is3D", KX_SoundActuator, m_is3d),
-       KX_PYATTRIBUTE_RW_FUNCTION("maxGain3D", KX_SoundActuator, pyattr_get_3d_property, pyattr_set_3d_property),
-       KX_PYATTRIBUTE_RW_FUNCTION("minGain3D", KX_SoundActuator, pyattr_get_3d_property, pyattr_set_3d_property),
-       KX_PYATTRIBUTE_RW_FUNCTION("referenceDistance3D", KX_SoundActuator, pyattr_get_3d_property, pyattr_set_3d_property),
-       KX_PYATTRIBUTE_RW_FUNCTION("maxDistance3D", KX_SoundActuator, pyattr_get_3d_property, pyattr_set_3d_property),
-       KX_PYATTRIBUTE_RW_FUNCTION("rolloffFactor3D", KX_SoundActuator, pyattr_get_3d_property, pyattr_set_3d_property),
-       KX_PYATTRIBUTE_RW_FUNCTION("coneInnerAngle3D", KX_SoundActuator, pyattr_get_3d_property, pyattr_set_3d_property),
-       KX_PYATTRIBUTE_RW_FUNCTION("coneOuterAngle3D", KX_SoundActuator, pyattr_get_3d_property, pyattr_set_3d_property),
-       KX_PYATTRIBUTE_RW_FUNCTION("coneOuterGain3D", KX_SoundActuator, pyattr_get_3d_property, pyattr_set_3d_property),
-       
+       KX_PYATTRIBUTE_RW_FUNCTION("volume_maximum", KX_SoundActuator, pyattr_get_3d_property, pyattr_set_3d_property),
+       KX_PYATTRIBUTE_RW_FUNCTION("volume_minimum", KX_SoundActuator, pyattr_get_3d_property, pyattr_set_3d_property),
+       KX_PYATTRIBUTE_RW_FUNCTION("distance_reference", KX_SoundActuator, pyattr_get_3d_property, pyattr_set_3d_property),
+       KX_PYATTRIBUTE_RW_FUNCTION("distance_maximum", KX_SoundActuator, pyattr_get_3d_property, pyattr_set_3d_property),
+       KX_PYATTRIBUTE_RW_FUNCTION("attenuation", KX_SoundActuator, pyattr_get_3d_property, pyattr_set_3d_property),
+       KX_PYATTRIBUTE_RW_FUNCTION("cone_angle_inner", KX_SoundActuator, pyattr_get_3d_property, pyattr_set_3d_property),
+       KX_PYATTRIBUTE_RW_FUNCTION("cone_angle_outer", KX_SoundActuator, pyattr_get_3d_property, pyattr_set_3d_property),
+       KX_PYATTRIBUTE_RW_FUNCTION("cone_volume_outer", KX_SoundActuator, pyattr_get_3d_property, pyattr_set_3d_property),
+
        KX_PYATTRIBUTE_RW_FUNCTION("time", KX_SoundActuator, pyattr_get_audposition, pyattr_set_audposition),
        KX_PYATTRIBUTE_RW_FUNCTION("volume", KX_SoundActuator, pyattr_get_gain, pyattr_set_gain),
        KX_PYATTRIBUTE_RW_FUNCTION("pitch", KX_SoundActuator, pyattr_get_pitch, pyattr_set_pitch),
-       KX_PYATTRIBUTE_RW_FUNCTION("rollOffFactor", KX_SoundActuator, pyattr_get_rollOffFactor, pyattr_set_rollOffFactor),
        KX_PYATTRIBUTE_ENUM_RW("mode",KX_SoundActuator::KX_SOUNDACT_NODEF+1,KX_SoundActuator::KX_SOUNDACT_MAX-1,false,KX_SoundActuator,m_type),
        { NULL }        //Sentinel
 };
@@ -358,28 +335,28 @@ PyObject* KX_SoundActuator::pyattr_get_3d_property(void *self, const struct KX_P
        const char* prop = attrdef->m_name;
        float result_value = 0.0;
 
-       if(!strcmp(prop, "maxGain3D")) {
+       if(!strcmp(prop, "volume_maximum")) {
                result_value = actuator->m_3d.max_gain;
 
-       } else if (!strcmp(prop, "minGain3D")) {
+       } else if (!strcmp(prop, "volume_minimum")) {
                result_value = actuator->m_3d.min_gain;
 
-       } else if (!strcmp(prop, "referenceDistance3D")) {
+       } else if (!strcmp(prop, "distance_reference")) {
                result_value = actuator->m_3d.reference_distance;
 
-       } else if (!strcmp(prop, "maxDistance3D")) {
+       } else if (!strcmp(prop, "distance_maximum")) {
                result_value = actuator->m_3d.max_distance;
 
-       } else if (!strcmp(prop, "rolloffFactor3D")) {
+       } else if (!strcmp(prop, "attenuation")) {
                result_value = actuator->m_3d.rolloff_factor;
 
-       } else if (!strcmp(prop, "coneInnerAngle3D")) {
+       } else if (!strcmp(prop, "cone_angle_inner")) {
                result_value = actuator->m_3d.cone_inner_angle;
 
-       } else if (!strcmp(prop, "coneOuterAngle3D")) {
+       } else if (!strcmp(prop, "cone_angle_outer")) {
                result_value = actuator->m_3d.cone_outer_angle;
 
-       } else if (!strcmp(prop, "coneOuterGain3D")) {
+       } else if (!strcmp(prop, "cone_volume_outer")) {
                result_value = actuator->m_3d.cone_outer_gain;
 
        } else {
@@ -423,66 +400,63 @@ PyObject* KX_SoundActuator::pyattr_get_pitch(void *self, const struct KX_PYATTRI
        return result;
 }
 
-PyObject* KX_SoundActuator::pyattr_get_rollOffFactor(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
-{
-       KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
-       float rollofffactor = actuator->m_3d.rolloff_factor;
-       PyObject* result = PyFloat_FromDouble(rollofffactor);
-
-       return result;
-}
-
 int KX_SoundActuator::pyattr_set_3d_property(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
 {
        KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
        const char* prop = attrdef->m_name;
        float prop_value = 0.0;
-       AUD_3DSourceSetting setting = AUD_3DSS_NONE;
 
        if (!PyArg_Parse(value, "f", &prop_value))
                return PY_SET_ATTR_FAIL;
 
-       // update the internal value
-       if(!strcmp(prop, "maxGain3D")) {
+       // if sound is working and 3D, set the new setting
+       if(!actuator->m_is3d)
+               return PY_SET_ATTR_FAIL;
+
+       if(!strcmp(prop, "volume_maximum")) {
                actuator->m_3d.max_gain = prop_value;
-               setting = AUD_3DSS_MAX_GAIN;
+               if(actuator->m_handle)
+                       AUD_setVolumeMaximum(actuator->m_handle, prop_value);
 
-       } else if (!strcmp(prop, "minGain3D")) {
+       } else if (!strcmp(prop, "volume_minimum")) {
                actuator->m_3d.min_gain = prop_value;
-               setting = AUD_3DSS_MIN_GAIN;
+               if(actuator->m_handle)
+                       AUD_setVolumeMinimum(actuator->m_handle, prop_value);
 
-       } else if (!strcmp(prop, "referenceDistance3D")) {
+       } else if (!strcmp(prop, "distance_reference")) {
                actuator->m_3d.reference_distance = prop_value;
-               setting = AUD_3DSS_REFERENCE_DISTANCE;
+               if(actuator->m_handle)
+                       AUD_setDistanceReference(actuator->m_handle, prop_value);
 
-       } else if (!strcmp(prop, "maxDistance3D")) {
+       } else if (!strcmp(prop, "distance_maximum")) {
                actuator->m_3d.max_distance = prop_value;
-               setting = AUD_3DSS_MAX_DISTANCE;
+               if(actuator->m_handle)
+                       AUD_setDistanceMaximum(actuator->m_handle, prop_value);
 
-       } else if (!strcmp(prop, "rolloffFactor3D")) {
+       } else if (!strcmp(prop, "attenuation")) {
                actuator->m_3d.rolloff_factor = prop_value;
-               setting = AUD_3DSS_ROLLOFF_FACTOR;
+               if(actuator->m_handle)
+                       AUD_setAttenuation(actuator->m_handle, prop_value);
 
-       } else if (!!strcmp(prop, "coneInnerAngle3D")) {
+       } else if (!!strcmp(prop, "cone_angle_inner")) {
                actuator->m_3d.cone_inner_angle = prop_value;
-               setting = AUD_3DSS_CONE_INNER_ANGLE;
+               if(actuator->m_handle)
+                       AUD_setConeAngleInner(actuator->m_handle, prop_value);
 
-       } else if (!strcmp(prop, "coneOuterAngle3D")) {
+       } else if (!strcmp(prop, "cone_angle_outer")) {
                actuator->m_3d.cone_outer_angle = prop_value;
-               setting = AUD_3DSS_CONE_OUTER_ANGLE;
+               if(actuator->m_handle)
+                       AUD_setConeAngleOuter(actuator->m_handle, prop_value);
 
-       } else if (!strcmp(prop, "coneOuterGain3D")) {
+       } else if (!strcmp(prop, "cone_volume_outer")) {
                actuator->m_3d.cone_outer_gain = prop_value;
-               setting = AUD_3DSS_CONE_OUTER_GAIN;
+               if(actuator->m_handle)
+                       AUD_setConeVolumeOuter(actuator->m_handle, prop_value);
 
        } else {
                return PY_SET_ATTR_FAIL;
-       }       
+       }
        
-       // if sound is working and 3D, set the new setting
-       if(actuator->m_handle && actuator->m_is3d && setting != AUD_3DSS_NONE)
-               AUD_set3DSourceSetting(actuator->m_handle, setting, prop_value);
-
        return PY_SET_ATTR_SUCCESS;
 }
 
@@ -527,18 +501,4 @@ int KX_SoundActuator::pyattr_set_pitch(void *self, const struct KX_PYATTRIBUTE_D
        return PY_SET_ATTR_SUCCESS;
 }
 
-int KX_SoundActuator::pyattr_set_rollOffFactor(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
-{
-       KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
-       float rollofffactor = 1.0;
-       if (!PyArg_Parse(value, "f", &rollofffactor))
-               return PY_SET_ATTR_FAIL;
-
-       actuator->m_3d.rolloff_factor = rollofffactor;
-       if(actuator->m_handle)
-               AUD_set3DSourceSetting(actuator->m_handle, AUD_3DSS_ROLLOFF_FACTOR, rollofffactor);
-
-       return PY_SET_ATTR_SUCCESS;
-}
-
 #endif // DISABLE_PYTHON