diff options
-rw-r--r-- | intern/audaspace/CMakeLists.txt | 8 | ||||
-rw-r--r-- | intern/audaspace/Python/AUD_PyAPI.cpp | 3149 | ||||
-rw-r--r-- | intern/audaspace/Python/AUD_PyAPI.h | 67 | ||||
-rw-r--r-- | intern/audaspace/SConscript | 5 | ||||
-rw-r--r-- | intern/audaspace/intern/AUD_C-API.cpp | 105 | ||||
-rw-r--r-- | intern/audaspace/intern/AUD_C-API.h | 51 | ||||
-rw-r--r-- | source/blender/python/CMakeLists.txt | 1 | ||||
-rw-r--r-- | source/blender/python/SConscript | 2 | ||||
-rw-r--r-- | source/blender/python/intern/bpy.c | 7 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_PythonInit.cpp | 5 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_SoundActuator.h | 2 |
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(); |