svn merge -r 30566:30717 https://svn.blender.org/svnroot/bf-blender/trunk/blender
authorJoerg Mueller <nexyon@gmail.com>
Sun, 25 Jul 2010 13:12:58 +0000 (13:12 +0000)
committerJoerg Mueller <nexyon@gmail.com>
Sun, 25 Jul 2010 13:12:58 +0000 (13:12 +0000)
26 files changed:
intern/audaspace/CMakeLists.txt
intern/audaspace/FX/AUD_DoubleFactory.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_DoubleFactory.h [new file with mode: 0644]
intern/audaspace/FX/AUD_PingPongFactory.h
intern/audaspace/FX/AUD_SuperposeFactory.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_SuperposeFactory.h [new file with mode: 0644]
intern/audaspace/FX/AUD_SuperposeReader.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_SuperposeReader.h [new file with mode: 0644]
intern/audaspace/Python/AUD_PyAPI.cpp [new file with mode: 0644]
intern/audaspace/Python/AUD_PyAPI.h [new file with mode: 0644]
intern/audaspace/SConscript
intern/audaspace/intern/AUD_C-API.cpp
intern/audaspace/intern/AUD_C-API.h
source/blender/editors/mesh/editmesh_tools.c
source/blender/python/CMakeLists.txt
source/blender/python/SConscript
source/blender/python/doc/sphinx_doc_gen.py
source/blender/python/intern/bpy.c
source/blender/windowmanager/WM_api.h
source/blender/windowmanager/intern/wm_init_exit.c
source/blender/windowmanager/intern/wm_window.c
source/blender/windowmanager/wm_window.h
source/creator/creator.c
source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
source/gameengine/Ketsji/KX_PythonInit.cpp
source/gameengine/Ketsji/KX_SoundActuator.h

index 0965a467201172cbfe5930306c29a68d4ee494c8..c1d59dcd3e9c145e48cc8fd753fd96ee37758da8 100644 (file)
@@ -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/FX/AUD_DoubleFactory.cpp b/intern/audaspace/FX/AUD_DoubleFactory.cpp
new file mode 100644 (file)
index 0000000..402d884
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * $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_DoubleFactory.h"
+#include "AUD_DoubleReader.h"
+
+AUD_DoubleFactory::AUD_DoubleFactory(AUD_IFactory* factory1, AUD_IFactory* factory2) :
+               m_factory1(factory1), m_factory2(factory2) {}
+
+AUD_IReader* AUD_DoubleFactory::createReader()
+{
+       AUD_IReader* reader1 = m_factory1->createReader();
+       if(!reader1)
+               return 0;
+       AUD_IReader* reader2;
+       try
+       {
+               reader2 = m_factory2->createReader();
+               if(!reader2)
+               {
+                       delete reader1; AUD_DELETE("reader")
+                       return 0;
+               }
+       }
+       catch(AUD_Exception&)
+       {
+               delete reader1; AUD_DELETE("reader")
+               throw;
+       }
+
+       AUD_IReader* reader = new AUD_DoubleReader(reader1, reader2);
+       return reader;
+}
diff --git a/intern/audaspace/FX/AUD_DoubleFactory.h b/intern/audaspace/FX/AUD_DoubleFactory.h
new file mode 100644 (file)
index 0000000..03c7de1
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * $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_DOUBLEFACTORY
+#define AUD_DOUBLEFACTORY
+
+#include "AUD_IFactory.h"
+
+/**
+ * This factory plays two other factories behind each other.
+ * \note Readers from the underlying factories must have the same sample rate and channel count.
+ */
+class AUD_DoubleFactory : public AUD_IFactory
+{
+private:
+       /**
+        * First played factory.
+        */
+       AUD_IFactory* m_factory1;
+
+       /**
+        * Second played factory.
+        */
+       AUD_IFactory* m_factory2;
+
+public:
+       /**
+        * Creates a new double factory.
+        * \param factory1 The first input factory.
+        * \param factory2 The second input factory.
+        */
+       AUD_DoubleFactory(AUD_IFactory* factory1, AUD_IFactory* factory2);
+
+       virtual AUD_IReader* createReader();
+};
+
+#endif //AUD_DOUBLEFACTORY
index b8854da550a85c1518bb06a865ddf0e7d9fe7b08..1bf5d5e2508011caae0393274c8c9aa4f254f6f9 100644 (file)
@@ -41,10 +41,6 @@ public:
         */
        AUD_PingPongFactory(AUD_IFactory* factory = 0);
 
-       /**
-        * Destroys the factory.
-        */
-
        virtual AUD_IReader* createReader();
 };
 
