668aaeb7e9337d64c462637cbab47e6f65aebbce
[blender-staging.git] / intern / audaspace / Python / AUD_PyAPI.cpp
1 /*
2  * $Id$
3  *
4  * ***** BEGIN LGPL LICENSE BLOCK *****
5  *
6  * Copyright 2009 Jörg Hermann Müller
7  *
8  * This file is part of AudaSpace.
9  *
10  * AudaSpace is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU Lesser General Public License as published by
12  * the Free Software Foundation, either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * AudaSpace is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
22  *
23  * ***** END LGPL LICENSE BLOCK *****
24  */
25
26 #include "AUD_PyAPI.h"
27 #include "structmember.h"
28
29 #include "AUD_NULLDevice.h"
30 #include "AUD_SourceCaps.h"
31 #include "AUD_DelayFactory.h"
32 #include "AUD_DoubleFactory.h"
33 #include "AUD_FaderFactory.h"
34 #include "AUD_HighpassFactory.h"
35 #include "AUD_LimiterFactory.h"
36 #include "AUD_LoopFactory.h"
37 #include "AUD_LowpassFactory.h"
38 #include "AUD_PingPongFactory.h"
39 #include "AUD_PitchFactory.h"
40 #include "AUD_ReverseFactory.h"
41 #include "AUD_SinusFactory.h"
42 #include "AUD_FileFactory.h"
43 #include "AUD_SquareFactory.h"
44 #include "AUD_StreamBufferFactory.h"
45 #include "AUD_SuperposeFactory.h"
46 #include "AUD_VolumeFactory.h"
47
48 #ifdef WITH_SDL
49 #include "AUD_SDLDevice.h"
50 #endif
51
52 #ifdef WITH_OPENAL
53 #include "AUD_OpenALDevice.h"
54 #endif
55
56 #ifdef WITH_JACK
57 #include "AUD_JackDevice.h"
58 #endif
59
60 #include <cstdlib>
61 #include <unistd.h>
62
63 // ====================================================================
64
65 #define PY_MODULE_ADD_CONSTANT(module, name) PyModule_AddIntConstant(module, #name, name)
66
67 // ====================================================================
68
69 static PyObject* AUDError;
70
71 // ====================================================================
72
73 static void
74 Sound_dealloc(Sound* self)
75 {
76         if(self->factory)
77                 delete self->factory;
78         Py_XDECREF(self->child_list);
79         Py_TYPE(self)->tp_free((PyObject*)self);
80 }
81
82 static PyObject *
83 Sound_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
84 {
85         Sound *self;
86
87         self = (Sound*)type->tp_alloc(type, 0);
88         if(self != NULL)
89         {
90                 static const char *kwlist[] = {"filename", NULL};
91                 const char* filename = NULL;
92
93                 if(!PyArg_ParseTupleAndKeywords(args, kwds, "|s", const_cast<char**>(kwlist), &filename))
94                 {
95                         Py_DECREF(self);
96                         return NULL;
97                 }
98                 else if(filename == NULL)
99                 {
100                         Py_DECREF(self);
101                         PyErr_SetString(AUDError, "Missing filename parameter!");
102                         return NULL;
103                 }
104
105                 try
106                 {
107                         self->factory = new AUD_FileFactory(filename);
108                 }
109                 catch(AUD_Exception&)
110                 {
111                         Py_DECREF(self);
112                         PyErr_SetString(AUDError, "Filefactory couldn't be created!");
113                         return NULL;
114                 }
115         }
116
117         return (PyObject *)self;
118 }
119
120 PyDoc_STRVAR(M_aud_Sound_sine_doc,
121                          "sine(frequency)\n\n"
122                          "Creates a sine sound wave.\n\n"
123                          ":arg frequency: The frequency of the sine wave in Hz.\n"
124                          ":type frequency: float\n"
125                          ":return: The created aud.Sound object.\n"
126                          ":rtype: aud.Sound");
127
128 static PyObject *
129 Sound_sine(PyObject* nothing, PyObject* args);
130
131 PyDoc_STRVAR(M_aud_Sound_file_doc,
132                          "file(filename)\n\n"
133                          "Creates a sound object of a sound file.\n\n"
134                          ":arg filename: Path of the file.\n"
135                          ":type filename: string\n"
136                          ":return: The created aud.Sound object.\n"
137                          ":rtype: aud.Sound");
138
139 static PyObject *
140 Sound_file(PyObject* nothing, PyObject* args);
141
142 PyDoc_STRVAR(M_aud_Sound_lowpass_doc,
143                          "lowpass(sound, frequency)\n\n"
144                          "Creates a low quality lowpass filter.\n\n"
145                          ":arg sound: The sound to filter.\n"
146                          ":type sound: aud.Sound\n"
147                          ":arg frequency: The cut off trequency of the lowpass.\n"
148                          ":type frequency: float\n"
149                          ":return: The created aud.Sound object.\n"
150                          ":rtype: aud.Sound");
151
152 static PyObject *
153 Sound_lowpass(PyObject* nothing, PyObject* args);
154
155 PyDoc_STRVAR(M_aud_Sound_delay_doc,
156                          "delay(sound, time)\n\n"
157                          "Delays a sound by playing silence before the sound starts.\n\n"
158                          ":arg sound: The sound to filter.\n"
159                          ":type sound: aud.Sound\n"
160                          ":arg time: How many seconds of silence should be added before the sound.\n"
161                          ":type time: float\n"
162                          ":return: The created aud.Sound object.\n"
163                          ":rtype: aud.Sound");
164
165 static PyObject *
166 Sound_delay(PyObject* nothing, PyObject* args);
167
168 PyDoc_STRVAR(M_aud_Sound_double_doc,
169                          "double(first, second)\n\n"
170                          "Plays two sounds in sequence.\n\n"
171                          ":arg first: The sound to play first.\n"
172                          ":type first: aud.Sound\n"
173                          ":arg second: The sound to play second.\n"
174                          ":type second: aud.Sound\n"
175                          ":return: The created aud.Sound object.\n"
176                          ":rtype: aud.Sound\n"
177                          ".. note:: The two sounds have to have the same specifications "
178                          "(channels and samplerate).");
179
180 static PyObject *
181 Sound_double(PyObject* nothing, PyObject* args);
182
183 PyDoc_STRVAR(M_aud_Sound_highpass_doc,
184                          "highpass(sound, frequency)\n\n"
185                          "Creates a low quality highpass filter.\n\n"
186                          ":arg sound: The sound to filter.\n"
187                          ":type sound: aud.Sound\n"
188                          ":arg frequency: The cut off trequency of the highpass.\n"
189                          ":type frequency: float\n"
190                          ":return: The created aud.Sound object.\n"
191                          ":rtype: aud.Sound");
192
193 static PyObject *
194 Sound_highpass(PyObject* nothing, PyObject* args);
195
196 PyDoc_STRVAR(M_aud_Sound_limiter_doc,
197                          "limit(sound, start, end)\n\n"
198                          "Limits a sound within a specific start and end time.\n\n"
199                          ":arg sound: The sound to filter.\n"
200                          ":type sound: aud.Sound\n"
201                          ":arg start: Start time in seconds.\n"
202                          ":type start: float\n"
203                          ":arg end: End time in seconds.\n"
204                          ":type end: float\n"
205                          ":return: The created aud.Sound object.\n"
206                          ":rtype: aud.Sound");
207
208 static PyObject *
209 Sound_limiter(PyObject* nothing, PyObject* args);
210
211 PyDoc_STRVAR(M_aud_Sound_pitch_doc,
212                          "pitch(sound, factor)\n\n"
213                          "Changes the pitch of a sound with a specific factor.\n\n"
214                          ":arg sound: The sound to filter.\n"
215                          ":type sound: aud.Sound\n"
216                          ":arg factor: The factor to change the pitch with.\n"
217                          ":type factor: float\n"
218                          ":return: The created aud.Sound object.\n"
219                          ":rtype: aud.Sound\n"
220                          ".. note:: This is done by changing the sample rate of the "
221                          "underlying sound, which has to be an integer, so the factor "
222                          "value rounded and the factor may not be 100 % accurate.");
223
224 static PyObject *
225 Sound_pitch(PyObject* nothing, PyObject* args);
226
227 PyDoc_STRVAR(M_aud_Sound_volume_doc,
228                          "volume(sound, volume)\n\n"
229                          "Changes the volume of a sound.\n\n"
230                          ":arg sound: The sound to filter.\n"
231                          ":type sound: aud.Sound\n"
232                          ":arg volume: The new volume..\n"
233                          ":type volume: float\n"
234                          ":return: The created aud.Sound object.\n"
235                          ":rtype: aud.Sound\n"
236                          ".. note:: Should be in the range [0, 1] to avoid clipping.");
237
238 static PyObject *
239 Sound_volume(PyObject* nothing, PyObject* args);
240
241 PyDoc_STRVAR(M_aud_Sound_fadein_doc,
242                          "fadein(sound, start, length)\n\n"
243                          "Fades a sound in.\n\n"
244                          ":arg sound: The sound to filter.\n"
245                          ":type sound: aud.Sound\n"
246                          ":arg start: Time in seconds when the fading should start.\n"
247                          ":type filename: float\n"
248                          ":arg length: Time in seconds how long the fading should last.\n"
249                          ":type filename: float\n"
250                          ":return: The created aud.Sound object.\n"
251                          ":rtype: aud.Sound");
252
253 static PyObject *
254 Sound_fadein(PyObject* nothing, PyObject* args);
255
256 PyDoc_STRVAR(M_aud_Sound_fadeout_doc,
257                          "fadeout(sound, start, length)\n\n"
258                          "Fades a sound out.\n\n"
259                          ":arg sound: The sound to filter.\n"
260                          ":type sound: aud.Sound\n"
261                          ":arg start: Time in seconds when the fading should start.\n"
262                          ":type filename: float\n"
263                          ":arg length: Time in seconds how long the fading should last.\n"
264                          ":type filename: float\n"
265                          ":return: The created aud.Sound object.\n"
266                          ":rtype: aud.Sound");
267
268 static PyObject *
269 Sound_fadeout(PyObject* nothing, PyObject* args);
270
271 PyDoc_STRVAR(M_aud_Sound_loop_doc,
272                          "loop(sound, count)\n\n"
273                          "Loops a sound.\n\n"
274                          ":arg sound: The sound to filter.\n"
275                          ":type sound: aud.Sound\n"
276                          ":arg count: How often the sound should be looped. "
277                          "Negative values mean endlessly.\n"
278                          ":type count: integer\n"
279                          ":return: The created aud.Sound object.\n"
280                          ":rtype: aud.Sound");
281
282 static PyObject *
283 Sound_loop(PyObject* nothing, PyObject* args);
284
285 PyDoc_STRVAR(M_aud_Sound_superpose_doc,
286                          "superpose(sound1, sound2)\n\n"
287                          "Mixes two sounds.\n\n"
288                          ":arg sound1: The sound to filter.\n"
289                          ":type sound1: aud.Sound\n"
290                          ":arg sound2: The sound to filter.\n"
291                          ":type sound2: aud.Sound\n"
292                          ":return: The created aud.Sound object.\n"
293                          ":rtype: aud.Sound");
294
295 static PyObject *
296 Sound_superpose(PyObject* nothing, PyObject* args);
297
298 PyDoc_STRVAR(M_aud_Sound_pingpong_doc,
299                          "pingpong(sound)\n\n"
300                          "Plays a sound forward and then backward.\n\n"
301                          ":arg sound: The sound to filter.\n"
302                          ":type sound: aud.Sound\n"
303                          ":return: The created aud.Sound object.\n"
304                          ":rtype: aud.Sound\n"
305                          ".. note:: The sound has to be buffered to be played reverse.");
306
307 static PyObject *
308 Sound_pingpong(PyObject* nothing, PyObject* args);
309
310 PyDoc_STRVAR(M_aud_Sound_reverse_doc,
311                          "reverse(sound)\n\n"
312                          "Plays a sound reversed.\n\n"
313                          ":arg sound: The sound to filter.\n"
314                          ":type sound: aud.Sound\n"
315                          ":return: The created aud.Sound object.\n"
316                          ":rtype: aud.Sound\n"
317                          ".. note:: The sound has to be buffered to be played reverse.");
318
319 static PyObject *
320 Sound_reverse(PyObject* nothing, PyObject* args);
321
322 PyDoc_STRVAR(M_aud_Sound_buffer_doc,
323                          "buffer(sound)\n\n"
324                          "Buffers a sound into RAM.\n\n"
325                          ":arg sound: The sound to buffer.\n"
326                          ":type sound: aud.Sound\n"
327                          ":return: The created aud.Sound object.\n"
328                          ":rtype: aud.Sound\n"
329                          ".. note:: Raw PCM data needs a lot of space, only buffer short sounds.");
330
331 static PyObject *
332 Sound_buffer(PyObject* nothing, PyObject* args);
333
334 PyDoc_STRVAR(M_aud_Sound_square_doc,
335                          "squre(sound, threshold)\n\n"
336                          "Makes a square wave out of an audio wave.\n\n"
337                          ":arg sound: The sound to filter.\n"
338                          ":type sound: aud.Sound\n"
339                          ":arg threshold: Threshold value over which an amplitude counts non-zero.\n"
340                          ":type threshold: float\n"
341                          ":return: The created aud.Sound object.\n"
342                          ":rtype: aud.Sound");
343
344 static PyObject *
345 Sound_square(PyObject* nothing, PyObject* args);
346
347 static PyMethodDef Sound_methods[] = {
348         {"sine", (PyCFunction)Sound_sine, METH_VARARGS | METH_STATIC,
349          M_aud_Sound_sine_doc
350         },
351         {"file", (PyCFunction)Sound_file, METH_VARARGS | METH_STATIC,
352          M_aud_Sound_file_doc
353         },
354         {"lowpass", (PyCFunction)Sound_lowpass, METH_VARARGS | METH_STATIC,
355          M_aud_Sound_lowpass_doc
356         },
357         {"delay", (PyCFunction)Sound_delay, METH_VARARGS | METH_STATIC,
358          M_aud_Sound_delay_doc
359         },
360         {"double", (PyCFunction)Sound_double, METH_VARARGS | METH_STATIC,
361          M_aud_Sound_double_doc
362         },
363         {"highpass", (PyCFunction)Sound_highpass, METH_VARARGS | METH_STATIC,
364          M_aud_Sound_highpass_doc
365         },
366         {"limiter", (PyCFunction)Sound_limiter, METH_VARARGS | METH_STATIC,
367          M_aud_Sound_limiter_doc
368         },
369         {"pitch", (PyCFunction)Sound_pitch, METH_VARARGS | METH_STATIC,
370          M_aud_Sound_pitch_doc
371         },
372         {"volume", (PyCFunction)Sound_volume, METH_VARARGS | METH_STATIC,
373          M_aud_Sound_volume_doc
374         },
375         {"fadein", (PyCFunction)Sound_fadein, METH_VARARGS | METH_STATIC,
376          M_aud_Sound_fadein_doc
377         },
378         {"fadeout", (PyCFunction)Sound_fadeout, METH_VARARGS | METH_STATIC,
379          M_aud_Sound_fadeout_doc
380         },
381         {"loop", (PyCFunction)Sound_loop, METH_VARARGS | METH_STATIC,
382          M_aud_Sound_loop_doc
383         },
384         {"superpose", (PyCFunction)Sound_superpose, METH_VARARGS | METH_STATIC,
385          M_aud_Sound_superpose_doc
386         },
387         {"pingpong", (PyCFunction)Sound_pingpong, METH_O | METH_STATIC,
388          M_aud_Sound_pingpong_doc
389         },
390         {"reverse", (PyCFunction)Sound_reverse, METH_O | METH_STATIC,
391          M_aud_Sound_reverse_doc
392         },
393         {"buffer", (PyCFunction)Sound_buffer, METH_O | METH_STATIC,
394          M_aud_Sound_buffer_doc
395         },
396         {"square", (PyCFunction)Sound_square, METH_VARARGS | METH_STATIC,
397          M_aud_Sound_square_doc
398         },
399         {NULL}  /* Sentinel */
400 };
401
402 static PyTypeObject SoundType = {
403         PyVarObject_HEAD_INIT(NULL, 0)
404         "aud.Sound",               /* tp_name */
405         sizeof(Sound),             /* tp_basicsize */
406         0,                         /* tp_itemsize */
407         (destructor)Sound_dealloc, /* tp_dealloc */
408         0,                         /* tp_print */
409         0,                         /* tp_getattr */
410         0,                         /* tp_setattr */
411         0,                         /* tp_reserved */
412         0,                         /* tp_repr */
413         0,                         /* tp_as_number */
414         0,                         /* tp_as_sequence */
415         0,                         /* tp_as_mapping */
416         0,                         /* tp_hash  */
417         0,                         /* tp_call */
418         0,                         /* tp_str */
419         0,                         /* tp_getattro */
420         0,                         /* tp_setattro */
421         0,                         /* tp_as_buffer */
422         Py_TPFLAGS_DEFAULT,        /* tp_flags */
423         "Sound object",            /* tp_doc */
424         0,                                 /* tp_traverse */
425         0,                                 /* tp_clear */
426         0,                                 /* tp_richcompare */
427         0,                                 /* tp_weaklistoffset */
428         0,                                 /* tp_iter */
429         0,                                 /* tp_iternext */
430         Sound_methods,             /* tp_methods */
431         0,                         /* tp_members */
432         0,                         /* tp_getset */
433         0,                         /* tp_base */
434         0,                         /* tp_dict */
435         0,                         /* tp_descr_get */
436         0,                         /* tp_descr_set */
437         0,                         /* tp_dictoffset */
438         0,                         /* tp_init */
439         0,                         /* tp_alloc */
440         Sound_new,                 /* tp_new */
441 };
442
443 static PyObject *
444 Sound_sine(PyObject* nothing, PyObject* args)
445 {
446         double frequency;
447
448         if(!PyArg_ParseTuple(args, "d", &frequency))
449                 return NULL;
450
451         Sound *self;
452
453         self = (Sound*)SoundType.tp_alloc(&SoundType, 0);
454         if(self != NULL)
455         {
456                 try
457                 {
458                         self->factory = new AUD_SinusFactory(frequency, (AUD_SampleRate)44100);
459                 }
460                 catch(AUD_Exception&)
461                 {
462                         Py_DECREF(self);
463                         PyErr_SetString(AUDError, "Sinusfactory couldn't be created!");
464                         return NULL;
465                 }
466         }
467
468         return (PyObject *)self;
469 }
470
471 static PyObject *
472 Sound_file(PyObject* nothing, PyObject* args)
473 {
474         const char* filename = NULL;
475
476         if(!PyArg_ParseTuple(args, "s", &filename))
477                 return NULL;
478
479         Sound *self;
480
481         self = (Sound*)SoundType.tp_alloc(&SoundType, 0);
482         if(self != NULL)
483         {
484                 try
485                 {
486                         self->factory = new AUD_FileFactory(filename);
487                 }
488                 catch(AUD_Exception&)
489                 {
490                         Py_DECREF(self);
491                         PyErr_SetString(AUDError, "Filefactory couldn't be created!");
492                         return NULL;
493                 }
494         }
495
496         return (PyObject *)self;
497 }
498
499 static PyObject *
500 Sound_lowpass(PyObject* nothing, PyObject* args)
501 {
502         float frequency;
503         PyObject* object;
504
505         if(!PyArg_ParseTuple(args, "Of", &object, &frequency))
506                 return NULL;
507
508         if(!PyObject_TypeCheck(object, &SoundType))
509         {
510                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Sound!");
511                 return NULL;
512         }
513
514         Sound *self;
515         Sound *child = (Sound*)object;
516
517         self = (Sound*)SoundType.tp_alloc(&SoundType, 0);
518         if(self != NULL)
519         {
520                 Py_INCREF(object);
521                 self->child_list = object;
522
523                 try
524                 {
525                         self->factory = new AUD_LowpassFactory(child->factory, frequency, 0.9);
526                 }
527                 catch(AUD_Exception&)
528                 {
529                         Py_DECREF(self);
530                         PyErr_SetString(AUDError, "Lowpassfactory couldn't be created!");
531                         return NULL;
532                 }
533         }
534
535         return (PyObject *)self;
536 }
537
538 static PyObject *
539 Sound_delay(PyObject* nothing, PyObject* args)
540 {
541         float delay;
542         PyObject* object;
543
544         if(!PyArg_ParseTuple(args, "Of", &object, &delay))
545                 return NULL;
546
547         if(!PyObject_TypeCheck(object, &SoundType))
548         {
549                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Sound!");
550                 return NULL;
551         }
552
553         Sound *self;
554         Sound *child = (Sound*)object;
555
556         self = (Sound*)SoundType.tp_alloc(&SoundType, 0);
557         if(self != NULL)
558         {
559                 Py_INCREF(object);
560                 self->child_list = object;
561
562                 try
563                 {
564                         self->factory = new AUD_DelayFactory(child->factory, delay);
565                 }
566                 catch(AUD_Exception&)
567                 {
568                         Py_DECREF(self);
569                         PyErr_SetString(AUDError, "Delayfactory couldn't be created!");
570                         return NULL;
571                 }
572         }
573
574         return (PyObject *)self;
575 }
576
577 static PyObject *
578 Sound_double(PyObject* nothing, PyObject* args)
579 {
580         PyObject* object1;
581         PyObject* object2;
582
583         if(!PyArg_ParseTuple(args, "OO", &object1, &object2))
584                 return NULL;
585
586         if(!PyObject_TypeCheck(object1, &SoundType))
587         {
588                 PyErr_SetString(PyExc_TypeError, "First object is not of type aud.Sound!");
589                 return NULL;
590         }
591
592         if(!PyObject_TypeCheck(object2, &SoundType))
593         {
594                 PyErr_SetString(PyExc_TypeError, "Second object is not of type aud.Sound!");
595                 return NULL;
596         }
597
598         Sound *self;
599         Sound *child1 = (Sound*)object1;
600         Sound *child2 = (Sound*)object2;
601
602         self = (Sound*)SoundType.tp_alloc(&SoundType, 0);
603         if(self != NULL)
604         {
605                 self->child_list = Py_BuildValue("(OO)", object1, object2);
606
607                 try
608                 {
609                         self->factory = new AUD_DoubleFactory(child1->factory, child2->factory);
610                 }
611                 catch(AUD_Exception&)
612                 {
613                         Py_DECREF(self);
614                         PyErr_SetString(AUDError, "Doublefactory couldn't be created!");
615                         return NULL;
616                 }
617         }
618
619         return (PyObject *)self;
620 }
621
622 static PyObject *
623 Sound_highpass(PyObject* nothing, PyObject* args)
624 {
625         float frequency;
626         PyObject* object;
627
628         if(!PyArg_ParseTuple(args, "Of", &object, &frequency))
629                 return NULL;
630
631         if(!PyObject_TypeCheck(object, &SoundType))
632         {
633                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Sound!");
634                 return NULL;
635         }
636
637         Sound *self;
638         Sound *child = (Sound*)object;
639
640         self = (Sound*)SoundType.tp_alloc(&SoundType, 0);
641         if(self != NULL)
642         {
643                 Py_INCREF(object);
644                 self->child_list = object;
645
646                 try
647                 {
648                         self->factory = new AUD_HighpassFactory(child->factory, frequency, 0.9);
649                 }
650                 catch(AUD_Exception&)
651                 {
652                         Py_DECREF(self);
653                         PyErr_SetString(AUDError, "Highpassfactory couldn't be created!");
654                         return NULL;
655                 }
656         }
657
658         return (PyObject *)self;
659 }
660
661 static PyObject *
662 Sound_limiter(PyObject* nothing, PyObject* args)
663 {
664         float start, end;
665         PyObject* object;
666
667         if(!PyArg_ParseTuple(args, "Off", &object, &start, &end))
668                 return NULL;
669
670         if(!PyObject_TypeCheck(object, &SoundType))
671         {
672                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Sound!");
673                 return NULL;
674         }
675
676         Sound *self;
677         Sound *child = (Sound*)object;
678
679         self = (Sound*)SoundType.tp_alloc(&SoundType, 0);
680         if(self != NULL)
681         {
682                 Py_INCREF(object);
683                 self->child_list = object;
684
685                 try
686                 {
687                         self->factory = new AUD_LimiterFactory(child->factory, start, end);
688                 }
689                 catch(AUD_Exception&)
690                 {
691                         Py_DECREF(self);
692                         PyErr_SetString(AUDError, "Limiterfactory couldn't be created!");
693                         return NULL;
694                 }
695         }
696
697         return (PyObject *)self;
698 }
699
700 static PyObject *
701 Sound_pitch(PyObject* nothing, PyObject* args)
702 {
703         float factor;
704         PyObject* object;
705
706         if(!PyArg_ParseTuple(args, "Of", &object, &factor))
707                 return NULL;
708
709         if(!PyObject_TypeCheck(object, &SoundType))
710         {
711                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Sound!");
712                 return NULL;
713         }
714
715         Sound *self;
716         Sound *child = (Sound*)object;
717
718         self = (Sound*)SoundType.tp_alloc(&SoundType, 0);
719         if(self != NULL)
720         {
721                 Py_INCREF(object);
722                 self->child_list = object;
723
724                 try
725                 {
726                         self->factory = new AUD_PitchFactory(child->factory, factor);
727                 }
728                 catch(AUD_Exception&)
729                 {
730                         Py_DECREF(self);
731                         PyErr_SetString(AUDError, "Pitchfactory couldn't be created!");
732                         return NULL;
733                 }
734         }
735
736         return (PyObject *)self;
737 }
738
739 static PyObject *
740 Sound_volume(PyObject* nothing, PyObject* args)
741 {
742         float volume;
743         PyObject* object;
744
745         if(!PyArg_ParseTuple(args, "Of", &object, &volume))
746                 return NULL;
747
748         if(!PyObject_TypeCheck(object, &SoundType))
749         {
750                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Sound!");
751                 return NULL;
752         }
753
754         Sound *self;
755         Sound *child = (Sound*)object;
756
757         self = (Sound*)SoundType.tp_alloc(&SoundType, 0);
758         if(self != NULL)
759         {
760                 Py_INCREF(object);
761                 self->child_list = object;
762
763                 try
764                 {
765                         self->factory = new AUD_VolumeFactory(child->factory, volume);
766                 }
767                 catch(AUD_Exception&)
768                 {
769                         Py_DECREF(self);
770                         PyErr_SetString(AUDError, "Volumefactory couldn't be created!");
771                         return NULL;
772                 }
773         }
774
775         return (PyObject *)self;
776 }
777
778 static PyObject *
779 Sound_fadein(PyObject* nothing, PyObject* args)
780 {
781         float start, length;
782         PyObject* object;
783
784         if(!PyArg_ParseTuple(args, "Off", &object, &start, &length))
785                 return NULL;
786
787         if(!PyObject_TypeCheck(object, &SoundType))
788         {
789                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Sound!");
790                 return NULL;
791         }
792
793         Sound *self;
794         Sound *child = (Sound*)object;
795
796         self = (Sound*)SoundType.tp_alloc(&SoundType, 0);
797         if(self != NULL)
798         {
799                 Py_INCREF(object);
800                 self->child_list = object;
801
802                 try
803                 {
804                         self->factory = new AUD_FaderFactory(child->factory, AUD_FADE_IN, start, length);
805                 }
806                 catch(AUD_Exception&)
807                 {
808                         Py_DECREF(self);
809                         PyErr_SetString(AUDError, "Faderfactory couldn't be created!");
810                         return NULL;
811                 }
812         }
813
814         return (PyObject *)self;
815 }
816
817 static PyObject *
818 Sound_fadeout(PyObject* nothing, PyObject* args)
819 {
820         float start, length;
821         PyObject* object;
822
823         if(!PyArg_ParseTuple(args, "Off", &object, &start, &length))
824                 return NULL;
825
826         if(!PyObject_TypeCheck(object, &SoundType))
827         {
828                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Sound!");
829                 return NULL;
830         }
831
832         Sound *self;
833         Sound *child = (Sound*)object;
834
835         self = (Sound*)SoundType.tp_alloc(&SoundType, 0);
836         if(self != NULL)
837         {
838                 Py_INCREF(object);
839                 self->child_list = object;
840
841                 try
842                 {
843                         self->factory = new AUD_FaderFactory(child->factory, AUD_FADE_OUT, start, length);
844                 }
845                 catch(AUD_Exception&)
846                 {
847                         Py_DECREF(self);
848                         PyErr_SetString(AUDError, "Faderfactory couldn't be created!");
849                         return NULL;
850                 }
851         }
852
853         return (PyObject *)self;
854 }
855
856 static PyObject *
857 Sound_loop(PyObject* nothing, PyObject* args)
858 {
859         int loop;
860         PyObject* object;
861
862         if(!PyArg_ParseTuple(args, "Oi", &object, &loop))
863                 return NULL;
864
865         if(!PyObject_TypeCheck(object, &SoundType))
866         {
867                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Sound!");
868                 return NULL;
869         }
870
871         Sound *self;
872         Sound *child = (Sound*)object;
873
874         self = (Sound*)SoundType.tp_alloc(&SoundType, 0);
875         if(self != NULL)
876         {
877                 Py_INCREF(object);
878                 self->child_list = object;
879
880                 try
881                 {
882                         self->factory = new AUD_LoopFactory(child->factory, loop);
883                 }
884                 catch(AUD_Exception&)
885                 {
886                         Py_DECREF(self);
887                         PyErr_SetString(AUDError, "Loopfactory couldn't be created!");
888                         return NULL;
889                 }
890         }
891
892         return (PyObject *)self;
893 }
894
895 static PyObject *
896 Sound_superpose(PyObject* nothing, PyObject* args)
897 {
898         PyObject* object1;
899         PyObject* object2;
900
901         if(!PyArg_ParseTuple(args, "OO", &object1, &object2))
902                 return NULL;
903
904         if(!PyObject_TypeCheck(object1, &SoundType))
905         {
906                 PyErr_SetString(PyExc_TypeError, "First object is not of type aud.Sound!");
907                 return NULL;
908         }
909
910         if(!PyObject_TypeCheck(object2, &SoundType))
911         {
912                 PyErr_SetString(PyExc_TypeError, "Second object is not of type aud.Sound!");
913                 return NULL;
914         }
915
916         Sound *self;
917         Sound *child1 = (Sound*)object1;
918         Sound *child2 = (Sound*)object2;
919
920         self = (Sound*)SoundType.tp_alloc(&SoundType, 0);
921         if(self != NULL)
922         {
923                 self->child_list = Py_BuildValue("(OO)", object1, object2);
924
925                 try
926                 {
927                         self->factory = new AUD_SuperposeFactory(child1->factory, child2->factory);
928                 }
929                 catch(AUD_Exception&)
930                 {
931                         Py_DECREF(self);
932                         PyErr_SetString(AUDError, "Superposefactory couldn't be created!");
933                         return NULL;
934                 }
935         }
936
937         return (PyObject *)self;
938 }
939
940 static PyObject *
941 Sound_pingpong(PyObject* nothing, PyObject* object)
942 {
943         if(!PyObject_TypeCheck(object, &SoundType))
944         {
945                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Sound!");
946                 return NULL;
947         }
948
949         Sound *self;
950         Sound *child = (Sound*)object;
951
952         self = (Sound*)SoundType.tp_alloc(&SoundType, 0);
953         if(self != NULL)
954         {
955                 Py_INCREF(object);
956                 self->child_list = object;
957
958                 try
959                 {
960                         self->factory = new AUD_PingPongFactory(child->factory);
961                 }
962                 catch(AUD_Exception&)
963                 {
964                         Py_DECREF(self);
965                         PyErr_SetString(AUDError, "Pingpongfactory couldn't be created!");
966                         return NULL;
967                 }
968         }
969
970         return (PyObject *)self;
971 }
972
973 static PyObject *
974 Sound_reverse(PyObject* nothing, PyObject* object)
975 {
976         if(!PyObject_TypeCheck(object, &SoundType))
977         {
978                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Sound!");
979                 return NULL;
980         }
981
982         Sound *self;
983         Sound *child = (Sound*)object;
984
985         self = (Sound*)SoundType.tp_alloc(&SoundType, 0);
986         if(self != NULL)
987         {
988                 Py_INCREF(object);
989                 self->child_list = object;
990
991                 try
992                 {
993                         self->factory = new AUD_ReverseFactory(child->factory);
994                 }
995                 catch(AUD_Exception&)
996                 {
997                         Py_DECREF(self);
998                         PyErr_SetString(AUDError, "Reversefactory couldn't be created!");
999                         return NULL;
1000                 }
1001         }
1002
1003         return (PyObject *)self;
1004 }
1005
1006 static PyObject *
1007 Sound_buffer(PyObject* nothing, PyObject* object)
1008 {
1009         if(!PyObject_TypeCheck(object, &SoundType))
1010         {
1011                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Sound!");
1012                 return NULL;
1013         }
1014
1015         Sound *self;
1016         Sound *child = (Sound*)object;
1017
1018         self = (Sound*)SoundType.tp_alloc(&SoundType, 0);
1019         if(self != NULL)
1020         {
1021                 try
1022                 {
1023                         self->factory = new AUD_StreamBufferFactory(child->factory);
1024                 }
1025                 catch(AUD_Exception&)
1026                 {
1027                         Py_DECREF(self);
1028                         PyErr_SetString(AUDError, "Bufferfactory couldn't be created!");
1029                         return NULL;
1030                 }
1031         }
1032
1033         return (PyObject *)self;
1034 }
1035
1036 static PyObject *
1037 Sound_square(PyObject* nothing, PyObject* args)
1038 {
1039         float threshold;
1040         PyObject* object;
1041
1042         if(!PyArg_ParseTuple(args, "Of", &object, &threshold))
1043                 return NULL;
1044
1045         if(!PyObject_TypeCheck(object, &SoundType))
1046         {
1047                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Sound!");
1048                 return NULL;
1049         }
1050
1051         Sound *self;
1052         Sound *child = (Sound*)object;
1053
1054         self = (Sound*)SoundType.tp_alloc(&SoundType, 0);
1055         if(self != NULL)
1056         {
1057                 Py_INCREF(object);
1058                 self->child_list = object;
1059
1060                 try
1061                 {
1062                         self->factory = new AUD_SquareFactory(child->factory, threshold);
1063                 }
1064                 catch(AUD_Exception&)
1065                 {
1066                         Py_DECREF(self);
1067                         PyErr_SetString(AUDError, "Squarefactory couldn't be created!");
1068                         return NULL;
1069                 }
1070         }
1071
1072         return (PyObject *)self;
1073 }
1074
1075 // ========== Handle ==================================================
1076
1077 static void
1078 Handle_dealloc(Handle* self)
1079 {
1080         Py_XDECREF(self->device);
1081         Py_TYPE(self)->tp_free((PyObject*)self);
1082 }
1083
1084 PyDoc_STRVAR(M_aud_Handle_pause_doc,
1085                          "pause()\n\n"
1086                          "Pauses playback.\n\n"
1087                          ":return: Whether the action succeeded.\n"
1088                          ":rtype: boolean");
1089
1090 static PyObject *
1091 Handle_pause(Handle *self)
1092 {
1093         return PyObject_CallMethod(self->device, const_cast<char*>("_pause"), const_cast<char*>("(O)"), self);
1094 }
1095
1096 PyDoc_STRVAR(M_aud_Handle_resume_doc,
1097                          "resume()\n\n"
1098                          "Resumes playback.\n\n"
1099                          ":return: Whether the action succeeded.\n"
1100                          ":rtype: boolean");
1101
1102 static PyObject *
1103 Handle_resume(Handle *self)
1104 {
1105         return PyObject_CallMethod(self->device, const_cast<char*>("_resume"), const_cast<char*>("(O)"), self);
1106 }
1107
1108 PyDoc_STRVAR(M_aud_Handle_stop_doc,
1109                          "stop()\n\n"
1110                          "Stops playback.\n\n"
1111                          ":return: Whether the action succeeded.\n"
1112                          ":rtype: boolean");
1113
1114 static PyObject *
1115 Handle_stop(Handle *self)
1116 {
1117         return PyObject_CallMethod(self->device, const_cast<char*>("_stop"), const_cast<char*>("(O)"), self);
1118 }
1119
1120 PyDoc_STRVAR(M_aud_Handle_update_doc,
1121                          "update(info)\n\n"
1122                          "Updates the 3D information of the source."
1123                          ":arg info: The 3D info in the format (fff)(fff)((fff)(fff)(fff))."
1124                          " Position, velocity and a 3x3 orientation matrix.\n"
1125                          ":type info: float tuple\n"
1126                          ":return: Whether the action succeeded.\n"
1127                          ":rtype: boolean");
1128
1129 static PyObject *
1130 Handle_update(Handle *self, PyObject *data)
1131 {
1132         return PyObject_CallMethod(self->device, const_cast<char*>("_update_source"), const_cast<char*>("(OO)"), self, data);
1133 }
1134
1135 static PyMethodDef Handle_methods[] = {
1136         {"pause", (PyCFunction)Handle_pause, METH_NOARGS,
1137          M_aud_Handle_pause_doc
1138         },
1139         {"resume", (PyCFunction)Handle_resume, METH_NOARGS,
1140          M_aud_Handle_resume_doc
1141         },
1142         {"stop", (PyCFunction)Handle_stop, METH_NOARGS,
1143          M_aud_Handle_stop_doc
1144         },
1145         {"update", (PyCFunction)Handle_update, METH_O,
1146          M_aud_Handle_update_doc
1147         },
1148         {NULL}  /* Sentinel */
1149 };
1150
1151 PyDoc_STRVAR(M_aud_Handle_position_doc,
1152                          "The playback position of the sound.");
1153
1154 static PyObject *
1155 Handle_get_position(Handle *self, void* nothing)
1156 {
1157         return PyObject_CallMethod(self->device, const_cast<char*>("_get_position"), const_cast<char*>("(O)"), self);
1158 }
1159
1160 static int
1161 Handle_set_position(Handle *self, PyObject* args, void* nothing)
1162 {
1163         PyObject* result = PyObject_CallMethod(self->device, const_cast<char*>("_seek"), const_cast<char*>("(OO)"), self, args);
1164         if(result)
1165         {
1166                 Py_DECREF(result);
1167                 return 0;
1168         }
1169         return -1;
1170 }
1171
1172 PyDoc_STRVAR(M_aud_Handle_keep_doc,
1173                          "Whether the sound should be kept paused in the device when its end is reached.");
1174
1175 static int
1176 Handle_set_keep(Handle *self, PyObject* args, void* nothing)
1177 {
1178         PyObject* result = PyObject_CallMethod(self->device, const_cast<char*>("_set_keep"), const_cast<char*>("(OO)"), self, args);
1179         if(result)
1180         {
1181                 Py_DECREF(result);
1182                 return 0;
1183         }
1184         return -1;
1185 }
1186
1187 PyDoc_STRVAR(M_aud_Handle_status_doc,
1188                          "Whether the sound is playing, paused or stopped.");
1189
1190 static PyObject *
1191 Handle_get_status(Handle *self, void* nothing)
1192 {
1193         return PyObject_CallMethod(self->device, const_cast<char*>("_get_status"), const_cast<char*>("(O)"), self);
1194 }
1195
1196 PyDoc_STRVAR(M_aud_Handle_volume_doc,
1197                          "The volume of the sound.");
1198
1199 static PyObject *
1200 Handle_get_volume(Handle *self, void* nothing)
1201 {
1202         return PyObject_CallMethod(self->device, const_cast<char*>("_get_volume"), const_cast<char*>("(O)"), self);
1203 }
1204
1205 static int
1206 Handle_set_volume(Handle *self, PyObject* args, void* nothing)
1207 {
1208         PyObject* result = PyObject_CallMethod(self->device, const_cast<char*>("_set_volume"), const_cast<char*>("(OO)"), self, args);
1209         if(result)
1210         {
1211                 Py_DECREF(result);
1212                 return 0;
1213         }
1214         return -1;
1215 }
1216
1217 PyDoc_STRVAR(M_aud_Handle_pitch_doc,
1218                          "The pitch of the sound.");
1219
1220 static int
1221 Handle_set_pitch(Handle *self, PyObject* args, void* nothing)
1222 {
1223         PyObject* result = PyObject_CallMethod(self->device, const_cast<char*>("_set_pitch"), const_cast<char*>("(OO)"), self, args);
1224         if(result)
1225         {
1226                 Py_DECREF(result);
1227                 return 0;
1228         }
1229         return -1;
1230 }
1231
1232 PyDoc_STRVAR(M_aud_Handle_loop_count_doc,
1233                          "The (remaining) loop count of the sound. A negative value indicates infinity.");
1234
1235 static int
1236 Handle_set_loop_count(Handle *self, PyObject* args, void* nothing)
1237 {
1238         PyObject* result = PyObject_CallMethod(self->device, const_cast<char*>("_set_loop_count"), const_cast<char*>("(OO)"), self, args);
1239         if(result)
1240         {
1241                 Py_DECREF(result);
1242                 return 0;
1243         }
1244         return -1;
1245 }
1246
1247 PyDoc_STRVAR(M_aud_Handle_relative_doc,
1248                          "Whether the source's position is relative or absolute to the listener.");
1249
1250 static PyObject *
1251 Handle_get_relative(Handle *self, void* nothing)
1252 {
1253         return PyObject_CallMethod(self->device, const_cast<char*>("_is_relative"), const_cast<char*>("(O)"), self);
1254 }
1255
1256 static int
1257 Handle_set_relative(Handle *self, PyObject* args, void* nothing)
1258 {
1259         PyObject* result = PyObject_CallMethod(self->device, const_cast<char*>("_set_relative"), const_cast<char*>("(OO)"), self, args);
1260         if(result)
1261         {
1262                 Py_DECREF(result);
1263                 return 0;
1264         }
1265         return -1;
1266 }
1267
1268 PyDoc_STRVAR(M_aud_Handle_min_gain_doc,
1269                          "The minimum gain of the source.");
1270
1271 static PyObject *
1272 Handle_get_min_gain(Handle *self, void* nothing)
1273 {
1274         return PyObject_CallMethod(self->device, const_cast<char*>("_get_min_gain"), const_cast<char*>("(O)"), self);
1275 }
1276
1277 static int
1278 Handle_set_min_gain(Handle *self, PyObject* args, void* nothing)
1279 {
1280         PyObject* result = PyObject_CallMethod(self->device, const_cast<char*>("_set_min_gain"), const_cast<char*>("(OO)"), self, args);
1281         if(result)
1282         {
1283                 Py_DECREF(result);
1284                 return 0;
1285         }
1286         return -1;
1287 }
1288
1289 PyDoc_STRVAR(M_aud_Handle_max_gain_doc,
1290                          "The maximum gain of the source.");
1291
1292 static PyObject *
1293 Handle_get_max_gain(Handle *self, void* nothing)
1294 {
1295         return PyObject_CallMethod(self->device, const_cast<char*>("_get_max_gain"), const_cast<char*>("(O)"), self);
1296 }
1297
1298 static int
1299 Handle_set_max_gain(Handle *self, PyObject* args, void* nothing)
1300 {
1301         PyObject* result = PyObject_CallMethod(self->device, const_cast<char*>("_set_max_gain"), const_cast<char*>("(OO)"), self, args);
1302         if(result)
1303         {
1304                 Py_DECREF(result);
1305                 return 0;
1306         }
1307         return -1;
1308 }
1309
1310 PyDoc_STRVAR(M_aud_Handle_reference_distance_doc,
1311                          "The reference distance of the source.");
1312
1313 static PyObject *
1314 Handle_get_reference_distance(Handle *self, void* nothing)
1315 {
1316         return PyObject_CallMethod(self->device, const_cast<char*>("_get_reference_distance"), const_cast<char*>("(O)"), self);
1317 }
1318
1319 static int
1320 Handle_set_reference_distance(Handle *self, PyObject* args, void* nothing)
1321 {
1322         PyObject* result = PyObject_CallMethod(self->device, const_cast<char*>("_set_reference_distance"), const_cast<char*>("(OO)"), self, args);
1323         if(result)
1324         {
1325                 Py_DECREF(result);
1326                 return 0;
1327         }
1328         return -1;
1329 }
1330
1331 PyDoc_STRVAR(M_aud_Handle_max_distance_doc,
1332                          "The maximum distance of the source.");
1333
1334 static PyObject *
1335 Handle_get_max_distance(Handle *self, void* nothing)
1336 {
1337         return PyObject_CallMethod(self->device, const_cast<char*>("_get_max_distance"), const_cast<char*>("(O)"), self);
1338 }
1339
1340 static int
1341 Handle_set_max_distance(Handle *self, PyObject* args, void* nothing)
1342 {
1343         PyObject* result = PyObject_CallMethod(self->device, const_cast<char*>("_set_max_distance"), const_cast<char*>("(OO)"), self, args);
1344         if(result)
1345         {
1346                 Py_DECREF(result);
1347                 return 0;
1348         }
1349         return -1;
1350 }
1351
1352 PyDoc_STRVAR(M_aud_Handle_rolloff_factor_doc,
1353                          "The rolloff factor of the source.");
1354
1355 static PyObject *
1356 Handle_get_rolloff_factor(Handle *self, void* nothing)
1357 {
1358         return PyObject_CallMethod(self->device, const_cast<char*>("_get_rolloff_factor"), const_cast<char*>("(O)"), self);
1359 }
1360
1361 static int
1362 Handle_set_rolloff_factor(Handle *self, PyObject* args, void* nothing)
1363 {
1364         PyObject* result = PyObject_CallMethod(self->device, const_cast<char*>("_set_rolloff_factor"), const_cast<char*>("(OO)"), self, args);
1365         if(result)
1366         {
1367                 Py_DECREF(result);
1368                 return 0;
1369         }
1370         return -1;
1371 }
1372
1373 PyDoc_STRVAR(M_aud_Handle_cone_inner_angle_doc,
1374                          "The cone inner angle of the source.");
1375
1376 static PyObject *
1377 Handle_get_cone_inner_angle(Handle *self, void* nothing)
1378 {
1379         return PyObject_CallMethod(self->device, const_cast<char*>("_get_cone_inner_angle"), const_cast<char*>("(O)"), self);
1380 }
1381
1382 static int
1383 Handle_set_cone_inner_angle(Handle *self, PyObject* args, void* nothing)
1384 {
1385         PyObject* result = PyObject_CallMethod(self->device, const_cast<char*>("_set_cone_inner_angle"), const_cast<char*>("(OO)"), self, args);
1386         if(result)
1387         {
1388                 Py_DECREF(result);
1389                 return 0;
1390         }
1391         return -1;
1392 }
1393
1394 PyDoc_STRVAR(M_aud_Handle_cone_outer_angle_doc,
1395                          "The cone outer angle of the source.");
1396
1397 static PyObject *
1398 Handle_get_cone_outer_angle(Handle *self, void* nothing)
1399 {
1400         return PyObject_CallMethod(self->device, const_cast<char*>("_get_cone_outer_angle"), const_cast<char*>("(O)"), self);
1401 }
1402
1403 static int
1404 Handle_set_cone_outer_angle(Handle *self, PyObject* args, void* nothing)
1405 {
1406         PyObject* result = PyObject_CallMethod(self->device, const_cast<char*>("_set_cone_outer_angle"), const_cast<char*>("(OO)"), self, args);
1407         if(result)
1408         {
1409                 Py_DECREF(result);
1410                 return 0;
1411         }
1412         return -1;
1413 }
1414
1415 PyDoc_STRVAR(M_aud_Handle_cone_outer_gain_doc,
1416                          "The cone outer gain of the source.");
1417
1418 static PyObject *
1419 Handle_get_cone_outer_gain(Handle *self, void* nothing)
1420 {
1421         return PyObject_CallMethod(self->device, const_cast<char*>("_get_cone_outer_gain"), const_cast<char*>("(O)"), self);
1422 }
1423
1424 static int
1425 Handle_set_cone_outer_gain(Handle *self, PyObject* args, void* nothing)
1426 {
1427         PyObject* result = PyObject_CallMethod(self->device, const_cast<char*>("_set_cone_outer_gain"), const_cast<char*>("(OO)"), self, args);
1428         if(result)
1429         {
1430                 Py_DECREF(result);
1431                 return 0;
1432         }
1433         return -1;
1434 }
1435
1436 static PyGetSetDef Handle_properties[] = {
1437         {(char*)"position", (getter)Handle_get_position, (setter)Handle_set_position,
1438          M_aud_Handle_position_doc, NULL },
1439         {(char*)"keep", NULL, (setter)Handle_set_keep,
1440          M_aud_Handle_keep_doc, NULL },
1441         {(char*)"status", (getter)Handle_get_status, NULL,
1442          M_aud_Handle_status_doc, NULL },
1443         {(char*)"volume", (getter)Handle_get_volume, (setter)Handle_set_volume,
1444          M_aud_Handle_volume_doc, NULL },
1445         {(char*)"pitch", NULL, (setter)Handle_set_pitch,
1446          M_aud_Handle_pitch_doc, NULL },
1447         {(char*)"loop_count", NULL, (setter)Handle_set_loop_count,
1448          M_aud_Handle_loop_count_doc, NULL },
1449         {(char*)"relative", (getter)Handle_get_relative, (setter)Handle_set_relative,
1450          M_aud_Handle_relative_doc, NULL },
1451         {(char*)"min_gain", (getter)Handle_get_min_gain, (setter)Handle_set_min_gain,
1452          M_aud_Handle_min_gain_doc, NULL },
1453         {(char*)"max_gain", (getter)Handle_get_max_gain, (setter)Handle_set_max_gain,
1454          M_aud_Handle_max_gain_doc, NULL },
1455         {(char*)"reference_distance", (getter)Handle_get_reference_distance, (setter)Handle_set_reference_distance,
1456          M_aud_Handle_reference_distance_doc, NULL },
1457         {(char*)"max_distance", (getter)Handle_get_max_distance, (setter)Handle_set_max_distance,
1458          M_aud_Handle_max_distance_doc, NULL },
1459         {(char*)"rolloff_factor", (getter)Handle_get_rolloff_factor, (setter)Handle_set_rolloff_factor,
1460          M_aud_Handle_rolloff_factor_doc, NULL },
1461         {(char*)"cone_inner_angle", (getter)Handle_get_cone_inner_angle, (setter)Handle_set_cone_inner_angle,
1462          M_aud_Handle_cone_inner_angle_doc, NULL },
1463         {(char*)"cone_outer_angle", (getter)Handle_get_cone_outer_angle, (setter)Handle_set_cone_outer_angle,
1464          M_aud_Handle_cone_outer_angle_doc, NULL },
1465         {(char*)"cone_outer_gain", (getter)Handle_get_cone_outer_gain, (setter)Handle_set_cone_outer_gain,
1466          M_aud_Handle_cone_outer_gain_doc, NULL },
1467         {NULL}  /* Sentinel */
1468 };
1469
1470 static PyTypeObject HandleType = {
1471         PyVarObject_HEAD_INIT(NULL, 0)
1472         "aud.Handle",              /* tp_name */
1473         sizeof(Handle),            /* tp_basicsize */
1474         0,                         /* tp_itemsize */
1475         (destructor)Handle_dealloc,/* tp_dealloc */
1476         0,                         /* tp_print */
1477         0,                         /* tp_getattr */
1478         0,                         /* tp_setattr */
1479         0,                         /* tp_reserved */
1480         0,                         /* tp_repr */
1481         0,                         /* tp_as_number */
1482         0,                         /* tp_as_sequence */
1483         0,                         /* tp_as_mapping */
1484         0,                         /* tp_hash  */
1485         0,                         /* tp_call */
1486         0,                         /* tp_str */
1487         0,                         /* tp_getattro */
1488         0,                         /* tp_setattro */
1489         0,                         /* tp_as_buffer */
1490         Py_TPFLAGS_DEFAULT,        /* tp_flags */
1491         "Handle object",           /* tp_doc */
1492         0,                                 /* tp_traverse */
1493         0,                                 /* tp_clear */
1494         0,                                 /* tp_richcompare */
1495         0,                                 /* tp_weaklistoffset */
1496         0,                                 /* tp_iter */
1497         0,                                 /* tp_iternext */
1498         Handle_methods,            /* tp_methods */
1499         0,                         /* tp_members */
1500         Handle_properties,         /* tp_getset */
1501         0,                         /* tp_base */
1502         0,                         /* tp_dict */
1503         0,                         /* tp_descr_get */
1504         0,                         /* tp_descr_set */
1505         0,                         /* tp_dictoffset */
1506         0,                         /* tp_init */
1507         0,                         /* tp_alloc */
1508         0,                         /* tp_new */
1509 };
1510
1511 // ========== Device ==================================================
1512
1513 static void
1514 Device_dealloc(Device* self)
1515 {
1516         if(self->device)
1517                 delete self->device;
1518         Py_TYPE(self)->tp_free((PyObject*)self);
1519 }
1520
1521 PyDoc_STRVAR(M_aud_Device_play_doc,
1522                          "play(sound[, keep])\n\n"
1523                          "Plays a sound.\n\n"
1524                          ":arg sound: The sound to play.\n"
1525                          ":type sound: aud.Sound\n"
1526                          ":arg keep: Whether the sound should be kept paused in the device when its end is reached.\n"
1527                          ":type keep: boolean\n"
1528                          ":return: The playback handle.\n"
1529                          ":rtype: aud.Handle");
1530
1531 static PyObject *
1532 Device_play(Device *self, PyObject *args, PyObject *kwds)
1533 {
1534         PyObject* object;
1535         PyObject* keepo = NULL;
1536
1537         bool keep = false;
1538
1539         static const char *kwlist[] = {"sound", "keep", NULL};
1540
1541         if(!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", const_cast<char**>(kwlist), &object, &keepo))
1542                 return NULL;
1543
1544         if(!PyObject_TypeCheck(object, &SoundType))
1545         {
1546                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Sound!");
1547                 return NULL;
1548         }
1549
1550         if(keepo != NULL)
1551         {
1552                 if(!PyBool_Check(keepo))
1553                 {
1554                         PyErr_SetString(PyExc_TypeError, "keep is not a boolean!");
1555                         return NULL;
1556                 }
1557
1558                 keep = keepo == Py_True;
1559         }
1560
1561         Sound* sound = (Sound*)object;
1562         Handle *handle;
1563
1564         handle = (Handle*)HandleType.tp_alloc(&HandleType, 0);
1565         if(handle != NULL)
1566         {
1567                 handle->device = (PyObject*)self;
1568                 Py_INCREF(self);
1569
1570                 try
1571                 {
1572                         handle->handle = self->device->play(sound->factory, keep);
1573                 }
1574                 catch(AUD_Exception&)
1575                 {
1576                         Py_DECREF(handle);
1577                         PyErr_SetString(AUDError, "Couldn't play the sound!");
1578                         return NULL;
1579                 }
1580         }
1581
1582         return (PyObject *)handle;
1583 }
1584
1585 static PyObject *
1586 Device_stop(Device *self, PyObject *object)
1587 {
1588         if(!PyObject_TypeCheck(object, &HandleType))
1589         {
1590                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
1591                 return NULL;
1592         }
1593
1594         Handle* handle = (Handle*)object;
1595
1596         try
1597         {
1598                 if(self->device->stop(handle->handle))
1599                 {
1600                         Py_RETURN_TRUE;
1601                 }
1602         }
1603         catch(AUD_Exception&)
1604         {
1605                 PyErr_SetString(AUDError, "Couldn't stop the sound!");
1606                 return NULL;
1607         }
1608
1609         Py_RETURN_FALSE;
1610 }
1611
1612 static PyObject *
1613 Device_pause(Device *self, PyObject *object)
1614 {
1615         if(!PyObject_TypeCheck(object, &HandleType))
1616         {
1617                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
1618                 return NULL;
1619         }
1620
1621         Handle* handle = (Handle*)object;
1622
1623         try
1624         {
1625                 if(self->device->pause(handle->handle))
1626                 {
1627                         Py_RETURN_TRUE;
1628                 }
1629         }
1630         catch(AUD_Exception&)
1631         {
1632                 PyErr_SetString(AUDError, "Couldn't pause the sound!");
1633                 return NULL;
1634         }
1635
1636         Py_RETURN_FALSE;
1637 }
1638
1639 static PyObject *
1640 Device_resume(Device *self, PyObject *object)
1641 {
1642         if(!PyObject_TypeCheck(object, &HandleType))
1643         {
1644                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
1645                 return NULL;
1646         }
1647
1648         Handle* handle = (Handle*)object;
1649
1650         try
1651         {
1652                 if(self->device->resume(handle->handle))
1653                 {
1654                         Py_RETURN_TRUE;
1655                 }
1656         }
1657         catch(AUD_Exception&)
1658         {
1659                 PyErr_SetString(AUDError, "Couldn't resume the sound!");
1660                 return NULL;
1661         }
1662
1663         Py_RETURN_FALSE;
1664 }
1665
1666 static PyObject *
1667 Device_set_keep(Device *self, PyObject *args)
1668 {
1669         PyObject* object;
1670         PyObject* keepo;
1671
1672         if(!PyArg_ParseTuple(args, "OO", &object, &keepo))
1673                 return NULL;
1674
1675         if(!PyObject_TypeCheck(object, &HandleType))
1676         {
1677                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
1678                 return NULL;
1679         }
1680
1681         if(!PyBool_Check(keepo))
1682         {
1683                 PyErr_SetString(PyExc_TypeError, "keep is not a boolean!");
1684                 return NULL;
1685         }
1686
1687         bool keep = keepo == Py_True;
1688         Handle* handle = (Handle*)object;
1689
1690         try
1691         {
1692                 if(self->device->setKeep(handle->handle, keep))
1693                 {
1694                         Py_RETURN_TRUE;
1695                 }
1696         }
1697         catch(AUD_Exception&)
1698         {
1699                 PyErr_SetString(AUDError, "Couldn't set keep of the sound!");
1700                 return NULL;
1701         }
1702
1703         Py_RETURN_FALSE;
1704 }
1705
1706 static PyObject *
1707 Device_seek(Device *self, PyObject *args)
1708 {
1709         PyObject* object;
1710         float position;
1711
1712         if(!PyArg_ParseTuple(args, "Of", &object, &position))
1713                 return NULL;
1714
1715         if(!PyObject_TypeCheck(object, &HandleType))
1716         {
1717                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
1718                 return NULL;
1719         }
1720
1721         Handle* handle = (Handle*)object;
1722
1723         try
1724         {
1725                 if(self->device->seek(handle->handle, position))
1726                 {
1727                         Py_RETURN_TRUE;
1728                 }
1729         }
1730         catch(AUD_Exception&)
1731         {
1732                 PyErr_SetString(AUDError, "Couldn't seek the sound!");
1733                 return NULL;
1734         }
1735
1736         Py_RETURN_FALSE;
1737 }
1738
1739 static PyObject *
1740 Device_get_position(Device *self, PyObject *object)
1741 {
1742         if(!PyObject_TypeCheck(object, &HandleType))
1743         {
1744                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
1745                 return NULL;
1746         }
1747
1748         Handle* handle = (Handle*)object;
1749
1750         try
1751         {
1752                 return Py_BuildValue("f", self->device->getPosition(handle->handle));
1753         }
1754         catch(AUD_Exception&)
1755         {
1756                 PyErr_SetString(AUDError, "Couldn't retrieve the position of the sound!");
1757                 return NULL;
1758         }
1759 }
1760
1761 static PyObject *
1762 Device_get_status(Device *self, PyObject *object)
1763 {
1764         if(!PyObject_TypeCheck(object, &HandleType))
1765         {
1766                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
1767                 return NULL;
1768         }
1769
1770         Handle* handle = (Handle*)object;
1771
1772         try
1773         {
1774                 return Py_BuildValue("i", self->device->getStatus(handle->handle));
1775         }
1776         catch(AUD_Exception&)
1777         {
1778                 PyErr_SetString(AUDError, "Couldn't retrieve the status of the sound!");
1779                 return NULL;
1780         }
1781 }
1782
1783 PyDoc_STRVAR(M_aud_Device_lock_doc,
1784                          "lock()\n\n"
1785                          "Locks the device so that it's guaranteed, that no samples are "
1786                          "read from the streams until the unlock is called. The device has "
1787                          "to be unlocked as often as locked to be able to continue "
1788                          "playback. Make sure the time between locking and unlocking is as "
1789                          "short as possible to avoid clicks.");
1790
1791 static PyObject *
1792 Device_lock(Device *self)
1793 {
1794         try
1795         {
1796                 self->device->lock();
1797                 Py_RETURN_NONE;
1798         }
1799         catch(AUD_Exception&)
1800         {
1801                 PyErr_SetString(AUDError, "Couldn't lock the device!");
1802                 return NULL;
1803         }
1804 }
1805
1806 PyDoc_STRVAR(M_aud_Device_unlock_doc,
1807                          "unlock()\n\n"
1808                          "Plays a sound.\n\n"
1809                          "Unlocks the device after a lock call, see lock() for details.");
1810
1811 static PyObject *
1812 Device_unlock(Device *self)
1813 {
1814         try
1815         {
1816                 self->device->unlock();
1817                 Py_RETURN_NONE;
1818         }
1819         catch(AUD_Exception&)
1820         {
1821                 PyErr_SetString(AUDError, "Couldn't unlock the device!");
1822                 return NULL;
1823         }
1824 }
1825
1826 static PyObject *
1827 Device_set_source_volume(Device *self, PyObject *args)
1828 {
1829         PyObject* object;
1830         float volume;
1831
1832         if(!PyArg_ParseTuple(args, "Of", &object, &volume))
1833                 return NULL;
1834
1835         if(!PyObject_TypeCheck(object, &HandleType))
1836         {
1837                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
1838                 return NULL;
1839         }
1840
1841         Handle* handle = (Handle*)object;
1842
1843         try
1844         {
1845                 AUD_SourceCaps caps;
1846                 caps.handle = handle->handle;
1847                 caps.value = volume;
1848                 if(self->device->setCapability(AUD_CAPS_SOURCE_VOLUME, &caps))
1849                 {
1850                         Py_RETURN_TRUE;
1851                 }
1852         }
1853         catch(AUD_Exception&)
1854         {
1855                 PyErr_SetString(AUDError, "Couldn't set the sound volume!");
1856                 return NULL;
1857         }
1858
1859         Py_RETURN_FALSE;
1860 }
1861
1862 static PyObject *
1863 Device_get_source_volume(Device *self, PyObject *object)
1864 {
1865         if(!PyObject_TypeCheck(object, &HandleType))
1866         {
1867                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
1868                 return NULL;
1869         }
1870
1871         Handle* handle = (Handle*)object;
1872
1873         try
1874         {
1875                 AUD_SourceCaps caps;
1876                 caps.handle = handle->handle;
1877                 caps.value = 1.0f;
1878                 if(self->device->getCapability(AUD_CAPS_SOURCE_VOLUME, &caps))
1879                 {
1880                         return Py_BuildValue("f", caps.value);
1881                 }
1882         }
1883         catch(AUD_Exception&)
1884         {
1885                 PyErr_SetString(AUDError, "Couldn't get the sound volume!");
1886                 return NULL;
1887         }
1888
1889         Py_RETURN_NAN;
1890 }
1891
1892 static PyObject *
1893 Device_set_loop_count(Device *self, PyObject *args)
1894 {
1895         PyObject* object;
1896         int loops;
1897
1898         if(!PyArg_ParseTuple(args, "Oi", &object, &loops))
1899                 return NULL;
1900
1901         if(!PyObject_TypeCheck(object, &HandleType))
1902         {
1903                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
1904                 return NULL;
1905         }
1906
1907         Handle* handle = (Handle*)object;
1908
1909         try
1910         {
1911                 AUD_Message message;
1912                 message.loopcount = loops;
1913                 message.type = AUD_MSG_LOOP;
1914                 if(self->device->sendMessage(handle->handle, message))
1915                 {
1916                         Py_RETURN_TRUE;
1917                 }
1918         }
1919         catch(AUD_Exception&)
1920         {
1921                 PyErr_SetString(AUDError, "Couldn't set the loop count!");
1922                 return NULL;
1923         }
1924
1925         Py_RETURN_FALSE;
1926 }
1927
1928 static PyObject *
1929 Device_set_pitch(Device *self, PyObject *args)
1930 {
1931         PyObject* object;
1932         float pitch;
1933
1934         if(!PyArg_ParseTuple(args, "Of", &object, &pitch))
1935                 return NULL;
1936
1937         if(!PyObject_TypeCheck(object, &HandleType))
1938         {
1939                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
1940                 return NULL;
1941         }
1942
1943         Handle* handle = (Handle*)object;
1944
1945         try
1946         {
1947                 AUD_SourceCaps caps;
1948                 caps.handle = handle->handle;
1949                 caps.value = pitch;
1950                 if(self->device->setCapability(AUD_CAPS_SOURCE_PITCH, &caps))
1951                 {
1952                         Py_RETURN_TRUE;
1953                 }
1954         }
1955         catch(AUD_Exception&)
1956         {
1957                 PyErr_SetString(AUDError, "Couldn't set the sound pitch!");
1958                 return NULL;
1959         }
1960
1961         Py_RETURN_FALSE;
1962 }
1963
1964 PyDoc_STRVAR(M_aud_Device_play3D_doc,
1965                          "play3d(sound[, keep])\n\n"
1966                          "Plays a sound 3 dimensional if possible.\n\n"
1967                          ":arg sound: The sound to play.\n"
1968                          ":type sound: aud.Sound\n"
1969                          ":arg keep: Whether the sound should be kept paused in the device when its end is reached.\n"
1970                          ":type keep: boolean\n"
1971                          ":return: The playback handle.\n"
1972                          ":rtype: aud.Handle");
1973
1974 static PyObject *
1975 Device_play3D(Device *self, PyObject *args, PyObject *kwds)
1976 {
1977         PyObject* object;
1978         PyObject* keepo = NULL;
1979
1980         bool keep = false;
1981
1982         static const char *kwlist[] = {"sound", "keep", NULL};
1983
1984         if(!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", const_cast<char**>(kwlist), &object, &keepo))
1985                 return NULL;
1986
1987         if(!PyObject_TypeCheck(object, &SoundType))
1988         {
1989                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Sound!");
1990                 return NULL;
1991         }
1992
1993         if(keepo != NULL)
1994         {
1995                 if(!PyBool_Check(keepo))
1996                 {
1997                         PyErr_SetString(PyExc_TypeError, "keep is not a boolean!");
1998                         return NULL;
1999                 }
2000
2001                 keep = keepo == Py_True;
2002         }
2003
2004         Sound* sound = (Sound*)object;
2005         Handle *handle;
2006
2007         handle = (Handle*)HandleType.tp_alloc(&HandleType, 0);
2008         if(handle != NULL)
2009         {
2010                 handle->device = (PyObject*)self;
2011                 Py_INCREF(self);
2012
2013                 try
2014                 {
2015                         AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
2016                         if(device)
2017                         {
2018                                 handle->handle = device->play3D(sound->factory, keep);
2019                         }
2020                         else
2021                         {
2022                                 Py_DECREF(handle);
2023                                 PyErr_SetString(AUDError, "Device is not a 3D device!");
2024                                 return NULL;
2025                         }
2026                 }
2027                 catch(AUD_Exception&)
2028                 {
2029                         Py_DECREF(handle);
2030                         PyErr_SetString(AUDError, "Couldn't play the sound!");
2031                         return NULL;
2032                 }
2033         }
2034
2035         return (PyObject *)handle;
2036 }
2037
2038 PyDoc_STRVAR(M_aud_Device_update_listener_doc,
2039                          "update_listener(info)\n\n"
2040                          "Updates the 3D information of the listener."
2041                          ":arg info: The 3D info in the format (fff)(fff)((fff)(fff)(fff))."
2042                          " Position, velocity and a 3x3 orientation matrix.\n"
2043                          ":type info: float tuple");
2044
2045 static PyObject *
2046 Device_update_listener(Device *self, PyObject *args)
2047 {
2048         AUD_3DData data;
2049
2050         if(!PyArg_ParseTuple(args, "(fff)(fff)((fff)(fff)(fff))",
2051                                                  &data.position[0], &data.position[1], &data.position[2],
2052                                                  &data.velocity[0], &data.velocity[1], &data.velocity[2],
2053                                                  &data.orientation[0], &data.orientation[1], &data.orientation[2],
2054                                                  &data.orientation[3], &data.orientation[4], &data.orientation[5],
2055                                                  &data.orientation[6], &data.orientation[7], &data.orientation[8]))
2056                 return NULL;
2057
2058         try
2059         {
2060                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
2061                 if(device)
2062                 {
2063                         device->updateListener(data);
2064                 }
2065                 else
2066                 {
2067                         PyErr_SetString(AUDError, "Device is not a 3D device!");
2068                         return NULL;
2069                 }
2070         }
2071         catch(AUD_Exception&)
2072         {
2073                 PyErr_SetString(AUDError, "Couldn't update the listener!");
2074                 return NULL;
2075         }
2076
2077         Py_RETURN_NONE;
2078 }
2079
2080 static PyObject *
2081 Device_update_source(Device *self, PyObject *args)
2082 {
2083         PyObject* object;
2084         AUD_3DData data;
2085
2086         if(!PyArg_ParseTuple(args, "O(fff)(fff)((fff)(fff)(fff))", &object,
2087                                                  &data.position[0], &data.position[1], &data.position[2],
2088                                                  &data.velocity[0], &data.velocity[1], &data.velocity[2],
2089                                                  &data.orientation[0], &data.orientation[1], &data.orientation[2],
2090                                                  &data.orientation[3], &data.orientation[4], &data.orientation[5],
2091                                                  &data.orientation[6], &data.orientation[7], &data.orientation[8]))
2092                 return NULL;
2093
2094         if(!PyObject_TypeCheck(object, &HandleType))
2095         {
2096                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
2097                 return NULL;
2098         }
2099
2100         Handle* handle = (Handle*)object;
2101
2102         try
2103         {
2104                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
2105                 if(device)
2106                 {
2107                         if(device->updateSource(handle->handle, data))
2108                                 Py_RETURN_TRUE;
2109                 }
2110                 else
2111                 {
2112                         PyErr_SetString(AUDError, "Device is not a 3D device!");
2113                         return NULL;
2114                 }
2115         }
2116         catch(AUD_Exception&)
2117         {
2118                 PyErr_SetString(AUDError, "Couldn't update the source!");
2119                 return NULL;
2120         }
2121
2122         Py_RETURN_FALSE;
2123 }
2124
2125 static PyObject *
2126 Device_is_relative(Device *self, PyObject *object)
2127 {
2128         if(!PyObject_TypeCheck(object, &HandleType))
2129         {
2130                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
2131                 return NULL;
2132         }
2133
2134         Handle* handle = (Handle*)object;
2135
2136         try
2137         {
2138                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
2139                 if(device)
2140                 {
2141                         if(device->getSourceSetting(handle->handle, AUD_3DSS_IS_RELATIVE) > 0)
2142                         {
2143                                 Py_RETURN_TRUE;
2144                         }
2145                         else
2146                         {
2147                                 Py_RETURN_FALSE;
2148                         }
2149                 }
2150                 else
2151                 {
2152                         PyErr_SetString(AUDError, "Device is not a 3D device!");
2153                         return NULL;
2154                 }
2155         }
2156         catch(AUD_Exception&)
2157         {
2158                 PyErr_SetString(AUDError, "Couldn't retrieve the status of the sound!");
2159                 return NULL;
2160         }
2161 }
2162
2163 static PyObject *
2164 Device_set_relative(Device *self, PyObject *args)
2165 {
2166         PyObject* object;
2167         PyObject* relativeo;
2168
2169         if(!PyArg_ParseTuple(args, "OO", &object, &relativeo))
2170                 return NULL;
2171
2172         if(!PyObject_TypeCheck(object, &HandleType))
2173         {
2174                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
2175                 return NULL;
2176         }
2177
2178         if(!PyBool_Check(relativeo))
2179         {
2180                 PyErr_SetString(PyExc_TypeError, "Value is not a boolean!");
2181                 return NULL;
2182         }
2183
2184         float relative = (relativeo == Py_True);
2185         Handle* handle = (Handle*)object;
2186
2187         try
2188         {
2189                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
2190                 if(device)
2191                 {
2192                         device->setSourceSetting(handle->handle, AUD_3DSS_IS_RELATIVE, relative);
2193                         Py_RETURN_TRUE;
2194                 }
2195                 else
2196                 {
2197                         PyErr_SetString(AUDError, "Device is not a 3D device!");
2198                         return NULL;
2199                 }
2200         }
2201         catch(AUD_Exception&)
2202         {
2203                 PyErr_SetString(AUDError, "Couldn't set the status!");
2204                 return NULL;
2205         }
2206
2207         Py_RETURN_FALSE;
2208 }
2209
2210 static PyObject *
2211 Device_get_min_gain(Device *self, PyObject *object)
2212 {
2213         if(!PyObject_TypeCheck(object, &HandleType))
2214         {
2215                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
2216                 return NULL;
2217         }
2218
2219         Handle* handle = (Handle*)object;
2220
2221         try
2222         {
2223                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
2224                 if(device)
2225                 {
2226                         return Py_BuildValue("f", device->getSourceSetting(handle->handle, AUD_3DSS_MIN_GAIN));
2227                 }
2228                 else
2229                 {
2230                         PyErr_SetString(AUDError, "Device is not a 3D device!");
2231                         return NULL;
2232                 }
2233         }
2234         catch(AUD_Exception&)
2235         {
2236                 PyErr_SetString(AUDError, "Couldn't retrieve the minimum gain of the sound!");
2237                 return NULL;
2238         }
2239 }
2240
2241 static PyObject *
2242 Device_set_min_gain(Device *self, PyObject *args)
2243 {
2244         PyObject* object;
2245         float gain;
2246
2247         if(!PyArg_ParseTuple(args, "Of", &object, &gain))
2248                 return NULL;
2249
2250         if(!PyObject_TypeCheck(object, &HandleType))
2251         {
2252                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
2253                 return NULL;
2254         }
2255
2256         Handle* handle = (Handle*)object;
2257
2258         try
2259         {
2260                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
2261                 if(device)
2262                 {
2263                         device->setSourceSetting(handle->handle, AUD_3DSS_MIN_GAIN, gain);
2264                         Py_RETURN_TRUE;
2265                 }
2266                 else
2267                 {
2268                         PyErr_SetString(AUDError, "Device is not a 3D device!");
2269                         return NULL;
2270                 }
2271         }
2272         catch(AUD_Exception&)
2273         {
2274                 PyErr_SetString(AUDError, "Couldn't set the minimum source gain!");
2275                 return NULL;
2276         }
2277
2278         Py_RETURN_FALSE;
2279 }
2280
2281 static PyObject *
2282 Device_get_max_gain(Device *self, PyObject *object)
2283 {
2284         if(!PyObject_TypeCheck(object, &HandleType))
2285         {
2286                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
2287                 return NULL;
2288         }
2289
2290         Handle* handle = (Handle*)object;
2291
2292         try
2293         {
2294                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
2295                 if(device)
2296                 {
2297                         return Py_BuildValue("f", device->getSourceSetting(handle->handle, AUD_3DSS_MAX_GAIN));
2298                 }
2299                 else
2300                 {
2301                         PyErr_SetString(AUDError, "Device is not a 3D device!");
2302                         return NULL;
2303                 }
2304         }
2305         catch(AUD_Exception&)
2306         {
2307                 PyErr_SetString(AUDError, "Couldn't retrieve the maximum gain of the sound!");
2308                 return NULL;
2309         }
2310 }
2311
2312 static PyObject *
2313 Device_set_max_gain(Device *self, PyObject *args)
2314 {
2315         PyObject* object;
2316         float gain;
2317
2318         if(!PyArg_ParseTuple(args, "Of", &object, &gain))
2319                 return NULL;
2320
2321         if(!PyObject_TypeCheck(object, &HandleType))
2322         {
2323                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
2324                 return NULL;
2325         }
2326
2327         Handle* handle = (Handle*)object;
2328
2329         try
2330         {
2331                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
2332                 if(device)
2333                 {
2334                         device->setSourceSetting(handle->handle, AUD_3DSS_MAX_GAIN, gain);
2335                         Py_RETURN_TRUE;
2336                 }
2337                 else
2338                 {
2339                         PyErr_SetString(AUDError, "Device is not a 3D device!");
2340                         return NULL;
2341                 }
2342         }
2343         catch(AUD_Exception&)
2344         {
2345                 PyErr_SetString(AUDError, "Couldn't set the maximum source gain!");
2346                 return NULL;
2347         }
2348
2349         Py_RETURN_FALSE;
2350 }
2351
2352 static PyObject *
2353 Device_get_reference_distance(Device *self, PyObject *object)
2354 {
2355         if(!PyObject_TypeCheck(object, &HandleType))
2356         {
2357                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
2358                 return NULL;
2359         }
2360
2361         Handle* handle = (Handle*)object;
2362
2363         try
2364         {
2365                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
2366                 if(device)
2367                 {
2368                         return Py_BuildValue("f", device->getSourceSetting(handle->handle, AUD_3DSS_REFERENCE_DISTANCE));
2369                 }
2370                 else
2371                 {
2372                         PyErr_SetString(AUDError, "Device is not a 3D device!");
2373                         return NULL;
2374                 }
2375         }
2376         catch(AUD_Exception&)
2377         {
2378                 PyErr_SetString(AUDError, "Couldn't retrieve the reference distance of the sound!");
2379                 return NULL;
2380         }
2381 }
2382
2383 static PyObject *
2384 Device_set_reference_distance(Device *self, PyObject *args)
2385 {
2386         PyObject* object;
2387         float distance;
2388
2389         if(!PyArg_ParseTuple(args, "Of", &object, &distance))
2390                 return NULL;
2391
2392         if(!PyObject_TypeCheck(object, &HandleType))
2393         {
2394                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
2395                 return NULL;
2396         }
2397
2398         Handle* handle = (Handle*)object;
2399
2400         try
2401         {
2402                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
2403                 if(device)
2404                 {
2405                         device->setSourceSetting(handle->handle, AUD_3DSS_REFERENCE_DISTANCE, distance);
2406                         Py_RETURN_TRUE;
2407                 }
2408                 else
2409                 {
2410                         PyErr_SetString(AUDError, "Device is not a 3D device!");
2411                         return NULL;
2412                 }
2413         }
2414         catch(AUD_Exception&)
2415         {
2416                 PyErr_SetString(AUDError, "Couldn't set the reference distance!");
2417                 return NULL;
2418         }
2419
2420         Py_RETURN_FALSE;
2421 }
2422
2423 static PyObject *
2424 Device_get_max_distance(Device *self, PyObject *object)
2425 {
2426         if(!PyObject_TypeCheck(object, &HandleType))
2427         {
2428                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
2429                 return NULL;
2430         }
2431
2432         Handle* handle = (Handle*)object;
2433
2434         try
2435         {
2436                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
2437                 if(device)
2438                 {
2439                         return Py_BuildValue("f", device->getSourceSetting(handle->handle, AUD_3DSS_MAX_DISTANCE));
2440                 }
2441                 else
2442                 {
2443                         PyErr_SetString(AUDError, "Device is not a 3D device!");
2444                         return NULL;
2445                 }
2446         }
2447         catch(AUD_Exception&)
2448         {
2449                 PyErr_SetString(AUDError, "Couldn't retrieve the maximum distance of the sound!");
2450                 return NULL;
2451         }
2452 }
2453
2454 static PyObject *
2455 Device_set_max_distance(Device *self, PyObject *args)
2456 {
2457         PyObject* object;
2458         float distance;
2459
2460         if(!PyArg_ParseTuple(args, "Of", &object, &distance))
2461                 return NULL;
2462
2463         if(!PyObject_TypeCheck(object, &HandleType))
2464         {
2465                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
2466                 return NULL;
2467         }
2468
2469         Handle* handle = (Handle*)object;
2470
2471         try
2472         {
2473                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
2474                 if(device)
2475                 {
2476                         device->setSourceSetting(handle->handle, AUD_3DSS_MAX_DISTANCE, distance);
2477                         Py_RETURN_TRUE;
2478                 }
2479                 else
2480                 {
2481                         PyErr_SetString(AUDError, "Device is not a 3D device!");
2482                         return NULL;
2483                 }
2484         }
2485         catch(AUD_Exception&)
2486         {
2487                 PyErr_SetString(AUDError, "Couldn't set the maximum distance!");
2488                 return NULL;
2489         }
2490
2491         Py_RETURN_FALSE;
2492 }
2493
2494 static PyObject *
2495 Device_get_rolloff_factor(Device *self, PyObject *object)
2496 {
2497         if(!PyObject_TypeCheck(object, &HandleType))
2498         {
2499                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
2500                 return NULL;
2501         }
2502
2503         Handle* handle = (Handle*)object;
2504
2505         try
2506         {
2507                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
2508                 if(device)
2509                 {
2510                         return Py_BuildValue("f", device->getSourceSetting(handle->handle, AUD_3DSS_ROLLOFF_FACTOR));
2511                 }
2512                 else
2513                 {
2514                         PyErr_SetString(AUDError, "Device is not a 3D device!");
2515                         return NULL;
2516                 }
2517         }
2518         catch(AUD_Exception&)
2519         {
2520                 PyErr_SetString(AUDError, "Couldn't retrieve the rolloff factor of the sound!");
2521                 return NULL;
2522         }
2523 }
2524
2525 static PyObject *
2526 Device_set_rolloff_factor(Device *self, PyObject *args)
2527 {
2528         PyObject* object;
2529         float factor;
2530
2531         if(!PyArg_ParseTuple(args, "Of", &object, &factor))
2532                 return NULL;
2533
2534         if(!PyObject_TypeCheck(object, &HandleType))
2535         {
2536                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
2537                 return NULL;
2538         }
2539
2540         Handle* handle = (Handle*)object;
2541
2542         try
2543         {
2544                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
2545                 if(device)
2546                 {
2547                         device->setSourceSetting(handle->handle, AUD_3DSS_ROLLOFF_FACTOR, factor);
2548                         Py_RETURN_TRUE;
2549                 }
2550                 else
2551                 {
2552                         PyErr_SetString(AUDError, "Device is not a 3D device!");
2553                         return NULL;
2554                 }
2555         }
2556         catch(AUD_Exception&)
2557         {
2558                 PyErr_SetString(AUDError, "Couldn't set the rolloff factor!");
2559                 return NULL;
2560         }
2561
2562         Py_RETURN_FALSE;
2563 }
2564
2565 static PyObject *
2566 Device_get_cone_inner_angle(Device *self, PyObject *object)
2567 {
2568         if(!PyObject_TypeCheck(object, &HandleType))
2569         {
2570                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
2571                 return NULL;
2572         }
2573
2574         Handle* handle = (Handle*)object;
2575
2576         try
2577         {
2578                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
2579                 if(device)
2580                 {
2581                         return Py_BuildValue("f", device->getSourceSetting(handle->handle, AUD_3DSS_CONE_INNER_ANGLE));
2582                 }
2583                 else
2584                 {
2585                         PyErr_SetString(AUDError, "Device is not a 3D device!");
2586                         return NULL;
2587                 }
2588         }
2589         catch(AUD_Exception&)
2590         {
2591                 PyErr_SetString(AUDError, "Couldn't retrieve the cone inner angle of the sound!");
2592                 return NULL;
2593         }
2594 }
2595
2596 static PyObject *
2597 Device_set_cone_inner_angle(Device *self, PyObject *args)
2598 {
2599         PyObject* object;
2600         float angle;
2601
2602         if(!PyArg_ParseTuple(args, "Of", &object, &angle))
2603                 return NULL;
2604
2605         if(!PyObject_TypeCheck(object, &HandleType))
2606         {
2607                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
2608                 return NULL;
2609         }
2610
2611         Handle* handle = (Handle*)object;
2612
2613         try
2614         {
2615                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
2616                 if(device)
2617                 {
2618                         device->setSourceSetting(handle->handle, AUD_3DSS_CONE_INNER_ANGLE, angle);
2619                         Py_RETURN_TRUE;
2620                 }
2621                 else
2622                 {
2623                         PyErr_SetString(AUDError, "Device is not a 3D device!");
2624                         return NULL;
2625                 }
2626         }
2627         catch(AUD_Exception&)
2628         {
2629                 PyErr_SetString(AUDError, "Couldn't set the cone inner angle!");
2630                 return NULL;
2631         }
2632
2633         Py_RETURN_FALSE;
2634 }
2635
2636 static PyObject *
2637 Device_get_cone_outer_angle(Device *self, PyObject *object)
2638 {
2639         if(!PyObject_TypeCheck(object, &HandleType))
2640         {
2641                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
2642                 return NULL;
2643         }
2644
2645         Handle* handle = (Handle*)object;
2646
2647         try
2648         {
2649                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
2650                 if(device)
2651                 {
2652                         return Py_BuildValue("f", device->getSourceSetting(handle->handle, AUD_3DSS_CONE_OUTER_ANGLE));
2653                 }
2654                 else
2655                 {
2656                         PyErr_SetString(AUDError, "Device is not a 3D device!");
2657                         return NULL;
2658                 }
2659         }
2660         catch(AUD_Exception&)
2661         {
2662                 PyErr_SetString(AUDError, "Couldn't retrieve the cone outer angle of the sound!");
2663                 return NULL;
2664         }
2665 }
2666
2667 static PyObject *
2668 Device_set_cone_outer_angle(Device *self, PyObject *args)
2669 {
2670         PyObject* object;
2671         float angle;
2672
2673         if(!PyArg_ParseTuple(args, "Of", &object, &angle))
2674                 return NULL;
2675
2676         if(!PyObject_TypeCheck(object, &HandleType))
2677         {
2678                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
2679                 return NULL;
2680         }
2681
2682         Handle* handle = (Handle*)object;
2683
2684         try
2685         {
2686                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
2687                 if(device)
2688                 {
2689                         device->setSourceSetting(handle->handle, AUD_3DSS_CONE_OUTER_ANGLE, angle);
2690                         Py_RETURN_TRUE;
2691                 }
2692                 else
2693                 {
2694                         PyErr_SetString(AUDError, "Device is not a 3D device!");
2695                         return NULL;
2696                 }
2697         }
2698         catch(AUD_Exception&)
2699         {
2700                 PyErr_SetString(AUDError, "Couldn't set the cone outer angle!");
2701                 return NULL;
2702         }
2703
2704         Py_RETURN_FALSE;
2705 }
2706
2707 static PyObject *
2708 Device_get_cone_outer_gain(Device *self, PyObject *object)
2709 {
2710         if(!PyObject_TypeCheck(object, &HandleType))
2711         {
2712                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
2713                 return NULL;
2714         }
2715
2716         Handle* handle = (Handle*)object;
2717
2718         try
2719         {
2720                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
2721                 if(device)
2722                 {
2723                         return Py_BuildValue("f", device->getSourceSetting(handle->handle, AUD_3DSS_CONE_OUTER_GAIN));
2724                 }
2725                 else
2726                 {
2727                         PyErr_SetString(AUDError, "Device is not a 3D device!");
2728                         return NULL;
2729                 }
2730         }
2731         catch(AUD_Exception&)
2732         {
2733                 PyErr_SetString(AUDError, "Couldn't retrieve the cone outer gain of the sound!");
2734                 return NULL;
2735         }
2736 }
2737
2738 static PyObject *
2739 Device_set_cone_outer_gain(Device *self, PyObject *args)
2740 {
2741         PyObject* object;
2742         float gain;
2743
2744         if(!PyArg_ParseTuple(args, "Of", &object, &gain))
2745                 return NULL;
2746
2747         if(!PyObject_TypeCheck(object, &HandleType))
2748         {
2749                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Handle!");
2750                 return NULL;
2751         }
2752
2753         Handle* handle = (Handle*)object;
2754
2755         try
2756         {
2757                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
2758                 if(device)
2759                 {
2760                         device->setSourceSetting(handle->handle, AUD_3DSS_CONE_OUTER_GAIN, gain);
2761                         Py_RETURN_TRUE;
2762                 }
2763                 else
2764                 {
2765                         PyErr_SetString(AUDError, "Device is not a 3D device!");
2766                         return NULL;
2767                 }
2768         }
2769         catch(AUD_Exception&)
2770         {
2771                 PyErr_SetString(AUDError, "Couldn't set the cone outer gain!");
2772                 return NULL;
2773         }
2774
2775         Py_RETURN_FALSE;
2776 }
2777
2778 PyDoc_STRVAR(M_aud_Device_OpenAL_doc,
2779                          "OpenAL([frequency[, buffer_size]])\n\n"
2780                          "Creates an OpenAL device.\n\n"
2781                          ":arg frequency: The prefered sampling frequency.\n"
2782                          ":type frequency: integer\n"
2783                          ":arg buffer_size: The size of a playback buffer, "
2784                          "must be at least 128.\n"
2785                          ":type buffer_size: integer\n"
2786                          ":return: The created aud.Device object.\n"
2787                          ":rtype: aud.Device");
2788
2789 static PyObject *
2790 Device_OpenAL(PyTypeObject *type, PyObject *args, PyObject *kwds);
2791
2792 PyDoc_STRVAR(M_aud_Device_SDL_doc,
2793                          "SDL([frequency[, buffer_size]])\n\n"
2794                          "Creates an SDL device.\n\n"
2795                          ":arg frequency: The sampling frequency.\n"
2796                          ":type frequency: integer\n"
2797                          ":arg buffer_size: The size of the playback buffer, "
2798                          "must be at least 128.\n"
2799                          ":type buffer_size: integer\n"
2800                          ":return: The created aud.Device object.\n"
2801                          ":rtype: aud.Device");
2802
2803 static PyObject *
2804 Device_SDL(PyTypeObject *type, PyObject *args, PyObject *kwds);
2805
2806 PyDoc_STRVAR(M_aud_Device_Jack_doc,
2807                          "Jack([channels[, buffer_size]])\n\n"
2808                          "Creates a Jack device.\n\n"
2809                          ":arg channels: The count of channels.\n"
2810                          ":type channels: integer\n"
2811                          ":arg buffer_size: The size of the playback buffer, "
2812                          "must be at least 128.\n"
2813                          ":type buffer_size: integer\n"
2814                          ":return: The created aud.Device object.\n"
2815                          ":rtype: aud.Device");
2816
2817 static PyObject *
2818 Device_Jack(PyTypeObject *type, PyObject *args, PyObject *kwds);
2819
2820 PyDoc_STRVAR(M_aud_Device_Null_doc,
2821                          "Null()\n\n"
2822                          "Creates a Null device.\n\n"
2823                          ":return: The created aud.Device object.\n"
2824                          ":rtype: aud.Device");
2825
2826 static PyObject *
2827 Device_Null(PyTypeObject *type);
2828
2829 static PyMethodDef Device_methods[] = {
2830         {"play", (PyCFunction)Device_play, METH_VARARGS | METH_KEYWORDS,
2831          M_aud_Device_play_doc
2832         },
2833         {"_stop", (PyCFunction)Device_stop, METH_O,
2834          ""
2835         },
2836         {"_pause", (PyCFunction)Device_pause, METH_O,
2837          ""
2838         },
2839         {"_resume", (PyCFunction)Device_resume, METH_O,
2840          ""
2841         },
2842         {"_set_keep", (PyCFunction)Device_set_keep, METH_VARARGS,
2843          ""
2844         },
2845         {"_seek", (PyCFunction)Device_seek, METH_VARARGS,
2846          ""
2847         },
2848         {"_get_position", (PyCFunction)Device_get_position, METH_O,
2849          ""
2850         },
2851         {"_get_status", (PyCFunction)Device_get_status, METH_O,
2852          ""
2853         },
2854         {"lock", (PyCFunction)Device_lock, METH_NOARGS,
2855          M_aud_Device_lock_doc
2856         },
2857         {"unlock", (PyCFunction)Device_unlock, METH_NOARGS,
2858          M_aud_Device_unlock_doc
2859         },
2860         {"_set_volume", (PyCFunction)Device_set_source_volume, METH_VARARGS,
2861          ""
2862         },
2863         {"_get_volume", (PyCFunction)Device_get_source_volume, METH_O,
2864          ""
2865         },
2866         {"_set_loop_count", (PyCFunction)Device_set_loop_count, METH_VARARGS,
2867          ""
2868         },
2869         {"_set_pitch", (PyCFunction)Device_set_pitch, METH_VARARGS,
2870          ""
2871         },
2872         {"play3D", (PyCFunction)Device_play3D, METH_VARARGS | METH_KEYWORDS,
2873          M_aud_Device_play3D_doc
2874         },
2875         {"update_listener", (PyCFunction)Device_update_listener, METH_VARARGS,
2876          M_aud_Device_update_listener_doc
2877         },
2878         {"_update_source", (PyCFunction)Device_update_source, METH_VARARGS,
2879          ""
2880         },
2881         {"_is_relative", (PyCFunction)Device_is_relative, METH_O,
2882          ""
2883         },
2884         {"_set_relative", (PyCFunction)Device_set_relative, METH_VARARGS,
2885          ""
2886         },
2887         {"_get_min_gain", (PyCFunction)Device_get_min_gain, METH_O,
2888          ""
2889         },
2890         {"_set_min_gain", (PyCFunction)Device_set_min_gain, METH_VARARGS,
2891          ""
2892         },
2893         {"_get_max_gain", (PyCFunction)Device_get_max_gain, METH_O,
2894          ""
2895         },
2896         {"_set_max_gain", (PyCFunction)Device_set_max_gain, METH_VARARGS,
2897          ""
2898         },
2899         {"_get_reference_distance", (PyCFunction)Device_get_reference_distance, METH_O,
2900          ""
2901         },
2902         {"_set_reference_distance", (PyCFunction)Device_set_reference_distance, METH_VARARGS,
2903          ""
2904         },
2905         {"_get_max_distance", (PyCFunction)Device_get_max_distance, METH_O,
2906          ""
2907         },
2908         {"_set_max_distance", (PyCFunction)Device_set_max_distance, METH_VARARGS,
2909          ""
2910         },
2911         {"_get_rolloff_factor", (PyCFunction)Device_get_rolloff_factor, METH_O,
2912          ""
2913         },
2914         {"_set_rolloff_factor", (PyCFunction)Device_set_rolloff_factor, METH_VARARGS,
2915          ""
2916         },
2917         {"_get_cone_inner_angle", (PyCFunction)Device_get_cone_inner_angle, METH_O,
2918          ""
2919         },
2920         {"_set_cone_inner_angle", (PyCFunction)Device_set_cone_inner_angle, METH_VARARGS,
2921          ""
2922         },
2923         {"_get_cone_outer_angle", (PyCFunction)Device_get_cone_outer_angle, METH_O,
2924          ""
2925         },
2926         {"_set_cone_outer_angle", (PyCFunction)Device_set_cone_outer_angle, METH_VARARGS,
2927          ""
2928         },
2929         {"_get_cone_outer_gain", (PyCFunction)Device_get_cone_outer_gain, METH_O,
2930          ""
2931         },
2932         {"_set_cone_outer_gain", (PyCFunction)Device_set_cone_outer_gain, METH_VARARGS,
2933          ""
2934         },
2935         {"OpenAL", (PyCFunction)Device_OpenAL, METH_VARARGS | METH_STATIC | METH_KEYWORDS,
2936          M_aud_Device_OpenAL_doc
2937         },
2938         {"SDL", (PyCFunction)Device_SDL, METH_VARARGS | METH_STATIC | METH_KEYWORDS,
2939          M_aud_Device_SDL_doc
2940         },
2941         {"Jack", (PyCFunction)Device_Jack, METH_VARARGS | METH_STATIC | METH_KEYWORDS,
2942          M_aud_Device_Jack_doc
2943         },
2944         {"Null", (PyCFunction)Device_Null, METH_NOARGS | METH_STATIC,
2945          M_aud_Device_Null_doc
2946         },
2947         {NULL}  /* Sentinel */
2948 };
2949
2950 PyDoc_STRVAR(M_aud_Device_rate_doc,
2951                          "The sampling rate of the device in Hz.");
2952
2953 static PyObject *
2954 Device_get_rate(Device *self, void* nothing)
2955 {
2956         try
2957         {
2958                 AUD_DeviceSpecs specs = self->device->getSpecs();
2959                 return Py_BuildValue("i", specs.rate);
2960         }
2961         catch(AUD_Exception&)
2962         {
2963                 PyErr_SetString(AUDError, "Couldn't retrieve device stats!");
2964                 return NULL;
2965         }
2966 }
2967
2968 PyDoc_STRVAR(M_aud_Device_format_doc,
2969                          "The native sample format of the device.");
2970
2971 static PyObject *
2972 Device_get_format(Device *self, void* nothing)
2973 {
2974         try
2975         {
2976                 AUD_DeviceSpecs specs = self->device->getSpecs();
2977                 return Py_BuildValue("i", specs.format);
2978         }
2979         catch(AUD_Exception&)
2980         {
2981                 PyErr_SetString(AUDError, "Couldn't retrieve device stats!");
2982                 return NULL;
2983         }
2984 }
2985
2986 PyDoc_STRVAR(M_aud_Device_channels_doc,
2987                          "The channel count of the device.");
2988
2989 static PyObject *
2990 Device_get_channels(Device *self, void* nothing)
2991 {
2992         try
2993         {
2994                 AUD_DeviceSpecs specs = self->device->getSpecs();
2995                 return Py_BuildValue("i", specs.channels);
2996         }
2997         catch(AUD_Exception&)
2998         {
2999                 PyErr_SetString(AUDError, "Couldn't retrieve device stats!");
3000                 return NULL;
3001         }
3002 }
3003
3004 PyDoc_STRVAR(M_aud_Device_volume_doc,
3005                          "The overall volume of the device.");
3006
3007 static PyObject *
3008 Device_get_volume(Device *self, void* nothing)
3009 {
3010         try
3011         {
3012                 float volume = 0.0;
3013                 if(self->device->getCapability(AUD_CAPS_VOLUME, &volume))
3014                         return Py_BuildValue("f", volume);
3015         }
3016         catch(AUD_Exception&)
3017         {
3018                 PyErr_SetString(AUDError, "Couldn't retrieve device volume!");
3019                 return NULL;
3020         }
3021
3022         Py_RETURN_NAN;
3023 }
3024
3025 static int
3026 Device_set_volume(Device *self, PyObject* args, void* nothing)
3027 {
3028         float volume;
3029
3030         if(!PyArg_Parse(args, "f", &volume))
3031                 return -1;
3032
3033         try
3034         {
3035                 if(self->device->setCapability(AUD_CAPS_VOLUME, &volume))
3036                         return 0;
3037         }
3038         catch(AUD_Exception&)
3039         {
3040                 PyErr_SetString(AUDError, "Couldn't set device volume!");
3041         }
3042
3043         return -1;
3044 }
3045
3046 PyDoc_STRVAR(M_aud_Device_speed_of_sound_doc,
3047                          "The speed of sound of the device.");
3048
3049 static PyObject *
3050 Device_get_speed_of_sound(Device *self, void* nothing)
3051 {
3052         try
3053         {
3054                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
3055                 if(device)
3056                 {
3057                         return Py_BuildValue("f", device->getSetting(AUD_3DS_SPEED_OF_SOUND));
3058                 }
3059                 else
3060                 {
3061                         PyErr_SetString(AUDError, "Device is not a 3D device!");
3062                         return NULL;
3063                 }
3064         }
3065         catch(AUD_Exception&)
3066         {
3067                 PyErr_SetString(AUDError, "Couldn't retrieve device speed of sound!");
3068                 return NULL;
3069         }
3070 }
3071
3072 static int
3073 Device_set_speed_of_sound(Device *self, PyObject* args, void* nothing)
3074 {
3075         float speed;
3076
3077         if(!PyArg_Parse(args, "f", &speed))
3078                 return -1;
3079
3080         try
3081         {
3082                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
3083                 if(device)
3084                 {
3085                         device->setSetting(AUD_3DS_SPEED_OF_SOUND, speed);
3086                         return 0;
3087                 }
3088                 else
3089                 {
3090                         PyErr_SetString(AUDError, "Device is not a 3D device!");
3091                 }
3092         }
3093         catch(AUD_Exception&)
3094         {
3095                 PyErr_SetString(AUDError, "Couldn't set device speed of sound!");
3096         }
3097
3098         return -1;
3099 }
3100
3101 PyDoc_STRVAR(M_aud_Device_doppler_factor_doc,
3102                          "The doppler factor of the device.");
3103
3104 static PyObject *
3105 Device_get_doppler_factor(Device *self, void* nothing)
3106 {
3107         try
3108         {
3109                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
3110                 if(device)
3111                 {
3112                         return Py_BuildValue("f", device->getSetting(AUD_3DS_DOPPLER_FACTOR));
3113                 }
3114                 else
3115                 {
3116                         PyErr_SetString(AUDError, "Device is not a 3D device!");
3117                         return NULL;
3118                 }
3119         }
3120         catch(AUD_Exception&)
3121         {
3122                 PyErr_SetString(AUDError, "Couldn't retrieve device doppler factor!");
3123                 return NULL;
3124         }
3125 }
3126
3127 static int
3128 Device_set_doppler_factor(Device *self, PyObject* args, void* nothing)
3129 {
3130         float factor;
3131
3132         if(!PyArg_Parse(args, "f", &factor))
3133                 return -1;
3134
3135         try
3136         {
3137                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
3138                 if(device)
3139                 {
3140                         device->setSetting(AUD_3DS_DOPPLER_FACTOR, factor);
3141                         return 0;
3142                 }
3143                 else
3144                 {
3145                         PyErr_SetString(AUDError, "Device is not a 3D device!");
3146                 }
3147         }
3148         catch(AUD_Exception&)
3149         {
3150                 PyErr_SetString(AUDError, "Couldn't set device doppler factor!");
3151         }
3152
3153         return -1;
3154 }
3155
3156 PyDoc_STRVAR(M_aud_Device_distance_model_doc,
3157                          "The distance model of the device.");
3158
3159 static PyObject *
3160 Device_get_distance_model(Device *self, void* nothing)
3161 {
3162         try
3163         {
3164                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
3165                 if(device)
3166                 {
3167                         return Py_BuildValue("i", int(device->getSetting(AUD_3DS_DISTANCE_MODEL)));
3168                 }
3169                 else
3170                 {
3171                         PyErr_SetString(AUDError, "Device is not a 3D device!");
3172                         return NULL;
3173                 }
3174         }
3175         catch(AUD_Exception&)
3176         {
3177                 PyErr_SetString(AUDError, "Couldn't retrieve device distance model!");
3178                 return NULL;
3179         }
3180 }
3181
3182 static int
3183 Device_set_distance_model(Device *self, PyObject* args, void* nothing)
3184 {
3185         int model;
3186
3187         if(!PyArg_Parse(args, "i", &model))
3188                 return -1;
3189
3190         try
3191         {
3192                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
3193                 if(device)
3194                 {
3195                         device->setSetting(AUD_3DS_DISTANCE_MODEL, model);
3196                         return 0;
3197                 }
3198                 else
3199                 {
3200                         PyErr_SetString(AUDError, "Device is not a 3D device!");
3201                 }
3202         }
3203         catch(AUD_Exception&)
3204         {
3205                 PyErr_SetString(AUDError, "Couldn't set device distance model!");
3206         }
3207
3208         return -1;
3209 }
3210
3211 static PyGetSetDef Device_properties[] = {
3212         {(char*)"rate", (getter)Device_get_rate, NULL,
3213          M_aud_Device_rate_doc, NULL },
3214         {(char*)"format", (getter)Device_get_format, NULL,
3215          M_aud_Device_format_doc, NULL },
3216         {(char*)"channels", (getter)Device_get_channels, NULL,
3217          M_aud_Device_channels_doc, NULL },
3218         {(char*)"volume", (getter)Device_get_volume, (setter)Device_set_volume,
3219          M_aud_Device_volume_doc, NULL },
3220         {(char*)"speed_of_sound", (getter)Device_get_speed_of_sound, (setter)Device_set_speed_of_sound,
3221          M_aud_Device_speed_of_sound_doc, NULL },
3222         {(char*)"doppler_factor", (getter)Device_get_doppler_factor, (setter)Device_set_doppler_factor,
3223          M_aud_Device_doppler_factor_doc, NULL },
3224         {(char*)"distance_model", (getter)Device_get_distance_model, (setter)Device_set_distance_model,
3225          M_aud_Device_distance_model_doc, NULL },
3226         {NULL}  /* Sentinel */
3227 };
3228
3229 static PyTypeObject DeviceType = {
3230         PyVarObject_HEAD_INIT(NULL, 0)
3231         "aud.Device",              /* tp_name */
3232         sizeof(Device),            /* tp_basicsize */
3233         0,                         /* tp_itemsize */
3234         (destructor)Device_dealloc,/* tp_dealloc */
3235         0,                         /* tp_print */
3236         0,                         /* tp_getattr */
3237         0,                         /* tp_setattr */
3238         0,                         /* tp_reserved */
3239         0,                         /* tp_repr */
3240         0,                         /* tp_as_number */
3241         0,                         /* tp_as_sequence */
3242         0,                         /* tp_as_mapping */
3243         0,                         /* tp_hash  */
3244         0,                         /* tp_call */
3245         0,                         /* tp_str */
3246         0,                         /* tp_getattro */
3247         0,                         /* tp_setattro */
3248         0,                         /* tp_as_buffer */
3249         Py_TPFLAGS_DEFAULT,        /* tp_flags */
3250         "Device object",           /* tp_doc */
3251         0,                                 /* tp_traverse */
3252         0,                                 /* tp_clear */
3253         0,                                 /* tp_richcompare */
3254         0,                                 /* tp_weaklistoffset */
3255         0,                                 /* tp_iter */
3256         0,                                 /* tp_iternext */
3257         Device_methods,            /* tp_methods */
3258         0,                         /* tp_members */
3259         Device_properties,         /* tp_getset */
3260         0,                         /* tp_base */
3261         0,                         /* tp_dict */
3262         0,                         /* tp_descr_get */
3263         0,                         /* tp_descr_set */
3264         0,                         /* tp_dictoffset */
3265         0,                         /* tp_init */
3266         0,                         /* tp_alloc */
3267         0,                         /* tp_new */
3268 };
3269
3270 static PyObject *
3271 Device_OpenAL(PyTypeObject *type, PyObject *args, PyObject *kwds)
3272 {
3273 #ifdef WITH_OPENAL
3274         int buffersize = AUD_DEFAULT_BUFFER_SIZE;
3275         int frequency = AUD_RATE_44100;
3276
3277         static const char *kwlist[] = {"frequency", "buffer_size", NULL};
3278
3279         if(!PyArg_ParseTupleAndKeywords(args, kwds, "|ii", const_cast<char**>(kwlist), &frequency, &buffersize))
3280                 return NULL;
3281
3282         if(buffersize < 128)
3283         {
3284                 PyErr_SetString(PyExc_ValueError, "buffer_size must be greater than 127!");
3285                 return NULL;
3286         }
3287
3288         Device *self;
3289
3290         self = (Device*)DeviceType.tp_alloc(&DeviceType, 0);
3291         if(self != NULL)
3292         {
3293                 try
3294                 {
3295                         AUD_DeviceSpecs specs;
3296                         specs.rate = static_cast<AUD_SampleRate>(frequency);
3297                         specs.channels = AUD_CHANNELS_STEREO;
3298                         specs.format = AUD_FORMAT_S16;
3299                         self->device = new AUD_OpenALDevice(specs, buffersize);
3300                 }
3301                 catch(AUD_Exception&)
3302                 {
3303                         Py_DECREF(self);
3304                         PyErr_SetString(AUDError, "OpenAL device couldn't be created!");
3305                         return NULL;
3306                 }
3307         }
3308
3309         return (PyObject *)self;
3310 #else
3311         PyErr_SetString(AUDError, "OpenAL device couldn't be created!");
3312         return NULL;
3313 #endif
3314 }
3315
3316 static PyObject *
3317 Device_SDL(PyTypeObject *type, PyObject *args, PyObject *kwds)
3318 {
3319 #ifdef WITH_SDL
3320         int buffersize = AUD_DEFAULT_BUFFER_SIZE;
3321         int frequency = AUD_RATE_44100;<