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