diff options
Diffstat (limited to 'intern/audaspace/Python/AUD_PyAPI.cpp')
-rw-r--r-- | intern/audaspace/Python/AUD_PyAPI.cpp | 2918 |
1 files changed, 0 insertions, 2918 deletions
diff --git a/intern/audaspace/Python/AUD_PyAPI.cpp b/intern/audaspace/Python/AUD_PyAPI.cpp deleted file mode 100644 index 757131e44e2..00000000000 --- a/intern/audaspace/Python/AUD_PyAPI.cpp +++ /dev/null @@ -1,2918 +0,0 @@ -/* - * Copyright 2009-2011 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 General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Audaspace; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file audaspace/Python/AUD_PyAPI.cpp - * \ingroup audpython - */ - - -#include "AUD_PyAPI.h" -#include <structmember.h> - -#include "AUD_I3DDevice.h" -#include "AUD_I3DHandle.h" -#include "AUD_NULLDevice.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" -#include "AUD_IIRFilterFactory.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 - -// ==================================================================== - -typedef enum -{ - AUD_DEVICE_NULL = 0, - AUD_DEVICE_OPENAL, - AUD_DEVICE_SDL, - AUD_DEVICE_JACK, - AUD_DEVICE_READ, -} AUD_DeviceTypes; - -// ==================================================================== - -#define PY_MODULE_ADD_CONSTANT(module, name) PyModule_AddIntConstant(module, #name, name) - -// ==================================================================== - -static PyObject *AUDError; - -static const char* device_not_3d_error = "Device is not a 3D device!"; - -// ==================================================================== - -static void -Factory_dealloc(Factory* self) -{ - if(self->factory) - delete reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(self->factory); - Py_XDECREF(self->child_list); - Py_TYPE(self)->tp_free((PyObject *)self); -} - -static PyObject * -Factory_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - Factory *self; - - self = (Factory*)type->tp_alloc(type, 0); - if(self != NULL) - { - static const char *kwlist[] = {"filename", NULL}; - const char* filename = NULL; - - if(!PyArg_ParseTupleAndKeywords(args, kwds, "s:Factory", const_cast<char**>(kwlist), &filename)) - { - Py_DECREF(self); - return NULL; - } - - try - { - self->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_FileFactory(filename)); - } - catch(AUD_Exception& e) - { - Py_DECREF(self); - PyErr_SetString(AUDError, e.str); - return NULL; - } - } - - return (PyObject *)self; -} - -PyDoc_STRVAR(M_aud_Factory_sine_doc, - "sine(frequency, rate=48000)\n\n" - "Creates a sine factory which plays a sine wave.\n\n" - ":arg frequency: The frequency of the sine wave in Hz.\n" - ":type frequency: float\n" - ":arg rate: The sampling rate in Hz. It's recommended to set this " - "value to the playback device's samling rate to avoid resamping.\n" - ":type rate: int\n" - ":return: The created :class:`Factory` object.\n" - ":rtype: :class:`Factory`"); - -static PyObject * -Factory_sine(PyTypeObject* type, PyObject *args) -{ - float frequency; - double rate = 48000; - - if(!PyArg_ParseTuple(args, "f|d:sine", &frequency, &rate)) - return NULL; - - Factory *self; - - self = (Factory*)type->tp_alloc(type, 0); - if(self != NULL) - { - try - { - self->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_SinusFactory(frequency, (AUD_SampleRate)rate)); - } - catch(AUD_Exception& e) - { - Py_DECREF(self); - PyErr_SetString(AUDError, e.str); - return NULL; - } - } - - return (PyObject *)self; -} - -PyDoc_STRVAR(M_aud_Factory_file_doc, - "file(filename)\n\n" - "Creates a factory object of a sound file.\n\n" - ":arg filename: Path of the file.\n" - ":type filename: string\n" - ":return: The created :class:`Factory` object.\n" - ":rtype: :class:`Factory`\n\n" - ".. warning:: If the file doesn't exist or can't be read you will " - "not get an exception immediately, but when you try to start " - "playback of that factory."); - -static PyObject * -Factory_file(PyTypeObject* type, PyObject *args) -{ - const char* filename = NULL; - - if(!PyArg_ParseTuple(args, "s:file", &filename)) - return NULL; - - Factory *self; - - self = (Factory*)type->tp_alloc(type, 0); - if(self != NULL) - { - try - { - self->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_FileFactory(filename)); - } - catch(AUD_Exception& e) - { - Py_DECREF(self); - PyErr_SetString(AUDError, e.str); - return NULL; - } - } - - return (PyObject *)self; -} - -PyDoc_STRVAR(M_aud_Factory_lowpass_doc, - "lowpass(frequency, Q=0.5)\n\n" - "Creates a second order lowpass filter based on the transfer " - "function H(s) = 1 / (s^2 + s/Q + 1)\n\n" - ":arg frequency: The cut off trequency of the lowpass.\n" - ":type frequency: float\n" - ":arg Q: Q factor of the lowpass.\n" - ":type Q: float\n" - ":return: The created :class:`Factory` object.\n" - ":rtype: :class:`Factory`"); - -static PyObject * -Factory_lowpass(Factory* self, PyObject *args) -{ - float frequency; - float Q = 0.5; - - if(!PyArg_ParseTuple(args, "f|f:lowpass", &frequency, &Q)) - return NULL; - - PyTypeObject* type = Py_TYPE(self); - Factory *parent = (Factory*)type->tp_alloc(type, 0); - - if(parent != NULL) - { - Py_INCREF(self); - parent->child_list = (PyObject *)self; - - try - { - parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_LowpassFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(self->factory), frequency, Q)); - } - catch(AUD_Exception& e) - { - Py_DECREF(parent); - PyErr_SetString(AUDError, e.str); - return NULL; - } - } - - return (PyObject *)parent; -} - -PyDoc_STRVAR(M_aud_Factory_delay_doc, - "delay(time)\n\n" - "Delays by playing adding silence in front of the other factory's " - "data.\n\n" - ":arg time: How many seconds of silence should be added before " - "the factory.\n" - ":type time: float\n" - ":return: The created :class:`Factory` object.\n" - ":rtype: :class:`Factory`"); - -static PyObject * -Factory_delay(Factory* self, PyObject *args) -{ - float delay; - - if(!PyArg_ParseTuple(args, "f:delay", &delay)) - return NULL; - - PyTypeObject* type = Py_TYPE(self); - Factory *parent = (Factory*)type->tp_alloc(type, 0); - - if(parent != NULL) - { - Py_INCREF(self); - parent->child_list = (PyObject *)self; - - try - { - parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_DelayFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(self->factory), delay)); - } - catch(AUD_Exception& e) - { - Py_DECREF(parent); - PyErr_SetString(AUDError, e.str); - return NULL; - } - } - - return (PyObject *)parent; -} - -PyDoc_STRVAR(M_aud_Factory_join_doc, - "join(factory)\n\n" - "Plays two factories in sequence.\n\n" - ":arg factory: The factory to play second.\n" - ":type factory: :class:`Factory`\n" - ":return: The created :class:`Factory` object.\n" - ":rtype: :class:`Factory`\n\n" - ".. note:: The two factories have to have the same specifications " - "(channels and samplerate)."); - -static PyObject * -Factory_join(Factory* self, PyObject *object) -{ - PyTypeObject* type = Py_TYPE(self); - - if(!PyObject_TypeCheck(object, type)) - { - PyErr_SetString(PyExc_TypeError, "Object has to be of type Factory!"); - return NULL; - } - - Factory *parent; - Factory *child = (Factory*)object; - - parent = (Factory*)type->tp_alloc(type, 0); - if(parent != NULL) - { - parent->child_list = Py_BuildValue("(OO)", self, object); - - try - { - parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_DoubleFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(self->factory), *reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(child->factory))); - } - catch(AUD_Exception& e) - { - Py_DECREF(parent); - PyErr_SetString(AUDError, e.str); - return NULL; - } - } - - return (PyObject *)parent; -} - -PyDoc_STRVAR(M_aud_Factory_highpass_doc, - "highpass(frequency, Q=0.5)\n\n" - "Creates a second order highpass filter based on the transfer " - "function H(s) = s^2 / (s^2 + s/Q + 1)\n\n" - ":arg frequency: The cut off trequency of the highpass.\n" - ":type frequency: float\n" - ":arg Q: Q factor of the lowpass.\n" - ":type Q: float\n" - ":return: The created :class:`Factory` object.\n" - ":rtype: :class:`Factory`"); - -static PyObject * -Factory_highpass(Factory* self, PyObject *args) -{ - float frequency; - float Q = 0.5; - - if(!PyArg_ParseTuple(args, "f|f:highpass", &frequency, &Q)) - return NULL; - - PyTypeObject* type = Py_TYPE(self); - Factory *parent = (Factory*)type->tp_alloc(type, 0); - - if(parent != NULL) - { - Py_INCREF(self); - parent->child_list = (PyObject *)self; - - try - { - parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_HighpassFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(self->factory), frequency, Q)); - } - catch(AUD_Exception& e) - { - Py_DECREF(parent); - PyErr_SetString(AUDError, e.str); - return NULL; - } - } - - return (PyObject *)parent; -} - -PyDoc_STRVAR(M_aud_Factory_limit_doc, - "limit(start, end)\n\n" - "Limits a factory within a specific start and end time.\n\n" - ":arg start: Start time in seconds.\n" - ":type start: float\n" - ":arg end: End time in seconds.\n" - ":type end: float\n" - ":return: The created :class:`Factory` object.\n" - ":rtype: :class:`Factory`"); - -static PyObject * -Factory_limit(Factory* self, PyObject *args) -{ - float start, end; - - if(!PyArg_ParseTuple(args, "ff:limit", &start, &end)) - return NULL; - - PyTypeObject* type = Py_TYPE(self); - Factory *parent = (Factory*)type->tp_alloc(type, 0); - - if(parent != NULL) - { - Py_INCREF(self); - parent->child_list = (PyObject *)self; - - try - { - parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_LimiterFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(self->factory), start, end)); - } - catch(AUD_Exception& e) - { - Py_DECREF(parent); - PyErr_SetString(AUDError, e.str); - return NULL; - } - } - - return (PyObject *)parent; -} - -PyDoc_STRVAR(M_aud_Factory_pitch_doc, - "pitch(factor)\n\n" - "Changes the pitch of a factory with a specific factor.\n\n" - ":arg factor: The factor to change the pitch with.\n" - ":type factor: float\n" - ":return: The created :class:`Factory` object.\n" - ":rtype: :class:`Factory`\n\n" - ".. note:: This is done by changing the sample rate of the " - "underlying factory, which has to be an integer, so the factor " - "value rounded and the factor may not be 100 % accurate.\n\n" - ".. note:: This is a filter function, you might consider using " - ":attr:`Handle.pitch` instead."); - -static PyObject * -Factory_pitch(Factory* self, PyObject *args) -{ - float factor; - - if(!PyArg_ParseTuple(args, "f:pitch", &factor)) - return NULL; - - PyTypeObject* type = Py_TYPE(self); - Factory *parent = (Factory*)type->tp_alloc(type, 0); - - if(parent != NULL) - { - Py_INCREF(self); - parent->child_list = (PyObject *)self; - - try - { - parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_PitchFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(self->factory), factor)); - } - catch(AUD_Exception& e) - { - Py_DECREF(parent); - PyErr_SetString(AUDError, e.str); - return NULL; - } - } - - return (PyObject *)parent; -} - -PyDoc_STRVAR(M_aud_Factory_volume_doc, - "volume(volume)\n\n" - "Changes the volume of a factory.\n\n" - ":arg volume: The new volume..\n" - ":type volume: float\n" - ":return: The created :class:`Factory` object.\n" - ":rtype: :class:`Factory`\n\n" - ".. note:: Should be in the range [0, 1] to avoid clipping.\n\n" - ".. note:: This is a filter function, you might consider using " - ":attr:`Handle.volume` instead."); - -static PyObject * -Factory_volume(Factory* self, PyObject *args) -{ - float volume; - - if(!PyArg_ParseTuple(args, "f:volume", &volume)) - return NULL; - - PyTypeObject* type = Py_TYPE(self); - Factory *parent = (Factory*)type->tp_alloc(type, 0); - - if(parent != NULL) - { - Py_INCREF(self); - parent->child_list = (PyObject *)self; - - try - { - parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_VolumeFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(self->factory), volume)); - } - catch(AUD_Exception& e) - { - Py_DECREF(parent); - PyErr_SetString(AUDError, e.str); - return NULL; - } - } - - return (PyObject *)parent; -} - -PyDoc_STRVAR(M_aud_Factory_fadein_doc, - "fadein(start, length)\n\n" - "Fades a factory in by raising the volume linearly in the given " - "time interval.\n\n" - ":arg start: Time in seconds when the fading should start.\n" - ":type start: float\n" - ":arg length: Time in seconds how long the fading should last.\n" - ":type length: float\n" - ":return: The created :class:`Factory` object.\n" - ":rtype: :class:`Factory`\n\n" - ".. note:: Before the fade starts it plays silence."); - -static PyObject * -Factory_fadein(Factory* self, PyObject *args) -{ - float start, length; - - if(!PyArg_ParseTuple(args, "ff:fadein", &start, &length)) - return NULL; - - PyTypeObject* type = Py_TYPE(self); - Factory *parent = (Factory*)type->tp_alloc(type, 0); - - if(parent != NULL) - { - Py_INCREF(self); - parent->child_list = (PyObject *)self; - - try - { - parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_FaderFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(self->factory), AUD_FADE_IN, start, length)); - } - catch(AUD_Exception& e) - { - Py_DECREF(parent); - PyErr_SetString(AUDError, e.str); - return NULL; - } - } - - return (PyObject *)parent; -} - -PyDoc_STRVAR(M_aud_Factory_fadeout_doc, - "fadeout(start, length)\n\n" - "Fades a factory in by lowering the volume linearly in the given " - "time interval.\n\n" - ":arg start: Time in seconds when the fading should start.\n" - ":type start: float\n" - ":arg length: Time in seconds how long the fading should last.\n" - ":type length: float\n" - ":return: The created :class:`Factory` object.\n" - ":rtype: :class:`Factory`\n\n" - ".. note:: After the fade this factory plays silence, so that " - "the length of the factory is not altered."); - -static PyObject * -Factory_fadeout(Factory* self, PyObject *args) -{ - float start, length; - - if(!PyArg_ParseTuple(args, "ff:fadeout", &start, &length)) - return NULL; - - PyTypeObject* type = Py_TYPE(self); - Factory *parent = (Factory*)type->tp_alloc(type, 0); - - if(parent != NULL) - { - Py_INCREF(self); - parent->child_list = (PyObject *)self; - - try - { - parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_FaderFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(self->factory), AUD_FADE_OUT, start, length)); - } - catch(AUD_Exception& e) - { - Py_DECREF(parent); - PyErr_SetString(AUDError, e.str); - return NULL; - } - } - - return (PyObject *)parent; -} - -PyDoc_STRVAR(M_aud_Factory_loop_doc, - "loop(count)\n\n" - "Loops a factory.\n\n" - ":arg count: How often the factory should be looped. " - "Negative values mean endlessly.\n" - ":type count: integer\n" - ":return: The created :class:`Factory` object.\n" - ":rtype: :class:`Factory`\n\n" - ".. note:: This is a filter function, you might consider using " - ":attr:`Handle.loop_count` instead."); - -static PyObject * -Factory_loop(Factory* self, PyObject *args) -{ - int loop; - - if(!PyArg_ParseTuple(args, "i:loop", &loop)) - return NULL; - - PyTypeObject* type = Py_TYPE(self); - Factory *parent = (Factory*)type->tp_alloc(type, 0); - - if(parent != NULL) - { - Py_INCREF(self); - parent->child_list = (PyObject *)self; - - try - { - parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_LoopFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(self->factory), loop)); - } - catch(AUD_Exception& e) - { - Py_DECREF(parent); - PyErr_SetString(AUDError, e.str); - return NULL; - } - } - - return (PyObject *)parent; -} - -PyDoc_STRVAR(M_aud_Factory_mix_doc, - "mix(factory)\n\n" - "Mixes two factories.\n\n" - ":arg factory: The factory to mix over the other.\n" - ":type factory: :class:`Factory`\n" - ":return: The created :class:`Factory` object.\n" - ":rtype: :class:`Factory`\n\n" - ".. note:: The two factories have to have the same specifications " - "(channels and samplerate)."); - -static PyObject * -Factory_mix(Factory* self, PyObject *object) -{ - PyTypeObject* type = Py_TYPE(self); - - if(!PyObject_TypeCheck(object, type)) - { - PyErr_SetString(PyExc_TypeError, "Object is not of type Factory!"); - return NULL; - } - - Factory *parent = (Factory*)type->tp_alloc(type, 0); - Factory *child = (Factory*)object; - - if(parent != NULL) - { - parent->child_list = Py_BuildValue("(OO)", self, object); - - try - { - parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_SuperposeFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(self->factory), *reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(child->factory))); - } - catch(AUD_Exception& e) - { - Py_DECREF(parent); - PyErr_SetString(AUDError, e.str); - return NULL; - } - } - - return (PyObject *)parent; -} - -PyDoc_STRVAR(M_aud_Factory_pingpong_doc, - "pingpong()\n\n" - "Plays a factory forward and then backward.\n" - "This is like joining a factory with its reverse.\n\n" - ":return: The created :class:`Factory` object.\n" - ":rtype: :class:`Factory`"); - -static PyObject * -Factory_pingpong(Factory* self) -{ - PyTypeObject* type = Py_TYPE(self); - Factory *parent = (Factory*)type->tp_alloc(type, 0); - - if(parent != NULL) - { - Py_INCREF(self); - parent->child_list = (PyObject *)self; - - try - { - parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_PingPongFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(self->factory))); - } - catch(AUD_Exception& e) - { - Py_DECREF(parent); - PyErr_SetString(AUDError, e.str); - return NULL; - } - } - - return (PyObject *)parent; -} - -PyDoc_STRVAR(M_aud_Factory_reverse_doc, - "reverse()\n\n" - "Plays a factory reversed.\n\n" - ":return: The created :class:`Factory` object.\n" - ":rtype: :class:`Factory`\n\n" - ".. note:: The factory has to have a finite length and has to be " - "seekable. It's recommended to use this only with factories with " - "fast and accurate seeking, which is not true for encoded audio " - "files, such ones should be buffered using :meth:`buffer` before " - "being played reversed.\n\n" - ".. warning:: If seeking is not accurate in the underlying factory " - "you'll likely hear skips/jumps/cracks."); - -static PyObject * -Factory_reverse(Factory* self) -{ - PyTypeObject* type = Py_TYPE(self); - Factory *parent = (Factory*)type->tp_alloc(type, 0); - - if(parent != NULL) - { - Py_INCREF(self); - parent->child_list = (PyObject *)self; - - try - { - parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_ReverseFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(self->factory))); - } - catch(AUD_Exception& e) - { - Py_DECREF(parent); - PyErr_SetString(AUDError, e.str); - return NULL; - } - } - - return (PyObject *)parent; -} - -PyDoc_STRVAR(M_aud_Factory_buffer_doc, - "buffer()\n\n" - "Buffers a factory into RAM.\n" - "This saves CPU usage needed for decoding and file access if the " - "underlying factory reads from a file on the harddisk, but it " - "consumes a lot of memory.\n\n" - ":return: The created :class:`Factory` object.\n" - ":rtype: :class:`Factory`\n\n" - ".. note:: Only known-length factories can be buffered.\n\n" - ".. warning:: Raw PCM data needs a lot of space, only buffer " - "short factories."); - -static PyObject * -Factory_buffer(Factory* self) -{ - PyTypeObject* type = Py_TYPE(self); - Factory *parent = (Factory*)type->tp_alloc(type, 0); - - if(parent != NULL) - { - try - { - parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_StreamBufferFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(self->factory))); - } - catch(AUD_Exception& e) - { - Py_DECREF(parent); - PyErr_SetString(AUDError, e.str); - return NULL; - } - } - - return (PyObject *)parent; -} - -PyDoc_STRVAR(M_aud_Factory_square_doc, - "square(threshold = 0)\n\n" - "Makes a square wave out of an audio wave by setting all samples " - "with a amplitude >= threshold to 1, all <= -threshold to -1 and " - "all between to 0.\n\n" - ":arg threshold: Threshold value over which an amplitude counts " - "non-zero.\n" - ":type threshold: float\n" - ":return: The created :class:`Factory` object.\n" - ":rtype: :class:`Factory`"); - -static PyObject * -Factory_square(Factory* self, PyObject *args) -{ - float threshold = 0; - - if(!PyArg_ParseTuple(args, "|f:square", &threshold)) - return NULL; - - PyTypeObject* type = Py_TYPE(self); - Factory *parent = (Factory*)type->tp_alloc(type, 0); - - if(parent != NULL) - { - Py_INCREF(self); - parent->child_list = (PyObject *)self; - - try - { - parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_SquareFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(self->factory), threshold)); - } - catch(AUD_Exception& e) - { - Py_DECREF(parent); - PyErr_SetString(AUDError, e.str); - return NULL; - } - } - - return (PyObject *)parent; -} - -PyDoc_STRVAR(M_aud_Factory_filter_doc, - "filter(b, a = (1))\n\n" - "Filters a factory with the supplied IIR filter coefficients.\n" - "Without the second parameter you'll get a FIR filter.\n" - "If the first value of the a sequence is 0 it will be set to 1 " - "automatically.\n" - "If the first value of the a sequence is neither 0 nor 1, all " - "filter coefficients will be scaled by this value so that it is 1 " - "in the end, you don't have to scale yourself.\n\n" - ":arg b: The nominator filter coefficients.\n" - ":type b: sequence of float\n" - ":arg a: The denominator filter coefficients.\n" - ":type a: sequence of float\n" - ":return: The created :class:`Factory` object.\n" - ":rtype: :class:`Factory`"); - -static PyObject * -Factory_filter(Factory* self, PyObject *args) -{ - PyObject *py_b; - PyObject *py_a = NULL; - Py_ssize_t py_a_len; - Py_ssize_t py_b_len; - - if(!PyArg_ParseTuple(args, "O|O:filter", &py_b, &py_a)) - return NULL; - - if(!PySequence_Check(py_b) || (py_a != NULL && !PySequence_Check(py_a))) - { - PyErr_SetString(PyExc_TypeError, "Parameter is not a sequence!"); - return NULL; - } - - py_a_len= py_a ? PySequence_Size(py_a) : 0; - py_b_len= PySequence_Size(py_b); - - if(!py_b_len || ((py_a != NULL) && !py_a_len)) - { - PyErr_SetString(PyExc_ValueError, "The sequence has to contain at least one value!"); - return NULL; - } - - std::vector<float> a, b; - PyObject *py_value; - float value; - - for(Py_ssize_t i = 0; i < py_b_len; i++) - { - py_value = PySequence_GetItem(py_b, i); - value= (float)PyFloat_AsDouble(py_value); - Py_DECREF(py_value); - - if (value==-1.0f && PyErr_Occurred()) { - return NULL; - } - - b.push_back(value); - } - - if(py_a) - { - for(Py_ssize_t i = 0; i < py_a_len; i++) - { - py_value = PySequence_GetItem(py_a, i); - value= (float)PyFloat_AsDouble(py_value); - Py_DECREF(py_value); - - if (value==-1.0f && PyErr_Occurred()) { - return NULL; - } - - a.push_back(value); - } - - if(a[0] == 0) - a[0] = 1; - } - else - a.push_back(1); - - PyTypeObject* type = Py_TYPE(self); - Factory *parent = (Factory*)type->tp_alloc(type, 0); - - if(parent != NULL) - { - Py_INCREF(self); - parent->child_list = (PyObject *)self; - - try - { - parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_IIRFilterFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(self->factory), b, a)); - } - catch(AUD_Exception& e) - { - Py_DECREF(parent); - PyErr_SetString(AUDError, e.str); - return NULL; - } - } - - return (PyObject *)parent; -} - -static PyMethodDef Factory_methods[] = { - {"sine", (PyCFunction)Factory_sine, METH_VARARGS | METH_CLASS, - M_aud_Factory_sine_doc - }, - {"file", (PyCFunction)Factory_file, METH_VARARGS | METH_CLASS, - M_aud_Factory_file_doc - }, - {"lowpass", (PyCFunction)Factory_lowpass, METH_VARARGS, - M_aud_Factory_lowpass_doc - }, - {"delay", (PyCFunction)Factory_delay, METH_VARARGS, - M_aud_Factory_delay_doc - }, - {"join", (PyCFunction)Factory_join, METH_O, - M_aud_Factory_join_doc - }, - {"highpass", (PyCFunction)Factory_highpass, METH_VARARGS, - M_aud_Factory_highpass_doc - }, - {"limit", (PyCFunction)Factory_limit, METH_VARARGS, - M_aud_Factory_limit_doc - }, - {"pitch", (PyCFunction)Factory_pitch, METH_VARARGS, - M_aud_Factory_pitch_doc - }, - {"volume", (PyCFunction)Factory_volume, METH_VARARGS, - M_aud_Factory_volume_doc - }, - {"fadein", (PyCFunction)Factory_fadein, METH_VARARGS, - M_aud_Factory_fadein_doc - }, - {"fadeout", (PyCFunction)Factory_fadeout, METH_VARARGS, - M_aud_Factory_fadeout_doc - }, - {"loop", (PyCFunction)Factory_loop, METH_VARARGS, - M_aud_Factory_loop_doc - }, - {"mix", (PyCFunction)Factory_mix, METH_O, - M_aud_Factory_mix_doc - }, - {"pingpong", (PyCFunction)Factory_pingpong, METH_NOARGS, - M_aud_Factory_pingpong_doc - }, - {"reverse", (PyCFunction)Factory_reverse, METH_NOARGS, - M_aud_Factory_reverse_doc - }, - {"buffer", (PyCFunction)Factory_buffer, METH_NOARGS, - M_aud_Factory_buffer_doc - }, - {"square", (PyCFunction)Factory_square, METH_VARARGS, - M_aud_Factory_square_doc - }, - {"filter", (PyCFunction)Factory_filter, METH_VARARGS, - M_aud_Factory_filter_doc - }, - {NULL} /* Sentinel */ -}; - -PyDoc_STRVAR(M_aud_Factory_doc, - "Factory objects are immutable and represent a sound that can be " - "played simultaneously multiple times. They are called factories " - "because they create reader objects internally that are used for " - "playback."); - -static PyTypeObject FactoryType = { - PyVarObject_HEAD_INIT(NULL, 0) - "aud.Factory", /* tp_name */ - sizeof(Factory), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)Factory_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 */ - M_aud_Factory_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - Factory_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 */ - Factory_new, /* tp_new */ -}; - -// ========== Handle ================================================== - -static void -Handle_dealloc(Handle* self) -{ - if(self->handle) - delete reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle); - Py_TYPE(self)->tp_free((PyObject *)self); -} - -PyDoc_STRVAR(M_aud_Handle_pause_doc, - "pause()\n\n" - "Pauses playback.\n\n" - ":return: Whether the action succeeded.\n" - ":rtype: bool"); - -static PyObject * -Handle_pause(Handle *self) -{ - try - { - return PyBool_FromLong((long)(*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->pause()); - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - return NULL; - } -} - -PyDoc_STRVAR(M_aud_Handle_resume_doc, - "resume()\n\n" - "Resumes playback.\n\n" - ":return: Whether the action succeeded.\n" - ":rtype: bool"); - -static PyObject * -Handle_resume(Handle *self) -{ - try - { - return PyBool_FromLong((long)(*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->resume()); - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - return NULL; - } -} - -PyDoc_STRVAR(M_aud_Handle_stop_doc, - "stop()\n\n" - "Stops playback.\n\n" - ":return: Whether the action succeeded.\n" - ":rtype: bool\n\n" - ".. note:: This makes the handle invalid."); - -static PyObject * -Handle_stop(Handle *self) -{ - try - { - return PyBool_FromLong((long)(*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->stop()); - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - return NULL; - } -} - -static PyMethodDef Handle_methods[] = { - {"pause", (PyCFunction)Handle_pause, METH_NOARGS, - M_aud_Handle_pause_doc - }, - {"resume", (PyCFunction)Handle_resume, METH_NOARGS, - M_aud_Handle_resume_doc - }, - {"stop", (PyCFunction)Handle_stop, METH_NOARGS, - M_aud_Handle_stop_doc - }, - {NULL} /* Sentinel */ -}; - -PyDoc_STRVAR(M_aud_Handle_position_doc, - "The playback position of the sound in seconds."); - -static PyObject * -Handle_get_position(Handle *self, void* nothing) -{ - try - { - return Py_BuildValue("f", (*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->getPosition()); - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - return NULL; - } -} - -static int -Handle_set_position(Handle *self, PyObject *args, void* nothing) -{ - float position; - - if(!PyArg_Parse(args, "f:position", &position)) - return -1; - - try - { - if((*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->seek(position)) - return 0; - PyErr_SetString(AUDError, "Couldn't seek the sound!"); - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - } - - return -1; -} - -PyDoc_STRVAR(M_aud_Handle_keep_doc, - "Whether the sound should be kept paused in the device when its " - "end is reached.\n" - "This can be used to seek the sound to some position and start " - "playback again.\n\n" - ".. warning:: If this is set to true and you forget stopping this " - "equals a memory leak as the handle exists until the device is " - "destroyed."); - -static PyObject * -Handle_get_keep(Handle *self, void* nothing) -{ - try - { - return PyBool_FromLong((long)(*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->getKeep()); - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - return NULL; - } -} - -static int -Handle_set_keep(Handle *self, PyObject *args, void* nothing) -{ - if(!PyBool_Check(args)) - { - PyErr_SetString(PyExc_TypeError, "keep is not a boolean!"); - return -1; - } - - bool keep = args == Py_True; - - try - { - if((*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->setKeep(keep)) - return 0; - PyErr_SetString(AUDError, "Couldn't set keep of the sound!"); - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - } - - return -1; -} - -PyDoc_STRVAR(M_aud_Handle_status_doc, - "Whether the sound is playing, paused or stopped (=invalid)."); - -static PyObject * -Handle_get_status(Handle *self, void* nothing) -{ - try - { - return PyBool_FromLong((long)(*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->getStatus()); - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - return NULL; - } -} - -PyDoc_STRVAR(M_aud_Handle_volume_doc, - "The volume of the sound."); - -static PyObject * -Handle_get_volume(Handle *self, void* nothing) -{ - try - { - return Py_BuildValue("f", (*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->getVolume()); - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - return NULL; - } -} - -static int -Handle_set_volume(Handle *self, PyObject *args, void* nothing) -{ - float volume; - - if(!PyArg_Parse(args, "f:volume", &volume)) - return -1; - - try - { - if((*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->setVolume(volume)) - return 0; - PyErr_SetString(AUDError, "Couldn't set the sound volume!"); - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - } - - return -1; -} - -PyDoc_STRVAR(M_aud_Handle_pitch_doc, - "The pitch of the sound."); - -static PyObject * -Handle_get_pitch(Handle *self, void* nothing) -{ - try - { - return Py_BuildValue("f", (*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->getPitch()); - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - return NULL; - } -} - -static int -Handle_set_pitch(Handle *self, PyObject *args, void* nothing) -{ - float pitch; - - if(!PyArg_Parse(args, "f:pitch", &pitch)) - return -1; - - try - { - if((*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->setPitch(pitch)) - return 0; - PyErr_SetString(AUDError, "Couldn't set the sound pitch!"); - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - } - - return -1; -} - -PyDoc_STRVAR(M_aud_Handle_loop_count_doc, - "The (remaining) loop count of the sound. A negative value indicates infinity."); - -static PyObject * -Handle_get_loop_count(Handle *self, void* nothing) -{ - try - { - return Py_BuildValue("i", (*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->getLoopCount()); - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - return NULL; - } -} - -static int -Handle_set_loop_count(Handle *self, PyObject *args, void* nothing) -{ - int loops; - - if(!PyArg_Parse(args, "i:loop_count", &loops)) - return -1; - - try - { - if((*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->setLoopCount(loops)) - return 0; - PyErr_SetString(AUDError, "Couldn't set the loop count!"); - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - } - - return -1; -} - -PyDoc_STRVAR(M_aud_Handle_location_doc, - "The source's location in 3D space, a 3D tuple of floats."); - -static PyObject * -Handle_get_location(Handle *self, void* nothing) -{ - try - { - AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get()); - if(handle) - { - AUD_Vector3 v = handle->getSourceLocation(); - return Py_BuildValue("(fff)", v.x(), v.y(), v.z()); - } - else - { - PyErr_SetString(AUDError, device_not_3d_error); - } - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - } - - return NULL; -} - -static int -Handle_set_location(Handle *self, PyObject *args, void* nothing) -{ - float x, y, z; - - if(!PyArg_Parse(args, "(fff):location", &x, &y, &z)) - return -1; - - try - { - AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get()); - if(handle) - { - AUD_Vector3 location(x, y, z); - if(handle->setSourceLocation(location)) - return 0; - PyErr_SetString(AUDError, "Location couldn't be set!"); - } - else - PyErr_SetString(AUDError, device_not_3d_error); - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - } - - return -1; -} - -PyDoc_STRVAR(M_aud_Handle_velocity_doc, - "The source's velocity in 3D space, a 3D tuple of floats."); - -static PyObject * -Handle_get_velocity(Handle *self, void* nothing) -{ - try - { - AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get()); - if(handle) - { - AUD_Vector3 v = handle->getSourceVelocity(); - return Py_BuildValue("(fff)", v.x(), v.y(), v.z()); - } - else - { - PyErr_SetString(AUDError, device_not_3d_error); - } - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - } - - return NULL; -} - -static int -Handle_set_velocity(Handle *self, PyObject *args, void* nothing) -{ - float x, y, z; - - if(!PyArg_Parse(args, "(fff):velocity", &x, &y, &z)) - return -1; - - try - { - AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get()); - if(handle) - { - AUD_Vector3 velocity(x, y, z); - if(handle->setSourceVelocity(velocity)) - return 0; - PyErr_SetString(AUDError, "Couldn't set the velocity!"); - } - else - PyErr_SetString(AUDError, device_not_3d_error); - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - } - - return -1; -} - -PyDoc_STRVAR(M_aud_Handle_orientation_doc, - "The source's orientation in 3D space as quaternion, a 4 float tuple."); - -static PyObject * -Handle_get_orientation(Handle *self, void* nothing) -{ - try - { - AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get()); - if(handle) - { - AUD_Quaternion o = handle->getSourceOrientation(); - return Py_BuildValue("(ffff)", o.w(), o.x(), o.y(), o.z()); - } - else - { - PyErr_SetString(AUDError, device_not_3d_error); - } - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - } - - return NULL; -} - -static int -Handle_set_orientation(Handle *self, PyObject *args, void* nothing) -{ - float w, x, y, z; - - if(!PyArg_Parse(args, "(ffff):orientation", &w, &x, &y, &z)) - return -1; - - try - { - AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get()); - if(handle) - { - AUD_Quaternion orientation(w, x, y, z); - if(handle->setSourceOrientation(orientation)) - return 0; - PyErr_SetString(AUDError, "Couldn't set the orientation!"); - } - else - PyErr_SetString(AUDError, device_not_3d_error); - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - } - - return -1; -} - -PyDoc_STRVAR(M_aud_Handle_relative_doc, - "Whether the source's location, velocity and orientation is relative or absolute to the listener."); - -static PyObject * -Handle_get_relative(Handle *self, void* nothing) -{ - try - { - AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get()); - if(handle) - { - return PyBool_FromLong((long)handle->isRelative()); - } - else - { - PyErr_SetString(AUDError, device_not_3d_error); - } - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - } - - return NULL; -} - -static int -Handle_set_relative(Handle *self, PyObject *args, void* nothing) -{ - if(!PyBool_Check(args)) - { - PyErr_SetString(PyExc_TypeError, "Value is not a boolean!"); - return -1; - } - - bool relative = (args == Py_True); - - try - { - AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get()); - if(handle) - { - if(handle->setRelative(relative)) - return 0; - PyErr_SetString(AUDError, "Couldn't set the relativeness!"); - } - else - PyErr_SetString(AUDError, device_not_3d_error); - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - } - - return -1; -} - -PyDoc_STRVAR(M_aud_Handle_volume_minimum_doc, - "The minimum volume of the source.\n\n" - ".. seealso:: :attr:`Device.distance_model`"); - -static PyObject * -Handle_get_volume_minimum(Handle *self, void* nothing) -{ - try - { - AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get()); - if(handle) - { - return Py_BuildValue("f", handle->getVolumeMinimum()); - } - else - { - PyErr_SetString(AUDError, device_not_3d_error); - return NULL; - } - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - return NULL; - } -} - -static int -Handle_set_volume_minimum(Handle *self, PyObject *args, void* nothing) -{ - float volume; - - if(!PyArg_Parse(args, "f:volume_minimum", &volume)) - return -1; - - try - { - AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get()); - if(handle) - { - if(handle->setVolumeMinimum(volume)) - return 0; - PyErr_SetString(AUDError, "Couldn't set the minimum volume!"); - } - else - PyErr_SetString(AUDError, device_not_3d_error); - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - } - - return -1; -} - -PyDoc_STRVAR(M_aud_Handle_volume_maximum_doc, - "The maximum volume of the source.\n\n" - ".. seealso:: :attr:`Device.distance_model`"); - -static PyObject * -Handle_get_volume_maximum(Handle *self, void* nothing) -{ - try - { - AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get()); - if(handle) - { - return Py_BuildValue("f", handle->getVolumeMaximum()); - } - else - { - PyErr_SetString(AUDError, device_not_3d_error); - return NULL; - } - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - return NULL; - } -} - -static int -Handle_set_volume_maximum(Handle *self, PyObject *args, void* nothing) -{ - float volume; - - if(!PyArg_Parse(args, "f:volume_maximum", &volume)) - return -1; - - try - { - AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get()); - if(handle) - { - if(handle->setVolumeMaximum(volume)) - return 0; - PyErr_SetString(AUDError, "Couldn't set the maximum volume!"); - } - else - PyErr_SetString(AUDError, device_not_3d_error); - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - } - - return -1; -} - -PyDoc_STRVAR(M_aud_Handle_distance_reference_doc, - "The reference distance of the source.\n" - "At this distance the volume will be exactly :attr:`volume`.\n\n" - ".. seealso:: :attr:`Device.distance_model`"); - -static PyObject * -Handle_get_distance_reference(Handle *self, void* nothing) -{ - try - { - AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get()); - if(handle) - { - return Py_BuildValue("f", handle->getDistanceReference()); - } - else - { - PyErr_SetString(AUDError, device_not_3d_error); - return NULL; - } - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - return NULL; - } -} - -static int -Handle_set_distance_reference(Handle *self, PyObject *args, void* nothing) -{ - float distance; - - if(!PyArg_Parse(args, "f:distance_reference", &distance)) - return -1; - - try - { - AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get()); - if(handle) - { - if(handle->setDistanceReference(distance)) - return 0; - PyErr_SetString(AUDError, "Couldn't set the reference distance!"); - } - else - PyErr_SetString(AUDError, device_not_3d_error); - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - } - - return -1; -} - -PyDoc_STRVAR(M_aud_Handle_distance_maximum_doc, - "The maximum distance of the source.\n" - "If the listener is further away the source volume will be 0.\n\n" - ".. seealso:: :attr:`Device.distance_model`"); - -static PyObject * -Handle_get_distance_maximum(Handle *self, void* nothing) -{ - try - { - AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get()); - if(handle) - { - return Py_BuildValue("f", handle->getDistanceMaximum()); - } - else - { - PyErr_SetString(AUDError, device_not_3d_error); - return NULL; - } - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - return NULL; - } -} - -static int -Handle_set_distance_maximum(Handle *self, PyObject *args, void* nothing) -{ - float distance; - - if(!PyArg_Parse(args, "f:distance_maximum", &distance)) - return -1; - - try - { - AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get()); - if(handle) - { - if(handle->setDistanceMaximum(distance)) - return 0; - PyErr_SetString(AUDError, "Couldn't set the maximum distance!"); - } - else - PyErr_SetString(AUDError, device_not_3d_error); - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - } - - return -1; -} - -PyDoc_STRVAR(M_aud_Handle_attenuation_doc, - "This factor is used for distance based attenuation of the " - "source.\n\n" - ".. seealso:: :attr:`Device.distance_model`"); - -static PyObject * -Handle_get_attenuation(Handle *self, void* nothing) -{ - try - { - AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get()); - if(handle) - { - return Py_BuildValue("f", handle->getAttenuation()); - } - else - { - PyErr_SetString(AUDError, device_not_3d_error); - return NULL; - } - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - return NULL; - } -} - -static int -Handle_set_attenuation(Handle *self, PyObject *args, void* nothing) -{ - float factor; - - if(!PyArg_Parse(args, "f:attenuation", &factor)) - return -1; - - try - { - AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get()); - if(handle) - { - if(handle->setAttenuation(factor)) - return 0; - PyErr_SetString(AUDError, "Couldn't set the attenuation!"); - } - else - PyErr_SetString(AUDError, device_not_3d_error); - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - } - - return -1; -} - -PyDoc_STRVAR(M_aud_Handle_cone_angle_inner_doc, - "The opening angle of the inner cone of the source. If the cone " - "values of a source are set there are two (audible) cones with " - "the apex at the :attr:`location` of the source and with infinite " - "height, heading in the direction of the source's " - ":attr:`orientation`.\n" - "In the inner cone the volume is normal. Outside the outer cone " - "the volume will be :attr:`cone_volume_outer` and in the area " - "between the volume will be interpolated linearly."); - -static PyObject * -Handle_get_cone_angle_inner(Handle *self, void* nothing) -{ - try - { - AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get()); - if(handle) - { - return Py_BuildValue("f", handle->getConeAngleInner()); - } - else - { - PyErr_SetString(AUDError, device_not_3d_error); - return NULL; - } - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - return NULL; - } -} - -static int -Handle_set_cone_angle_inner(Handle *self, PyObject *args, void* nothing) -{ - float angle; - - if(!PyArg_Parse(args, "f:cone_angle_inner", &angle)) - return -1; - - try - { - AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get()); - if(handle) - { - if(handle->setConeAngleInner(angle)) - return 0; - PyErr_SetString(AUDError, "Couldn't set the cone inner angle!"); - } - else - PyErr_SetString(AUDError, device_not_3d_error); - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - } - - return -1; -} - -PyDoc_STRVAR(M_aud_Handle_cone_angle_outer_doc, - "The opening angle of the outer cone of the source.\n\n" - ".. seealso:: :attr:`cone_angle_inner`"); - -static PyObject * -Handle_get_cone_angle_outer(Handle *self, void* nothing) -{ - try - { - AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get()); - if(handle) - { - return Py_BuildValue("f", handle->getConeAngleOuter()); - } - else - { - PyErr_SetString(AUDError, device_not_3d_error); - return NULL; - } - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - return NULL; - } -} - -static int -Handle_set_cone_angle_outer(Handle *self, PyObject *args, void* nothing) -{ - float angle; - - if(!PyArg_Parse(args, "f:cone_angle_outer", &angle)) - return -1; - - try - { - AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get()); - if(handle) - { - if(handle->setConeAngleOuter(angle)) - return 0; - PyErr_SetString(AUDError, "Couldn't set the cone outer angle!"); - } - else - PyErr_SetString(AUDError, device_not_3d_error); - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - } - - return -1; -} - -PyDoc_STRVAR(M_aud_Handle_cone_volume_outer_doc, - "The volume outside the outer cone of the source.\n\n" - ".. seealso:: :attr:`cone_angle_inner`"); - -static PyObject * -Handle_get_cone_volume_outer(Handle *self, void* nothing) -{ - try - { - AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get()); - if(handle) - { - return Py_BuildValue("f", handle->getConeVolumeOuter()); - } - else - { - PyErr_SetString(AUDError, device_not_3d_error); - return NULL; - } - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - return NULL; - } -} - -static int -Handle_set_cone_volume_outer(Handle *self, PyObject *args, void* nothing) -{ - float volume; - - if(!PyArg_Parse(args, "f:cone_volume_outer", &volume)) - return -1; - - try - { - AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get()); - if(handle) - { - if(handle->setConeVolumeOuter(volume)) - return 0; - PyErr_SetString(AUDError, "Couldn't set the cone outer volume!"); - } - else - PyErr_SetString(AUDError, device_not_3d_error); - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - } - - return -1; -} - -static PyGetSetDef Handle_properties[] = { - {(char*)"position", (getter)Handle_get_position, (setter)Handle_set_position, - M_aud_Handle_position_doc, NULL }, - {(char*)"keep", (getter)Handle_get_keep, (setter)Handle_set_keep, - M_aud_Handle_keep_doc, NULL }, - {(char*)"status", (getter)Handle_get_status, NULL, - M_aud_Handle_status_doc, NULL }, - {(char*)"volume", (getter)Handle_get_volume, (setter)Handle_set_volume, - M_aud_Handle_volume_doc, NULL }, - {(char*)"pitch", (getter)Handle_get_pitch, (setter)Handle_set_pitch, - M_aud_Handle_pitch_doc, NULL }, - {(char*)"loop_count", (getter)Handle_get_loop_count, (setter)Handle_set_loop_count, - M_aud_Handle_loop_count_doc, NULL }, - {(char*)"location", (getter)Handle_get_location, (setter)Handle_set_location, - M_aud_Handle_location_doc, NULL }, - {(char*)"velocity", (getter)Handle_get_velocity, (setter)Handle_set_velocity, - M_aud_Handle_velocity_doc, NULL }, - {(char*)"orientation", (getter)Handle_get_orientation, (setter)Handle_set_orientation, - M_aud_Handle_orientation_doc, NULL }, - {(char*)"relative", (getter)Handle_get_relative, (setter)Handle_set_relative, - M_aud_Handle_relative_doc, NULL }, - {(char*)"volume_minimum", (getter)Handle_get_volume_minimum, (setter)Handle_set_volume_minimum, - M_aud_Handle_volume_minimum_doc, NULL }, - {(char*)"volume_maximum", (getter)Handle_get_volume_maximum, (setter)Handle_set_volume_maximum, - M_aud_Handle_volume_maximum_doc, NULL }, - {(char*)"distance_reference", (getter)Handle_get_distance_reference, (setter)Handle_set_distance_reference, - M_aud_Handle_distance_reference_doc, NULL }, - {(char*)"distance_maximum", (getter)Handle_get_distance_maximum, (setter)Handle_set_distance_maximum, - M_aud_Handle_distance_maximum_doc, NULL }, - {(char*)"attenuation", (getter)Handle_get_attenuation, (setter)Handle_set_attenuation, - M_aud_Handle_attenuation_doc, NULL }, - {(char*)"cone_angle_inner", (getter)Handle_get_cone_angle_inner, (setter)Handle_set_cone_angle_inner, - M_aud_Handle_cone_angle_inner_doc, NULL }, - {(char*)"cone_angle_outer", (getter)Handle_get_cone_angle_outer, (setter)Handle_set_cone_angle_outer, - M_aud_Handle_cone_angle_outer_doc, NULL }, - {(char*)"cone_volume_outer", (getter)Handle_get_cone_volume_outer, (setter)Handle_set_cone_volume_outer, - M_aud_Handle_cone_volume_outer_doc, NULL }, - {NULL} /* Sentinel */ -}; - -PyDoc_STRVAR(M_aud_Handle_doc, - "Handle objects are playback handles that can be used to control " - "playback of a sound. If a sound is played back multiple times " - "then there are as many handles."); - -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 */ - M_aud_Handle_doc, /* 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 reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device); - Py_TYPE(self)->tp_free((PyObject *)self); -} - -static PyObject * -Device_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - Device *self; - - static const char *kwlist[] = {"type", "rate", "channels", "format", "buffer_size", "name", NULL}; - int device; - double rate = AUD_RATE_48000; - int channels = AUD_CHANNELS_STEREO; - int format = AUD_FORMAT_FLOAT32; - int buffersize = AUD_DEFAULT_BUFFER_SIZE; - const char* name = "Audaspace"; - - if(!PyArg_ParseTupleAndKeywords(args, kwds, "i|diiis:Device", const_cast<char**>(kwlist), - &device, &rate, &channels, &format, &buffersize, &name)) - return NULL; - - if(buffersize < 128) - { - PyErr_SetString(PyExc_ValueError, "buffer_size must be greater than 127!"); - return NULL; - } - - self = (Device*)type->tp_alloc(type, 0); - if(self != NULL) - { - AUD_DeviceSpecs specs; - specs.channels = (AUD_Channels)channels; - specs.format = (AUD_SampleFormat)format; - specs.rate = (AUD_SampleRate)rate; - - self->device = NULL; - - try - { - switch(device) - { - case AUD_DEVICE_NULL: - (void)specs; /* quiet warning when others disabled */ - self->device = new boost::shared_ptr<AUD_IDevice>(new AUD_NULLDevice()); - break; - case AUD_DEVICE_OPENAL: -#ifdef WITH_OPENAL - self->device = new boost::shared_ptr<AUD_IDevice>(new AUD_OpenALDevice(specs, buffersize)); -#endif - break; - case AUD_DEVICE_SDL: -#ifdef WITH_SDL - self->device = new boost::shared_ptr<AUD_IDevice>(new AUD_SDLDevice(specs, buffersize)); -#endif - break; - case AUD_DEVICE_JACK: -#ifdef WITH_JACK - self->device = new boost::shared_ptr<AUD_IDevice>(new AUD_JackDevice(name, specs, buffersize)); -#endif - break; - case AUD_DEVICE_READ: - break; - } - - } - catch(AUD_Exception& e) - { - Py_DECREF(self); - PyErr_SetString(AUDError, e.str); - return NULL; - } - - if(!self->device) - { - Py_DECREF(self); - PyErr_SetString(AUDError, "Unsupported device type!"); - return NULL; - } - } - - return (PyObject *)self; -} - -PyDoc_STRVAR(M_aud_Device_play_doc, - "play(factory, keep=False)\n\n" - "Plays a factory.\n\n" - ":arg factory: The factory to play.\n" - ":type factory: :class:`Factory`\n" - ":arg keep: See :attr:`Handle.keep`.\n" - ":type keep: bool\n" - ":return: The playback handle with which playback can be " - "controlled with.\n" - ":rtype: :class:`Handle`"); - -static PyObject * -Device_play(Device *self, PyObject *args, PyObject *kwds) -{ - PyObject *object; - PyObject *keepo = NULL; - - bool keep = false; - - static const char *kwlist[] = {"factory", "keep", NULL}; - - if(!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:play", const_cast<char**>(kwlist), &object, &keepo)) - return NULL; - - if(!PyObject_TypeCheck(object, &FactoryType)) - { - PyErr_SetString(PyExc_TypeError, "Object is not of type Factory!"); - return NULL; - } - - if(keepo != NULL) - { - if(!PyBool_Check(keepo)) - { - PyErr_SetString(PyExc_TypeError, "keep is not a boolean!"); - return NULL; - } - - keep = keepo == Py_True; - } - - Factory* sound = (Factory*)object; - Handle *handle; - - handle = (Handle*)HandleType.tp_alloc(&HandleType, 0); - if(handle != NULL) - { - try - { - handle->handle = new boost::shared_ptr<AUD_IHandle>((*reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device))->play(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(sound->factory), keep)); - } - catch(AUD_Exception& e) - { - Py_DECREF(handle); - PyErr_SetString(AUDError, e.str); - return NULL; - } - } - - return (PyObject *)handle; -} - -PyDoc_STRVAR(M_aud_Device_stopAll_doc, - "stopAll()\n\n" - "Stops all playing and paused sounds."); - -static PyObject * -Device_stopAll(Device *self) -{ - try - { - (*reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device))->stopAll(); - Py_RETURN_NONE; - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - return NULL; - } -} - -PyDoc_STRVAR(M_aud_Device_lock_doc, - "lock()\n\n" - "Locks the device so that it's guaranteed, that no samples are " - "read from the streams until :meth:`unlock` is called.\n" - "This is useful if you want to do start/stop/pause/resume some " - "sounds at the same time.\n\n" - ".. note:: The device has to be unlocked as often as locked to be " - "able to continue playback.\n\n" - ".. warning:: Make sure the time between locking and unlocking is " - "as short as possible to avoid clicks."); - -static PyObject * -Device_lock(Device *self) -{ - try - { - (*reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device))->lock(); - Py_RETURN_NONE; - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - return NULL; - } -} - -PyDoc_STRVAR(M_aud_Device_unlock_doc, - "unlock()\n\n" - "Unlocks the device after a lock call, see :meth:`lock` for " - "details."); - -static PyObject * -Device_unlock(Device *self) -{ - try - { - (*reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device))->unlock(); - Py_RETURN_NONE; - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - return NULL; - } -} - -static PyMethodDef Device_methods[] = { - {"play", (PyCFunction)Device_play, METH_VARARGS | METH_KEYWORDS, - M_aud_Device_play_doc - }, - {"stopAll", (PyCFunction)Device_stopAll, METH_NOARGS, - M_aud_Device_stopAll_doc - }, - {"lock", (PyCFunction)Device_lock, METH_NOARGS, - M_aud_Device_lock_doc - }, - {"unlock", (PyCFunction)Device_unlock, METH_NOARGS, - M_aud_Device_unlock_doc - }, - {NULL} /* Sentinel */ -}; - -PyDoc_STRVAR(M_aud_Device_rate_doc, - "The sampling rate of the device in Hz."); - -static PyObject * -Device_get_rate(Device *self, void* nothing) -{ - try - { - AUD_DeviceSpecs specs = (*reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device))->getSpecs(); - return Py_BuildValue("d", specs.rate); - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - return NULL; - } -} - -PyDoc_STRVAR(M_aud_Device_format_doc, - "The native sample format of the device."); - -static PyObject * -Device_get_format(Device *self, void* nothing) -{ - try - { - AUD_DeviceSpecs specs = (*reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device))->getSpecs(); - return Py_BuildValue("i", specs.format); - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - return NULL; - } -} - -PyDoc_STRVAR(M_aud_Device_channels_doc, - "The channel count of the device."); - -static PyObject * -Device_get_channels(Device *self, void* nothing) -{ - try - { - AUD_DeviceSpecs specs = (*reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device))->getSpecs(); - return Py_BuildValue("i", specs.channels); - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - return NULL; - } -} - -PyDoc_STRVAR(M_aud_Device_volume_doc, - "The overall volume of the device."); - -static PyObject * -Device_get_volume(Device *self, void* nothing) -{ - try - { - return Py_BuildValue("f", (*reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device))->getVolume()); - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - return NULL; - } -} - -static int -Device_set_volume(Device *self, PyObject *args, void* nothing) -{ - float volume; - - if(!PyArg_Parse(args, "f:volume", &volume)) - return -1; - - try - { - (*reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device))->setVolume(volume); - return 0; - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - return -1; - } -} - -PyDoc_STRVAR(M_aud_Device_listener_location_doc, - "The listeners's location in 3D space, a 3D tuple of floats."); - -static PyObject * -Device_get_listener_location(Device *self, void* nothing) -{ - try - { - AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device)->get()); - if(device) - { - AUD_Vector3 v = device->getListenerLocation(); - return Py_BuildValue("(fff)", v.x(), v.y(), v.z()); - } - else - { - PyErr_SetString(AUDError, device_not_3d_error); - } - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - } - - return NULL; -} - -static int -Device_set_listener_location(Device *self, PyObject *args, void* nothing) -{ - float x, y, z; - - if(!PyArg_Parse(args, "(fff):listener_location", &x, &y, &z)) - return -1; - - try - { - AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device)->get()); - if(device) - { - AUD_Vector3 location(x, y, z); - device->setListenerLocation(location); - return 0; - } - else - PyErr_SetString(AUDError, device_not_3d_error); - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - } - - return -1; -} - -PyDoc_STRVAR(M_aud_Device_listener_velocity_doc, - "The listener's velocity in 3D space, a 3D tuple of floats."); - -static PyObject * -Device_get_listener_velocity(Device *self, void* nothing) -{ - try - { - AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device)->get()); - if(device) - { - AUD_Vector3 v = device->getListenerVelocity(); - return Py_BuildValue("(fff)", v.x(), v.y(), v.z()); - } - else - { - PyErr_SetString(AUDError, device_not_3d_error); - } - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - } - - return NULL; -} - -static int -Device_set_listener_velocity(Device *self, PyObject *args, void* nothing) -{ - float x, y, z; - - if(!PyArg_Parse(args, "(fff):listener_velocity", &x, &y, &z)) - return -1; - - try - { - AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device)->get()); - if(device) - { - AUD_Vector3 velocity(x, y, z); - device->setListenerVelocity(velocity); - return 0; - } - else - PyErr_SetString(AUDError, device_not_3d_error); - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - } - - return -1; -} - -PyDoc_STRVAR(M_aud_Device_listener_orientation_doc, - "The listener's orientation in 3D space as quaternion, a 4 float tuple."); - -static PyObject * -Device_get_listener_orientation(Device *self, void* nothing) -{ - try - { - AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device)->get()); - if(device) - { - AUD_Quaternion o = device->getListenerOrientation(); - return Py_BuildValue("(ffff)", o.w(), o.x(), o.y(), o.z()); - } - else - { - PyErr_SetString(AUDError, device_not_3d_error); - } - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - } - - return NULL; -} - -static int -Device_set_listener_orientation(Device *self, PyObject *args, void* nothing) -{ - float w, x, y, z; - - if(!PyArg_Parse(args, "(ffff):listener_orientation", &w, &x, &y, &z)) - return -1; - - try - { - AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device)->get()); - if(device) - { - AUD_Quaternion orientation(w, x, y, z); - device->setListenerOrientation(orientation); - return 0; - } - else - PyErr_SetString(AUDError, device_not_3d_error); - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - } - - return -1; -} - -PyDoc_STRVAR(M_aud_Device_speed_of_sound_doc, - "The speed of sound of the device.\n" - "The speed of sound in air is typically 343.3 m/s."); - -static PyObject * -Device_get_speed_of_sound(Device *self, void* nothing) -{ - try - { - AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device)->get()); - if(device) - { - return Py_BuildValue("f", device->getSpeedOfSound()); - } - else - { - PyErr_SetString(AUDError, device_not_3d_error); - return NULL; - } - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - return NULL; - } -} - -static int -Device_set_speed_of_sound(Device *self, PyObject *args, void* nothing) -{ - float speed; - - if(!PyArg_Parse(args, "f:speed_of_sound", &speed)) - return -1; - - try - { - AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device)->get()); - if(device) - { - device->setSpeedOfSound(speed); - return 0; - } - else - PyErr_SetString(AUDError, device_not_3d_error); - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - } - - return -1; -} - -PyDoc_STRVAR(M_aud_Device_doppler_factor_doc, - "The doppler factor of the device.\n" - "This factor is a scaling factor for the velocity vectors in " - "doppler calculation. So a value bigger than 1 will exaggerate " - "the effect as it raises the velocity."); - -static PyObject * -Device_get_doppler_factor(Device *self, void* nothing) -{ - try - { - AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device)->get()); - if(device) - { - return Py_BuildValue("f", device->getDopplerFactor()); - } - else - { - PyErr_SetString(AUDError, device_not_3d_error); - return NULL; - } - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - return NULL; - } -} - -static int -Device_set_doppler_factor(Device *self, PyObject *args, void* nothing) -{ - float factor; - - if(!PyArg_Parse(args, "f:doppler_factor", &factor)) - return -1; - - try - { - AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device)->get()); - if(device) - { - device->setDopplerFactor(factor); - return 0; - } - else - PyErr_SetString(AUDError, device_not_3d_error); - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - } - - return -1; -} - -PyDoc_STRVAR(M_aud_Device_distance_model_doc, - "The distance model of the device.\n\n" - ".. seealso:: `OpenAL documentation <https://www.openal.org/documentation>`__"); - -static PyObject * -Device_get_distance_model(Device *self, void* nothing) -{ - try - { - AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device)->get()); - if(device) - { - return Py_BuildValue("i", int(device->getDistanceModel())); - } - else - { - PyErr_SetString(AUDError, device_not_3d_error); - return NULL; - } - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - return NULL; - } -} - -static int -Device_set_distance_model(Device *self, PyObject *args, void* nothing) -{ - int model; - - if(!PyArg_Parse(args, "i:distance_model", &model)) - return -1; - - try - { - AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device)->get()); - if(device) - { - device->setDistanceModel(AUD_DistanceModel(model)); - return 0; - } - else - PyErr_SetString(AUDError, device_not_3d_error); - } - catch(AUD_Exception& e) - { - PyErr_SetString(AUDError, e.str); - } - - return -1; -} - -static PyGetSetDef Device_properties[] = { - {(char*)"rate", (getter)Device_get_rate, NULL, - M_aud_Device_rate_doc, NULL }, - {(char*)"format", (getter)Device_get_format, NULL, - M_aud_Device_format_doc, NULL }, - {(char*)"channels", (getter)Device_get_channels, NULL, - M_aud_Device_channels_doc, NULL }, - {(char*)"volume", (getter)Device_get_volume, (setter)Device_set_volume, - M_aud_Device_volume_doc, NULL }, - {(char*)"listener_location", (getter)Device_get_listener_location, (setter)Device_set_listener_location, - M_aud_Device_listener_location_doc, NULL }, - {(char*)"listener_velocity", (getter)Device_get_listener_velocity, (setter)Device_set_listener_velocity, - M_aud_Device_listener_velocity_doc, NULL }, - {(char*)"listener_orientation", (getter)Device_get_listener_orientation, (setter)Device_set_listener_orientation, - M_aud_Device_listener_orientation_doc, NULL }, - {(char*)"speed_of_sound", (getter)Device_get_speed_of_sound, (setter)Device_set_speed_of_sound, - M_aud_Device_speed_of_sound_doc, NULL }, - {(char*)"doppler_factor", (getter)Device_get_doppler_factor, (setter)Device_set_doppler_factor, - M_aud_Device_doppler_factor_doc, NULL }, - {(char*)"distance_model", (getter)Device_get_distance_model, (setter)Device_set_distance_model, - M_aud_Device_distance_model_doc, NULL }, - {NULL} /* Sentinel */ -}; - -PyDoc_STRVAR(M_aud_Device_doc, - "Device objects represent an audio output backend like OpenAL or " - "SDL, but might also represent a file output or RAM buffer " - "output."); - -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 */ - M_aud_Device_doc, /* 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 */ - Device_new, /* tp_new */ -}; - -PyObject * -Device_empty() -{ - return DeviceType.tp_alloc(&DeviceType, 0); -} - -PyObject * -Factory_empty() -{ - return FactoryType.tp_alloc(&FactoryType, 0); -} - -Factory* -checkFactory(PyObject *factory) -{ - if(!PyObject_TypeCheck(factory, &FactoryType)) - { - PyErr_SetString(PyExc_TypeError, "Object is not of type Factory!"); - return NULL; - } - - return (Factory*)factory; -} - - -// ==================================================================== - -PyDoc_STRVAR(M_aud_doc, - "This module provides access to the audaspace audio library."); - -static struct PyModuleDef audmodule = { - PyModuleDef_HEAD_INIT, - "aud", /* name of module */ - M_aud_doc, /* module documentation */ - -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(&FactoryType) < 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(&FactoryType); - PyModule_AddObject(m, "Factory", (PyObject *)&FactoryType); - - 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); - - // device constants - PY_MODULE_ADD_CONSTANT(m, AUD_DEVICE_NULL); - PY_MODULE_ADD_CONSTANT(m, AUD_DEVICE_OPENAL); - PY_MODULE_ADD_CONSTANT(m, AUD_DEVICE_SDL); - PY_MODULE_ADD_CONSTANT(m, AUD_DEVICE_JACK); - //PY_MODULE_ADD_CONSTANT(m, AUD_DEVICE_READ); - // 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); - PY_MODULE_ADD_CONSTANT(m, AUD_STATUS_STOPPED); - // 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_INVALID); - - return m; -} |