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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--intern/audaspace/CMakeLists.txt8
-rw-r--r--intern/audaspace/Python/AUD_PyAPI.cpp3149
-rw-r--r--intern/audaspace/Python/AUD_PyAPI.h67
-rw-r--r--intern/audaspace/SConscript5
-rw-r--r--intern/audaspace/intern/AUD_C-API.cpp105
-rw-r--r--intern/audaspace/intern/AUD_C-API.h51
-rw-r--r--source/blender/python/CMakeLists.txt1
-rw-r--r--source/blender/python/SConscript2
-rw-r--r--source/blender/python/intern/bpy.c7
-rw-r--r--source/gameengine/Ketsji/KX_PythonInit.cpp5
-rw-r--r--source/gameengine/Ketsji/KX_SoundActuator.h2
11 files changed, 3354 insertions, 48 deletions
diff --git a/intern/audaspace/CMakeLists.txt b/intern/audaspace/CMakeLists.txt
index 0965a467201..c1d59dcd3e9 100644
--- a/intern/audaspace/CMakeLists.txt
+++ b/intern/audaspace/CMakeLists.txt
@@ -60,6 +60,12 @@ IF(WITH_FFTW3)
ADD_DEFINITIONS(-DWITH_FFTW3)
ENDIF(WITH_FFTW3)
-SET(SRC ${SRC} ${FFMPEGSRC} ${SNDFILESRC} ${FFTW3SRC} ${SDLSRC} ${OPENALSRC} ${JACKSRC})
+IF(WITH_PYTHON)
+ SET(INC ${INC} Python ${PYTHON_INC})
+ FILE(GLOB PYTHONSRC Python/*.cpp)
+ ADD_DEFINITIONS(-DWITH_PYTHON)
+ENDIF(WITH_PYTHON)
+
+SET(SRC ${SRC} ${FFMPEGSRC} ${SNDFILESRC} ${FFTW3SRC} ${SDLSRC} ${OPENALSRC} ${JACKSRC} ${PYTHONSRC})
BLENDERLIB(bf_audaspace "${SRC}" "${INC}")
diff --git a/intern/audaspace/Python/AUD_PyAPI.cpp b/intern/audaspace/Python/AUD_PyAPI.cpp
new file mode 100644
index 00000000000..095a9b81ab3
--- /dev/null
+++ b/intern/audaspace/Python/AUD_PyAPI.cpp
@@ -0,0 +1,3149 @@
+/*
+ * $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 *****
+ */
+
+#include "AUD_PyAPI.h"
+#include "structmember.h"
+
+#include "AUD_NULLDevice.h"
+#include "AUD_SourceCaps.h"
+#include "AUD_DelayFactory.h"
+#include "AUD_DoubleFactory.h"
+#include "AUD_FaderFactory.h"
+#include "AUD_HighpassFactory.h"
+#include "AUD_LimiterFactory.h"
+#include "AUD_LoopFactory.h"
+#include "AUD_LowpassFactory.h"
+#include "AUD_PingPongFactory.h"
+#include "AUD_PitchFactory.h"
+#include "AUD_ReverseFactory.h"
+#include "AUD_SinusFactory.h"
+#include "AUD_FileFactory.h"
+#include "AUD_SquareFactory.h"
+#include "AUD_StreamBufferFactory.h"
+#include "AUD_SuperposeFactory.h"
+#include "AUD_VolumeFactory.h"
+
+#ifdef WITH_SDL
+#include "AUD_SDLDevice.h"
+#endif
+
+#ifdef WITH_OPENAL
+#include "AUD_OpenALDevice.h"
+#endif
+
+#ifdef WITH_JACK
+#include "AUD_JackDevice.h"
+#endif
+
+#include <cstdlib>
+#include <unistd.h>
+
+#define PY_MODULE_ADD_CONSTANT(module, name) PyModule_AddIntConstant(module, #name, name)
+
+static PyObject* AUDError;
+
+// ====================================================================
+
+static void
+Sound_dealloc(Sound* self)
+{
+ if(self->factory)
+ delete self->factory;
+ Py_XDECREF(self->child_list);
+ Py_TYPE(self)->tp_free((PyObject*)self);
+}
+
+static PyObject *
+Sound_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ Sound *self;
+
+ self = (Sound*)type->tp_alloc(type, 0);
+ if(self != NULL)
+ {
+ static char *kwlist[] = {"filename", NULL};
+ const char* filename = NULL;
+
+ if(!PyArg_ParseTupleAndKeywords(args, kwds, "|s", kwlist, &filename))
+ {
+ Py_DECREF(self);
+ return NULL;
+ }
+ else if(filename == NULL)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, "Missing filename parameter!");
+ return NULL;
+ }
+
+ try
+ {
+ self->factory = new AUD_FileFactory(filename);
+ }
+ catch(AUD_Exception&)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, "Filefactory couldn't be created!");
+ return NULL;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+static PyObject *
+Sound_sine(PyObject* nothing, PyObject* args);
+
+static PyObject *
+Sound_file(PyObject* nothing, PyObject* args);
+
+static PyObject *
+Sound_lowpass(PyObject* nothing, PyObject* args);
+
+static PyObject *
+Sound_delay(PyObject* nothing, PyObject* args);
+
+static PyObject *
+Sound_double(PyObject* nothing, PyObject* args);
+
+static PyObject *
+Sound_highpass(PyObject* nothing, PyObject* args);
+
+static PyObject *
+Sound_limiter(PyObject* nothing, PyObject* args);
+
+static PyObject *
+Sound_pitch(PyObject* nothing, PyObject* args);
+
+static PyObject *
+Sound_volume(PyObject* nothing, PyObject* args);
+
+static PyObject *
+Sound_fadein(PyObject* nothing, PyObject* args);
+
+static PyObject *
+Sound_fadeout(PyObject* nothing, PyObject* args);
+
+static PyObject *
+Sound_loop(PyObject* nothing, PyObject* args);
+
+static PyObject *
+Sound_superpose(PyObject* nothing, PyObject* args);
+
+static PyObject *
+Sound_pingpong(PyObject* nothing, PyObject* args);
+
+static PyObject *
+Sound_reverse(PyObject* nothing, PyObject* args);
+
+static PyObject *
+Sound_buffer(PyObject* nothing, PyObject* args);
+
+static PyObject *
+Sound_square(PyObject* nothing, PyObject* args);
+
+static PyMethodDef Sound_methods[] = {
+ {"sine", (PyCFunction)Sound_sine, METH_VARARGS | METH_STATIC,
+ "Creates a sine sound at a specific frequency."
+ },
+ {"file", (PyCFunction)Sound_file, METH_VARARGS | METH_STATIC,
+ "Creates a sound object of a sound file."
+ },
+ {"lowpass", (PyCFunction)Sound_lowpass, METH_VARARGS | METH_STATIC,
+ "Creates a lowpass filter with a specific cut off frequency."
+ },
+ {"delay", (PyCFunction)Sound_delay, METH_VARARGS | METH_STATIC,
+ "Delays a sound by a specific amount of seconds."
+ },
+ {"double", (PyCFunction)Sound_double, METH_VARARGS | METH_STATIC,
+ "Plays two sounds of the same specs in sequence."
+ },
+ {"highpass", (PyCFunction)Sound_highpass, METH_VARARGS | METH_STATIC,
+ "Creates a highpass filter with a specific cut off frequency."
+ },
+ {"limiter", (PyCFunction)Sound_limiter, METH_VARARGS | METH_STATIC,
+ "Limits a sound within a specific start and end time."
+ },
+ {"pitch", (PyCFunction)Sound_pitch, METH_VARARGS | METH_STATIC,
+ "Changes the pitch of a sound with a specific factor."
+ },
+ {"volume", (PyCFunction)Sound_volume, METH_VARARGS | METH_STATIC,
+ "Changes the volume of a sound with a specific factor."
+ },
+ {"fadein", (PyCFunction)Sound_fadein, METH_VARARGS | METH_STATIC,
+ "Fades a sound in from a specific start time and with a specific length."
+ },
+ {"fadeout", (PyCFunction)Sound_fadeout, METH_VARARGS | METH_STATIC,
+ "Fades a sound out from a specific start time and with a specific length."
+ },
+ {"loop", (PyCFunction)Sound_loop, METH_VARARGS | METH_STATIC,
+ "Loops a sound a specific amount of times, negative values mean endlessly."
+ },
+ {"superpose", (PyCFunction)Sound_superpose, METH_VARARGS | METH_STATIC,
+ "Mixes two sounds of the same specs."
+ },
+ {"pingpong", (PyCFunction)Sound_pingpong, METH_O | METH_STATIC,
+ "Plays a sound forward and then backward."
+ },
+ {"reverse", (PyCFunction)Sound_reverse, METH_O | METH_STATIC,
+ "Plays a sound reversed."
+ },
+ {"buffer", (PyCFunction)Sound_buffer, METH_O | METH_STATIC,
+ "Buffers a sound into RAM."
+ },
+ {"square", (PyCFunction)Sound_square, METH_VARARGS | METH_STATIC,
+ "Makes a square wave out of an audio wave depending on a threshold value."
+ },
+ {NULL} /* Sentinel */
+};
+
+static PyTypeObject SoundType = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "aud.Sound", /* tp_name */
+ sizeof(Sound), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)Sound_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ "Sound object", /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ Sound_methods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ Sound_new, /* tp_new */
+};
+
+static PyObject *
+Sound_sine(PyObject* nothing, PyObject* args)
+{
+ double frequency;
+
+ if(!PyArg_ParseTuple(args, "d", &frequency))
+ return NULL;
+
+ Sound *self;
+
+ self = (Sound*)SoundType.tp_alloc(&SoundType, 0);
+ if(self != NULL)
+ {
+ try
+ {
+ self->factory = new AUD_SinusFactory(frequency, (AUD_SampleRate)44100);
+ }
+ catch(AUD_Exception&)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, "Sinusfactory couldn't be created!");
+ return NULL;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+static PyObject *
+Sound_file(PyObject* nothing, PyObject* args)
+{
+ const char* filename = NULL;
+
+ if(!PyArg_ParseTuple(args, "s", &filename))
+ return NULL;
+
+ Sound *self;
+
+ self = (Sound*)SoundType.tp_alloc(&SoundType, 0);
+ if(self != NULL)
+ {
+ try
+ {
+ self->factory = new AUD_FileFactory(filename);
+ }
+ catch(AUD_Exception&)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, "Filefactory couldn't be created!");
+ return NULL;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+static PyObject *
+Sound_lowpass(PyObject* nothing, PyObject* args)
+{
+ float frequency;
+ PyObject* object;
+
+ if(!PyArg_ParseTuple(args, "Of", &object, &frequency))
+ return NULL;
+
+ if(!PyObject_TypeCheck(object, &SoundType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Sound!");
+ return NULL;
+ }
+
+ Sound *self;
+ Sound *child = (Sound*)object;
+
+ self = (Sound*)SoundType.tp_alloc(&SoundType, 0);
+ if(self != NULL)
+ {
+ Py_INCREF(object);
+ self->child_list = object;
+
+ try
+ {
+ self->factory = new AUD_LowpassFactory(child->factory, frequency, 0.9);
+ }
+ catch(AUD_Exception&)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, "Lowpassfactory couldn't be created!");
+ return NULL;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+static PyObject *
+Sound_delay(PyObject* nothing, PyObject* args)
+{
+ float delay;
+ PyObject* object;
+
+ if(!PyArg_ParseTuple(args, "Of", &object, &delay))
+ return NULL;
+
+ if(!PyObject_TypeCheck(object, &SoundType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Sound!");
+ return NULL;
+ }
+
+ Sound *self;
+ Sound *child = (Sound*)object;
+
+ self = (Sound*)SoundType.tp_alloc(&SoundType, 0);
+ if(self != NULL)
+ {
+ Py_INCREF(object);
+ self->child_list = object;
+
+ try
+ {
+ self->factory = new AUD_DelayFactory(child->factory, delay);
+ }
+ catch(AUD_Exception&)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, "Delayfactory couldn't be created!");
+ return NULL;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+static PyObject *
+Sound_double(PyObject* nothing, PyObject* args)
+{
+ PyObject* object1;
+ PyObject* object2;
+
+ if(!PyArg_ParseTuple(args, "OO", &object1, &object2))
+ return NULL;
+
+ if(!PyObject_TypeCheck(object1, &SoundType))
+ {
+ PyErr_SetString(PyExc_TypeError, "First object is not of type aud.Sound!");
+ return NULL;
+ }
+
+ if(!PyObject_TypeCheck(object2, &SoundType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Second object is not of type aud.Sound!");
+ return NULL;
+ }
+
+ Sound *self;
+ Sound *child1 = (Sound*)object1;
+ Sound *child2 = (Sound*)object2;
+
+ self = (Sound*)SoundType.tp_alloc(&SoundType, 0);
+ if(self != NULL)
+ {
+ self->child_list = Py_BuildValue("(OO)", object1, object2);
+
+ try
+ {
+ self->factory = new AUD_DoubleFactory(child1->factory, child2->factory);
+ }
+ catch(AUD_Exception&)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, "Doublefactory couldn't be created!");
+ return NULL;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+static PyObject *
+Sound_superpose(PyObject* nothing, PyObject* args)
+{
+ PyObject* object1;
+ PyObject* object2;
+
+ if(!PyArg_ParseTuple(args, "OO", &object1, &object2))
+ return NULL;
+
+ if(!PyObject_TypeCheck(object1, &SoundType))
+ {
+ PyErr_SetString(PyExc_TypeError, "First object is not of type aud.Sound!");
+ return NULL;
+ }
+
+ if(!PyObject_TypeCheck(object2, &SoundType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Second object is not of type aud.Sound!");
+ return NULL;
+ }
+
+ Sound *self;
+ Sound *child1 = (Sound*)object1;
+ Sound *child2 = (Sound*)object2;
+
+ self = (Sound*)SoundType.tp_alloc(&SoundType, 0);
+ if(self != NULL)
+ {
+ self->child_list = Py_BuildValue("(OO)", object1, object2);
+
+ try
+ {
+ self->factory = new AUD_SuperposeFactory(child1->factory, child2->factory);
+ }
+ catch(AUD_Exception&)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, "Superposefactory couldn't be created!");
+ return NULL;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+static PyObject *
+Sound_highpass(PyObject* nothing, PyObject* args)
+{
+ float frequency;
+ PyObject* object;
+
+ if(!PyArg_ParseTuple(args, "Of", &object, &frequency))
+ return NULL;
+
+ if(!PyObject_TypeCheck(object, &SoundType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Sound!");
+ return NULL;
+ }
+
+ Sound *self;
+ Sound *child = (Sound*)object;
+
+ self = (Sound*)SoundType.tp_alloc(&SoundType, 0);
+ if(self != NULL)
+ {
+ Py_INCREF(object);
+ self->child_list = object;
+
+ try
+ {
+ self->factory = new AUD_HighpassFactory(child->factory, frequency, 0.9);
+ }
+ catch(AUD_Exception&)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, "Highpassfactory couldn't be created!");
+ return NULL;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+static PyObject *
+Sound_limiter(PyObject* nothing, PyObject* args)
+{
+ float start, end;
+ PyObject* object;
+
+ if(!PyArg_ParseTuple(args, "Off", &object, &start, &end))
+ return NULL;
+
+ if(!PyObject_TypeCheck(object, &SoundType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Sound!");
+ return NULL;
+ }
+
+ Sound *self;
+ Sound *child = (Sound*)object;
+
+ self = (Sound*)SoundType.tp_alloc(&SoundType, 0);
+ if(self != NULL)
+ {
+ Py_INCREF(object);
+ self->child_list = object;
+
+ try
+ {
+ self->factory = new AUD_LimiterFactory(child->factory, start, end);
+ }
+ catch(AUD_Exception&)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, "Limiterfactory couldn't be created!");
+ return NULL;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+static PyObject *
+Sound_pitch(PyObject* nothing, PyObject* args)
+{
+ float factor;
+ PyObject* object;
+
+ if(!PyArg_ParseTuple(args, "Of", &object, &factor))
+ return NULL;
+
+ if(!PyObject_TypeCheck(object, &SoundType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Sound!");
+ return NULL;
+ }
+
+ Sound *self;
+ Sound *child = (Sound*)object;
+
+ self = (Sound*)SoundType.tp_alloc(&SoundType, 0);
+ if(self != NULL)
+ {
+ Py_INCREF(object);
+ self->child_list = object;
+
+ try
+ {
+ self->factory = new AUD_PitchFactory(child->factory, factor);
+ }
+ catch(AUD_Exception&)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, "Pitchfactory couldn't be created!");
+ return NULL;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+static PyObject *
+Sound_volume(PyObject* nothing, PyObject* args)
+{
+ float volume;
+ PyObject* object;
+
+ if(!PyArg_ParseTuple(args, "Of", &object, &volume))
+ return NULL;
+
+ if(!PyObject_TypeCheck(object, &SoundType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Sound!");
+ return NULL;
+ }
+
+ Sound *self;
+ Sound *child = (Sound*)object;
+
+ self = (Sound*)SoundType.tp_alloc(&SoundType, 0);
+ if(self != NULL)
+ {
+ Py_INCREF(object);
+ self->child_list = object;
+
+ try
+ {
+ self->factory = new AUD_VolumeFactory(child->factory, volume);
+ }
+ catch(AUD_Exception&)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, "Volumefactory couldn't be created!");
+ return NULL;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+static PyObject *
+Sound_square(PyObject* nothing, PyObject* args)
+{
+ float threshold;
+ PyObject* object;
+
+ if(!PyArg_ParseTuple(args, "Of", &object, &threshold))
+ return NULL;
+
+ if(!PyObject_TypeCheck(object, &SoundType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Sound!");
+ return NULL;
+ }
+
+ Sound *self;
+ Sound *child = (Sound*)object;
+
+ self = (Sound*)SoundType.tp_alloc(&SoundType, 0);
+ if(self != NULL)
+ {
+ Py_INCREF(object);
+ self->child_list = object;
+
+ try
+ {
+ self->factory = new AUD_SquareFactory(child->factory, threshold);
+ }
+ catch(AUD_Exception&)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, "Squarefactory couldn't be created!");
+ return NULL;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+static PyObject *
+Sound_fadein(PyObject* nothing, PyObject* args)
+{
+ float start, length;
+ PyObject* object;
+
+ if(!PyArg_ParseTuple(args, "Off", &object, &start, &length))
+ return NULL;
+
+ if(!PyObject_TypeCheck(object, &SoundType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Sound!");
+ return NULL;
+ }
+
+ Sound *self;
+ Sound *child = (Sound*)object;
+
+ self = (Sound*)SoundType.tp_alloc(&SoundType, 0);
+ if(self != NULL)
+ {
+ Py_INCREF(object);
+ self->child_list = object;
+
+ try
+ {
+ self->factory = new AUD_FaderFactory(child->factory, AUD_FADE_IN, start, length);
+ }
+ catch(AUD_Exception&)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, "Faderfactory couldn't be created!");
+ return NULL;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+static PyObject *
+Sound_fadeout(PyObject* nothing, PyObject* args)
+{
+ float start, length;
+ PyObject* object;
+
+ if(!PyArg_ParseTuple(args, "Off", &object, &start, &length))
+ return NULL;
+
+ if(!PyObject_TypeCheck(object, &SoundType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Sound!");
+ return NULL;
+ }
+
+ Sound *self;
+ Sound *child = (Sound*)object;
+
+ self = (Sound*)SoundType.tp_alloc(&SoundType, 0);
+ if(self != NULL)
+ {
+ Py_INCREF(object);
+ self->child_list = object;
+
+ try
+ {
+ self->factory = new AUD_FaderFactory(child->factory, AUD_FADE_OUT, start, length);
+ }
+ catch(AUD_Exception&)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, "Faderfactory couldn't be created!");
+ return NULL;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+static PyObject *
+Sound_loop(PyObject* nothing, PyObject* args)
+{
+ int loop;
+ PyObject* object;
+
+ if(!PyArg_ParseTuple(args, "Oi", &object, &loop))
+ return NULL;
+
+ if(!PyObject_TypeCheck(object, &SoundType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Sound!");
+ return NULL;
+ }
+
+ Sound *self;
+ Sound *child = (Sound*)object;
+
+ self = (Sound*)SoundType.tp_alloc(&SoundType, 0);
+ if(self != NULL)
+ {
+ Py_INCREF(object);
+ self->child_list = object;
+
+ try
+ {
+ self->factory = new AUD_LoopFactory(child->factory, loop);
+ }
+ catch(AUD_Exception&)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, "Loopfactory couldn't be created!");
+ return NULL;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+static PyObject *
+Sound_pingpong(PyObject* nothing, PyObject* object)
+{
+ if(!PyObject_TypeCheck(object, &SoundType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Sound!");
+ return NULL;
+ }
+
+ Sound *self;
+ Sound *child = (Sound*)object;
+
+ self = (Sound*)SoundType.tp_alloc(&SoundType, 0);
+ if(self != NULL)
+ {
+ Py_INCREF(object);
+ self->child_list = object;
+
+ try
+ {
+ self->factory = new AUD_PingPongFactory(child->factory);
+ }
+ catch(AUD_Exception&)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, "Pingpongfactory couldn't be created!");
+ return NULL;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+static PyObject *
+Sound_reverse(PyObject* nothing, PyObject* object)
+{
+ if(!PyObject_TypeCheck(object, &SoundType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Sound!");
+ return NULL;
+ }
+
+ Sound *self;
+ Sound *child = (Sound*)object;
+
+ self = (Sound*)SoundType.tp_alloc(&SoundType, 0);
+ if(self != NULL)
+ {
+ Py_INCREF(object);
+ self->child_list = object;
+
+ try
+ {
+ self->factory = new AUD_ReverseFactory(child->factory);
+ }
+ catch(AUD_Exception&)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, "Reversefactory couldn't be created!");
+ return NULL;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+static PyObject *
+Sound_buffer(PyObject* nothing, PyObject* object)
+{
+ if(!PyObject_TypeCheck(object, &SoundType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Sound!");
+ return NULL;
+ }
+
+ Sound *self;
+ Sound *child = (Sound*)object;
+
+ self = (Sound*)SoundType.tp_alloc(&SoundType, 0);
+ if(self != NULL)
+ {
+ try
+ {
+ self->factory = new AUD_StreamBufferFactory(child->factory);
+ }
+ catch(AUD_Exception&)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, "Bufferfactory couldn't be created!");
+ return NULL;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+// ========== Handle ==================================================
+
+static void
+Handle_dealloc(Handle* self)
+{
+ Py_XDECREF(self->device);
+ Py_TYPE(self)->tp_free((PyObject*)self);
+}
+
+static PyObject *
+Handle_pause(Handle *self)
+{
+ return PyObject_CallMethod(self->device, "pause", "(O)", self);
+}
+
+static PyObject *
+Handle_resume(Handle *self)
+{
+ return PyObject_CallMethod(self->device, "resume", "(O)", self);
+}
+
+static PyObject *
+Handle_stop(Handle *self)
+{
+ return PyObject_CallMethod(self->device, "stop", "(O)", self);
+}
+
+static PyObject *
+Handle_update(Handle *self, PyObject *data)
+{
+ return PyObject_CallMethod(self->device, "updateSource", "(OO)", self, data);
+}
+
+static PyMethodDef Handle_methods[] = {
+ {"pause", (PyCFunction)Handle_pause, METH_NOARGS,
+ "Pauses the sound."
+ },
+ {"resume", (PyCFunction)Handle_resume, METH_NOARGS,
+ "Resumes the sound."
+ },
+ {"stop", (PyCFunction)Handle_stop, METH_NOARGS,
+ "Stops the sound."
+ },
+ {"update", (PyCFunction)Handle_update, METH_O,
+ "Updates the 3D information of the source. Awaits a 3D position and velocity vector and a 3x3 orientation matrix."
+ },
+ {NULL} /* Sentinel */
+};
+
+static PyObject *
+Handle_getPosition(Handle *self, void* nothing)
+{
+ return PyObject_CallMethod(self->device, "getPosition", "(O)", self);
+}
+
+static int
+Handle_setPosition(Handle *self, PyObject* args, void* nothing)
+{
+ PyObject* result = PyObject_CallMethod(self->device, "seek", "(OO)", self, args);
+ if(result)
+ {
+ Py_DECREF(result);
+ return 0;
+ }
+ return -1;
+}
+
+static int
+Handle_setKeep(Handle *self, PyObject* args, void* nothing)
+{
+ PyObject* result = PyObject_CallMethod(self->device, "setKeep", "(OO)", self, args);
+ if(result)
+ {
+ Py_DECREF(result);
+ return 0;
+ }
+ return -1;
+}
+
+static PyObject *
+Handle_getStatus(Handle *self, void* nothing)
+{
+ return PyObject_CallMethod(self->device, "getStatus", "(O)", self);
+}
+
+static PyObject *
+Handle_getVolume(Handle *self, void* nothing)
+{
+ return PyObject_CallMethod(self->device, "getVolume", "(O)", self);
+}
+
+static int
+Handle_setVolume(Handle *self, PyObject* args, void* nothing)
+{
+ PyObject* result = PyObject_CallMethod(self->device, "setVolume", "(OO)", self, args);
+ if(result)
+ {
+ Py_DECREF(result);
+ return 0;
+ }
+ return -1;
+}
+
+static int
+Handle_setPitch(Handle *self, PyObject* args, void* nothing)
+{
+ PyObject* result = PyObject_CallMethod(self->device, "setPitch", "(OO)", self, args);
+ if(result)
+ {
+ Py_DECREF(result);
+ return 0;
+ }
+ return -1;
+}
+
+static int
+Handle_setLoopCount(Handle *self, PyObject* args, void* nothing)
+{
+ PyObject* result = PyObject_CallMethod(self->device, "setLoopCount", "(OO)", self, args);
+ if(result)
+ {
+ Py_DECREF(result);
+ return 0;
+ }
+ return -1;
+}
+
+static PyObject *
+Handle_getRelative(Handle *self, void* nothing)
+{
+ return PyObject_CallMethod(self->device, "isRelative", "(O)", self);
+}
+
+static int
+Handle_setRelative(Handle *self, PyObject* args, void* nothing)
+{
+ PyObject* result = PyObject_CallMethod(self->device, "setRelative", "(OO)", self, args);
+ if(result)
+ {
+ Py_DECREF(result);
+ return 0;
+ }
+ return -1;
+}
+
+static PyObject *
+Handle_getMinGain(Handle *self, void* nothing)
+{
+ return PyObject_CallMethod(self->device, "getMinGain", "(O)", self);
+}
+
+static int
+Handle_setMinGain(Handle *self, PyObject* args, void* nothing)
+{
+ PyObject* result = PyObject_CallMethod(self->device, "setMinGain", "(OO)", self, args);
+ if(result)
+ {
+ Py_DECREF(result);
+ return 0;
+ }
+ return -1;
+}
+
+static PyObject *
+Handle_getMaxGain(Handle *self, void* nothing)
+{
+ return PyObject_CallMethod(self->device, "getMaxGain", "(O)", self);
+}
+
+static int
+Handle_setMaxGain(Handle *self, PyObject* args, void* nothing)
+{
+ PyObject* result = PyObject_CallMethod(self->device, "setMaxGain", "(OO)", self, args);
+ if(result)
+ {
+ Py_DECREF(result);
+ return 0;
+ }
+ return -1;
+}
+
+static PyObject *
+Handle_getReferenceDistance(Handle *self, void* nothing)
+{
+ return PyObject_CallMethod(self->device, "getReferenceDistance", "(O)", self);
+}
+
+static int
+Handle_setReferenceDistance(Handle *self, PyObject* args, void* nothing)
+{
+ PyObject* result = PyObject_CallMethod(self->device, "setReferenceDistance", "(OO)", self, args);
+ if(result)
+ {
+ Py_DECREF(result);
+ return 0;
+ }
+ return -1;
+}
+
+static PyObject *
+Handle_getMaxDistance(Handle *self, void* nothing)
+{
+ return PyObject_CallMethod(self->device, "getMaxDistance", "(O)", self);
+}
+
+static int
+Handle_setMaxDistance(Handle *self, PyObject* args, void* nothing)
+{
+ PyObject* result = PyObject_CallMethod(self->device, "setMaxDistance", "(OO)", self, args);
+ if(result)
+ {
+ Py_DECREF(result);
+ return 0;
+ }
+ return -1;
+}
+
+static PyObject *
+Handle_getRolloffFactor(Handle *self, void* nothing)
+{
+ return PyObject_CallMethod(self->device, "getRolloffFactor", "(O)", self);
+}
+
+static int
+Handle_setRolloffFactor(Handle *self, PyObject* args, void* nothing)
+{
+ PyObject* result = PyObject_CallMethod(self->device, "setRolloffFactor", "(OO)", self, args);
+ if(result)
+ {
+ Py_DECREF(result);
+ return 0;
+ }
+ return -1;
+}
+
+static PyObject *
+Handle_getConeInnerAngle(Handle *self, void* nothing)
+{
+ return PyObject_CallMethod(self->device, "getConeInnerAngle", "(O)", self);
+}
+
+static int
+Handle_setConeInnerAngle(Handle *self, PyObject* args, void* nothing)
+{
+ PyObject* result = PyObject_CallMethod(self->device, "setConeInnerAngle", "(OO)", self, args);
+ if(result)
+ {
+ Py_DECREF(result);
+ return 0;
+ }
+ return -1;
+}
+
+static PyObject *
+Handle_getConeOuterAngle(Handle *self, void* nothing)
+{
+ return PyObject_CallMethod(self->device, "getConeOuterAngle", "(O)", self);
+}
+
+static int
+Handle_setConeOuterAngle(Handle *self, PyObject* args, void* nothing)
+{
+ PyObject* result = PyObject_CallMethod(self->device, "setConeOuterAngle", "(OO)", self, args);
+ if(result)
+ {
+ Py_DECREF(result);
+ return 0;
+ }
+ return -1;
+}
+
+static PyObject *
+Handle_getConeOuterGain(Handle *self, void* nothing)
+{
+ return PyObject_CallMethod(self->device, "getConeOuterGain", "(O)", self);
+}
+
+static int
+Handle_setConeOuterGain(Handle *self, PyObject* args, void* nothing)
+{
+ PyObject* result = PyObject_CallMethod(self->device, "setConeOuterGain", "(OO)", self, args);
+ if(result)
+ {
+ Py_DECREF(result);
+ return 0;
+ }
+ return -1;
+}
+
+static PyGetSetDef Handle_properties[] = {
+ {"position", (getter)Handle_getPosition, (setter)Handle_setPosition,
+ "The playback position of the sound.", NULL },
+ {"keep", NULL, (setter)Handle_setKeep,
+ "Whether the sound should be kept paused in the device when it's end is reached.", NULL },
+ {"status", (getter)Handle_getStatus, NULL,
+ "Whether the sound is playing, paused or stopped.", NULL },
+ {"volume", (getter)Handle_getVolume, (setter)Handle_setVolume,
+ "The volume of the sound.", NULL },
+ {"pitch", NULL, (setter)Handle_setPitch,
+ "The pitch of the sound.", NULL },
+ {"loopcount", NULL, (setter)Handle_setLoopCount,
+ "The loop count of the sound. A negative value indicates infinity.", NULL },
+ {"relative", (getter)Handle_getRelative, (setter)Handle_setRelative,
+ "Whether the source's position is relative or absolute to the listener.", NULL },
+ {"min_gain", (getter)Handle_getMinGain, (setter)Handle_setMinGain,
+ "The minimum gain of the source.", NULL },
+ {"max_gain", (getter)Handle_getMaxGain, (setter)Handle_setMaxGain,
+ "The maximum gain of the source.", NULL },
+ {"reference_distance", (getter)Handle_getReferenceDistance, (setter)Handle_setReferenceDistance,
+ "The reference distance of the source.", NULL },
+ {"max_distance", (getter)Handle_getMaxDistance, (setter)Handle_setMaxDistance,
+ "The maximum distance of the source.", NULL },
+ {"rolloff_factor", (getter)Handle_getRolloffFactor, (setter)Handle_setRolloffFactor,
+ "The rolloff factor of the source.", NULL },
+ {"cone_inner_angle", (getter)Handle_getConeInnerAngle, (setter)Handle_setConeInnerAngle,
+ "The cone inner angle of the source.", NULL },
+ {"cone_outer_angle", (getter)Handle_getConeOuterAngle, (setter)Handle_setConeOuterAngle,
+ "The cone outer angle of the source.", NULL },
+ {"cone_outer_gain", (getter)Handle_getConeOuterGain, (setter)Handle_setConeOuterGain,
+ "The cone outer gain of the source.", NULL },
+ {NULL} /* Sentinel */
+};
+
+static PyTypeObject HandleType = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "aud.Handle", /* tp_name */
+ sizeof(Handle), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)Handle_dealloc,/* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ "Handle object", /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ Handle_methods, /* tp_methods */
+ 0, /* tp_members */
+ Handle_properties, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ 0, /* tp_new */
+};
+
+// ========== Device ==================================================
+
+static void
+Device_dealloc(Device* self)
+{
+ if(self->device)
+ delete self->device;
+ Py_TYPE(self)->tp_free((PyObject*)self);
+}
+
+static PyObject *
+Device_play(Device *self, PyObject *args, PyObject *kwds)
+{
+ PyObject* object;
+ PyObject* keepo = NULL;
+
+ bool keep = false;
+
+ static char *kwlist[] = {"sound", "keep", NULL};
+
+ if(!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", 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
+ {
+ handle->handle = self->device->play(sound->factory, keep);
+ }
+ catch(AUD_Exception&)
+ {
+ Py_DECREF(handle);
+ PyErr_SetString(AUDError, "Couldn't play the sound!");
+ return NULL;
+ }
+ }
+
+ return (PyObject *)handle;
+}
+
+static PyObject *
+Device_stop(Device *self, PyObject *object)
+{
+ if(!PyObject_TypeCheck(object, &HandleType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
+ return NULL;
+ }
+
+ Handle* handle = (Handle*)object;
+
+ try
+ {
+ if(self->device->stop(handle->handle))
+ {
+ Py_RETURN_TRUE;
+ }
+ }
+ catch(AUD_Exception&)
+ {
+ PyErr_SetString(AUDError, "Couldn't stop the sound!");
+ return NULL;
+ }
+
+ Py_RETURN_FALSE;
+}
+
+static PyObject *
+Device_pause(Device *self, PyObject *object)
+{
+ if(!PyObject_TypeCheck(object, &HandleType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
+ return NULL;
+ }
+
+ Handle* handle = (Handle*)object;
+
+ try
+ {
+ if(self->device->pause(handle->handle))
+ {
+ Py_RETURN_TRUE;
+ }
+ }
+ catch(AUD_Exception&)
+ {
+ PyErr_SetString(AUDError, "Couldn't pause the sound!");
+ return NULL;
+ }
+
+ Py_RETURN_FALSE;
+}
+
+static PyObject *
+Device_resume(Device *self, PyObject *object)
+{
+ if(!PyObject_TypeCheck(object, &HandleType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
+ return NULL;
+ }
+
+ Handle* handle = (Handle*)object;
+
+ try
+ {
+ if(self->device->resume(handle->handle))
+ {
+ Py_RETURN_TRUE;
+ }
+ }
+ catch(AUD_Exception&)
+ {
+ PyErr_SetString(AUDError, "Couldn't resume the sound!");
+ return NULL;
+ }
+
+ Py_RETURN_FALSE;
+}
+
+static PyObject *
+Device_setKeep(Device *self, PyObject *args)
+{
+ PyObject* object;
+ PyObject* keepo;
+
+ if(!PyArg_ParseTuple(args, "OO", &object, &keepo))
+ return NULL;
+
+ if(!PyObject_TypeCheck(object, &HandleType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
+ return NULL;
+ }
+
+ if(!PyBool_Check(keepo))
+ {
+ PyErr_SetString(PyExc_TypeError, "keep is not a boolean!");
+ return NULL;
+ }
+
+ bool keep = keepo == Py_True;
+ Handle* handle = (Handle*)object;
+
+ try
+ {
+ if(self->device->setKeep(handle->handle, keep))
+ {
+ Py_RETURN_TRUE;
+ }
+ }
+ catch(AUD_Exception&)
+ {
+ PyErr_SetString(AUDError, "Couldn't set keep of the sound!");
+ return NULL;
+ }
+
+ Py_RETURN_FALSE;
+}
+
+static PyObject *
+Device_seek(Device *self, PyObject *args)
+{
+ PyObject* object;
+ float position;
+
+ if(!PyArg_ParseTuple(args, "Of", &object, &position))
+ return NULL;
+
+ if(!PyObject_TypeCheck(object, &HandleType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
+ return NULL;
+ }
+
+ Handle* handle = (Handle*)object;
+
+ try
+ {
+ if(self->device->seek(handle->handle, position))
+ {
+ Py_RETURN_TRUE;
+ }
+ }
+ catch(AUD_Exception&)
+ {
+ PyErr_SetString(AUDError, "Couldn't seek the sound!");
+ return NULL;
+ }
+
+ Py_RETURN_FALSE;
+}
+
+static PyObject *
+Device_getPosition(Device *self, PyObject *object)
+{
+ if(!PyObject_TypeCheck(object, &HandleType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
+ return NULL;
+ }
+
+ Handle* handle = (Handle*)object;
+
+ try
+ {
+ return Py_BuildValue("f", self->device->getPosition(handle->handle));
+ }
+ catch(AUD_Exception&)
+ {
+ PyErr_SetString(AUDError, "Couldn't retrieve the position of the sound!");
+ return NULL;
+ }
+}
+
+static PyObject *
+Device_getStatus(Device *self, PyObject *object)
+{
+ if(!PyObject_TypeCheck(object, &HandleType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
+ return NULL;
+ }
+
+ Handle* handle = (Handle*)object;
+
+ try
+ {
+ return Py_BuildValue("i", self->device->getStatus(handle->handle));
+ }
+ catch(AUD_Exception&)
+ {
+ PyErr_SetString(AUDError, "Couldn't retrieve the status of the sound!");
+ return NULL;
+ }
+}
+
+static PyObject *
+Device_lock(Device *self)
+{
+ try
+ {
+ self->device->lock();
+ Py_RETURN_NONE;
+ }
+ catch(AUD_Exception&)
+ {
+ PyErr_SetString(AUDError, "Couldn't lock the device!");
+ return NULL;
+ }
+}
+
+static PyObject *
+Device_unlock(Device *self)
+{
+ try
+ {
+ self->device->unlock();
+ Py_RETURN_NONE;
+ }
+ catch(AUD_Exception&)
+ {
+ PyErr_SetString(AUDError, "Couldn't unlock the device!");
+ return NULL;
+ }
+}
+
+static PyObject *
+Device_setSourceVolume(Device *self, PyObject *args)
+{
+ PyObject* object;
+ float volume;
+
+ if(!PyArg_ParseTuple(args, "Of", &object, &volume))
+ return NULL;
+
+ if(!PyObject_TypeCheck(object, &HandleType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
+ return NULL;
+ }
+
+ Handle* handle = (Handle*)object;
+
+ try
+ {
+ AUD_SourceCaps caps;
+ caps.handle = handle->handle;
+ caps.value = volume;
+ if(self->device->setCapability(AUD_CAPS_SOURCE_VOLUME, &caps))
+ {
+ Py_RETURN_TRUE;
+ }
+ }
+ catch(AUD_Exception&)
+ {
+ PyErr_SetString(AUDError, "Couldn't set the sound volume!");
+ return NULL;
+ }
+
+ Py_RETURN_FALSE;
+}
+
+static PyObject *
+Device_getSourceVolume(Device *self, PyObject *object)
+{
+ if(!PyObject_TypeCheck(object, &HandleType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
+ return NULL;
+ }
+
+ Handle* handle = (Handle*)object;
+
+ try
+ {
+ AUD_SourceCaps caps;
+ caps.handle = handle->handle;
+ caps.value = 1.0f;
+ if(self->device->getCapability(AUD_CAPS_SOURCE_VOLUME, &caps))
+ {
+ return Py_BuildValue("f", caps.value);
+ }
+ }
+ catch(AUD_Exception&)
+ {
+ PyErr_SetString(AUDError, "Couldn't get the sound volume!");
+ return NULL;
+ }
+
+ Py_RETURN_NAN;
+}
+
+static PyObject *
+Device_setLoopCount(Device *self, PyObject *args)
+{
+ PyObject* object;
+ int loops;
+
+ if(!PyArg_ParseTuple(args, "Oi", &object, &loops))
+ return NULL;
+
+ if(!PyObject_TypeCheck(object, &HandleType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
+ return NULL;
+ }
+
+ Handle* handle = (Handle*)object;
+
+ try
+ {
+ AUD_Message message;
+ message.loopcount = loops;
+ message.type = AUD_MSG_LOOP;
+ if(self->device->sendMessage(handle->handle, message))
+ {
+ Py_RETURN_TRUE;
+ }
+ }
+ catch(AUD_Exception&)
+ {
+ PyErr_SetString(AUDError, "Couldn't set the loop count!");
+ return NULL;
+ }
+
+ Py_RETURN_FALSE;
+}
+
+static PyObject *
+Device_setPitch(Device *self, PyObject *args)
+{
+ PyObject* object;
+ float pitch;
+
+ if(!PyArg_ParseTuple(args, "Of", &object, &pitch))
+ return NULL;
+
+ if(!PyObject_TypeCheck(object, &HandleType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
+ return NULL;
+ }
+
+ Handle* handle = (Handle*)object;
+
+ try
+ {
+ AUD_SourceCaps caps;
+ caps.handle = handle->handle;
+ caps.value = pitch;
+ if(self->device->setCapability(AUD_CAPS_SOURCE_PITCH, &caps))
+ {
+ Py_RETURN_TRUE;
+ }
+ }
+ catch(AUD_Exception&)
+ {
+ PyErr_SetString(AUDError, "Couldn't set the sound pitch!");
+ return NULL;
+ }
+
+ Py_RETURN_FALSE;
+}
+
+static PyObject *
+Device_play3D(Device *self, PyObject *args, PyObject *kwds)
+{
+ PyObject* object;
+ PyObject* keepo = NULL;
+
+ bool keep = false;
+
+ static char *kwlist[] = {"sound", "keep", NULL};
+
+ if(!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", 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;
+}
+
+static PyObject *
+Device_updateListener(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;
+}
+
+static PyObject *
+Device_updateSource(Device *self, PyObject *args)
+{
+ PyObject* object;
+ AUD_3DData data;
+
+ if(!PyArg_ParseTuple(args, "O(fff)(fff)((fff)(fff)(fff))", &object,
+ &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;
+
+ if(!PyObject_TypeCheck(object, &HandleType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
+ return NULL;
+ }
+
+ Handle* handle = (Handle*)object;
+
+ try
+ {
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ if(device)
+ {
+ if(device->updateSource(handle->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 PyObject *
+Device_isRelative(Device *self, PyObject *object)
+{
+ if(!PyObject_TypeCheck(object, &HandleType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
+ return NULL;
+ }
+
+ Handle* handle = (Handle*)object;
+
+ try
+ {
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ if(device)
+ {
+ if(device->getSourceSetting(handle->handle, AUD_3DSS_IS_RELATIVE) > 0)
+ {
+ Py_RETURN_TRUE;
+ }
+ else
+ {
+ Py_RETURN_FALSE;
+ }
+ }
+ else
+ {
+ PyErr_SetString(AUDError, "Device is not a 3D device!");
+ return NULL;
+ }
+ }
+ catch(AUD_Exception&)
+ {
+ PyErr_SetString(AUDError, "Couldn't retrieve the status of the sound!");
+ return NULL;
+ }
+}
+
+static PyObject *
+Device_setRelative(Device *self, PyObject *args)
+{
+ PyObject* object;
+ PyObject* relativeo;
+
+ if(!PyArg_ParseTuple(args, "OO", &object, &relativeo))
+ return NULL;
+
+ if(!PyObject_TypeCheck(object, &HandleType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
+ return NULL;
+ }
+
+ if(!PyBool_Check(relativeo))
+ {
+ PyErr_SetString(PyExc_TypeError, "Value is not a boolean!");
+ return NULL;
+ }
+
+ float relative = (relativeo == Py_True);
+ Handle* handle = (Handle*)object;
+
+ try
+ {
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ if(device)
+ {
+ device->setSourceSetting(handle->handle, AUD_3DSS_IS_RELATIVE, relative);
+ Py_RETURN_TRUE;
+ }
+ else
+ {
+ PyErr_SetString(AUDError, "Device is not a 3D device!");
+ return NULL;
+ }
+ }
+ catch(AUD_Exception&)
+ {
+ PyErr_SetString(AUDError, "Couldn't set the status!");
+ return NULL;
+ }
+
+ Py_RETURN_FALSE;
+}
+
+static PyObject *
+Device_getMinGain(Device *self, PyObject *object)
+{
+ if(!PyObject_TypeCheck(object, &HandleType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
+ return NULL;
+ }
+
+ Handle* handle = (Handle*)object;
+
+ try
+ {
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ if(device)
+ {
+ return Py_BuildValue("f", device->getSourceSetting(handle->handle, AUD_3DSS_MIN_GAIN));
+ }
+ else
+ {
+ PyErr_SetString(AUDError, "Device is not a 3D device!");
+ return NULL;
+ }
+ }
+ catch(AUD_Exception&)
+ {
+ PyErr_SetString(AUDError, "Couldn't retrieve the minimum gain of the sound!");
+ return NULL;
+ }
+}
+
+static PyObject *
+Device_setMinGain(Device *self, PyObject *args)
+{
+ PyObject* object;
+ float gain;
+
+ if(!PyArg_ParseTuple(args, "Of", &object, &gain))
+ return NULL;
+
+ if(!PyObject_TypeCheck(object, &HandleType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
+ return NULL;
+ }
+
+ Handle* handle = (Handle*)object;
+
+ try
+ {
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ if(device)
+ {
+ device->setSourceSetting(handle->handle, AUD_3DSS_MIN_GAIN, gain);
+ Py_RETURN_TRUE;
+ }
+ else
+ {
+ PyErr_SetString(AUDError, "Device is not a 3D device!");
+ return NULL;
+ }
+ }
+ catch(AUD_Exception&)
+ {
+ PyErr_SetString(AUDError, "Couldn't set the minimum source gain!");
+ return NULL;
+ }
+
+ Py_RETURN_FALSE;
+}
+
+static PyObject *
+Device_getMaxGain(Device *self, PyObject *object)
+{
+ if(!PyObject_TypeCheck(object, &HandleType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
+ return NULL;
+ }
+
+ Handle* handle = (Handle*)object;
+
+ try
+ {
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ if(device)
+ {
+ return Py_BuildValue("f", device->getSourceSetting(handle->handle, AUD_3DSS_MAX_GAIN));
+ }
+ else
+ {
+ PyErr_SetString(AUDError, "Device is not a 3D device!");
+ return NULL;
+ }
+ }
+ catch(AUD_Exception&)
+ {
+ PyErr_SetString(AUDError, "Couldn't retrieve the maximum gain of the sound!");
+ return NULL;
+ }
+}
+
+static PyObject *
+Device_setMaxGain(Device *self, PyObject *args)
+{
+ PyObject* object;
+ float gain;
+
+ if(!PyArg_ParseTuple(args, "Of", &object, &gain))
+ return NULL;
+
+ if(!PyObject_TypeCheck(object, &HandleType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
+ return NULL;
+ }
+
+ Handle* handle = (Handle*)object;
+
+ try
+ {
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ if(device)
+ {
+ device->setSourceSetting(handle->handle, AUD_3DSS_MAX_GAIN, gain);
+ Py_RETURN_TRUE;
+ }
+ else
+ {
+ PyErr_SetString(AUDError, "Device is not a 3D device!");
+ return NULL;
+ }
+ }
+ catch(AUD_Exception&)
+ {
+ PyErr_SetString(AUDError, "Couldn't set the maximum source gain!");
+ return NULL;
+ }
+
+ Py_RETURN_FALSE;
+}
+
+static PyObject *
+Device_getReferenceDistance(Device *self, PyObject *object)
+{
+ if(!PyObject_TypeCheck(object, &HandleType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
+ return NULL;
+ }
+
+ Handle* handle = (Handle*)object;
+
+ try
+ {
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ if(device)
+ {
+ return Py_BuildValue("f", device->getSourceSetting(handle->handle, AUD_3DSS_REFERENCE_DISTANCE));
+ }
+ else
+ {
+ PyErr_SetString(AUDError, "Device is not a 3D device!");
+ return NULL;
+ }
+ }
+ catch(AUD_Exception&)
+ {
+ PyErr_SetString(AUDError, "Couldn't retrieve the reference distance of the sound!");
+ return NULL;
+ }
+}
+
+static PyObject *
+Device_setReferenceDistance(Device *self, PyObject *args)
+{
+ PyObject* object;
+ float distance;
+
+ if(!PyArg_ParseTuple(args, "Of", &object, &distance))
+ return NULL;
+
+ if(!PyObject_TypeCheck(object, &HandleType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
+ return NULL;
+ }
+
+ Handle* handle = (Handle*)object;
+
+ try
+ {
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ if(device)
+ {
+ device->setSourceSetting(handle->handle, AUD_3DSS_REFERENCE_DISTANCE, distance);
+ Py_RETURN_TRUE;
+ }
+ else
+ {
+ PyErr_SetString(AUDError, "Device is not a 3D device!");
+ return NULL;
+ }
+ }
+ catch(AUD_Exception&)
+ {
+ PyErr_SetString(AUDError, "Couldn't set the reference distance!");
+ return NULL;
+ }
+
+ Py_RETURN_FALSE;
+}
+
+static PyObject *
+Device_getMaxDistance(Device *self, PyObject *object)
+{
+ if(!PyObject_TypeCheck(object, &HandleType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
+ return NULL;
+ }
+
+ Handle* handle = (Handle*)object;
+
+ try
+ {
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ if(device)
+ {
+ return Py_BuildValue("f", device->getSourceSetting(handle->handle, AUD_3DSS_MAX_DISTANCE));
+ }
+ else
+ {
+ PyErr_SetString(AUDError, "Device is not a 3D device!");
+ return NULL;
+ }
+ }
+ catch(AUD_Exception&)
+ {
+ PyErr_SetString(AUDError, "Couldn't retrieve the maximum distance of the sound!");
+ return NULL;
+ }
+}
+
+static PyObject *
+Device_setMaxDistance(Device *self, PyObject *args)
+{
+ PyObject* object;
+ float distance;
+
+ if(!PyArg_ParseTuple(args, "Of", &object, &distance))
+ return NULL;
+
+ if(!PyObject_TypeCheck(object, &HandleType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
+ return NULL;
+ }
+
+ Handle* handle = (Handle*)object;
+
+ try
+ {
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ if(device)
+ {
+ device->setSourceSetting(handle->handle, AUD_3DSS_MAX_DISTANCE, distance);
+ Py_RETURN_TRUE;
+ }
+ else
+ {
+ PyErr_SetString(AUDError, "Device is not a 3D device!");
+ return NULL;
+ }
+ }
+ catch(AUD_Exception&)
+ {
+ PyErr_SetString(AUDError, "Couldn't set the maximum distance!");
+ return NULL;
+ }
+
+ Py_RETURN_FALSE;
+}
+
+static PyObject *
+Device_getRolloffFactor(Device *self, PyObject *object)
+{
+ if(!PyObject_TypeCheck(object, &HandleType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
+ return NULL;
+ }
+
+ Handle* handle = (Handle*)object;
+
+ try
+ {
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ if(device)
+ {
+ return Py_BuildValue("f", device->getSourceSetting(handle->handle, AUD_3DSS_ROLLOFF_FACTOR));
+ }
+ else
+ {
+ PyErr_SetString(AUDError, "Device is not a 3D device!");
+ return NULL;
+ }
+ }
+ catch(AUD_Exception&)
+ {
+ PyErr_SetString(AUDError, "Couldn't retrieve the rolloff factor of the sound!");
+ return NULL;
+ }
+}
+
+static PyObject *
+Device_setRolloffFactor(Device *self, PyObject *args)
+{
+ PyObject* object;
+ float factor;
+
+ if(!PyArg_ParseTuple(args, "Of", &object, &factor))
+ return NULL;
+
+ if(!PyObject_TypeCheck(object, &HandleType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
+ return NULL;
+ }
+
+ Handle* handle = (Handle*)object;
+
+ try
+ {
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ if(device)
+ {
+ device->setSourceSetting(handle->handle, AUD_3DSS_ROLLOFF_FACTOR, factor);
+ Py_RETURN_TRUE;
+ }
+ else
+ {
+ PyErr_SetString(AUDError, "Device is not a 3D device!");
+ return NULL;
+ }
+ }
+ catch(AUD_Exception&)
+ {
+ PyErr_SetString(AUDError, "Couldn't set the rolloff factor!");
+ return NULL;
+ }
+
+ Py_RETURN_FALSE;
+}
+
+static PyObject *
+Device_getConeInnerAngle(Device *self, PyObject *object)
+{
+ if(!PyObject_TypeCheck(object, &HandleType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
+ return NULL;
+ }
+
+ Handle* handle = (Handle*)object;
+
+ try
+ {
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ if(device)
+ {
+ return Py_BuildValue("f", device->getSourceSetting(handle->handle, AUD_3DSS_CONE_INNER_ANGLE));
+ }
+ else
+ {
+ PyErr_SetString(AUDError, "Device is not a 3D device!");
+ return NULL;
+ }
+ }
+ catch(AUD_Exception&)
+ {
+ PyErr_SetString(AUDError, "Couldn't retrieve the cone inner angle of the sound!");
+ return NULL;
+ }
+}
+
+static PyObject *
+Device_setConeInnerAngle(Device *self, PyObject *args)
+{
+ PyObject* object;
+ float angle;
+
+ if(!PyArg_ParseTuple(args, "Of", &object, &angle))
+ return NULL;
+
+ if(!PyObject_TypeCheck(object, &HandleType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
+ return NULL;
+ }
+
+ Handle* handle = (Handle*)object;
+
+ try
+ {
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ if(device)
+ {
+ device->setSourceSetting(handle->handle, AUD_3DSS_CONE_INNER_ANGLE, angle);
+ Py_RETURN_TRUE;
+ }
+ else
+ {
+ PyErr_SetString(AUDError, "Device is not a 3D device!");
+ return NULL;
+ }
+ }
+ catch(AUD_Exception&)
+ {
+ PyErr_SetString(AUDError, "Couldn't set the cone inner angle!");
+ return NULL;
+ }
+
+ Py_RETURN_FALSE;
+}
+
+static PyObject *
+Device_getConeOuterAngle(Device *self, PyObject *object)
+{
+ if(!PyObject_TypeCheck(object, &HandleType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
+ return NULL;
+ }
+
+ Handle* handle = (Handle*)object;
+
+ try
+ {
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ if(device)
+ {
+ return Py_BuildValue("f", device->getSourceSetting(handle->handle, AUD_3DSS_CONE_OUTER_ANGLE));
+ }
+ else
+ {
+ PyErr_SetString(AUDError, "Device is not a 3D device!");
+ return NULL;
+ }
+ }
+ catch(AUD_Exception&)
+ {
+ PyErr_SetString(AUDError, "Couldn't retrieve the cone outer angle of the sound!");
+ return NULL;
+ }
+}
+
+static PyObject *
+Device_setConeOuterAngle(Device *self, PyObject *args)
+{
+ PyObject* object;
+ float angle;
+
+ if(!PyArg_ParseTuple(args, "Of", &object, &angle))
+ return NULL;
+
+ if(!PyObject_TypeCheck(object, &HandleType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
+ return NULL;
+ }
+
+ Handle* handle = (Handle*)object;
+
+ try
+ {
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ if(device)
+ {
+ device->setSourceSetting(handle->handle, AUD_3DSS_CONE_OUTER_ANGLE, angle);
+ Py_RETURN_TRUE;
+ }
+ else
+ {
+ PyErr_SetString(AUDError, "Device is not a 3D device!");
+ return NULL;
+ }
+ }
+ catch(AUD_Exception&)
+ {
+ PyErr_SetString(AUDError, "Couldn't set the cone outer angle!");
+ return NULL;
+ }
+
+ Py_RETURN_FALSE;
+}
+
+static PyObject *
+Device_getConeOuterGain(Device *self, PyObject *object)
+{
+ if(!PyObject_TypeCheck(object, &HandleType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
+ return NULL;
+ }
+
+ Handle* handle = (Handle*)object;
+
+ try
+ {
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ if(device)
+ {
+ return Py_BuildValue("f", device->getSourceSetting(handle->handle, AUD_3DSS_CONE_OUTER_GAIN));
+ }
+ else
+ {
+ PyErr_SetString(AUDError, "Device is not a 3D device!");
+ return NULL;
+ }
+ }
+ catch(AUD_Exception&)
+ {
+ PyErr_SetString(AUDError, "Couldn't retrieve the cone outer gain of the sound!");
+ return NULL;
+ }
+}
+
+static PyObject *
+Device_setConeOuterGain(Device *self, PyObject *args)
+{
+ PyObject* object;
+ float gain;
+
+ if(!PyArg_ParseTuple(args, "Of", &object, &gain))
+ return NULL;
+
+ if(!PyObject_TypeCheck(object, &HandleType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
+ return NULL;
+ }
+
+ Handle* handle = (Handle*)object;
+
+ try
+ {
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ if(device)
+ {
+ device->setSourceSetting(handle->handle, AUD_3DSS_CONE_OUTER_GAIN, gain);
+ Py_RETURN_TRUE;
+ }
+ else
+ {
+ PyErr_SetString(AUDError, "Device is not a 3D device!");
+ return NULL;
+ }
+ }
+ catch(AUD_Exception&)
+ {
+ PyErr_SetString(AUDError, "Couldn't set the cone outer gain!");
+ return NULL;
+ }
+
+ Py_RETURN_FALSE;
+}
+
+static PyObject *
+Device_OpenAL(PyTypeObject *type, PyObject *args, PyObject *kwds);
+
+static PyObject *
+Device_SDL(PyTypeObject *type, PyObject *args, PyObject *kwds);
+
+static PyObject *
+Device_Jack(PyTypeObject *type, PyObject *args, PyObject *kwds);
+
+static PyObject *
+Device_Null(PyTypeObject *type);
+
+static PyMethodDef Device_methods[] = {
+ {"play", (PyCFunction)Device_play, METH_VARARGS | METH_KEYWORDS,
+ "Plays a sound."
+ },
+ {"stop", (PyCFunction)Device_stop, METH_O,
+ "Stops a playing sound."
+ },
+ {"pause", (PyCFunction)Device_pause, METH_O,
+ "Pauses a playing sound."
+ },
+ {"resume", (PyCFunction)Device_resume, METH_O,
+ "Resumes a playing sound."
+ },
+ {"setKeep", (PyCFunction)Device_setKeep, METH_VARARGS,
+ "Sets whether a sound should be kept or not."
+ },
+ {"seek", (PyCFunction)Device_seek, METH_VARARGS,
+ "Seeks the sound to a specific position expressed in seconds."
+ },
+ {"getPosition", (PyCFunction)Device_getPosition, METH_O,
+ "Retrieves the playback position of a sound in seconds."
+ },
+ {"getStatus", (PyCFunction)Device_getStatus, METH_O,
+ "Retrieves the playback status of a sound."
+ },
+ {"lock", (PyCFunction)Device_lock, METH_NOARGS,
+ "Locks the sound device."
+ },
+ {"unlock", (PyCFunction)Device_unlock, METH_NOARGS,
+ "Unlocks the sound device."
+ },
+ {"setVolume", (PyCFunction)Device_setSourceVolume, METH_VARARGS,
+ "Sets the volume of a source."
+ },
+ {"getVolume", (PyCFunction)Device_getSourceVolume, METH_O,
+ "Gets the volume of a source."
+ },
+ {"setLoopCount", (PyCFunction)Device_setLoopCount, METH_VARARGS,
+ "Sets the loop count of a source."
+ },
+ {"setPitch", (PyCFunction)Device_setPitch, METH_VARARGS,
+ "Sets the pitch of a source."
+ },
+ {"play3D", (PyCFunction)Device_play3D, METH_VARARGS | METH_KEYWORDS,
+ "Plays a sound 3 dimensional if possible."
+ },
+ {"updateListener", (PyCFunction)Device_updateListener, METH_VARARGS,
+ "Updates the listener's position, velocity and orientation."
+ },
+ {"updateSource", (PyCFunction)Device_updateSource, METH_VARARGS,
+ "Updates the soucre's position, velocity and orientation."
+ },
+ {"isRelative", (PyCFunction)Device_isRelative, METH_O,
+ "Checks whether the source's position is relative or absolute to the listener."
+ },
+ {"setRelative", (PyCFunction)Device_setRelative, METH_VARARGS,
+ "Sets whether the source's position is relative or absolute to the listener."
+ },
+ {"getMinGain", (PyCFunction)Device_getMinGain, METH_O,
+ "Gets the minimum gain of a source."
+ },
+ {"setMinGain", (PyCFunction)Device_setMinGain, METH_VARARGS,
+ "Sets the minimum gain of a source."
+ },
+ {"getMaxGain", (PyCFunction)Device_getMaxGain, METH_O,
+ "Gets the maximum gain of a source."
+ },
+ {"setMaxGain", (PyCFunction)Device_setMaxGain, METH_VARARGS,
+ "Sets the maximum gain of a source."
+ },
+ {"getReferenceDistance", (PyCFunction)Device_getReferenceDistance, METH_O,
+ "Gets the reference distance of a source."
+ },
+ {"setReferenceDistance", (PyCFunction)Device_setReferenceDistance, METH_VARARGS,
+ "Sets the reference distance of a source."
+ },
+ {"getMaxDistance", (PyCFunction)Device_getMaxDistance, METH_O,
+ "Gets the maximum distance of a source."
+ },
+ {"setMaxDistance", (PyCFunction)Device_setMaxDistance, METH_VARARGS,
+ "Sets the maximum distance of a source."
+ },
+ {"getRolloffFactor", (PyCFunction)Device_getRolloffFactor, METH_O,
+ "Gets the rolloff factor of a source."
+ },
+ {"setRolloffFactor", (PyCFunction)Device_setRolloffFactor, METH_VARARGS,
+ "Sets the rolloff factor of a source."
+ },
+ {"getConeInnerAngle", (PyCFunction)Device_getConeInnerAngle, METH_O,
+ "Gets the cone inner angle of a source."
+ },
+ {"setConeInnerAngle", (PyCFunction)Device_setConeInnerAngle, METH_VARARGS,
+ "Sets the cone inner angle of a source."
+ },
+ {"getConeOuterAngle", (PyCFunction)Device_getConeOuterAngle, METH_O,
+ "Gets the cone outer angle of a source."
+ },
+ {"setConeOuterAngle", (PyCFunction)Device_setConeOuterAngle, METH_VARARGS,
+ "Sets the cone outer angle of a source."
+ },
+ {"getConeOuterGain", (PyCFunction)Device_getConeOuterGain, METH_O,
+ "Gets the cone outer gain of a source."
+ },
+ {"setConeOuterGain", (PyCFunction)Device_setConeOuterGain, METH_VARARGS,
+ "Sets the cone outer gain of a source."
+ },
+ {"OpenAL", (PyCFunction)Device_OpenAL, METH_VARARGS | METH_STATIC | METH_KEYWORDS,
+ "Creates an OpenAL device."
+ },
+ {"SDL", (PyCFunction)Device_SDL, METH_VARARGS | METH_STATIC | METH_KEYWORDS,
+ "Creates an SDL device."
+ },
+ {"Jack", (PyCFunction)Device_Jack, METH_VARARGS | METH_STATIC | METH_KEYWORDS,
+ "Creates an Jack device."
+ },
+ {"Null", (PyCFunction)Device_Null, METH_NOARGS | METH_STATIC,
+ "Creates an Null device."
+ },
+ {NULL} /* Sentinel */
+};
+
+static PyObject *
+Device_getRate(Device *self, void* nothing)
+{
+ try
+ {
+ AUD_DeviceSpecs specs = self->device->getSpecs();
+ return Py_BuildValue("i", specs.rate);
+ }
+ catch(AUD_Exception&)
+ {
+ PyErr_SetString(AUDError, "Couldn't retrieve device stats!");
+ return NULL;
+ }
+}
+
+static PyObject *
+Device_getFormat(Device *self, void* nothing)
+{
+ try
+ {
+ AUD_DeviceSpecs specs = self->device->getSpecs();
+ return Py_BuildValue("i", specs.format);
+ }
+ catch(AUD_Exception&)
+ {
+ PyErr_SetString(AUDError, "Couldn't retrieve device stats!");
+ return NULL;
+ }
+}
+
+static PyObject *
+Device_getChannels(Device *self, void* nothing)
+{
+ try
+ {
+ AUD_DeviceSpecs specs = self->device->getSpecs();
+ return Py_BuildValue("i", specs.channels);
+ }
+ catch(AUD_Exception&)
+ {
+ PyErr_SetString(AUDError, "Couldn't retrieve device stats!");
+ return NULL;
+ }
+}
+
+static PyObject *
+Device_getVolume(Device *self, void* nothing)
+{
+ try
+ {
+ float volume = 0.0;
+ if(self->device->getCapability(AUD_CAPS_VOLUME, &volume))
+ return Py_BuildValue("f", volume);
+ }
+ catch(AUD_Exception&)
+ {
+ PyErr_SetString(AUDError, "Couldn't retrieve device volume!");
+ return NULL;
+ }
+
+ Py_RETURN_NAN;
+}
+
+static int
+Device_setVolume(Device *self, PyObject* args, void* nothing)
+{
+ float volume;
+
+ if(!PyArg_Parse(args, "f", &volume))
+ return -1;
+
+ try
+ {
+ if(self->device->setCapability(AUD_CAPS_VOLUME, &volume))
+ return 0;
+ }
+ catch(AUD_Exception&)
+ {
+ PyErr_SetString(AUDError, "Couldn't set device volume!");
+ }
+
+ return -1;
+}
+
+static PyObject *
+Device_getSpeedOfSound(Device *self, void* nothing)
+{
+ try
+ {
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ if(device)
+ {
+ return Py_BuildValue("f", device->getSetting(AUD_3DS_SPEED_OF_SOUND));
+ }
+ else
+ {
+ PyErr_SetString(AUDError, "Device is not a 3D device!");
+ return NULL;
+ }
+ }
+ catch(AUD_Exception&)
+ {
+ PyErr_SetString(AUDError, "Couldn't retrieve device speed of sound!");
+ return NULL;
+ }
+}
+
+static int
+Device_setSpeedOfSound(Device *self, PyObject* args, void* nothing)
+{
+ float speed;
+
+ if(!PyArg_Parse(args, "f", &speed))
+ return -1;
+
+ try
+ {
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ if(device)
+ {
+ device->setSetting(AUD_3DS_SPEED_OF_SOUND, speed);
+ return 0;
+ }
+ else
+ {
+ PyErr_SetString(AUDError, "Device is not a 3D device!");
+ }
+ }
+ catch(AUD_Exception&)
+ {
+ PyErr_SetString(AUDError, "Couldn't set device speed of sound!");
+ }
+
+ return -1;
+}
+
+static PyObject *
+Device_getDopplerFactor(Device *self, void* nothing)
+{
+ try
+ {
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ if(device)
+ {
+ return Py_BuildValue("f", device->getSetting(AUD_3DS_DOPPLER_FACTOR));
+ }
+ else
+ {
+ PyErr_SetString(AUDError, "Device is not a 3D device!");
+ return NULL;
+ }
+ }
+ catch(AUD_Exception&)
+ {
+ PyErr_SetString(AUDError, "Couldn't retrieve device doppler factor!");
+ return NULL;
+ }
+}
+
+static int
+Device_setDopplerFactor(Device *self, PyObject* args, void* nothing)
+{
+ float factor;
+
+ if(!PyArg_Parse(args, "f", &factor))
+ return -1;
+
+ try
+ {
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ if(device)
+ {
+ device->setSetting(AUD_3DS_DOPPLER_FACTOR, factor);
+ return 0;
+ }
+ else
+ {
+ PyErr_SetString(AUDError, "Device is not a 3D device!");
+ }
+ }
+ catch(AUD_Exception&)
+ {
+ PyErr_SetString(AUDError, "Couldn't set device doppler factor!");
+ }
+
+ return -1;
+}
+
+static PyObject *
+Device_getDistanceModel(Device *self, void* nothing)
+{
+ try
+ {
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ if(device)
+ {
+ return Py_BuildValue("i", int(device->getSetting(AUD_3DS_DISTANCE_MODEL)));
+ }
+ else
+ {
+ PyErr_SetString(AUDError, "Device is not a 3D device!");
+ return NULL;
+ }
+ }
+ catch(AUD_Exception&)
+ {
+ PyErr_SetString(AUDError, "Couldn't retrieve device distance model!");
+ return NULL;
+ }
+}
+
+static int
+Device_setDistanceModel(Device *self, PyObject* args, void* nothing)
+{
+ int model;
+
+ if(!PyArg_Parse(args, "i", &model))
+ return -1;
+
+ try
+ {
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ if(device)
+ {
+ device->setSetting(AUD_3DS_DISTANCE_MODEL, model);
+ return 0;
+ }
+ else
+ {
+ PyErr_SetString(AUDError, "Device is not a 3D device!");
+ }
+ }
+ catch(AUD_Exception&)
+ {
+ PyErr_SetString(AUDError, "Couldn't set device distance model!");
+ }
+
+ return -1;
+}
+
+static PyGetSetDef Device_properties[] = {
+ {"rate", (getter)Device_getRate, NULL,
+ "The sampling rate of the device in Hz.", NULL },
+ {"format", (getter)Device_getFormat, NULL,
+ "The native sample format of the device.", NULL },
+ {"channels", (getter)Device_getChannels, NULL,
+ "The channel count of the device.", NULL },
+ {"volume", (getter)Device_getVolume, (setter)Device_setVolume,
+ "The overall volume of the device.", NULL },
+ {"speedofsound", (getter)Device_getSpeedOfSound, (setter)Device_setSpeedOfSound,
+ "The speed of sound of the device.", NULL },
+ {"dopplerfactor", (getter)Device_getDopplerFactor, (setter)Device_setDopplerFactor,
+ "The doppler factor of the device.", NULL },
+ {"distancemodel", (getter)Device_getDistanceModel, (setter)Device_setDistanceModel,
+ "The distance model of the device.", NULL },
+ {NULL} /* Sentinel */
+};
+
+static PyTypeObject DeviceType = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "aud.Device", /* tp_name */
+ sizeof(Device), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)Device_dealloc,/* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ "Device object", /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ Device_methods, /* tp_methods */
+ 0, /* tp_members */
+ Device_properties, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ 0, /* tp_new */
+};
+
+static PyObject *
+Device_OpenAL(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+#ifdef WITH_OPENAL
+ int buffersize = AUD_DEFAULT_BUFFER_SIZE;
+ int frequency = AUD_RATE_44100;
+
+ static char *kwlist[] = {"frequency", "buffersize", NULL};
+
+ if(!PyArg_ParseTupleAndKeywords(args, kwds, "|ii", kwlist, &frequency, &buffersize))
+ return NULL;
+
+ if(buffersize < 128)
+ {
+ PyErr_SetString(PyExc_ValueError, "buffersize must be greater than 127!");
+ return NULL;
+ }
+
+ Device *self;
+
+ self = (Device*)DeviceType.tp_alloc(&DeviceType, 0);
+ if(self != NULL)
+ {
+ try
+ {
+ AUD_DeviceSpecs specs;
+ specs.rate = static_cast<AUD_SampleRate>(frequency);
+ specs.channels = AUD_CHANNELS_STEREO;
+ specs.format = AUD_FORMAT_S16;
+ self->device = new AUD_OpenALDevice(specs, buffersize);
+ }
+ catch(AUD_Exception&)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, "OpenAL device couldn't be created!");
+ return NULL;
+ }
+ }
+
+ return (PyObject *)self;
+#else
+ PyErr_SetString(AUDError, "OpenAL device couldn't be created!");
+ return NULL;
+#endif
+}
+
+static PyObject *
+Device_SDL(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+#ifdef WITH_SDL
+ int buffersize = AUD_DEFAULT_BUFFER_SIZE;
+ int frequency = AUD_RATE_44100;
+
+ static char *kwlist[] = {"frequency", "buffersize", NULL};
+
+ if(!PyArg_ParseTupleAndKeywords(args, kwds, "|ii", kwlist, &frequency, &buffersize))
+ return NULL;
+
+ if(buffersize < 128)
+ {
+ PyErr_SetString(PyExc_ValueError, "buffersize must be greater than 127!");
+ return NULL;
+ }
+
+ Device *self;
+
+ self = (Device*)DeviceType.tp_alloc(&DeviceType, 0);
+ if(self != NULL)
+ {
+ try
+ {
+ AUD_DeviceSpecs specs;
+ specs.rate = static_cast<AUD_SampleRate>(frequency);
+ specs.channels = AUD_CHANNELS_STEREO;
+ specs.format = AUD_FORMAT_S16;
+ self->device = new AUD_SDLDevice(specs, buffersize);
+ }
+ catch(AUD_Exception&)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, "SDL device couldn't be created!");
+ return NULL;
+ }
+ }
+
+ return (PyObject *)self;
+#else
+ PyErr_SetString(AUDError, "SDL device couldn't be created!");
+ return NULL;
+#endif
+}
+
+static PyObject *
+Device_Jack(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+#ifdef WITH_JACK
+ int buffersize = AUD_DEFAULT_BUFFER_SIZE;
+ int channels = AUD_CHANNELS_STEREO;
+
+ static char *kwlist[] = {"channels", "buffersize", NULL};
+
+ if(!PyArg_ParseTupleAndKeywords(args, kwds, "|ii", kwlist, &channels, &buffersize))
+ return NULL;
+
+ if(buffersize < 128)
+ {
+ PyErr_SetString(PyExc_ValueError, "buffersize must be greater than 127!");
+ return NULL;
+ }
+
+ Device *self;
+
+ self = (Device*)DeviceType.tp_alloc(&DeviceType, 0);
+ if(self != NULL)
+ {
+ try
+ {
+ AUD_DeviceSpecs specs;
+ specs.rate = AUD_RATE_44100;
+ specs.channels = static_cast<AUD_Channels>(channels);
+ specs.format = AUD_FORMAT_FLOAT32;
+ self->device = new AUD_JackDevice(specs, buffersize);
+ }
+ catch(AUD_Exception&)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, "Jack device couldn't be created!");
+ return NULL;
+ }
+ }
+
+ return (PyObject *)self;
+#else
+ PyErr_SetString(AUDError, "Jack device couldn't be created!");
+ return NULL;
+#endif
+}
+
+static PyObject *
+Device_Null(PyTypeObject *type)
+{
+ Device *self;
+
+ self = (Device*)DeviceType.tp_alloc(&DeviceType, 0);
+ if(self != NULL)
+ {
+ try
+ {
+ self->device = new AUD_NULLDevice();
+ }
+ catch(AUD_Exception&)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, "Null device couldn't be created!");
+ return NULL;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+PyObject *
+Device_empty()
+{
+ return DeviceType.tp_alloc(&DeviceType, 0);
+}
+
+// ====================================================================
+
+static struct PyModuleDef audmodule = {
+ PyModuleDef_HEAD_INIT,
+ "aud", /* name of module */
+ NULL, /* module documentation, may be NULL */
+ -1, /* size of per-interpreter state of the module,
+ or -1 if the module keeps state in global variables. */
+ NULL, NULL, NULL, NULL, NULL
+};
+
+PyMODINIT_FUNC
+PyInit_aud(void)
+{
+ PyObject* m;
+
+ if(PyType_Ready(&SoundType) < 0)
+ return NULL;
+
+ if(PyType_Ready(&DeviceType) < 0)
+ return NULL;
+
+ if(PyType_Ready(&HandleType) < 0)
+ return NULL;
+
+ m = PyModule_Create(&audmodule);
+ if(m == NULL)
+ return NULL;
+
+ Py_INCREF(&SoundType);
+ PyModule_AddObject(m, "Sound", (PyObject*)&SoundType);
+
+ Py_INCREF(&DeviceType);
+ PyModule_AddObject(m, "Device", (PyObject*)&DeviceType);
+
+ Py_INCREF(&HandleType);
+ PyModule_AddObject(m, "Handle", (PyObject*)&HandleType);
+
+ AUDError = PyErr_NewException("aud.error", NULL, NULL);
+ Py_INCREF(AUDError);
+ PyModule_AddObject(m, "error", AUDError);
+
+ // format constants
+ PY_MODULE_ADD_CONSTANT(m, AUD_FORMAT_FLOAT32);
+ PY_MODULE_ADD_CONSTANT(m, AUD_FORMAT_FLOAT64);
+ PY_MODULE_ADD_CONSTANT(m, AUD_FORMAT_INVALID);
+ PY_MODULE_ADD_CONSTANT(m, AUD_FORMAT_S16);
+ PY_MODULE_ADD_CONSTANT(m, AUD_FORMAT_S24);
+ PY_MODULE_ADD_CONSTANT(m, AUD_FORMAT_S32);
+ PY_MODULE_ADD_CONSTANT(m, AUD_FORMAT_U8);
+ // status constants
+ PY_MODULE_ADD_CONSTANT(m, AUD_STATUS_INVALID);
+ PY_MODULE_ADD_CONSTANT(m, AUD_STATUS_PAUSED);
+ PY_MODULE_ADD_CONSTANT(m, AUD_STATUS_PLAYING);
+ // distance model constants
+ PY_MODULE_ADD_CONSTANT(m, AUD_DISTANCE_MODEL_EXPONENT);
+ PY_MODULE_ADD_CONSTANT(m, AUD_DISTANCE_MODEL_EXPONENT_CLAMPED);
+ PY_MODULE_ADD_CONSTANT(m, AUD_DISTANCE_MODEL_INVERSE);
+ 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);
+
+ return m;
+}
diff --git a/intern/audaspace/Python/AUD_PyAPI.h b/intern/audaspace/Python/AUD_PyAPI.h
new file mode 100644
index 00000000000..f7a86e1ca19
--- /dev/null
+++ b/intern/audaspace/Python/AUD_PyAPI.h
@@ -0,0 +1,67 @@
+/*
+ * $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_PYAPI
+#define AUD_PYAPI
+
+#include "Python.h"
+
+#ifdef __cplusplus
+extern "C" {
+#include "AUD_IDevice.h"
+#else
+typedef void AUD_IFactory;
+typedef void AUD_IDevice;
+typedef void AUD_Handle;
+#endif
+
+typedef struct {
+ PyObject_HEAD
+ PyObject* child_list;
+ AUD_IFactory* factory;
+} Sound;
+
+typedef struct {
+ PyObject_HEAD
+ AUD_Handle* handle;
+ PyObject* device;
+} Handle;
+
+typedef struct {
+ PyObject_HEAD
+ AUD_IDevice* device;
+} Device;
+
+PyMODINIT_FUNC
+PyInit_aud(void);
+
+extern PyObject *
+Device_empty();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //AUD_PYAPI
diff --git a/intern/audaspace/SConscript b/intern/audaspace/SConscript
index bbd2442c480..35c457aad4e 100644
--- a/intern/audaspace/SConscript
+++ b/intern/audaspace/SConscript
@@ -36,6 +36,11 @@ if env['WITH_BF_FFTW3']:
incs += ' fftw ' + env['BF_FFTW3_INC']
defs.append('WITH_FFTW3')
+if env['WITH_BF_PYTHON']:
+ sources += env.Glob('Python/*.cpp')
+ incs += ' Python ' + env['BF_PYTHON_INC']
+ defs.append('WITH_PYTHON')
+
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
incs += ' ' + env['BF_PTHREADS_INC']
diff --git a/intern/audaspace/intern/AUD_C-API.cpp b/intern/audaspace/intern/AUD_C-API.cpp
index 8740f62c9a7..21294ce5df5 100644
--- a/intern/audaspace/intern/AUD_C-API.cpp
+++ b/intern/audaspace/intern/AUD_C-API.cpp
@@ -23,11 +23,18 @@
* ***** END LGPL LICENSE BLOCK *****
*/
+#ifdef WITH_PYTHON
+#include "AUD_PyAPI.h"
+
+Device* g_device;
+bool g_pyinitialized = false;
+#endif
+
#include <cstdlib>
#include <cstring>
#include <cmath>
-#ifdef WITH_FFMPEG
+#ifndef __STDC_CONSTANT_MACROS
// needed for INT64_C
#define __STDC_CONSTANT_MACROS
#endif
@@ -78,6 +85,7 @@ extern "C" {
typedef AUD_IFactory AUD_Sound;
typedef AUD_ReadDevice AUD_Device;
+typedef AUD_Handle AUD_Channel;
#define AUD_CAPI_IMPLEMENTATION
#include "AUD_C-API.h"
@@ -134,6 +142,17 @@ int AUD_init(AUD_DeviceType device, AUD_DeviceSpecs specs, int buffersize)
if(AUD_device->checkCapability(AUD_CAPS_3D_DEVICE))
AUD_3ddevice = dynamic_cast<AUD_I3DDevice*>(AUD_device);
+#ifdef WITH_PYTHON
+ if(g_pyinitialized)
+ {
+ g_device = (Device*)Device_empty();
+ if(g_device != NULL)
+ {
+ g_device->device = dev;
+ }
+ }
+#endif
+
return true;
}
catch(AUD_Exception)
@@ -160,13 +179,51 @@ int* AUD_enumDevices()
void AUD_exit()
{
- if(AUD_device)
+#ifdef WITH_PYTHON
+ if(g_device)
{
+ Py_XDECREF(g_device);
+ g_device = NULL;
+ }
+ else
+#endif
+ if(AUD_device)
delete AUD_device;
- AUD_device = NULL;
- AUD_3ddevice = NULL;
+ AUD_device = NULL;
+ AUD_3ddevice = NULL;
+}
+
+#ifdef WITH_PYTHON
+static PyObject* AUD_getCDevice(PyObject* self)
+{
+ if(g_device)
+ {
+ Py_INCREF(g_device);
+ return (PyObject*)g_device;
+ }
+ Py_RETURN_NONE;
+}
+
+static PyMethodDef meth_getcdevice[] = {{ "getCDevice", (PyCFunction)AUD_getCDevice, METH_NOARGS, "Returns the C API Device."}};
+
+PyObject* AUD_initPython()
+{
+ PyObject* module = PyInit_aud();
+ PyModule_AddObject(module, "getCDevice", (PyObject *)PyCFunction_New(meth_getcdevice, NULL));
+ PyDict_SetItemString(PySys_GetObject("modules"), "aud", module);
+ if(AUD_device)
+ {
+ g_device = (Device*)Device_empty();
+ if(g_device != NULL)
+ {
+ g_device->device = AUD_device;
+ }
}
+ g_pyinitialized = true;
+
+ return module;
}
+#endif
void AUD_lock()
{
@@ -285,7 +342,7 @@ AUD_Sound* AUD_loopSound(AUD_Sound* sound)
}
}
-int AUD_setLoop(AUD_Handle* handle, int loops, float time)
+int AUD_setLoop(AUD_Channel* handle, int loops, float time)
{
if(handle)
{
@@ -325,7 +382,7 @@ void AUD_unload(AUD_Sound* sound)
delete sound;
}
-AUD_Handle* AUD_play(AUD_Sound* sound, int keep)
+AUD_Channel* AUD_play(AUD_Sound* sound, int keep)
{
assert(AUD_device);
assert(sound);
@@ -339,50 +396,50 @@ AUD_Handle* AUD_play(AUD_Sound* sound, int keep)
}
}
-int AUD_pause(AUD_Handle* handle)
+int AUD_pause(AUD_Channel* handle)
{
assert(AUD_device);
return AUD_device->pause(handle);
}
-int AUD_resume(AUD_Handle* handle)
+int AUD_resume(AUD_Channel* handle)
{
assert(AUD_device);
return AUD_device->resume(handle);
}
-int AUD_stop(AUD_Handle* handle)
+int AUD_stop(AUD_Channel* handle)
{
if(AUD_device)
return AUD_device->stop(handle);
return false;
}
-int AUD_setKeep(AUD_Handle* handle, int keep)
+int AUD_setKeep(AUD_Channel* handle, int keep)
{
assert(AUD_device);
return AUD_device->setKeep(handle, keep);
}
-int AUD_seek(AUD_Handle* handle, float seekTo)
+int AUD_seek(AUD_Channel* handle, float seekTo)
{
assert(AUD_device);
return AUD_device->seek(handle, seekTo);
}
-float AUD_getPosition(AUD_Handle* handle)
+float AUD_getPosition(AUD_Channel* handle)
{
assert(AUD_device);
return AUD_device->getPosition(handle);
}
-AUD_Status AUD_getStatus(AUD_Handle* handle)
+AUD_Status AUD_getStatus(AUD_Channel* handle)
{
assert(AUD_device);
return AUD_device->getStatus(handle);
}
-AUD_Handle* AUD_play3D(AUD_Sound* sound, int keep)
+AUD_Channel* AUD_play3D(AUD_Sound* sound, int keep)
{
assert(AUD_device);
assert(sound);
@@ -446,7 +503,7 @@ float AUD_get3DSetting(AUD_3DSetting setting)
return 0.0f;
}
-int AUD_update3DSource(AUD_Handle* handle, AUD_3DData* data)
+int AUD_update3DSource(AUD_Channel* handle, AUD_3DData* data)
{
if(handle)
{
@@ -465,7 +522,7 @@ int AUD_update3DSource(AUD_Handle* handle, AUD_3DData* data)
return false;
}
-int AUD_set3DSourceSetting(AUD_Handle* handle,
+int AUD_set3DSourceSetting(AUD_Channel* handle,
AUD_3DSourceSetting setting, float value)
{
if(handle)
@@ -484,7 +541,7 @@ int AUD_set3DSourceSetting(AUD_Handle* handle,
return false;
}
-float AUD_get3DSourceSetting(AUD_Handle* handle, AUD_3DSourceSetting setting)
+float AUD_get3DSourceSetting(AUD_Channel* handle, AUD_3DSourceSetting setting)
{
if(handle)
{
@@ -502,7 +559,7 @@ float AUD_get3DSourceSetting(AUD_Handle* handle, AUD_3DSourceSetting setting)
return 0.0f;
}
-int AUD_setSoundVolume(AUD_Handle* handle, float volume)
+int AUD_setSoundVolume(AUD_Channel* handle, float volume)
{
if(handle)
{
@@ -520,7 +577,7 @@ int AUD_setSoundVolume(AUD_Handle* handle, float volume)
return false;
}
-int AUD_setSoundPitch(AUD_Handle* handle, float pitch)
+int AUD_setSoundPitch(AUD_Channel* handle, float pitch)
{
if(handle)
{
@@ -550,14 +607,14 @@ AUD_Device* AUD_openReadDevice(AUD_DeviceSpecs specs)
}
}
-AUD_Handle* AUD_playDevice(AUD_Device* device, AUD_Sound* sound, float seek)
+AUD_Channel* AUD_playDevice(AUD_Device* device, AUD_Sound* sound, float seek)
{
assert(device);
assert(sound);
try
{
- AUD_Handle* handle = device->play(sound);
+ AUD_Channel* handle = device->play(sound);
device->seek(handle, seek);
return handle;
}
@@ -580,7 +637,7 @@ int AUD_setDeviceVolume(AUD_Device* device, float volume)
return false;
}
-int AUD_setDeviceSoundVolume(AUD_Device* device, AUD_Handle* handle,
+int AUD_setDeviceSoundVolume(AUD_Device* device, AUD_Channel* handle,
float volume)
{
if(handle)
@@ -789,7 +846,7 @@ void AUD_stopPlayback()
#endif
}
-void AUD_seekSequencer(AUD_Handle* handle, float time)
+void AUD_seekSequencer(AUD_Channel* handle, float time)
{
#ifdef WITH_JACK
AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device);
@@ -802,7 +859,7 @@ void AUD_seekSequencer(AUD_Handle* handle, float time)
}
}
-float AUD_getSequencerPosition(AUD_Handle* handle)
+float AUD_getSequencerPosition(AUD_Channel* handle)
{
#ifdef WITH_JACK
AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device);
diff --git a/intern/audaspace/intern/AUD_C-API.h b/intern/audaspace/intern/AUD_C-API.h
index 55aed02153f..83feb234a6e 100644
--- a/intern/audaspace/intern/AUD_C-API.h
+++ b/intern/audaspace/intern/AUD_C-API.h
@@ -26,6 +26,10 @@
#ifndef AUD_CAPI
#define AUD_CAPI
+#ifdef WITH_PYTHON
+#include "Python.h"
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -48,7 +52,7 @@ typedef struct
#ifndef AUD_CAPI_IMPLEMENTATION
typedef void AUD_Sound;
- typedef void AUD_Handle;
+ typedef void AUD_Channel;
typedef void AUD_Device;
typedef void AUD_SequencerEntry;
typedef float (*AUD_volumeFunction)(void*, void*, float);
@@ -80,6 +84,13 @@ extern int* AUD_enumDevices();
*/
extern void AUD_exit();
+#ifdef WITH_PYTHON
+/**
+ * Initalizes the Python module.
+ */
+extern PyObject* AUD_initPython();
+#endif
+
/**
* Locks the playback device.
*/
@@ -157,7 +168,7 @@ extern AUD_Sound* AUD_loopSound(AUD_Sound* sound);
* \param time The time after which playback should stop, -1 for infinity.
* \return Whether the handle is valid.
*/
-extern int AUD_setLoop(AUD_Handle* handle, int loops, float time);
+extern int AUD_setLoop(AUD_Channel* handle, int loops, float time);
/**
* Rectifies a sound.
@@ -179,28 +190,28 @@ extern void AUD_unload(AUD_Sound* sound);
* paused when its end has been reached.
* \return A handle to the played back sound.
*/
-extern AUD_Handle* AUD_play(AUD_Sound* sound, int keep);
+extern AUD_Channel* AUD_play(AUD_Sound* sound, int keep);
/**
* Pauses a played back sound.
* \param handle The handle to the sound.
* \return Whether the handle has been playing or not.
*/
-extern int AUD_pause(AUD_Handle* handle);
+extern int AUD_pause(AUD_Channel* handle);
/**
* Resumes a paused sound.
* \param handle The handle to the sound.
* \return Whether the handle has been paused or not.
*/
-extern int AUD_resume(AUD_Handle* handle);
+extern int AUD_resume(AUD_Channel* handle);
/**
* Stops a playing or paused sound.
* \param handle The handle to the sound.
* \return Whether the handle has been valid or not.
*/
-extern int AUD_stop(AUD_Handle* handle);
+extern int AUD_stop(AUD_Channel* handle);
/**
* Sets the end behaviour of a playing or paused sound.
@@ -209,7 +220,7 @@ extern int AUD_stop(AUD_Handle* handle);
* paused when its end has been reached.
* \return Whether the handle has been valid or not.
*/
-extern int AUD_setKeep(AUD_Handle* handle, int keep);
+extern int AUD_setKeep(AUD_Channel* handle, int keep);
/**
* Seeks a playing or paused sound.
@@ -217,7 +228,7 @@ extern int AUD_setKeep(AUD_Handle* handle, int keep);
* \param seekTo From where the sound file should be played back in seconds.
* \return Whether the handle has been valid or not.
*/
-extern int AUD_seek(AUD_Handle* handle, float seekTo);
+extern int AUD_seek(AUD_Channel* handle, float seekTo);
/**
* Retrieves the playback position of a handle.
@@ -225,14 +236,14 @@ extern int AUD_seek(AUD_Handle* handle, float seekTo);
* \return The current playback position in seconds or 0.0 if the handle is
* invalid.
*/
-extern float AUD_getPosition(AUD_Handle* handle);
+extern float AUD_getPosition(AUD_Channel* handle);
/**
* Returns the status of a playing, paused or stopped sound.
* \param handle The handle to the sound.
* \return The status of the sound behind the handle.
*/
-extern AUD_Status AUD_getStatus(AUD_Handle* handle);
+extern AUD_Status AUD_getStatus(AUD_Channel* handle);
/**
* Plays a 3D sound.
@@ -243,7 +254,7 @@ extern AUD_Status AUD_getStatus(AUD_Handle* handle);
* \note The factory must provide a mono (single channel) source and the device
* must support 3D audio, otherwise the sound is played back normally.
*/
-extern AUD_Handle* AUD_play3D(AUD_Sound* sound, int keep);
+extern AUD_Channel* AUD_play3D(AUD_Sound* sound, int keep);
/**
* Updates the listener 3D data.
@@ -273,7 +284,7 @@ extern float AUD_get3DSetting(AUD_3DSetting setting);
* \param data The 3D data.
* \return Whether the action succeeded.
*/
-extern int AUD_update3DSource(AUD_Handle* handle, AUD_3DData* data);
+extern int AUD_update3DSource(AUD_Channel* handle, AUD_3DData* data);
/**
* Sets a 3D source setting.
@@ -282,7 +293,7 @@ extern int AUD_update3DSource(AUD_Handle* handle, AUD_3DData* data);
* \param value The new setting value.
* \return Whether the action succeeded.
*/
-extern int AUD_set3DSourceSetting(AUD_Handle* handle,
+extern int AUD_set3DSourceSetting(AUD_Channel* handle,
AUD_3DSourceSetting setting, float value);
/**
@@ -291,7 +302,7 @@ extern int AUD_set3DSourceSetting(AUD_Handle* handle,
* \param setting The setting type.
* \return The setting value.
*/
-extern float AUD_get3DSourceSetting(AUD_Handle* handle,
+extern float AUD_get3DSourceSetting(AUD_Channel* handle,
AUD_3DSourceSetting setting);
/**
@@ -300,7 +311,7 @@ extern float AUD_get3DSourceSetting(AUD_Handle* handle,
* \param volume The new volume, must be between 0.0 and 1.0.
* \return Whether the action succeeded.
*/
-extern int AUD_setSoundVolume(AUD_Handle* handle, float volume);
+extern int AUD_setSoundVolume(AUD_Channel* handle, float volume);
/**
* Sets the pitch of a played back sound.
@@ -308,7 +319,7 @@ extern int AUD_setSoundVolume(AUD_Handle* handle, float volume);
* \param pitch The new pitch.
* \return Whether the action succeeded.
*/
-extern int AUD_setSoundPitch(AUD_Handle* handle, float pitch);
+extern int AUD_setSoundPitch(AUD_Channel* handle, float pitch);
/**
* Opens a read device, with which audio data can be read.
@@ -332,7 +343,7 @@ extern int AUD_setDeviceVolume(AUD_Device* device, float volume);
* \param seek The position where the sound should be seeked to.
* \return A handle to the played back sound.
*/
-extern AUD_Handle* AUD_playDevice(AUD_Device* device, AUD_Sound* sound, float seek);
+extern AUD_Channel* AUD_playDevice(AUD_Device* device, AUD_Sound* sound, float seek);
/**
* Sets the volume of a played back sound of a read device.
@@ -342,7 +353,7 @@ extern AUD_Handle* AUD_playDevice(AUD_Device* device, AUD_Sound* sound, float se
* \return Whether the action succeeded.
*/
extern int AUD_setDeviceSoundVolume(AUD_Device* device,
- AUD_Handle* handle,
+ AUD_Channel* handle,
float volume);
/**
@@ -393,9 +404,9 @@ extern void AUD_startPlayback();
extern void AUD_stopPlayback();
-extern void AUD_seekSequencer(AUD_Handle* handle, float time);
+extern void AUD_seekSequencer(AUD_Channel* handle, float time);
-extern float AUD_getSequencerPosition(AUD_Handle* handle);
+extern float AUD_getSequencerPosition(AUD_Channel* handle);
#ifdef WITH_JACK
extern void AUD_setSyncCallback(AUD_syncFunction function, void* data);
diff --git a/source/blender/python/CMakeLists.txt b/source/blender/python/CMakeLists.txt
index 3c79e9d3056..dcfc8678faa 100644
--- a/source/blender/python/CMakeLists.txt
+++ b/source/blender/python/CMakeLists.txt
@@ -36,6 +36,7 @@ SET(INC
../windowmanager
../editors/include
../../../intern/guardedalloc
+ ../../../intern/audaspace/intern
${PYTHON_INC}
)
diff --git a/source/blender/python/SConscript b/source/blender/python/SConscript
index ca742a3646a..d6c24eb3bfc 100644
--- a/source/blender/python/SConscript
+++ b/source/blender/python/SConscript
@@ -6,7 +6,7 @@ sources = env.Glob('intern/*.c')
incs = '. ../editors/include ../makesdna ../makesrna ../blenlib ../blenkernel ../nodes'
incs += ' ../imbuf ../blenloader ../render/extern/include ../windowmanager'
incs += ' #intern/guardedalloc #intern/memutil #extern/glew/include'
-incs += ' ' + env['BF_PYTHON_INC']
+incs += ' #intern/audaspace/intern ' + env['BF_PYTHON_INC']
defs = []
diff --git a/source/blender/python/intern/bpy.c b/source/blender/python/intern/bpy.c
index b978e46f6da..fb5c56f383e 100644
--- a/source/blender/python/intern/bpy.c
+++ b/source/blender/python/intern/bpy.c
@@ -41,6 +41,11 @@
#include "../generic/blf_api.h"
#include "../generic/IDProp.h"
+#ifndef DISABLE_PYTHON
+#define WITH_PYTHON
+#endif
+#include "AUD_C-API.h"
+
static char bpy_home_paths_doc[] =
".. function:: home_paths(subfolder)\n"
"\n"
@@ -162,7 +167,7 @@ void BPy_init_modules( void )
BGL_Init();
BLF_Init();
IDProp_Init_Types();
-
+ AUD_initPython();
mod = PyModule_New("_bpy");
diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp
index 5fe62a0e220..73d45eb97aa 100644
--- a/source/gameengine/Ketsji/KX_PythonInit.cpp
+++ b/source/gameengine/Ketsji/KX_PythonInit.cpp
@@ -45,6 +45,10 @@ extern "C" {
#include "marshal.h" /* python header for loading/saving dicts */
}
+
+#define WITH_PYTHON
+#include "AUD_C-API.h"
+
#endif
#include "KX_PythonInit.h"
@@ -1989,6 +1993,7 @@ void setupGamePython(KX_KetsjiEngine* ketsjiengine, KX_Scene* startscene, Main *
initGeometry();
initBGL();
initBLF();
+ AUD_initPython();
#ifdef WITH_FFMPEG
initVideoTexture();
diff --git a/source/gameengine/Ketsji/KX_SoundActuator.h b/source/gameengine/Ketsji/KX_SoundActuator.h
index 1eaea276191..ce7612d4bcb 100644
--- a/source/gameengine/Ketsji/KX_SoundActuator.h
+++ b/source/gameengine/Ketsji/KX_SoundActuator.h
@@ -58,7 +58,7 @@ class KX_SoundActuator : public SCA_IActuator
float m_pitch;
bool m_is3d;
KX_3DSoundSettings m_3d;
- AUD_Handle* m_handle;
+ AUD_Channel* m_handle;
void play();