diff --git a/intern/audaspace/FX/AUD_SuperposeFactory.cpp b/intern/audaspace/FX/AUD_SuperposeFactory.cpp
new file mode 100644 (file)
index 0000000..afd1ec1
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * $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_SuperposeFactory.h"
+#include "AUD_SuperposeReader.h"
+
+AUD_SuperposeFactory::AUD_SuperposeFactory(AUD_IFactory* factory1, AUD_IFactory* factory2) :
+               m_factory1(factory1), m_factory2(factory2) {}
+
+AUD_IReader* AUD_SuperposeFactory::createReader()
+{
+       AUD_IReader* reader1 = m_factory1->createReader();
+       if(!reader1)
+               return 0;
+       AUD_IReader* reader2;
+       try
+       {
+               reader2 = m_factory2->createReader();
+               if(!reader2)
+               {
+                       delete reader1; AUD_DELETE("reader")
+                       return 0;
+               }
+       }
+       catch(AUD_Exception&)
+       {
+               delete reader1; AUD_DELETE("reader")
+               throw;
+       }
+
+       AUD_IReader* reader = new AUD_SuperposeReader(reader1, reader2);
+       return reader;
+}
diff --git a/intern/audaspace/FX/AUD_SuperposeFactory.h b/intern/audaspace/FX/AUD_SuperposeFactory.h
new file mode 100644 (file)
index 0000000..44e79d7
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * $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_SUPERPOSEFACTORY
+#define AUD_SUPERPOSEFACTORY
+
+#include "AUD_IFactory.h"
+
+/**
+ * This factory plays two other factories behind each other.
+ * \note Readers from the underlying factories must have the same sample rate and channel count.
+ */
+class AUD_SuperposeFactory : public AUD_IFactory
+{
+private:
+       /**
+        * First played factory.
+        */
+       AUD_IFactory* m_factory1;
+
+       /**
+        * Second played factory.
+        */
+       AUD_IFactory* m_factory2;
+
+public:
+       /**
+        * Creates a new superpose factory.
+        * \param factory1 The first input factory.
+        * \param factory2 The second input factory.
+        */
+       AUD_SuperposeFactory(AUD_IFactory* factory1, AUD_IFactory* factory2);
+
+       virtual AUD_IReader* createReader();
+};
+
+#endif //AUD_SUPERPOSEFACTORY
diff --git a/intern/audaspace/FX/AUD_SuperposeReader.cpp b/intern/audaspace/FX/AUD_SuperposeReader.cpp
new file mode 100644 (file)
index 0000000..6519f27
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * $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_SuperposeReader.h"
+#include "AUD_Buffer.h"
+
+#include <cstring>
+
+AUD_SuperposeReader::AUD_SuperposeReader(AUD_IReader* reader1, AUD_IReader* reader2) :
+       m_reader1(reader1), m_reader2(reader2)
+{
+       try
+       {
+               if(!reader1)
+                       AUD_THROW(AUD_ERROR_READER);
+
+               if(!reader2)
+                       AUD_THROW(AUD_ERROR_READER);
+
+               AUD_Specs s1, s2;
+               s1 = reader1->getSpecs();
+               s2 = reader2->getSpecs();
+               if(memcmp(&s1, &s2, sizeof(AUD_Specs)) != 0)
+                       AUD_THROW(AUD_ERROR_READER);
+       }
+
+       catch(AUD_Exception)
+       {
+               if(reader1)
+               {
+                       delete reader1; AUD_DELETE("reader")
+               }
+               if(reader2)
+               {
+                       delete reader2; AUD_DELETE("reader")
+               }
+
+               throw;
+       }
+
+       m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
+}
+
+AUD_SuperposeReader::~AUD_SuperposeReader()
+{
+       delete m_reader1; AUD_DELETE("reader")
+       delete m_reader2; AUD_DELETE("reader")
+       delete m_buffer; AUD_DELETE("buffer")
+}
+
+bool AUD_SuperposeReader::isSeekable()
+{
+       return m_reader1->isSeekable() && m_reader2->isSeekable();
+}
+
+void AUD_SuperposeReader::seek(int position)
+{
+       m_reader1->seek(position);
+       m_reader2->seek(position);
+}
+
+int AUD_SuperposeReader::getLength()
+{
+       int len1 = m_reader1->getLength();
+       int len2 = m_reader2->getLength();
+       if((len1 < 0) || (len2 < 0))
+               return -1;
+       if(len1 < len2)
+               return len2;
+       return len1;
+}
+
+int AUD_SuperposeReader::getPosition()
+{
+       int pos1 = m_reader1->getPosition();
+       int pos2 = m_reader2->getPosition();
+       return AUD_MAX(pos1, pos2);
+}
+
+AUD_Specs AUD_SuperposeReader::getSpecs()
+{
+       return m_reader1->getSpecs();
+}
+
+AUD_ReaderType AUD_SuperposeReader::getType()
+{
+       if(m_reader1->getType() == AUD_TYPE_BUFFER &&
+          m_reader2->getType() == AUD_TYPE_BUFFER)
+               return AUD_TYPE_BUFFER;
+       return AUD_TYPE_STREAM;
+}
+
+bool AUD_SuperposeReader::notify(AUD_Message &message)
+{
+       return m_reader1->notify(message) | m_reader2->notify(message);
+}
+
+void AUD_SuperposeReader::read(int & length, sample_t* & buffer)
+{
+       AUD_Specs specs = m_reader1->getSpecs();
+       int samplesize = AUD_SAMPLE_SIZE(specs);
+
+       if(m_buffer->getSize() < length * samplesize)
+               m_buffer->resize(length * samplesize);
+       buffer = m_buffer->getBuffer();
+
+       int len1 = length;
+       sample_t* buf;
+       m_reader1->read(len1, buf);
+       memcpy(buffer, buf, len1 * samplesize);
+
+       if(len1 < length)
+               memset(buffer + len1 * specs.channels, 0, (length - len1) * samplesize);
+
+       int len2 = length;
+       m_reader2->read(len2, buf);
+
+       for(int i = 0; i < len2 * specs.channels; i++)
+               buffer[i] += buf[i];
+
+       length = AUD_MAX(len1, len2);
+}
diff --git a/intern/audaspace/FX/AUD_SuperposeReader.h b/intern/audaspace/FX/AUD_SuperposeReader.h
new file mode 100644 (file)
index 0000000..71392b1
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * $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_SUPERPOSEREADER
+#define AUD_SUPERPOSEREADER
+
+#include "AUD_IReader.h"
+class AUD_Buffer;
+
+/**
+ * This reader plays two readers with the same specs sequently.
+ */
+class AUD_SuperposeReader : public AUD_IReader
+{
+private:
+       /**
+        * The first reader.
+        */
+       AUD_IReader* m_reader1;
+
+       /**
+        * The second reader.
+        */
+       AUD_IReader* m_reader2;
+
+       /**
+        * The playback buffer for the intersecting part.
+        */
+       AUD_Buffer* m_buffer;
+
+public:
+       /**
+        * Creates a new superpose reader.
+        * \param reader1 The first reader to read from.
+        * \param reader2 The second reader to read from.
+        * \exception AUD_Exception Thrown if one of the reader specified is NULL
+        *             or the specs from the readers differ.
+        */
+       AUD_SuperposeReader(AUD_IReader* reader1, AUD_IReader* reader2);
+
+       /**
+        * Destroys the reader.
+        */
+       virtual ~AUD_SuperposeReader();
+
+       virtual bool isSeekable();
+       virtual void seek(int position);
+       virtual int getLength();
+       virtual int getPosition();
+       virtual AUD_Specs getSpecs();
+       virtual AUD_ReaderType getType();
+       virtual bool notify(AUD_Message &message);
+       virtual void read(int & length, sample_t* & buffer);
+};
+
+#endif //AUD_SUPERPOSEREADER
diff --git a/intern/audaspace/Python/AUD_PyAPI.cpp b/intern/audaspace/Python/AUD_PyAPI.cpp
new file mode 100644 (file)
index 0000000..26bc007
--- /dev/null
@@ -0,0 +1,3517 @@
+/*
+ * $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 const char *kwlist[] = {"filename", NULL};
+               const char* filename = NULL;
+
+               if(!PyArg_ParseTupleAndKeywords(args, kwds, "|s", const_cast<char**>(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;
+}
+
+PyDoc_STRVAR(M_aud_Sound_sine_doc,
+                        "sine(frequency)\n\n"
+                        "Creates a sine sound wave.\n\n"
+                        ":arg frequency: The frequency of the sine wave in Hz.\n"
+                        ":type frequency: float\n"
+                        ":return: The created aud.Sound object.\n"
+                        ":rtype: aud.Sound");
+
+static PyObject *
+Sound_sine(PyObject* nothing, PyObject* args);
+
+PyDoc_STRVAR(M_aud_Sound_file_doc,
+                        "file(filename)\n\n"
+                        "Creates a sound object of a sound file.\n\n"
+                        ":arg filename: Path of the file.\n"
+                        ":type filename: string\n"
+                        ":return: The created aud.Sound object.\n"
+                        ":rtype: aud.Sound");
+
+static PyObject *
+Sound_file(PyObject* nothing, PyObject* args);
+
+PyDoc_STRVAR(M_aud_Sound_lowpass_doc,
+                        "lowpass(sound, frequency)\n\n"
+                        "Creates a low quality lowpass filter.\n\n"
+                        ":arg sound: The sound to filter.\n"
+                        ":type sound: aud.Sound\n"
+                        ":arg frequency: The cut off trequency of the lowpass.\n"
+                        ":type frequency: float\n"
+                        ":return: The created aud.Sound object.\n"
+                        ":rtype: aud.Sound");
+
+static PyObject *
+Sound_lowpass(PyObject* nothing, PyObject* args);
+
+PyDoc_STRVAR(M_aud_Sound_delay_doc,
+                        "delay(sound, time)\n\n"
+                        "Delays a sound by playing silence before the sound starts.\n\n"
+                        ":arg sound: The sound to filter.\n"
+                        ":type sound: aud.Sound\n"
+                        ":arg time: How many seconds of silence should be added before the sound.\n"
+                        ":type time: float\n"
+                        ":return: The created aud.Sound object.\n"
+                        ":rtype: aud.Sound");
+
+static PyObject *
+Sound_delay(PyObject* nothing, PyObject* args);
+
+PyDoc_STRVAR(M_aud_Sound_double_doc,
+                        "double(first, second)\n\n"
+                        "Plays two sounds in sequence.\n\n"
+                        ":arg first: The sound to play first.\n"
+                        ":type first: aud.Sound\n"
+                        ":arg second: The sound to play second.\n"
+                        ":type second: aud.Sound\n"
+                        ":return: The created aud.Sound object.\n"
+                        ":rtype: aud.Sound\n\n"
+                        ".. note:: The two sounds have to have the same specifications "
+                        "(channels and samplerate).");
+
+static PyObject *
+Sound_double(PyObject* nothing, PyObject* args);
+
+PyDoc_STRVAR(M_aud_Sound_highpass_doc,
+                        "highpass(sound, frequency)\n\n"
+                        "Creates a low quality highpass filter.\n\n"
+                        ":arg sound: The sound to filter.\n"
+                        ":type sound: aud.Sound\n"
+                        ":arg frequency: The cut off trequency of the highpass.\n"
+                        ":type frequency: float\n"
+                        ":return: The created aud.Sound object.\n"
+                        ":rtype: aud.Sound");
+
+static PyObject *
+Sound_highpass(PyObject* nothing, PyObject* args);
+
+PyDoc_STRVAR(M_aud_Sound_limiter_doc,
+                        "limit(sound, start, end)\n\n"
+                        "Limits a sound within a specific start and end time.\n\n"
+                        ":arg sound: The sound to filter.\n"
+                        ":type sound: aud.Sound\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 aud.Sound object.\n"
+                        ":rtype: aud.Sound");
+
+static PyObject *
+Sound_limiter(PyObject* nothing, PyObject* args);
+
+PyDoc_STRVAR(M_aud_Sound_pitch_doc,
+                        "pitch(sound, factor)\n\n"
+                        "Changes the pitch of a sound with a specific factor.\n\n"
+                        ":arg sound: The sound to filter.\n"
+                        ":type sound: aud.Sound\n"
+                        ":arg factor: The factor to change the pitch with.\n"
+                        ":type factor: float\n"
+                        ":return: The created aud.Sound object.\n"
+                        ":rtype: aud.Sound\n\n"
+                        ".. note:: This is done by changing the sample rate of the "
+                        "underlying sound, which has to be an integer, so the factor "
+                        "value rounded and the factor may not be 100 % accurate.");
+
+static PyObject *
+Sound_pitch(PyObject* nothing, PyObject* args);
+
+PyDoc_STRVAR(M_aud_Sound_volume_doc,
+                        "volume(sound, volume)\n\n"
+                        "Changes the volume of a sound.\n\n"
+                        ":arg sound: The sound to filter.\n"
+                        ":type sound: aud.Sound\n"
+                        ":arg volume: The new volume..\n"
+                        ":type volume: float\n"
+                        ":return: The created aud.Sound object.\n"
+                        ":rtype: aud.Sound\n\n"
+                        ".. note:: Should be in the range [0, 1] to avoid clipping.");
+
+static PyObject *
+Sound_volume(PyObject* nothing, PyObject* args);
+
+PyDoc_STRVAR(M_aud_Sound_fadein_doc,
+                        "fadein(sound, start, length)\n\n"
+                        "Fades a sound in.\n\n"
+                        ":arg sound: The sound to filter.\n"
+                        ":type sound: aud.Sound\n"
+                        ":arg start: Time in seconds when the fading should start.\n"
+                        ":type filename: float\n"
+                        ":arg length: Time in seconds how long the fading should last.\n"
+                        ":type filename: float\n"
+                        ":return: The created aud.Sound object.\n"
+                        ":rtype: aud.Sound");
+
+static PyObject *
+Sound_fadein(PyObject* nothing, PyObject* args);
+
+PyDoc_STRVAR(M_aud_Sound_fadeout_doc,
+                        "fadeout(sound, start, length)\n\n"
+                        "Fades a sound out.\n\n"
+                        ":arg sound: The sound to filter.\n"
+                        ":type sound: aud.Sound\n"
+                        ":arg start: Time in seconds when the fading should start.\n"
+                        ":type filename: float\n"
+                        ":arg length: Time in seconds how long the fading should last.\n"
+                        ":type filename: float\n"
+                        ":return: The created aud.Sound object.\n"
+                        ":rtype: aud.Sound");
+
+static PyObject *
+Sound_fadeout(PyObject* nothing, PyObject* args);
+
+PyDoc_STRVAR(M_aud_Sound_loop_doc,
+                        "loop(sound, count)\n\n"
+                        "Loops a sound.\n\n"
+                        ":arg sound: The sound to filter.\n"
+                        ":type sound: aud.Sound\n"
+                        ":arg count: How often the sound should be looped. "
+                        "Negative values mean endlessly.\n"
+                        ":type count: integer\n"
+                        ":return: The created aud.Sound object.\n"
+                        ":rtype: aud.Sound");
+
+static PyObject *
+Sound_loop(PyObject* nothing, PyObject* args);
+
+PyDoc_STRVAR(M_aud_Sound_superpose_doc,
+                        "superpose(sound1, sound2)\n\n"
+                        "Mixes two sounds.\n\n"
+                        ":arg sound1: The sound to filter.\n"
+                        ":type sound1: aud.Sound\n"
+                        ":arg sound2: The sound to filter.\n"
+                        ":type sound2: aud.Sound\n"
+                        ":return: The created aud.Sound object.\n"
+                        ":rtype: aud.Sound");
+
+static PyObject *
+Sound_superpose(PyObject* nothing, PyObject* args);
+
+PyDoc_STRVAR(M_aud_Sound_pingpong_doc,
+                        "pingpong(sound)\n\n"
+                        "Plays a sound forward and then backward.\n\n"
+                        ":arg sound: The sound to filter.\n"
+                        ":type sound: aud.Sound\n"
+                        ":return: The created aud.Sound object.\n"
+                        ":rtype: aud.Sound\n\n"
+                        ".. note:: The sound has to be buffered to be played reverse.");
+
+static PyObject *
+Sound_pingpong(PyObject* nothing, PyObject* args);
+
+PyDoc_STRVAR(M_aud_Sound_reverse_doc,
+                        "reverse(sound)\n\n"
+                        "Plays a sound reversed.\n\n"
+                        ":arg sound: The sound to filter.\n"
+                        ":type sound: aud.Sound\n"
+                        ":return: The created aud.Sound object.\n"
+                        ":rtype: aud.Sound\n\n"
+                        ".. note:: The sound has to be buffered to be played reverse.");
+
+static PyObject *
+Sound_reverse(PyObject* nothing, PyObject* args);
+
+PyDoc_STRVAR(M_aud_Sound_buffer_doc,
+                        "buffer(sound)\n\n"
+                        "Buffers a sound into RAM.\n\n"
+                        ":arg sound: The sound to buffer.\n"
+                        ":type sound: aud.Sound\n"
+                        ":return: The created aud.Sound object.\n"
+                        ":rtype: aud.Sound\n\n"
+                        ".. note:: Raw PCM data needs a lot of space, only buffer short sounds.");
+
+static PyObject *
+Sound_buffer(PyObject* nothing, PyObject* args);
+
+PyDoc_STRVAR(M_aud_Sound_square_doc,
+                        "squre(sound, threshold)\n\n"
+                        "Makes a square wave out of an audio wave.\n\n"
+                        ":arg sound: The sound to filter.\n"
+                        ":type sound: aud.Sound\n"
+                        ":arg threshold: Threshold value over which an amplitude counts non-zero.\n"
+                        ":type threshold: float\n"
+                        ":return: The created aud.Sound object.\n"
+                        ":rtype: aud.Sound");
+
+static PyObject *
+Sound_square(PyObject* nothing, PyObject* args);
+
+static PyMethodDef Sound_methods[] = {
+       {"sine", (PyCFunction)Sound_sine, METH_VARARGS | METH_STATIC,
+        M_aud_Sound_sine_doc
+       },
+       {"file", (PyCFunction)Sound_file, METH_VARARGS | METH_STATIC,
+        M_aud_Sound_file_doc
+       },
+       {"lowpass", (PyCFunction)Sound_lowpass, METH_VARARGS | METH_STATIC,
+        M_aud_Sound_lowpass_doc
+       },
+       {"delay", (PyCFunction)Sound_delay, METH_VARARGS | METH_STATIC,
+        M_aud_Sound_delay_doc
+       },
+       {"double", (PyCFunction)Sound_double, METH_VARARGS | METH_STATIC,
+        M_aud_Sound_double_doc
+       },
+       {"highpass", (PyCFunction)Sound_highpass, METH_VARARGS | METH_STATIC,
+        M_aud_Sound_highpass_doc
+       },
+       {"limiter", (PyCFunction)Sound_limiter, METH_VARARGS | METH_STATIC,
+        M_aud_Sound_limiter_doc
+       },
+       {"pitch", (PyCFunction)Sound_pitch, METH_VARARGS | METH_STATIC,
+        M_aud_Sound_pitch_doc
+       },
+       {"volume", (PyCFunction)Sound_volume, METH_VARARGS | METH_STATIC,
+        M_aud_Sound_volume_doc
+       },
+       {"fadein", (PyCFunction)Sound_fadein, METH_VARARGS | METH_STATIC,
+        M_aud_Sound_fadein_doc
+       },
+       {"fadeout", (PyCFunction)Sound_fadeout, METH_VARARGS | METH_STATIC,
+        M_aud_Sound_fadeout_doc
+       },
+       {"loop", (PyCFunction)Sound_loop, METH_VARARGS | METH_STATIC,
+        M_aud_Sound_loop_doc
+       },
+       {"superpose", (PyCFunction)Sound_superpose, METH_VARARGS | METH_STATIC,
+        M_aud_Sound_superpose_doc
+       },
+       {"pingpong", (PyCFunction)Sound_pingpong, METH_O | METH_STATIC,
+        M_aud_Sound_pingpong_doc
+       },
+       {"reverse", (PyCFunction)Sound_reverse, METH_O | METH_STATIC,
+        M_aud_Sound_reverse_doc
+       },
+       {"buffer", (PyCFunction)Sound_buffer, METH_O | METH_STATIC,
+        M_aud_Sound_buffer_doc
+       },
+       {"square", (PyCFunction)Sound_square, METH_VARARGS | METH_STATIC,
+        M_aud_Sound_square_doc
+       },
+       {NULL}  /* Sentinel */
+};
+
+PyDoc_STRVAR(M_aud_Sound_doc,
+                        "Sound objects are immutable and represent a sound that can be "
+                        "played simultaneously multiple times.");
+
+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 */
+       M_aud_Sound_doc,           /* 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_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_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_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_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;
+}
+
+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;
+}
+
+// ========== Handle ==================================================
+
+static void
+Handle_dealloc(Handle* self)
+{
+       Py_XDECREF(self->device);
+       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: boolean");
+
+static PyObject *
+Handle_pause(Handle *self)
+{
+       return PyObject_CallMethod(self->device, const_cast<char*>("_pause"), const_cast<char*>("(O)"), self);
+}
+
+PyDoc_STRVAR(M_aud_Handle_resume_doc,
+                        "resume()\n\n"
+                        "Resumes playback.\n\n"
+                        ":return: Whether the action succeeded.\n"
+                        ":rtype: boolean");
+
+static PyObject *
+Handle_resume(Handle *self)
+{
+       return PyObject_CallMethod(self->device, const_cast<char*>("_resume"), const_cast<char*>("(O)"), self);
+}
+
+PyDoc_STRVAR(M_aud_Handle_stop_doc,
+                        "stop()\n\n"
+                        "Stops playback.\n\n"
+                        ":return: Whether the action succeeded.\n"
+                        ":rtype: boolean");
+
+static PyObject *
+Handle_stop(Handle *self)
+{
+       return PyObject_CallMethod(self->device, const_cast<char*>("_stop"), const_cast<char*>("(O)"), self);
+}
+
+PyDoc_STRVAR(M_aud_Handle_update_doc,
+                        "update(info)\n\n"
+                        "Updates the 3D information of the source.\n\n"
+                        ":arg info: The 3D info in the format (fff)(fff)((fff)(fff)(fff))."
+                        " Position, velocity and a 3x3 orientation matrix.\n"
+                        ":type info: float tuple\n"
+                        ":return: Whether the action succeeded.\n"
+                        ":rtype: boolean");
+
+static PyObject *
+Handle_update(Handle *self, PyObject *data)
+{
+       return PyObject_CallMethod(self->device, const_cast<char*>("_update_source"), const_cast<char*>("(OO)"), self, data);
+}
+
+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
+       },
+       {"update", (PyCFunction)Handle_update, METH_O,
+        M_aud_Handle_update_doc
+       },
+       {NULL}  /* Sentinel */
+};
+
+PyDoc_STRVAR(M_aud_Handle_position_doc,
+                        "The playback position of the sound.");
+
+static PyObject *
+Handle_get_position(Handle *self, void* nothing)
+{
+       return PyObject_CallMethod(self->device, const_cast<char*>("_get_position"), const_cast<char*>("(O)"), self);
+}
+
+static int
+Handle_set_position(Handle *self, PyObject* args, void* nothing)
+{
+       PyObject* result = PyObject_CallMethod(self->device, const_cast<char*>("_seek"), const_cast<char*>("(OO)"), self, args);
+       if(result)
+       {
+               Py_DECREF(result);
+               return 0;
+       }
+       return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_keep_doc,
+                        "Whether the sound should be kept paused in the device when its end is reached.");
+
+static int
+Handle_set_keep(Handle *self, PyObject* args, void* nothing)
+{
+       PyObject* result = PyObject_CallMethod(self->device, const_cast<char*>("_set_keep"), const_cast<char*>("(OO)"), self, args);
+       if(result)
+       {
+               Py_DECREF(result);
+               return 0;
+       }
+       return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_status_doc,
+                        "Whether the sound is playing, paused or stopped.");
+
+static PyObject *
+Handle_get_status(Handle *self, void* nothing)
+{
+       return PyObject_CallMethod(self->device, const_cast<char*>("_get_status"), const_cast<char*>("(O)"), self);
+}
+
+PyDoc_STRVAR(M_aud_Handle_volume_doc,
+                        "The volume of the sound.");
+
+static PyObject *
+Handle_get_volume(Handle *self, void* nothing)
+{
+       return PyObject_CallMethod(self->device, const_cast<char*>("_get_volume"), const_cast<char*>("(O)"), self);
+}
+
+static int
+Handle_set_volume(Handle *self, PyObject* args, void* nothing)
+{
+       PyObject* result = PyObject_CallMethod(self->device, const_cast<char*>("_set_volume"), const_cast<char*>("(OO)"), self, args);
+       if(result)
+       {
+               Py_DECREF(result);
+               return 0;
+       }
+       return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_pitch_doc,
+                        "The pitch of the sound.");
+
+static int
+Handle_set_pitch(Handle *self, PyObject* args, void* nothing)
+{
+       PyObject* result = PyObject_CallMethod(self->device, const_cast<char*>("_set_pitch"), const_cast<char*>("(OO)"), self, args);
+       if(result)
+       {
+               Py_DECREF(result);
+               return 0;
+       }
+       return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_loop_count_doc,
+                        "The (remaining) loop count of the sound. A negative value indicates infinity.");
+
+static int
+Handle_set_loop_count(Handle *self, PyObject* args, void* nothing)
+{
+       PyObject* result = PyObject_CallMethod(self->device, const_cast<char*>("_set_loop_count"), const_cast<char*>("(OO)"), self, args);
+       if(result)
+       {
+               Py_DECREF(result);
+               return 0;
+       }
+       return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_relative_doc,
+                        "Whether the source's position is relative or absolute to the listener.");
+
+static PyObject *
+Handle_get_relative(Handle *self, void* nothing)
+{
+       return PyObject_CallMethod(self->device, const_cast<char*>("_is_relative"), const_cast<char*>("(O)"), self);
+}
+
+static int
+Handle_set_relative(Handle *self, PyObject* args, void* nothing)
+{
+       PyObject* result = PyObject_CallMethod(self->device, const_cast<char*>("_set_relative"), const_cast<char*>("(OO)"), self, args);
+       if(result)
+       {
+               Py_DECREF(result);
+               return 0;
+       }
+       return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_min_gain_doc,
+                        "The minimum gain of the source.");
+
+static PyObject *
+Handle_get_min_gain(Handle *self, void* nothing)
+{
+       return PyObject_CallMethod(self->device, const_cast<char*>("_get_min_gain"), const_cast<char*>("(O)"), self);
+}
+
+static int
+Handle_set_min_gain(Handle *self, PyObject* args, void* nothing)
+{
+       PyObject* result = PyObject_CallMethod(self->device, const_cast<char*>("_set_min_gain"), const_cast<char*>("(OO)"), self, args);
+       if(result)
+       {
+               Py_DECREF(result);
+               return 0;
+       }
+       return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_max_gain_doc,
+                        "The maximum gain of the source.");
+
+static PyObject *
+Handle_get_max_gain(Handle *self, void* nothing)
+{
+       return PyObject_CallMethod(self->device, const_cast<char*>("_get_max_gain"), const_cast<char*>("(O)"), self);
+}
+
+static int
+Handle_set_max_gain(Handle *self, PyObject* args, void* nothing)
+{
+       PyObject* result = PyObject_CallMethod(self->device, const_cast<char*>("_set_max_gain"), const_cast<char*>("(OO)"), self, args);
+       if(result)
+       {
+               Py_DECREF(result);
+               return 0;
+       }
+       return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_reference_distance_doc,
+                        "The reference distance of the source.");
+
+static PyObject *
+Handle_get_reference_distance(Handle *self, void* nothing)
+{
+       return PyObject_CallMethod(self->device, const_cast<char*>("_get_reference_distance"), const_cast<char*>("(O)"), self);
+}
+
+static int
+Handle_set_reference_distance(Handle *self, PyObject* args, void* nothing)
+{
+       PyObject* result = PyObject_CallMethod(self->device, const_cast<char*>("_set_reference_distance"), const_cast<char*>("(OO)"), self, args);
+       if(result)
+       {
+               Py_DECREF(result);
+               return 0;
+       }
+       return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_max_distance_doc,
+                        "The maximum distance of the source.");
+
+static PyObject *
+Handle_get_max_distance(Handle *self, void* nothing)
+{
+       return PyObject_CallMethod(self->device, const_cast<char*>("_get_max_distance"), const_cast<char*>("(O)"), self);
+}
+
+static int
+Handle_set_max_distance(Handle *self, PyObject* args, void* nothing)
+{
+       PyObject* result = PyObject_CallMethod(self->device, const_cast<char*>("_set_max_distance"), const_cast<char*>("(OO)"), self, args);
+       if(result)
+       {
+               Py_DECREF(result);
+               return 0;
+       }
+       return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_rolloff_factor_doc,
+                        "The rolloff factor of the source.");
+
+static PyObject *
+Handle_get_rolloff_factor(Handle *self, void* nothing)
+{
+       return PyObject_CallMethod(self->device, const_cast<char*>("_get_rolloff_factor"), const_cast<char*>("(O)"), self);
+}
+
+static int
+Handle_set_rolloff_factor(Handle *self, PyObject* args, void* nothing)
+{
+       PyObject* result = PyObject_CallMethod(self->device, const_cast<char*>("_set_rolloff_factor"), const_cast<char*>("(OO)"), self, args);
+       if(result)
+       {
+               Py_DECREF(result);
+               return 0;
+       }
+       return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_cone_inner_angle_doc,
+                        "The cone inner angle of the source.");
+
+static PyObject *
+Handle_get_cone_inner_angle(Handle *self, void* nothing)
+{
+       return PyObject_CallMethod(self->device, const_cast<char*>("_get_cone_inner_angle"), const_cast<char*>("(O)"), self);
+}
+
+static int
+Handle_set_cone_inner_angle(Handle *self, PyObject* args, void* nothing)
+{
+       PyObject* result = PyObject_CallMethod(self->device, const_cast<char*>("_set_cone_inner_angle"), const_cast<char*>("(OO)"), self, args);
+       if(result)
+       {
+               Py_DECREF(result);
+               return 0;
+       }
+       return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_cone_outer_angle_doc,
+                        "The cone outer angle of the source.");
+
+static PyObject *
+Handle_get_cone_outer_angle(Handle *self, void* nothing)
+{
+       return PyObject_CallMethod(self->device, const_cast<char*>("_get_cone_outer_angle"), const_cast<char*>("(O)"), self);
+}
+
+static int
+Handle_set_cone_outer_angle(Handle *self, PyObject* args, void* nothing)
+{
+       PyObject* result = PyObject_CallMethod(self->device, const_cast<char*>("_set_cone_outer_angle"), const_cast<char*>("(OO)"), self, args);
+       if(result)
+       {
+               Py_DECREF(result);
+               return 0;
+       }
+       return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_cone_outer_gain_doc,
+                        "The cone outer gain of the source.");
+
+static PyObject *
+Handle_get_cone_outer_gain(Handle *self, void* nothing)
+{
+       return PyObject_CallMethod(self->device, const_cast<char*>("_get_cone_outer_gain"), const_cast<char*>("(O)"), self);
+}
+
+static int
+Handle_set_cone_outer_gain(Handle *self, PyObject* args, void* nothing)
+{
+       PyObject* result = PyObject_CallMethod(self->device, const_cast<char*>("_set_cone_outer_gain"), const_cast<char*>("(OO)"), self, args);
+       if(result)
+       {
+               Py_DECREF(result);
+               return 0;
+       }
+       return -1;
+}
+
+static PyGetSetDef Handle_properties[] = {
+       {(char*)"position", (getter)Handle_get_position, (setter)Handle_set_position,
+        M_aud_Handle_position_doc, NULL },
+       {(char*)"keep", NULL, (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", NULL, (setter)Handle_set_pitch,
+        M_aud_Handle_pitch_doc, NULL },
+       {(char*)"loop_count", NULL, (setter)Handle_set_loop_count,
+        M_aud_Handle_loop_count_doc, NULL },
+       {(char*)"relative", (getter)Handle_get_relative, (setter)Handle_set_relative,
+        M_aud_Handle_relative_doc, NULL },
+       {(char*)"min_gain", (getter)Handle_get_min_gain, (setter)Handle_set_min_gain,
+        M_aud_Handle_min_gain_doc, NULL },
+       {(char*)"max_gain", (getter)Handle_get_max_gain, (setter)Handle_set_max_gain,
+        M_aud_Handle_max_gain_doc, NULL },
+       {(char*)"reference_distance", (getter)Handle_get_reference_distance, (setter)Handle_set_reference_distance,
+        M_aud_Handle_reference_distance_doc, NULL },
+       {(char*)"max_distance", (getter)Handle_get_max_distance, (setter)Handle_set_max_distance,
+        M_aud_Handle_max_distance_doc, NULL },
+       {(char*)"rolloff_factor", (getter)Handle_get_rolloff_factor, (setter)Handle_set_rolloff_factor,
+        M_aud_Handle_rolloff_factor_doc, NULL },
+       {(char*)"cone_inner_angle", (getter)Handle_get_cone_inner_angle, (setter)Handle_set_cone_inner_angle,
+        M_aud_Handle_cone_inner_angle_doc, NULL },
+       {(char*)"cone_outer_angle", (getter)Handle_get_cone_outer_angle, (setter)Handle_set_cone_outer_angle,
+        M_aud_Handle_cone_outer_angle_doc, NULL },
+       {(char*)"cone_outer_gain", (getter)Handle_get_cone_outer_gain, (setter)Handle_set_cone_outer_gain,
+        M_aud_Handle_cone_outer_gain_doc, NULL },
+       {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 self->device;
+       Py_TYPE(self)->tp_free((PyObject*)self);
+}
+
+PyDoc_STRVAR(M_aud_Device_play_doc,
+                        "play(sound[, keep])\n\n"
+                        "Plays a sound.\n\n"
+                        ":arg sound: The sound to play.\n"
+                        ":type sound: aud.Sound\n"
+                        ":arg keep: Whether the sound should be kept paused in the device when its end is reached.\n"
+                        ":type keep: boolean\n"
+                        ":return: The playback handle.\n"
+                        ":rtype: aud.Handle");
+
+static PyObject *
+Device_play(Device *self, PyObject *args, PyObject *kwds)
+{
+       PyObject* object;
+       PyObject* keepo = NULL;
+
+       bool keep = false;
+
+       static const char *kwlist[] = {"sound", "keep", NULL};
+
+       if(!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", const_cast<char**>(kwlist), &object, &keepo))
+               return NULL;
+
+       if(!PyObject_TypeCheck(object, &SoundType))
+       {
+               PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Sound!");
+               return NULL;
+       }
+
+       if(keepo != NULL)
+       {
+               if(!PyBool_Check(keepo))
+               {
+                       PyErr_SetString(PyExc_TypeError, "keep is not a boolean!");
+                       return NULL;
+               }
+
+               keep = keepo == Py_True;
+       }
+
+       Sound* sound = (Sound*)object;
+       Handle *handle;
+
+       handle = (Handle*)HandleType.tp_alloc(&HandleType, 0);
+       if(handle != NULL)
+       {
+               handle->device = (PyObject*)self;
+               Py_INCREF(self);
+
+               try
+               {
+                       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_set_keep(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_get_position(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_get_status(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;
+       }
+}
+
+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 the unlock is called. The device has "
+                        "to be unlocked as often as locked to be able to continue "
+                        "playback. Make sure the time between locking and unlocking is as "
+                        "short as possible to avoid clicks.");
+
+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;
+       }
+}
+
+PyDoc_STRVAR(M_aud_Device_unlock_doc,
+                        "unlock()\n\n"
+                        "Unlocks the device after a lock call, see lock() for details.");
+
+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_set_source_volume(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_get_source_volume(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_set_loop_count(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_set_pitch(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;
+}
+
+PyDoc_STRVAR(M_aud_Device_play3D_doc,
+                        "play3d(sound[, keep])\n\n"
+                        "Plays a sound 3 dimensional if possible.\n\n"
+                        ":arg sound: The sound to play.\n"
+                        ":type sound: aud.Sound\n"
+                        ":arg keep: Whether the sound should be kept paused in the device when its end is reached.\n"
+                        ":type keep: boolean\n"
+                        ":return: The playback handle.\n"
+                        ":rtype: aud.Handle");
+
+static PyObject *
+Device_play3D(Device *self, PyObject *args, PyObject *kwds)
+{
+       PyObject* object;
+       PyObject* keepo = NULL;
+
+       bool keep = false;
+
+       static const char *kwlist[] = {"sound", "keep", NULL};
+
+       if(!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", const_cast<char**>(kwlist), &object, &keepo))
+               return NULL;
+
+       if(!PyObject_TypeCheck(object, &SoundType))
+       {
+               PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Sound!");
+               return NULL;
+       }
+
+       if(keepo != NULL)
+       {
+               if(!PyBool_Check(keepo))
+               {
+                       PyErr_SetString(PyExc_TypeError, "keep is not a boolean!");
+                       return NULL;
+               }
+
+               keep = keepo == Py_True;
+       }
+
+       Sound* sound = (Sound*)object;
+       Handle *handle;
+
+       handle = (Handle*)HandleType.tp_alloc(&HandleType, 0);
+       if(handle != NULL)
+       {
+               handle->device = (PyObject*)self;
+               Py_INCREF(self);
+
+               try
+               {
+                       AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+                       if(device)
+                       {
+                               handle->handle = device->play3D(sound->factory, keep);
+                       }
+                       else
+                       {
+                               Py_DECREF(handle);
+                               PyErr_SetString(AUDError, "Device is not a 3D device!");
+                               return NULL;
+                       }
+               }
+               catch(AUD_Exception&)
+               {
+                       Py_DECREF(handle);
+                       PyErr_SetString(AUDError, "Couldn't play the sound!");
+                       return NULL;
+               }
+       }
+
+       return (PyObject *)handle;
+}
+
+PyDoc_STRVAR(M_aud_Device_update_listener_doc,
+                        "update_listener(info)\n\n"
+                        "Updates the 3D information of the listener.\n\n"
+                        ":arg info: The 3D info in the format (fff)(fff)((fff)(fff)(fff))."
+                        " Position, velocity and a 3x3 orientation matrix.\n"
+                        ":type info: float tuple");
+
+static PyObject *
+Device_update_listener(Device *self, PyObject *args)
+{
+       AUD_3DData data;
+
+       if(!PyArg_ParseTuple(args, "(fff)(fff)((fff)(fff)(fff))",
+                                                &data.position[0], &data.position[1], &data.position[2],
+                                                &data.velocity[0], &data.velocity[1], &data.velocity[2],
+                                                &data.orientation[0], &data.orientation[1], &data.orientation[2],
+                                                &data.orientation[3], &data.orientation[4], &data.orientation[5],
+                                                &data.orientation[6], &data.orientation[7], &data.orientation[8]))
+               return NULL;
+
+       try
+       {
+               AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+               if(device)
+               {
+                       device->updateListener(data);
+               }
+               else
+               {
+                       PyErr_SetString(AUDError, "Device is not a 3D device!");
+                       return NULL;
+               }
+       }
+       catch(AUD_Exception&)
+       {
+               PyErr_SetString(AUDError, "Couldn't update the listener!");
+               return NULL;
+       }
+
+       Py_RETURN_NONE;
+}
+
+static PyObject *
+Device_update_source(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_is_relative(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_set_relative(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_get_min_gain(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_set_min_gain(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_get_max_gain(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_set_max_gain(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_get_reference_distance(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_set_reference_distance(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_get_max_distance(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_set_max_distance(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_get_rolloff_factor(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_set_rolloff_factor(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_get_cone_inner_angle(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_set_cone_inner_angle(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_get_cone_outer_angle(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_set_cone_outer_angle(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_get_cone_outer_gain(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_set_cone_outer_gain(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;
+}
+
+PyDoc_STRVAR(M_aud_Device_OpenAL_doc,
+                        "OpenAL([frequency[, buffer_size]])\n\n"
+                        "Creates an OpenAL device.\n\n"
+                        ":arg frequency: The prefered sampling frequency.\n"
+                        ":type frequency: integer\n"
+                        ":arg buffer_size: The size of a playback buffer, "
+                        "must be at least 128.\n"
+                        ":type buffer_size: integer\n"
+                        ":return: The created aud.Device object.\n"
+                        ":rtype: aud.Device");
+
+static PyObject *
+Device_OpenAL(PyTypeObject *type, PyObject *args, PyObject *kwds);
+
+PyDoc_STRVAR(M_aud_Device_SDL_doc,
+                        "SDL([frequency[, buffer_size]])\n\n"
+                        "Creates an SDL device.\n\n"
+                        ":arg frequency: The sampling frequency.\n"
+                        ":type frequency: integer\n"
+                        ":arg buffer_size: The size of the playback buffer, "
+                        "must be at least 128.\n"
+                        ":type buffer_size: integer\n"
+                        ":return: The created aud.Device object.\n"
+                        ":rtype: aud.Device");
+
+static PyObject *
+Device_SDL(PyTypeObject *type, PyObject *args, PyObject *kwds);
+
+PyDoc_STRVAR(M_aud_Device_Jack_doc,
+                        "Jack([channels[, buffer_size]])\n\n"
+                        "Creates a Jack device.\n\n"
+                        ":arg channels: The count of channels.\n"
+                        ":type channels: integer\n"
+                        ":arg buffer_size: The size of the playback buffer, "
+                        "must be at least 128.\n"
+                        ":type buffer_size: integer\n"
+                        ":return: The created aud.Device object.\n"
+                        ":rtype: aud.Device");
+
+static PyObject *
+Device_Jack(PyTypeObject *type, PyObject *args, PyObject *kwds);
+
+PyDoc_STRVAR(M_aud_Device_Null_doc,
+                        "Null()\n\n"
+                        "Creates a Null device.\n\n"
+                        ":return: The created aud.Device object.\n"
+                        ":rtype: aud.Device");
+
+static PyObject *
+Device_Null(PyTypeObject *type);
+
+static PyMethodDef Device_methods[] = {
+       {"play", (PyCFunction)Device_play, METH_VARARGS | METH_KEYWORDS,
+        M_aud_Device_play_doc
+       },
+       {"_stop", (PyCFunction)Device_stop, METH_O,
+        ""
+       },
+       {"_pause", (PyCFunction)Device_pause, METH_O,
+        ""
+       },
+       {"_resume", (PyCFunction)Device_resume, METH_O,
+        ""
+       },
+       {"_set_keep", (PyCFunction)Device_set_keep, METH_VARARGS,
+        ""
+       },
+       {"_seek", (PyCFunction)Device_seek, METH_VARARGS,
+        ""
+       },
+       {"_get_position", (PyCFunction)Device_get_position, METH_O,
+        ""
+       },
+       {"_get_status", (PyCFunction)Device_get_status, METH_O,
+        ""
+       },
+       {"lock", (PyCFunction)Device_lock, METH_NOARGS,
+        M_aud_Device_lock_doc
+       },
+       {"unlock", (PyCFunction)Device_unlock, METH_NOARGS,
+        M_aud_Device_unlock_doc
+       },
+       {"_set_volume", (PyCFunction)Device_set_source_volume, METH_VARARGS,
+        ""
+       },
+       {"_get_volume", (PyCFunction)Device_get_source_volume, METH_O,
+        ""
+       },
+       {"_set_loop_count", (PyCFunction)Device_set_loop_count, METH_VARARGS,
+        ""
+       },
+       {"_set_pitch", (PyCFunction)Device_set_pitch, METH_VARARGS,
+        ""
+       },
+       {"play3D", (PyCFunction)Device_play3D, METH_VARARGS | METH_KEYWORDS,
+        M_aud_Device_play3D_doc
+       },
+       {"update_listener", (PyCFunction)Device_update_listener, METH_VARARGS,
+        M_aud_Device_update_listener_doc
+       },
+       {"_update_source", (PyCFunction)Device_update_source, METH_VARARGS,
+        ""
+       },
+       {"_is_relative", (PyCFunction)Device_is_relative, METH_O,
+        ""
+       },
+       {"_set_relative", (PyCFunction)Device_set_relative, METH_VARARGS,
+        ""
+       },
+       {"_get_min_gain", (PyCFunction)Device_get_min_gain, METH_O,
+        ""
+       },
+       {"_set_min_gain", (PyCFunction)Device_set_min_gain, METH_VARARGS,
+        ""
+       },
+       {"_get_max_gain", (PyCFunction)Device_get_max_gain, METH_O,
+        ""
+       },
+       {"_set_max_gain", (PyCFunction)Device_set_max_gain, METH_VARARGS,
+        ""
+       },
+       {"_get_reference_distance", (PyCFunction)Device_get_reference_distance, METH_O,
+        ""
+       },
+       {"_set_reference_distance", (PyCFunction)Device_set_reference_distance, METH_VARARGS,
+        ""
+       },
+       {"_get_max_distance", (PyCFunction)Device_get_max_distance, METH_O,
+        ""
+       },
+       {"_set_max_distance", (PyCFunction)Device_set_max_distance, METH_VARARGS,
+        ""
+       },
+       {"_get_rolloff_factor", (PyCFunction)Device_get_rolloff_factor, METH_O,
+        ""
+       },
+       {"_set_rolloff_factor", (PyCFunction)Device_set_rolloff_factor, METH_VARARGS,
+        ""
+       },
+       {"_get_cone_inner_angle", (PyCFunction)Device_get_cone_inner_angle, METH_O,
+        ""
+       },
+       {"_set_cone_inner_angle", (PyCFunction)Device_set_cone_inner_angle, METH_VARARGS,
+        ""
+       },
+       {"_get_cone_outer_angle", (PyCFunction)Device_get_cone_outer_angle, METH_O,
+        ""
+       },
+       {"_set_cone_outer_angle", (PyCFunction)Device_set_cone_outer_angle, METH_VARARGS,
+        ""
+       },
+       {"_get_cone_outer_gain", (PyCFunction)Device_get_cone_outer_gain, METH_O,
+        ""
+       },
+       {"_set_cone_outer_gain", (PyCFunction)Device_set_cone_outer_gain, METH_VARARGS,
+        ""
+       },
+       {"OpenAL", (PyCFunction)Device_OpenAL, METH_VARARGS | METH_STATIC | METH_KEYWORDS,
+        M_aud_Device_OpenAL_doc
+       },
+       {"SDL", (PyCFunction)Device_SDL, METH_VARARGS | METH_STATIC | METH_KEYWORDS,
+        M_aud_Device_SDL_doc
+       },
+       {"Jack", (PyCFunction)Device_Jack, METH_VARARGS | METH_STATIC | METH_KEYWORDS,
+        M_aud_Device_Jack_doc
+       },
+       {"Null", (PyCFunction)Device_Null, METH_NOARGS | METH_STATIC,
+        M_aud_Device_Null_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 = self->device->getSpecs();
+               return Py_BuildValue("i", specs.rate);
+       }
+       catch(AUD_Exception&)
+       {
+               PyErr_SetString(AUDError, "Couldn't retrieve device stats!");
+               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 = self->device->getSpecs();
+               return Py_BuildValue("i", specs.format);
+       }
+       catch(AUD_Exception&)
+       {
+               PyErr_SetString(AUDError, "Couldn't retrieve device stats!");
+               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 = self->device->getSpecs();
+               return Py_BuildValue("i", specs.channels);
+       }
+       catch(AUD_Exception&)
+       {
+               PyErr_SetString(AUDError, "Couldn't retrieve device stats!");
+               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
+       {
+               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_set_volume(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;
+}
+
+PyDoc_STRVAR(M_aud_Device_speed_of_sound_doc,
+                        "The speed of sound of the device.");
+
+static PyObject *
+Device_get_speed_of_sound(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_set_speed_of_sound(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;
+}
+
+PyDoc_STRVAR(M_aud_Device_doppler_factor_doc,
+                        "The doppler factor of the device.");
+
+static PyObject *
+Device_get_doppler_factor(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_set_doppler_factor(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;
+}
+
+PyDoc_STRVAR(M_aud_Device_distance_model_doc,
+                        "The distance model of the device.");
+
+static PyObject *
+Device_get_distance_model(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_set_distance_model(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[] = {
+       {(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*)"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 */
+       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 const char *kwlist[] = {"frequency", "buffer_size", NULL};
+
+       if(!PyArg_ParseTupleAndKeywords(args, kwds, "|ii", const_cast<char**>(kwlist), &frequency, &buffersize))
+               return NULL;
+
+       if(buffersize < 128)
+       {
+               PyErr_SetString(PyExc_ValueError, "buffer_size 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 const char *kwlist[] = {"frequency", "buffer_size", NULL};
+
+       if(!PyArg_ParseTupleAndKeywords(args, kwds, "|ii", const_cast<char**>(kwlist), &frequency, &buffersize))
+               return NULL;
+
+       if(buffersize < 128)
+       {
+               PyErr_SetString(PyExc_ValueError, "buffer_size 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 const char *kwlist[] = {"channels", "buffer_size", NULL};
+
+       if(!PyArg_ParseTupleAndKeywords(args, kwds, "|ii", const_cast<char**>(kwlist), &channels, &buffersize))
+               return NULL;
+
+       if(buffersize < 128)
+       {
+               PyErr_SetString(PyExc_ValueError, "buffer_size 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);
+}
+
+// ====================================================================
+
+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(&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 (file)
index 0000000..f7a86e1
--- /dev/null
@@ -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
index bbd2442c480b5339ca0be0ac2cdf20a7e04487b5..35c457aad4e9350f779b8404455be004c4f30332 100644 (file)
@@ -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']
 
index 8740f62c9a79a45fbb447b74a2a5d9dfbb6947fe..b0225109f3aa9b24369367325e8dc45a272d907a 100644 (file)
  * ***** 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,55 @@ 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[] = {{ "get_c_device", (PyCFunction)AUD_getCDevice, METH_NOARGS,
+                                                                                 "get_c_device()\n\n"
+                                                                                 "Returns the C API Device.\n\n"
+                                                                                 ":return: The C API Device.\n"
+                                                                                 ":rtype: aud.Device"}};
+
+PyObject* AUD_initPython()
+{
+       PyObject* module = PyInit_aud();
+       PyModule_AddObject(module, "get_c_device", (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 +346,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 +386,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 +400,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 +507,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 +526,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 +545,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 +563,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 +581,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 +611,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 +641,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 +850,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 +863,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);
index 55aed02153fcf17250e7053d3a2f90c850f76622..83feb234a6ebc749a206064fbf68305e44b8c9b0 100644 (file)
 #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);
index 4477f375aab649bfbfeee2400465ed33098cf6d3..ea89877b7cd33bff0836b37f67296934cda76c52 100644 (file)
@@ -485,16 +485,17 @@ static int removedoublesflag_exec(bContext *C, wmOperator *op)
 
        int count = removedoublesflag(em,1,0,RNA_float_get(op->ptr, "limit"));
        
-       if(count) {
-               recalc_editnormals(em);
+       if(!count)
+               return OPERATOR_CANCELLED;
 
-               DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
-               WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
-       }
+       recalc_editnormals(em);
 
        BKE_reportf(op->reports, RPT_INFO, "Removed %d vertices", count);
-       BKE_mesh_end_editmesh(obedit->data, em);
 
+       DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+       WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
+
+       BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_FINISHED;
 }
 
index 3c79e9d3056faf8f51a2f80d0b56da962fe322fe..dcfc8678faa23b4a69399f424995963cd8a38eb9 100644 (file)
@@ -36,6 +36,7 @@ SET(INC
        ../windowmanager
        ../editors/include
        ../../../intern/guardedalloc
+       ../../../intern/audaspace/intern
        ${PYTHON_INC}
 )
 
index ca742a3646a56db13b58a20e4ba06c6e5d34877e..d6c24eb3bfc3f167590037b43058beb131521fe5 100644 (file)
@@ -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 = []
 
index 04fdedd8c8fa62dca424b615c801ce8c15ef2ebe..145b6c3c31201d9179a5a527ea4fb7e789e8ef18 100644 (file)
@@ -143,7 +143,9 @@ def pyfunc2sphinx(ident, fw, identifier, py_func, is_class=True):
 
 
 def py_descr2sphinx(ident, fw, descr, module_name, type_name, identifier):    
-
+    if identifier.startswith("_"):
+        return
+    
     doc = descr.__doc__
     if not doc:
         doc = undocumented_message(module_name, type_name, identifier)
@@ -375,6 +377,7 @@ def rna2sphinx(BASEPATH):
 
     fw("   mathutils.rst\n\n")
     fw("   blf.rst\n\n")
+    fw("   aud.rst\n\n")
     
     # game engine
     fw("===================\n")
@@ -454,14 +457,30 @@ def rna2sphinx(BASEPATH):
     import blf as module
     pymodule2sphinx(BASEPATH, "blf", module, "Font Drawing (blf)")
     del module
+    
+    import aud as module
+    pymodule2sphinx(BASEPATH, "aud", module, "Audio System (aud)")
+    del module
 
     # game engine
-    import shutil
+    from bge import types as module
+    pymodule2sphinx(BASEPATH, "bge.types", module, "Game Engine bge.types Module")
+
+    from bge import logic as module
+    pymodule2sphinx(BASEPATH, "bge.logic", module, "Game Engine bge.logic Module")
+
+    from bge import render as module
+    pymodule2sphinx(BASEPATH, "bge.render", module, "Game Engine bge.render Module")
+
+    from bge import events as module
+    pymodule2sphinx(BASEPATH, "bge.events", module, "Game Engine bge.events Module")
+
+    #import shutil
     # copy2 keeps time/date stamps
-    shutil.copy2(os.path.join(BASEPATH, "../../../../gameengine/PyDoc/bge.types.rst"), BASEPATH)
-    shutil.copy2(os.path.join(BASEPATH, "../../../../gameengine/PyDoc/bge.logic.rst"), BASEPATH)
-    shutil.copy2(os.path.join(BASEPATH, "../../../../gameengine/PyDoc/bge.render.rst"), BASEPATH)
-    shutil.copy2(os.path.join(BASEPATH, "../../../../gameengine/PyDoc/bge.events.rst"), BASEPATH)
+    #shutil.copy2(os.path.join(BASEPATH, "../../../../gameengine/PyDoc/bge.types.rst"), BASEPATH)
+    #shutil.copy2(os.path.join(BASEPATH, "../../../../gameengine/PyDoc/bge.logic.rst"), BASEPATH)
+    #shutil.copy2(os.path.join(BASEPATH, "../../../../gameengine/PyDoc/bge.render.rst"), BASEPATH)
+    #shutil.copy2(os.path.join(BASEPATH, "../../../../gameengine/PyDoc/bge.events.rst"), BASEPATH)
 
 
     if 0:
@@ -755,7 +774,8 @@ def rna2sphinx(BASEPATH):
 
     file.close()
 
-if __name__ == '__main__':
+def main():
+    import bpy
     if 'bpy' not in dir():
         print("\nError, this script must run from inside blender2.5")
         print(script_help_msg)
@@ -825,3 +845,6 @@ if __name__ == '__main__':
 
     import sys
     sys.exit()
+
+if __name__ == '__main__':
+    main()
index 7933c2a1bc75e5ff02fd0438815fb9f71c4226af..9818bff0e22287a85daa6fe8c9e24dfeef1c61c6 100644 (file)
 #include "../generic/blf_api.h"
 #include "../generic/IDProp.h"
 
+#ifndef DISABLE_PYTHON
+#define WITH_PYTHON
+#endif
+#include "AUD_C-API.h"
+
 static char bpy_script_paths_doc[] =
 ".. function:: script_paths()\n"
 "\n"
@@ -153,7 +158,7 @@ void BPy_init_modules( void )
        BGL_Init();
        BLF_Init();
        IDProp_Init_Types();
-
+       AUD_initPython();
 
        mod = PyModule_New("_bpy");
 
index 46d42b300bfe1146184002f16200509322215af7..9e303333f2c1b4e8a148f0a385b5a75283d17e13 100644 (file)
@@ -57,7 +57,7 @@ void          WM_init                         (struct bContext *C, int argc, char **argv);
 void           WM_exit                         (struct bContext *C);
 void           WM_main                         (struct bContext *C);
 
-void           WM_init_game            (struct bContext *C);
+int            WM_init_game            (struct bContext *C);
 void           WM_init_splash          (struct bContext *C);
 
 
index 558d20021ce6ea0a3ac692443eb81f3abab93dac..45c851a55984a36b42c2b66b33595fb71fa49404 100644 (file)
@@ -49,6 +49,7 @@
 #include "BKE_font.h"
 #include "BKE_global.h"
 #include "BKE_library.h"
+#include "BKE_main.h"
 #include "BKE_mball.h"
 #include "BKE_report.h"
 #include "BKE_utildefines.h"
@@ -94,6 +95,7 @@
 
 #include "BKE_depsgraph.h"
 #include "BKE_sound.h"
+#include "GHOST_C-api.h"
 
 static void wm_init_reports(bContext *C)
 {
@@ -186,18 +188,113 @@ void WM_init_splash(bContext *C)
        }
 }
 
-void WM_init_game(bContext *C)
+static ScrArea *biggest_view3d(bContext *C)
+{
+       bScreen *sc= CTX_wm_screen(C);
+       ScrArea *sa, *big= NULL;
+       int size, maxsize= 0;
+
+       for(sa= sc->areabase.first; sa; sa= sa->next) {
+               if(sa->spacetype==SPACE_VIEW3D) {
+                       size= sa->winx * sa->winy;
+                       if(size > maxsize) {
+                               maxsize= size;
+                               big= sa;
+                       }
+               }
+       }
+       return big;
+}
+
+int WM_init_game(bContext *C)
 {
-       //XXX copied from WM_init_splash we may not even need those "window" related code
-       //XXX not working yet, it fails at the game_start_operator pool (it needs an area)
        wmWindowManager *wm= CTX_wm_manager(C);
-       wmWindow *prevwin= CTX_wm_window(C);
-       
-       if(wm->windows.first) {
-               CTX_wm_window_set(C, wm->windows.first);
+       wmWindow* win;
+
+       ScrArea *sa;
+       ARegion *ar;
+
+       Main *main = CTX_data_main(C);
+       Scene *scene= CTX_data_scene(C);
+
+       if (!scene)
+               scene= main->scene.first;
+
+       win = wm->windows.first;
+
+       //first to get a valid window
+       if(win)
+               CTX_wm_window_set(C, win);
+
+       sa = biggest_view3d(C);
+
+       if(sa)
+       {
+               for(ar=sa->regionbase.first; ar; ar=ar->next) {
+                       if(ar->regiontype == RGN_TYPE_WINDOW) {
+                               break;
+                       }
+               }
+       }
+
+       // if we have a valid 3D view
+       if (sa && ar) {
+               ARegion *arhide;
+
+               CTX_wm_area_set(C, sa);
+               CTX_wm_region_set(C, ar);
+
+               /* disable quad view */
+               if(ar->alignment == RGN_ALIGN_QSPLIT)
+                       WM_operator_name_call(C, "SCREEN_OT_region_quadview", WM_OP_EXEC_DEFAULT, NULL);
+
+               /* toolbox, properties panel and header are hidden */
+               for(arhide=sa->regionbase.first; arhide; arhide=arhide->next) {
+                       if(arhide->regiontype != RGN_TYPE_WINDOW) {
+                               if(!(arhide->flag & RGN_FLAG_HIDDEN)) {
+                                       ED_region_toggle_hidden(C, arhide);
+                               }
+                       }
+               }
+
+               /* full screen the area */
+               if(!sa->full) {
+                       ED_screen_full_toggle(C, wm->windows.first, sa);
+               }
+
+               /* Fullscreen */
+               if(scene->gm.fullscreen) {
+                       WM_operator_name_call(C, "WM_OT_window_fullscreen_toggle", WM_OP_EXEC_DEFAULT, NULL);
+                       wm_get_screensize(&ar->winrct.xmax, &ar->winrct.ymax);
+               }
+               else
+               {
+                       GHOST_RectangleHandle rect = GHOST_GetClientBounds(win->ghostwin);
+                       ar->winrct.ymax = GHOST_GetHeightRectangle(rect);
+                       ar->winrct.xmax = GHOST_GetWidthRectangle(rect);
+                       GHOST_DisposeRectangle(rect);
+               }
+
                WM_operator_name_call(C, "VIEW3D_OT_game_start", WM_OP_EXEC_DEFAULT, NULL);
-               CTX_wm_window_set(C, prevwin);
+
+               return 1;
+       }
+       else
+       {
+               ReportTimerInfo *rti;
+
+               BKE_report(&wm->reports, RPT_ERROR, "No valid 3D View found. Game auto start is not possible.");
+
+               /* After adding the report to the global list, reset the report timer. */
+               WM_event_remove_timer(wm, NULL, wm->reports.reporttimer);
+
+               /* Records time since last report was added */
+               wm->reports.reporttimer = WM_event_add_timer(wm, CTX_wm_window(C), TIMER, 0.02);
+
+               rti = MEM_callocN(sizeof(ReportTimerInfo), "ReportTimerInfo");
+               wm->reports.reporttimer->customdata = rti;
        }
+       return 0;
 }
 
 /* free strings of open recent files */
index e4bb5b797d34ea72dac7390fea1847aade76b891..45234464ef046957a737bc831ebdc396514baff9 100644 (file)
@@ -73,7 +73,7 @@ static int prefsizx= 0, prefsizy= 0, prefstax= 0, prefstay= 0;
 
 /* XXX this one should correctly check for apple top header...
  done for Cocoa : returns window contents (and not frame) max size*/
-static void wm_get_screensize(int *width_r, int *height_r) 
+void wm_get_screensize(int *width_r, int *height_r)
 {
        unsigned int uiwidth;
        unsigned int uiheight;
index fa244036645123529ac9b6bcf24861847e704d5c..d57fd0e75d825d0ca3fd68fc89f7115280964c29 100644 (file)
@@ -36,6 +36,8 @@ struct wmOperator;
 void           wm_ghost_init                   (bContext *C);
 void           wm_ghost_exit(void);
 
+void wm_get_screensize(int *width_r, int *height_r);
+
 wmWindow       *wm_window_new                  (bContext *C);
 void           wm_window_free                  (bContext *C, wmWindowManager *wm, wmWindow *win);
 void           wm_window_close                 (bContext *C, wmWindowManager *wm, wmWindow *win);
index 283511ef3ffabfae3890fb49495845122f45eaac..77961ec4d809ad602e9f9b99ff08674ff0589683 100644 (file)
@@ -1138,7 +1138,8 @@ int main(int argc, char **argv)
 
        else {
                if((G.fileflags & G_FILE_AUTOPLAY) && (G.f & G_SCRIPT_AUTOEXEC))
-                       WM_init_game(C);
+                       if(WM_init_game(C))
+                               return 0;
 
                else if(!G.file_loaded)
                        WM_init_splash(C);
index a83ec7e132ff83103bef477ce6d8464a2aeb3eb5..c4375ea2a30382de123a2aed0460f76898d05ba0 100644 (file)
@@ -392,6 +392,12 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c
                        AUD_set3DSetting(AUD_3DS_DOPPLER_FACTOR, scene->audio.doppler_factor);
                        AUD_set3DSetting(AUD_3DS_DISTANCE_MODEL, scene->audio.distance_model);
 
+                       // from see blender.c:
+                       // FIXME: this version patching should really be part of the file-reading code,
+                       // but we still get too many unrelated data-corruption crashes otherwise...
+                       if (blenderdata->versionfile < 250)
+                               do_versions_ipos_to_animato(blenderdata);
+
                        if (sceneconverter)
                        {
                                // convert and add scene
index 7327b9c08ff5f338b317af8d386f467924969baa..36f1f5cfa62f548c0c9c9e844dd6d6b6a13ff457 100644 (file)
@@ -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"
@@ -375,15 +379,6 @@ static PyObject* gPyGetSpectrum(PyObject*)
        return resultlist;
 }
 
-
-static PyObject* gPyStopDSP(PyObject*, PyObject* args)
-{
-        PyErr_SetString(PyExc_RuntimeError, "no audio device available");
-        return NULL;
-       
-       Py_RETURN_NONE;
-}
-
 static PyObject* gPySetLogicTicRate(PyObject*, PyObject* args)
 {
        float ticrate;
@@ -752,7 +747,6 @@ static struct PyMethodDef game_methods[] = {
        {"getRandomFloat",(PyCFunction) gPyGetRandomFloat, METH_NOARGS, (const char *)gPyGetRandomFloat_doc},
        {"setGravity",(PyCFunction) gPySetGravity, METH_O, (const char *)"set Gravitation"},
        {"getSpectrum",(PyCFunction) gPyGetSpectrum, METH_NOARGS, (const char *)"get audio spectrum"},
-       {"stopDSP",(PyCFunction) gPyStopDSP, METH_VARARGS, (const char *)"stop using the audio dsp (for performance reasons)"},
        {"getMaxLogicFrame", (PyCFunction) gPyGetMaxLogicFrame, METH_NOARGS, (const char *)"Gets the max number of logic frame per render frame"},
        {"setMaxLogicFrame", (PyCFunction) gPySetMaxLogicFrame, METH_VARARGS, (const char *)"Sets the max number of logic frame per render frame"},
        {"getMaxPhysicsFrame", (PyCFunction) gPyGetMaxPhysicsFrame, METH_NOARGS, (const char *)"Gets the max number of physics frame per render frame"},
@@ -935,7 +929,6 @@ static PyObject* gPyDisableMist(PyObject*)
        Py_RETURN_NONE;
 }
 
-
 static PyObject* gPySetMistStart(PyObject*, PyObject* args)
 {
 
@@ -1313,7 +1306,6 @@ PyObject* initGameLogic(KX_KetsjiEngine *engine, KX_Scene* scene) // quick hack
        KX_MACRO_addTypesToDict(d, KX_PROPSENSOR_EXPRESSION, SCA_PropertySensor::KX_PROPSENSOR_EXPRESSION);
 
        /* 3. Constraint actuator                                                  */
-       /* XXX, TODO NXBGE, move constants names from KX_ACT_CONSTRAINT_foo to KX_CONSTRAINTACT_foo */
        KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_LOCX, KX_ConstraintActuator::KX_ACT_CONSTRAINT_LOCX);
        KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_LOCY, KX_ConstraintActuator::KX_ACT_CONSTRAINT_LOCY);
        KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_LOCZ, KX_ConstraintActuator::KX_ACT_CONSTRAINT_LOCZ);
@@ -1329,18 +1321,18 @@ PyObject* initGameLogic(KX_KetsjiEngine *engine, KX_Scene* scene) // quick hack
        KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_ORIX, KX_ConstraintActuator::KX_ACT_CONSTRAINT_ORIX);
        KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_ORIY, KX_ConstraintActuator::KX_ACT_CONSTRAINT_ORIY);
        KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_ORIZ, KX_ConstraintActuator::KX_ACT_CONSTRAINT_ORIZ);
-       KX_MACRO_addTypesToDict(d, KX_ACT_CONSTRAINT_FHPX, KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHPX);
-       KX_MACRO_addTypesToDict(d, KX_ACT_CONSTRAINT_FHPY, KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHPY);
-       KX_MACRO_addTypesToDict(d, KX_ACT_CONSTRAINT_FHPZ, KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHPZ);
-       KX_MACRO_addTypesToDict(d, KX_ACT_CONSTRAINT_FHNX, KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHNX);
-       KX_MACRO_addTypesToDict(d, KX_ACT_CONSTRAINT_FHNY, KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHNY);
-       KX_MACRO_addTypesToDict(d, KX_ACT_CONSTRAINT_FHNZ, KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHNZ);
-       KX_MACRO_addTypesToDict(d, KX_ACT_CONSTRAINT_NORMAL, KX_ConstraintActuator::KX_ACT_CONSTRAINT_NORMAL);
-       KX_MACRO_addTypesToDict(d, KX_ACT_CONSTRAINT_MATERIAL, KX_ConstraintActuator::KX_ACT_CONSTRAINT_MATERIAL);
-       KX_MACRO_addTypesToDict(d, KX_ACT_CONSTRAINT_PERMANENT, KX_ConstraintActuator::KX_ACT_CONSTRAINT_PERMANENT);
-       KX_MACRO_addTypesToDict(d, KX_ACT_CONSTRAINT_DISTANCE, KX_ConstraintActuator::KX_ACT_CONSTRAINT_DISTANCE);
-       KX_MACRO_addTypesToDict(d, KX_ACT_CONSTRAINT_LOCAL, KX_ConstraintActuator::KX_ACT_CONSTRAINT_LOCAL);
-       KX_MACRO_addTypesToDict(d, KX_ACT_CONSTRAINT_DOROTFH, KX_ConstraintActuator::KX_ACT_CONSTRAINT_DOROTFH);
+       KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_FHPX, KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHPX);
+       KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_FHPY, KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHPY);
+       KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_FHPZ, KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHPZ);
+       KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_FHNX, KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHNX);
+       KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_FHNY, KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHNY);
+       KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_FHNZ, KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHNZ);
+       KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_NORMAL, KX_ConstraintActuator::KX_ACT_CONSTRAINT_NORMAL);
+       KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_MATERIAL, KX_ConstraintActuator::KX_ACT_CONSTRAINT_MATERIAL);
+       KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_PERMANENT, KX_ConstraintActuator::KX_ACT_CONSTRAINT_PERMANENT);
+       KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_DISTANCE, KX_ConstraintActuator::KX_ACT_CONSTRAINT_DISTANCE);
+       KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_LOCAL, KX_ConstraintActuator::KX_ACT_CONSTRAINT_LOCAL);
+       KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_DOROTFH, KX_ConstraintActuator::KX_ACT_CONSTRAINT_DOROTFH);
 
        /* 4. Ipo actuator, simple part                                            */
        KX_MACRO_addTypesToDict(d, KX_IPOACT_PLAY,     KX_IpoActuator::KX_ACT_IPO_PLAY);
@@ -1989,6 +1981,7 @@ void setupGamePython(KX_KetsjiEngine* ketsjiengine, KX_Scene* startscene, Main *
        initGeometry();
        initBGL();
        initBLF();
+       AUD_initPython();
        initVideoTexture();
 
        /* could be done a lot more nicely, but for now a quick way to get bge.* working */
index 1eaea276191f74397f8e7e945910a1bb6f08498d..ce7612d4bcb2bbfd92244f90bde644f813352418 100644 (file)
@@ -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();