Audaspace:
[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_I3DDevice.h"
30 #include "AUD_NULLDevice.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[, rate])\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                          ":arg rate: The sampling rate in Hz.\n"
126                          ":type rate: int\n"
127                          ":return: The created aud.Sound object.\n"
128                          ":rtype: aud.Sound");
129
130 static PyObject *
131 Sound_sine(PyObject* nothing, PyObject* args);
132
133 PyDoc_STRVAR(M_aud_Sound_file_doc,
134                          "file(filename)\n\n"
135                          "Creates a sound object of a sound file.\n\n"
136                          ":arg filename: Path of the file.\n"
137                          ":type filename: string\n"
138                          ":return: The created aud.Sound object.\n"
139                          ":rtype: aud.Sound");
140
141 static PyObject *
142 Sound_file(PyObject* nothing, PyObject* args);
143
144 PyDoc_STRVAR(M_aud_Sound_lowpass_doc,
145                          "lowpass(frequency)\n\n"
146                          "Creates a low quality lowpass filter.\n\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(Sound* self, PyObject* args);
154
155 PyDoc_STRVAR(M_aud_Sound_delay_doc,
156                          "delay(time)\n\n"
157                          "Delays a sound by playing silence before the sound starts.\n\n"
158                          ":arg time: How many seconds of silence should be added before the sound.\n"
159                          ":type time: float\n"
160                          ":return: The created aud.Sound object.\n"
161                          ":rtype: aud.Sound");
162
163 static PyObject *
164 Sound_delay(Sound* self, PyObject* args);
165
166 PyDoc_STRVAR(M_aud_Sound_join_doc,
167                          "join(sound)\n\n"
168                          "Plays two sounds in sequence.\n\n"
169                          ":arg sound: The sound to play second.\n"
170                          ":type sound: aud.Sound\n"
171                          ":return: The created aud.Sound object.\n"
172                          ":rtype: aud.Sound\n\n"
173                          ".. note:: The two sounds have to have the same specifications "
174                          "(channels and samplerate).");
175
176 static PyObject *
177 Sound_join(Sound* self, PyObject* object);
178
179 PyDoc_STRVAR(M_aud_Sound_highpass_doc,
180                          "highpass(frequency)\n\n"
181                          "Creates a low quality highpass filter.\n\n"
182                          ":arg frequency: The cut off trequency of the highpass.\n"
183                          ":type frequency: float\n"
184                          ":return: The created aud.Sound object.\n"
185                          ":rtype: aud.Sound");
186
187 static PyObject *
188 Sound_highpass(Sound* self, PyObject* args);
189
190 PyDoc_STRVAR(M_aud_Sound_limit_doc,
191                          "limit(start, end)\n\n"
192                          "Limits a sound within a specific start and end time.\n\n"
193                          ":arg start: Start time in seconds.\n"
194                          ":type start: float\n"
195                          ":arg end: End time in seconds.\n"
196                          ":type end: float\n"
197                          ":return: The created aud.Sound object.\n"
198                          ":rtype: aud.Sound");
199
200 static PyObject *
201 Sound_limit(Sound* self, PyObject* args);
202
203 PyDoc_STRVAR(M_aud_Sound_pitch_doc,
204                          "pitch(factor)\n\n"
205                          "Changes the pitch of a sound with a specific factor.\n\n"
206                          ":arg factor: The factor to change the pitch with.\n"
207                          ":type factor: float\n"
208                          ":return: The created aud.Sound object.\n"
209                          ":rtype: aud.Sound\n\n"
210                          ".. note:: This is done by changing the sample rate of the "
211                          "underlying sound, which has to be an integer, so the factor "
212                          "value rounded and the factor may not be 100 % accurate.");
213
214 static PyObject *
215 Sound_pitch(Sound* self, PyObject* args);
216
217 PyDoc_STRVAR(M_aud_Sound_volume_doc,
218                          "volume(volume)\n\n"
219                          "Changes the volume of a sound.\n\n"
220                          ":arg volume: The new volume..\n"
221                          ":type volume: float\n"
222                          ":return: The created aud.Sound object.\n"
223                          ":rtype: aud.Sound\n\n"
224                          ".. note:: Should be in the range [0, 1] to avoid clipping.\n\n"
225                          ".. note:: This is a filter function, you might consider using "
226                          "aud.Handle.pitch instead.");
227
228 static PyObject *
229 Sound_volume(Sound* self, PyObject* args);
230
231 PyDoc_STRVAR(M_aud_Sound_fadein_doc,
232                          "fadein(start, length)\n\n"
233                          "Fades a sound in.\n\n"
234                          ":arg start: Time in seconds when the fading should start.\n"
235                          ":type start: float\n"
236                          ":arg length: Time in seconds how long the fading should last.\n"
237                          ":type length: float\n"
238                          ":return: The created aud.Sound object.\n"
239                          ":rtype: aud.Sound\n\n"
240                          ".. note:: This is a filter function, you might consider using "
241                          "aud.Handle.volume instead.");
242
243 static PyObject *
244 Sound_fadein(Sound* self, PyObject* args);
245
246 PyDoc_STRVAR(M_aud_Sound_fadeout_doc,
247                          "fadeout(start, length)\n\n"
248                          "Fades a sound out.\n\n"
249                          ":arg start: Time in seconds when the fading should start.\n"
250                          ":type start: float\n"
251                          ":arg length: Time in seconds how long the fading should last.\n"
252                          ":type length: float\n"
253                          ":return: The created aud.Sound object.\n"
254                          ":rtype: aud.Sound");
255
256 static PyObject *
257 Sound_fadeout(Sound* self, PyObject* args);
258
259 PyDoc_STRVAR(M_aud_Sound_loop_doc,
260                          "loop(count)\n\n"
261                          "Loops a sound.\n\n"
262                          ":arg count: How often the sound should be looped. "
263                          "Negative values mean endlessly.\n"
264                          ":type count: integer\n"
265                          ":return: The created aud.Sound object.\n"
266                          ":rtype: aud.Sound");
267
268 static PyObject *
269 Sound_loop(Sound* self, PyObject* args);
270
271 PyDoc_STRVAR(M_aud_Sound_mix_doc,
272                          "mix(sound)\n\n"
273                          "Mixes two sounds.\n\n"
274                          ":arg sound: The sound to mix over the other.\n"
275                          ":type sound: aud.Sound\n"
276                          ":return: The created aud.Sound object.\n"
277                          ":rtype: aud.Sound\n\n"
278                          ".. note:: The two sounds have to have the same specifications "
279                          "(channels and samplerate).");
280
281 static PyObject *
282 Sound_mix(Sound* self, PyObject* object);
283
284 PyDoc_STRVAR(M_aud_Sound_pingpong_doc,
285                          "pingpong()\n\n"
286                          "Plays a sound forward and then backward.\n\n"
287                          ":return: The created aud.Sound object.\n"
288                          ":rtype: aud.Sound\n\n"
289                          ".. note:: The sound has to be buffered to be played reverse.");
290
291 static PyObject *
292 Sound_pingpong(Sound* self);
293
294 PyDoc_STRVAR(M_aud_Sound_reverse_doc,
295                          "reverse()\n\n"
296                          "Plays a sound reversed.\n\n"
297                          ":return: The created aud.Sound object.\n"
298                          ":rtype: aud.Sound\n\n"
299                          ".. note:: The sound has to be buffered to be played reverse.");
300
301 static PyObject *
302 Sound_reverse(Sound* self);
303
304 PyDoc_STRVAR(M_aud_Sound_buffer_doc,
305                          "buffer()\n\n"
306                          "Buffers a sound into RAM.\n\n"
307                          ":return: The created aud.Sound object.\n"
308                          ":rtype: aud.Sound\n\n"
309                          ".. note:: Raw PCM data needs a lot of space, only buffer short sounds.");
310
311 static PyObject *
312 Sound_buffer(Sound* self);
313
314 PyDoc_STRVAR(M_aud_Sound_square_doc,
315                          "squre([threshold = 0])\n\n"
316                          "Makes a square wave out of an audio wave.\n\n"
317                          ":arg threshold: Threshold value over which an amplitude counts non-zero.\n"
318                          ":type threshold: float\n"
319                          ":return: The created aud.Sound object.\n"
320                          ":rtype: aud.Sound");
321
322 static PyObject *
323 Sound_square(Sound* self, PyObject* args);
324
325 static PyMethodDef Sound_methods[] = {
326         {"sine", (PyCFunction)Sound_sine, METH_VARARGS | METH_STATIC,
327          M_aud_Sound_sine_doc
328         },
329         {"file", (PyCFunction)Sound_file, METH_VARARGS | METH_STATIC,
330          M_aud_Sound_file_doc
331         },
332         {"lowpass", (PyCFunction)Sound_lowpass, METH_VARARGS,
333          M_aud_Sound_lowpass_doc
334         },
335         {"delay", (PyCFunction)Sound_delay, METH_VARARGS,
336          M_aud_Sound_delay_doc
337         },
338         {"join", (PyCFunction)Sound_join, METH_O,
339          M_aud_Sound_join_doc
340         },
341         {"highpass", (PyCFunction)Sound_highpass, METH_VARARGS,
342          M_aud_Sound_highpass_doc
343         },
344         {"limit", (PyCFunction)Sound_limit, METH_VARARGS,
345          M_aud_Sound_limit_doc
346         },
347         {"pitch", (PyCFunction)Sound_pitch, METH_VARARGS,
348          M_aud_Sound_pitch_doc
349         },
350         {"volume", (PyCFunction)Sound_volume, METH_VARARGS,
351          M_aud_Sound_volume_doc
352         },
353         {"fadein", (PyCFunction)Sound_fadein, METH_VARARGS,
354          M_aud_Sound_fadein_doc
355         },
356         {"fadeout", (PyCFunction)Sound_fadeout, METH_VARARGS,
357          M_aud_Sound_fadeout_doc
358         },
359         {"loop", (PyCFunction)Sound_loop, METH_VARARGS,
360          M_aud_Sound_loop_doc
361         },
362         {"mix", (PyCFunction)Sound_mix, METH_O,
363          M_aud_Sound_mix_doc
364         },
365         {"pingpong", (PyCFunction)Sound_pingpong, METH_NOARGS,
366          M_aud_Sound_pingpong_doc
367         },
368         {"reverse", (PyCFunction)Sound_reverse, METH_NOARGS,
369          M_aud_Sound_reverse_doc
370         },
371         {"buffer", (PyCFunction)Sound_buffer, METH_NOARGS,
372          M_aud_Sound_buffer_doc
373         },
374         {"square", (PyCFunction)Sound_square, METH_VARARGS,
375          M_aud_Sound_square_doc
376         },
377         {NULL}  /* Sentinel */
378 };
379
380 PyDoc_STRVAR(M_aud_Sound_doc,
381                          "Sound objects are immutable and represent a sound that can be "
382                          "played simultaneously multiple times.");
383
384 static PyTypeObject SoundType = {
385         PyVarObject_HEAD_INIT(NULL, 0)
386         "aud.Sound",               /* tp_name */
387         sizeof(Sound),             /* tp_basicsize */
388         0,                         /* tp_itemsize */
389         (destructor)Sound_dealloc, /* tp_dealloc */
390         0,                         /* tp_print */
391         0,                         /* tp_getattr */
392         0,                         /* tp_setattr */
393         0,                         /* tp_reserved */
394         0,                         /* tp_repr */
395         0,                         /* tp_as_number */
396         0,                         /* tp_as_sequence */
397         0,                         /* tp_as_mapping */
398         0,                         /* tp_hash  */
399         0,                         /* tp_call */
400         0,                         /* tp_str */
401         0,                         /* tp_getattro */
402         0,                         /* tp_setattro */
403         0,                         /* tp_as_buffer */
404         Py_TPFLAGS_DEFAULT,        /* tp_flags */
405         M_aud_Sound_doc,           /* tp_doc */
406         0,                                 /* tp_traverse */
407         0,                                 /* tp_clear */
408         0,                                 /* tp_richcompare */
409         0,                                 /* tp_weaklistoffset */
410         0,                                 /* tp_iter */
411         0,                                 /* tp_iternext */
412         Sound_methods,             /* tp_methods */
413         0,                         /* tp_members */
414         0,                         /* tp_getset */
415         0,                         /* tp_base */
416         0,                         /* tp_dict */
417         0,                         /* tp_descr_get */
418         0,                         /* tp_descr_set */
419         0,                         /* tp_dictoffset */
420         0,                         /* tp_init */
421         0,                         /* tp_alloc */
422         Sound_new,                 /* tp_new */
423 };
424
425 static PyObject *
426 Sound_sine(PyObject* nothing, PyObject* args)
427 {
428         float frequency;
429         int rate = 44100;
430
431         if(!PyArg_ParseTuple(args, "f|i", &frequency, &rate))
432                 return NULL;
433
434         Sound *self;
435
436         self = (Sound*)SoundType.tp_alloc(&SoundType, 0);
437         if(self != NULL)
438         {
439                 try
440                 {
441                         self->factory = new AUD_SinusFactory(frequency, (AUD_SampleRate)rate);
442                 }
443                 catch(AUD_Exception&)
444                 {
445                         Py_DECREF(self);
446                         PyErr_SetString(AUDError, "Sinusfactory couldn't be created!");
447                         return NULL;
448                 }
449         }
450
451         return (PyObject *)self;
452 }
453
454 static PyObject *
455 Sound_file(PyObject* nothing, PyObject* args)
456 {
457         const char* filename = NULL;
458
459         if(!PyArg_ParseTuple(args, "s", &filename))
460                 return NULL;
461
462         Sound *self;
463
464         self = (Sound*)SoundType.tp_alloc(&SoundType, 0);
465         if(self != NULL)
466         {
467                 try
468                 {
469                         self->factory = new AUD_FileFactory(filename);
470                 }
471                 catch(AUD_Exception&)
472                 {
473                         Py_DECREF(self);
474                         PyErr_SetString(AUDError, "Filefactory couldn't be created!");
475                         return NULL;
476                 }
477         }
478
479         return (PyObject *)self;
480 }
481
482 static PyObject *
483 Sound_lowpass(Sound* self, PyObject* args)
484 {
485         float frequency;
486
487         if(!PyArg_ParseTuple(args, "f", &frequency))
488                 return NULL;
489
490         Sound *parent = (Sound*)SoundType.tp_alloc(&SoundType, 0);
491
492         if(parent != NULL)
493         {
494                 Py_INCREF(self);
495                 parent->child_list = (PyObject*)self;
496
497                 try
498                 {
499                         parent->factory = new AUD_LowpassFactory(self->factory, frequency, 0.9);
500                 }
501                 catch(AUD_Exception&)
502                 {
503                         Py_DECREF(parent);
504                         PyErr_SetString(AUDError, "Lowpassfactory couldn't be created!");
505                         return NULL;
506                 }
507         }
508
509         return (PyObject *)parent;
510 }
511
512 static PyObject *
513 Sound_delay(Sound* self, PyObject* args)
514 {
515         float delay;
516
517         if(!PyArg_ParseTuple(args, "f", &delay))
518                 return NULL;
519
520         Sound *parent = (Sound*)SoundType.tp_alloc(&SoundType, 0);
521         if(parent != NULL)
522         {
523                 Py_INCREF(self);
524                 parent->child_list = (PyObject*)self;
525
526                 try
527                 {
528                         parent->factory = new AUD_DelayFactory(self->factory, delay);
529                 }
530                 catch(AUD_Exception&)
531                 {
532                         Py_DECREF(parent);
533                         PyErr_SetString(AUDError, "Delayfactory couldn't be created!");
534                         return NULL;
535                 }
536         }
537
538         return (PyObject *)parent;
539 }
540
541 static PyObject *
542 Sound_join(Sound* self, PyObject* object)
543 {
544         if(!PyObject_TypeCheck(object, &SoundType))
545         {
546                 PyErr_SetString(PyExc_TypeError, "Object has to be of type aud.Sound!");
547                 return NULL;
548         }
549
550         Sound *parent;
551         Sound *child = (Sound*)object;
552
553         parent = (Sound*)SoundType.tp_alloc(&SoundType, 0);
554         if(parent != NULL)
555         {
556                 parent->child_list = Py_BuildValue("(OO)", self, object);
557
558                 try
559                 {
560                         parent->factory = new AUD_DoubleFactory(self->factory, child->factory);
561                 }
562                 catch(AUD_Exception&)
563                 {
564                         Py_DECREF(parent);
565                         PyErr_SetString(AUDError, "Doublefactory couldn't be created!");
566                         return NULL;
567                 }
568         }
569
570         return (PyObject *)parent;
571 }
572
573 static PyObject *
574 Sound_highpass(Sound* self, PyObject* args)
575 {
576         float frequency;
577
578         if(!PyArg_ParseTuple(args, "f", &frequency))
579                 return NULL;
580
581         Sound *parent = (Sound*)SoundType.tp_alloc(&SoundType, 0);
582
583         if(parent != NULL)
584         {
585                 Py_INCREF(self);
586                 parent->child_list = (PyObject*)self;
587
588                 try
589                 {
590                         parent->factory = new AUD_HighpassFactory(self->factory, frequency, 0.9);
591                 }
592                 catch(AUD_Exception&)
593                 {
594                         Py_DECREF(parent);
595                         PyErr_SetString(AUDError, "Highpassfactory couldn't be created!");
596                         return NULL;
597                 }
598         }
599
600         return (PyObject *)parent;
601 }
602
603 static PyObject *
604 Sound_limit(Sound* self, PyObject* args)
605 {
606         float start, end;
607
608         if(!PyArg_ParseTuple(args, "ff", &start, &end))
609                 return NULL;
610
611         Sound *parent = (Sound*)SoundType.tp_alloc(&SoundType, 0);
612
613         if(parent != NULL)
614         {
615                 Py_INCREF(self);
616                 parent->child_list = (PyObject*)self;
617
618                 try
619                 {
620                         parent->factory = new AUD_LimiterFactory(self->factory, start, end);
621                 }
622                 catch(AUD_Exception&)
623                 {
624                         Py_DECREF(parent);
625                         PyErr_SetString(AUDError, "Limiterfactory couldn't be created!");
626                         return NULL;
627                 }
628         }
629
630         return (PyObject *)parent;
631 }
632
633 static PyObject *
634 Sound_pitch(Sound* self, PyObject* args)
635 {
636         float factor;
637
638         if(!PyArg_ParseTuple(args, "f", &factor))
639                 return NULL;
640
641         Sound *parent = (Sound*)SoundType.tp_alloc(&SoundType, 0);
642
643         if(parent != NULL)
644         {
645                 Py_INCREF(self);
646                 parent->child_list = (PyObject*)self;
647
648                 try
649                 {
650                         parent->factory = new AUD_PitchFactory(self->factory, factor);
651                 }
652                 catch(AUD_Exception&)
653                 {
654                         Py_DECREF(parent);
655                         PyErr_SetString(AUDError, "Pitchfactory couldn't be created!");
656                         return NULL;
657                 }
658         }
659
660         return (PyObject *)parent;
661 }
662
663 static PyObject *
664 Sound_volume(Sound* self, PyObject* args)
665 {
666         float volume;
667
668         if(!PyArg_ParseTuple(args, "f", &volume))
669                 return NULL;
670
671         Sound *parent = (Sound*)SoundType.tp_alloc(&SoundType, 0);
672
673         if(parent != NULL)
674         {
675                 Py_INCREF(self);
676                 parent->child_list = (PyObject*)self;
677
678                 try
679                 {
680                         parent->factory = new AUD_VolumeFactory(self->factory, volume);
681                 }
682                 catch(AUD_Exception&)
683                 {
684                         Py_DECREF(parent);
685                         PyErr_SetString(AUDError, "Volumefactory couldn't be created!");
686                         return NULL;
687                 }
688         }
689
690         return (PyObject *)parent;
691 }
692
693 static PyObject *
694 Sound_fadein(Sound* self, PyObject* args)
695 {
696         float start, length;
697
698         if(!PyArg_ParseTuple(args, "ff", &start, &length))
699                 return NULL;
700
701         Sound *parent = (Sound*)SoundType.tp_alloc(&SoundType, 0);
702
703         if(parent != NULL)
704         {
705                 Py_INCREF(self);
706                 parent->child_list = (PyObject*)self;
707
708                 try
709                 {
710                         parent->factory = new AUD_FaderFactory(self->factory, AUD_FADE_IN, start, length);
711                 }
712                 catch(AUD_Exception&)
713                 {
714                         Py_DECREF(parent);
715                         PyErr_SetString(AUDError, "Faderfactory couldn't be created!");
716                         return NULL;
717                 }
718         }
719
720         return (PyObject *)parent;
721 }
722
723 static PyObject *
724 Sound_fadeout(Sound* self, PyObject* args)
725 {
726         float start, length;
727
728         if(!PyArg_ParseTuple(args, "ff", &start, &length))
729                 return NULL;
730
731         if(!PyObject_TypeCheck(self, &SoundType))
732         {
733                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Sound!");
734                 return NULL;
735         }
736
737         Sound *parent = (Sound*)SoundType.tp_alloc(&SoundType, 0);
738
739         if(parent != NULL)
740         {
741                 Py_INCREF(self);
742                 parent->child_list = (PyObject*)self;
743
744                 try
745                 {
746                         parent->factory = new AUD_FaderFactory(self->factory, AUD_FADE_OUT, start, length);
747                 }
748                 catch(AUD_Exception&)
749                 {
750                         Py_DECREF(parent);
751                         PyErr_SetString(AUDError, "Faderfactory couldn't be created!");
752                         return NULL;
753                 }
754         }
755
756         return (PyObject *)parent;
757 }
758
759 static PyObject *
760 Sound_loop(Sound* self, PyObject* args)
761 {
762         int loop;
763
764         if(!PyArg_ParseTuple(args, "i", &loop))
765                 return NULL;
766
767         Sound *parent = (Sound*)SoundType.tp_alloc(&SoundType, 0);
768
769         if(parent != NULL)
770         {
771                 Py_INCREF(self);
772                 parent->child_list = (PyObject*)self;
773
774                 try
775                 {
776                         parent->factory = new AUD_LoopFactory(self->factory, loop);
777                 }
778                 catch(AUD_Exception&)
779                 {
780                         Py_DECREF(parent);
781                         PyErr_SetString(AUDError, "Loopfactory couldn't be created!");
782                         return NULL;
783                 }
784         }
785
786         return (PyObject *)parent;
787 }
788
789 static PyObject *
790 Sound_mix(Sound* self, PyObject* object)
791 {
792         if(!PyObject_TypeCheck(object, &SoundType))
793         {
794                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Sound!");
795                 return NULL;
796         }
797
798         Sound *parent = (Sound*)SoundType.tp_alloc(&SoundType, 0);
799         Sound *child = (Sound*)object;
800
801         if(parent != NULL)
802         {
803                 parent->child_list = Py_BuildValue("(OO)", self, object);
804
805                 try
806                 {
807                         parent->factory = new AUD_SuperposeFactory(self->factory, child->factory);
808                 }
809                 catch(AUD_Exception&)
810                 {
811                         Py_DECREF(parent);
812                         PyErr_SetString(AUDError, "Superposefactory couldn't be created!");
813                         return NULL;
814                 }
815         }
816
817         return (PyObject *)parent;
818 }
819
820 static PyObject *
821 Sound_pingpong(Sound* self)
822 {
823         Sound *parent = (Sound*)SoundType.tp_alloc(&SoundType, 0);
824
825         if(parent != NULL)
826         {
827                 Py_INCREF(self);
828                 parent->child_list = (PyObject*)self;
829
830                 try
831                 {
832                         parent->factory = new AUD_PingPongFactory(self->factory);
833                 }
834                 catch(AUD_Exception&)
835                 {
836                         Py_DECREF(parent);
837                         PyErr_SetString(AUDError, "Pingpongfactory couldn't be created!");
838                         return NULL;
839                 }
840         }
841
842         return (PyObject *)parent;
843 }
844
845 static PyObject *
846 Sound_reverse(Sound* self)
847 {
848         Sound *parent = (Sound*)SoundType.tp_alloc(&SoundType, 0);
849
850         if(parent != NULL)
851         {
852                 Py_INCREF(self);
853                 parent->child_list = (PyObject*)self;
854
855                 try
856                 {
857                         parent->factory = new AUD_ReverseFactory(self->factory);
858                 }
859                 catch(AUD_Exception&)
860                 {
861                         Py_DECREF(parent);
862                         PyErr_SetString(AUDError, "Reversefactory couldn't be created!");
863                         return NULL;
864                 }
865         }
866
867         return (PyObject *)parent;
868 }
869
870 static PyObject *
871 Sound_buffer(Sound* self)
872 {
873         Sound *parent = (Sound*)SoundType.tp_alloc(&SoundType, 0);
874
875         if(parent != NULL)
876         {
877                 try
878                 {
879                         parent->factory = new AUD_StreamBufferFactory(self->factory);
880                 }
881                 catch(AUD_Exception&)
882                 {
883                         Py_DECREF(parent);
884                         PyErr_SetString(AUDError, "Bufferfactory couldn't be created!");
885                         return NULL;
886                 }
887         }
888
889         return (PyObject *)parent;
890 }
891
892 static PyObject *
893 Sound_square(Sound* self, PyObject* args)
894 {
895         float threshold = 0;
896
897         if(!PyArg_ParseTuple(args, "|f", &threshold))
898                 return NULL;
899
900         Sound *parent = (Sound*)SoundType.tp_alloc(&SoundType, 0);
901
902         if(parent != NULL)
903         {
904                 Py_INCREF(self);
905                 parent->child_list = (PyObject*)self;
906
907                 try
908                 {
909                         parent->factory = new AUD_SquareFactory(self->factory, threshold);
910                 }
911                 catch(AUD_Exception&)
912                 {
913                         Py_DECREF(parent);
914                         PyErr_SetString(AUDError, "Squarefactory couldn't be created!");
915                         return NULL;
916                 }
917         }
918
919         return (PyObject *)parent;
920 }
921
922 // ========== Handle ==================================================
923
924 static void
925 Handle_dealloc(Handle* self)
926 {
927         Py_XDECREF(self->device);
928         Py_TYPE(self)->tp_free((PyObject*)self);
929 }
930
931 PyDoc_STRVAR(M_aud_Handle_pause_doc,
932                          "pause()\n\n"
933                          "Pauses playback.\n\n"
934                          ":return: Whether the action succeeded.\n"
935                          ":rtype: boolean");
936
937 static PyObject *
938 Handle_pause(Handle *self)
939 {
940         Device* device = (Device*)self->device;
941
942         try
943         {
944                 if(device->device->pause(self->handle))
945                 {
946                         Py_RETURN_TRUE;
947                 }
948         }
949         catch(AUD_Exception&)
950         {
951                 PyErr_SetString(AUDError, "Couldn't pause the sound!");
952                 return NULL;
953         }
954
955         Py_RETURN_FALSE;
956 }
957
958 PyDoc_STRVAR(M_aud_Handle_resume_doc,
959                          "resume()\n\n"
960                          "Resumes playback.\n\n"
961                          ":return: Whether the action succeeded.\n"
962                          ":rtype: boolean");
963
964 static PyObject *
965 Handle_resume(Handle *self)
966 {
967         Device* device = (Device*)self->device;
968
969         try
970         {
971                 if(device->device->resume(self->handle))
972                 {
973                         Py_RETURN_TRUE;
974                 }
975         }
976         catch(AUD_Exception&)
977         {
978                 PyErr_SetString(AUDError, "Couldn't resume the sound!");
979                 return NULL;
980         }
981
982         Py_RETURN_FALSE;
983 }
984
985 PyDoc_STRVAR(M_aud_Handle_stop_doc,
986                          "stop()\n\n"
987                          "Stops playback.\n\n"
988                          ":return: Whether the action succeeded.\n"
989                          ":rtype: boolean");
990
991 static PyObject *
992 Handle_stop(Handle *self)
993 {
994         Device* device = (Device*)self->device;
995
996         try
997         {
998                 if(device->device->stop(self->handle))
999                 {
1000                         Py_RETURN_TRUE;
1001                 }
1002         }
1003         catch(AUD_Exception&)
1004         {
1005                 PyErr_SetString(AUDError, "Couldn't stop the sound!");
1006                 return NULL;
1007         }
1008
1009         Py_RETURN_FALSE;
1010 }
1011
1012 static PyMethodDef Handle_methods[] = {
1013         {"pause", (PyCFunction)Handle_pause, METH_NOARGS,
1014          M_aud_Handle_pause_doc
1015         },
1016         {"resume", (PyCFunction)Handle_resume, METH_NOARGS,
1017          M_aud_Handle_resume_doc
1018         },
1019         {"stop", (PyCFunction)Handle_stop, METH_NOARGS,
1020          M_aud_Handle_stop_doc
1021         },
1022         {NULL}  /* Sentinel */
1023 };
1024
1025 PyDoc_STRVAR(M_aud_Handle_position_doc,
1026                          "The playback position of the sound.");
1027
1028 static PyObject *
1029 Handle_get_position(Handle *self, void* nothing)
1030 {
1031         Device* device = (Device*)self->device;
1032
1033         try
1034         {
1035                 return Py_BuildValue("f", device->device->getPosition(self->handle));
1036         }
1037         catch(AUD_Exception&)
1038         {
1039                 PyErr_SetString(AUDError, "Couldn't retrieve the position of the sound!");
1040                 return NULL;
1041         }
1042 }
1043
1044 static int
1045 Handle_set_position(Handle *self, PyObject* args, void* nothing)
1046 {
1047         float position;
1048
1049         if(!PyArg_Parse(args, "f", &position))
1050                 return -1;
1051
1052         Device* device = (Device*)self->device;
1053
1054         try
1055         {
1056                 if(device->device->seek(self->handle, position))
1057                         return 0;
1058         }
1059         catch(AUD_Exception&)
1060         {
1061         }
1062
1063         PyErr_SetString(AUDError, "Couldn't seek the sound!");
1064         return -1;
1065 }
1066
1067 PyDoc_STRVAR(M_aud_Handle_keep_doc,
1068                          "Whether the sound should be kept paused in the device when its end is reached.");
1069
1070 static PyObject *
1071 Handle_get_keep(Handle *self, void* nothing)
1072 {
1073         Device* device = (Device*)self->device;
1074
1075         try
1076         {
1077                 if(device->device->getKeep(self->handle))
1078                 {
1079                         Py_RETURN_TRUE;
1080                 }
1081                 else
1082                 {
1083                         Py_RETURN_FALSE;
1084                 }
1085         }
1086         catch(AUD_Exception&)
1087         {
1088                 PyErr_SetString(AUDError, "Couldn't retrieve the status of the sound!");
1089                 return NULL;
1090         }
1091 }
1092
1093 static int
1094 Handle_set_keep(Handle *self, PyObject* args, void* nothing)
1095 {
1096         if(!PyBool_Check(args))
1097         {
1098                 PyErr_SetString(PyExc_TypeError, "keep is not a boolean!");
1099                 return -1;
1100         }
1101
1102         bool keep = args == Py_True;
1103         Device* device = (Device*)self->device;
1104
1105         try
1106         {
1107                 if(device->device->setKeep(self->handle, keep))
1108                         return 0;
1109         }
1110         catch(AUD_Exception&)
1111         {
1112         }
1113
1114         PyErr_SetString(AUDError, "Couldn't set keep of the sound!");
1115         return -1;
1116 }
1117
1118 PyDoc_STRVAR(M_aud_Handle_status_doc,
1119                          "Whether the sound is playing, paused or stopped.");
1120
1121 static PyObject *
1122 Handle_get_status(Handle *self, void* nothing)
1123 {
1124         Device* device = (Device*)self->device;
1125
1126         try
1127         {
1128                 return Py_BuildValue("i", device->device->getStatus(self->handle));
1129         }
1130         catch(AUD_Exception&)
1131         {
1132                 PyErr_SetString(AUDError, "Couldn't retrieve the status of the sound!");
1133                 return NULL;
1134         }
1135 }
1136
1137 PyDoc_STRVAR(M_aud_Handle_volume_doc,
1138                          "The volume of the sound.");
1139
1140 static PyObject *
1141 Handle_get_volume(Handle *self, void* nothing)
1142 {
1143         Device* device = (Device*)self->device;
1144
1145         try
1146         {
1147                 return Py_BuildValue("f", device->device->getVolume(self->handle));
1148         }
1149         catch(AUD_Exception&)
1150         {
1151                 PyErr_SetString(AUDError, "Couldn't get the sound volume!");
1152                 return NULL;
1153         }
1154 }
1155
1156 static int
1157 Handle_set_volume(Handle *self, PyObject* args, void* nothing)
1158 {
1159         float volume;
1160
1161         if(!PyArg_Parse(args, "f", &volume))
1162                 return -1;
1163
1164         Device* device = (Device*)self->device;
1165
1166         try
1167         {
1168                 if(device->device->setVolume(self->handle, volume))
1169                         return 0;
1170         }
1171         catch(AUD_Exception&)
1172         {
1173         }
1174
1175         PyErr_SetString(AUDError, "Couldn't set the sound volume!");
1176         return -1;
1177 }
1178
1179 PyDoc_STRVAR(M_aud_Handle_pitch_doc,
1180                          "The pitch of the sound.");
1181
1182 static PyObject *
1183 Handle_get_pitch(Handle *self, void* nothing)
1184 {
1185         Device* device = (Device*)self->device;
1186
1187         try
1188         {
1189                 return Py_BuildValue("f", device->device->getPitch(self->handle));
1190         }
1191         catch(AUD_Exception&)
1192         {
1193                 PyErr_SetString(AUDError, "Couldn't get the sound pitch!");
1194                 return NULL;
1195         }
1196 }
1197
1198 static int
1199 Handle_set_pitch(Handle *self, PyObject* args, void* nothing)
1200 {
1201         float pitch;
1202
1203         if(!PyArg_Parse(args, "f", &pitch))
1204                 return -1;
1205
1206         Device* device = (Device*)self->device;
1207
1208         try
1209         {
1210                 if(device->device->setPitch(self->handle, pitch))
1211                         return 0;
1212         }
1213         catch(AUD_Exception&)
1214         {
1215         }
1216
1217         PyErr_SetString(AUDError, "Couldn't set the sound pitch!");
1218         return -1;
1219 }
1220
1221 PyDoc_STRVAR(M_aud_Handle_loop_count_doc,
1222                          "The (remaining) loop count of the sound. A negative value indicates infinity.");
1223
1224 static PyObject *
1225 Handle_get_loop_count(Handle *self, void* nothing)
1226 {
1227         Device* device = (Device*)self->device;
1228
1229         try
1230         {
1231                 return Py_BuildValue("i", device->device->getLoopCount(self->handle));
1232         }
1233         catch(AUD_Exception&)
1234         {
1235                 PyErr_SetString(AUDError, "Couldn't get the loop count!");
1236                 return NULL;
1237         }
1238 }
1239
1240 static int
1241 Handle_set_loop_count(Handle *self, PyObject* args, void* nothing)
1242 {
1243         int loops;
1244
1245         if(!PyArg_Parse(args, "i", &loops))
1246                 return -1;
1247
1248         Device* device = (Device*)self->device;
1249
1250         try
1251         {
1252                 if(device->device->setLoopCount(self->handle, loops))
1253                         return 0;
1254         }
1255         catch(AUD_Exception&)
1256         {
1257         }
1258
1259         PyErr_SetString(AUDError, "Couldn't set the loop count!");
1260         return -1;
1261 }
1262
1263 PyDoc_STRVAR(M_aud_Handle_location_doc,
1264                          "The source's location in 3D space, a 3D tuple of floats.");
1265
1266 static PyObject *
1267 Handle_get_location(Handle *self, void* nothing)
1268 {
1269         Device* dev = (Device*)self->device;
1270
1271         try
1272         {
1273                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
1274                 if(device)
1275                 {
1276                         AUD_Vector3 v = device->getSourceLocation(self->handle);
1277                         return Py_BuildValue("(fff)", v.x(), v.y(), v.z());
1278                 }
1279                 else
1280                 {
1281                         PyErr_SetString(AUDError, "Device is not a 3D device!");
1282                 }
1283         }
1284         catch(AUD_Exception&)
1285         {
1286                 PyErr_SetString(AUDError, "Couldn't retrieve the location!");
1287         }
1288
1289         return NULL;
1290 }
1291
1292 static int
1293 Handle_set_location(Handle *self, PyObject* args, void* nothing)
1294 {
1295         float x, y, z;
1296
1297         if(!PyArg_Parse(args, "(fff)", &x, &y, &z))
1298                 return -1;
1299
1300         Device* dev = (Device*)self->device;
1301
1302         try
1303         {
1304                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
1305                 if(device)
1306                 {
1307                         AUD_Vector3 location(x, y, z);
1308                         device->setSourceLocation(self->handle, location);
1309                         return 0;
1310                 }
1311                 else
1312                         PyErr_SetString(AUDError, "Device is not a 3D device!");
1313         }
1314         catch(AUD_Exception&)
1315         {
1316                 PyErr_SetString(AUDError, "Couldn't set the location!");
1317         }
1318
1319         return -1;
1320 }
1321
1322 PyDoc_STRVAR(M_aud_Handle_velocity_doc,
1323                          "The source's velocity in 3D space, a 3D tuple of floats.");
1324
1325 static PyObject *
1326 Handle_get_velocity(Handle *self, void* nothing)
1327 {
1328         Device* dev = (Device*)self->device;
1329
1330         try
1331         {
1332                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
1333                 if(device)
1334                 {
1335                         AUD_Vector3 v = device->getSourceVelocity(self->handle);
1336                         return Py_BuildValue("(fff)", v.x(), v.y(), v.z());
1337                 }
1338                 else
1339                 {
1340                         PyErr_SetString(AUDError, "Device is not a 3D device!");
1341                 }
1342         }
1343         catch(AUD_Exception&)
1344         {
1345                 PyErr_SetString(AUDError, "Couldn't retrieve the velocity!");
1346         }
1347
1348         return NULL;
1349 }
1350
1351 static int
1352 Handle_set_velocity(Handle *self, PyObject* args, void* nothing)
1353 {
1354         float x, y, z;
1355
1356         if(!PyArg_Parse(args, "(fff)", &x, &y, &z))
1357                 return -1;
1358
1359         Device* dev = (Device*)self->device;
1360
1361         try
1362         {
1363                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
1364                 if(device)
1365                 {
1366                         AUD_Vector3 velocity(x, y, z);
1367                         device->setSourceVelocity(self->handle, velocity);
1368                         return 0;
1369                 }
1370                 else
1371                         PyErr_SetString(AUDError, "Device is not a 3D device!");
1372         }
1373         catch(AUD_Exception&)
1374         {
1375                 PyErr_SetString(AUDError, "Couldn't set the velocity!");
1376         }
1377
1378         return -1;
1379 }
1380
1381 PyDoc_STRVAR(M_aud_Handle_orientation_doc,
1382                          "The source's orientation in 3D space as quaternion, a 4 float tuple.");
1383
1384 static PyObject *
1385 Handle_get_orientation(Handle *self, void* nothing)
1386 {
1387         Device* dev = (Device*)self->device;
1388
1389         try
1390         {
1391                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
1392                 if(device)
1393                 {
1394                         AUD_Quaternion o = device->getSourceOrientation(self->handle);
1395                         return Py_BuildValue("(ffff)", o.w(), o.x(), o.y(), o.z());
1396                 }
1397                 else
1398                 {
1399                         PyErr_SetString(AUDError, "Device is not a 3D device!");
1400                 }
1401         }
1402         catch(AUD_Exception&)
1403         {
1404                 PyErr_SetString(AUDError, "Couldn't retrieve the orientation!");
1405         }
1406
1407         return NULL;
1408 }
1409
1410 static int
1411 Handle_set_orientation(Handle *self, PyObject* args, void* nothing)
1412 {
1413         float w, x, y, z;
1414
1415         if(!PyArg_Parse(args, "(ffff)", &w, &x, &y, &z))
1416                 return -1;
1417
1418         Device* dev = (Device*)self->device;
1419
1420         try
1421         {
1422                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
1423                 if(device)
1424                 {
1425                         AUD_Quaternion orientation(w, x, y, z);
1426                         device->setSourceOrientation(self->handle, orientation);
1427                         return 0;
1428                 }
1429                 else
1430                         PyErr_SetString(AUDError, "Device is not a 3D device!");
1431         }
1432         catch(AUD_Exception&)
1433         {
1434                 PyErr_SetString(AUDError, "Couldn't set the orientation!");
1435         }
1436
1437         return -1;
1438 }
1439
1440 PyDoc_STRVAR(M_aud_Handle_relative_doc,
1441                          "Whether the source's location, velocity and orientation is relative or absolute to the listener.");
1442
1443 static PyObject *
1444 Handle_get_relative(Handle *self, void* nothing)
1445 {
1446         Device* dev = (Device*)self->device;
1447
1448         try
1449         {
1450                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
1451                 if(device)
1452                 {
1453                         if(device->isRelative(self->handle))
1454                         {
1455                                 Py_RETURN_TRUE;
1456                         }
1457                         else
1458                         {
1459                                 Py_RETURN_FALSE;
1460                         }
1461                 }
1462                 else
1463                 {
1464                         PyErr_SetString(AUDError, "Device is not a 3D device!");
1465                 }
1466         }
1467         catch(AUD_Exception&)
1468         {
1469                 PyErr_SetString(AUDError, "Couldn't retrieve the status of the sound!");
1470         }
1471
1472         return NULL;
1473 }
1474
1475 static int
1476 Handle_set_relative(Handle *self, PyObject* args, void* nothing)
1477 {
1478         if(!PyBool_Check(args))
1479         {
1480                 PyErr_SetString(PyExc_TypeError, "Value is not a boolean!");
1481                 return -1;
1482         }
1483
1484         bool relative = (args == Py_True);
1485         Device* dev = (Device*)self->device;
1486
1487         try
1488         {
1489                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
1490                 if(device)
1491                 {
1492                         device->setRelative(self->handle, relative);
1493                         return 0;
1494                 }
1495                 else
1496                         PyErr_SetString(AUDError, "Device is not a 3D device!");
1497         }
1498         catch(AUD_Exception&)
1499         {
1500                 PyErr_SetString(AUDError, "Couldn't set the status!");
1501         }
1502
1503         return -1;
1504 }
1505
1506 PyDoc_STRVAR(M_aud_Handle_volume_minimum_doc,
1507                          "The minimum volume of the source.");
1508
1509 static PyObject *
1510 Handle_get_volume_minimum(Handle *self, void* nothing)
1511 {
1512         Device* dev = (Device*)self->device;
1513
1514         try
1515         {
1516                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
1517                 if(device)
1518                 {
1519                         return Py_BuildValue("f", device->getVolumeMinimum(self->handle));
1520                 }
1521                 else
1522                 {
1523                         PyErr_SetString(AUDError, "Device is not a 3D device!");
1524                         return NULL;
1525                 }
1526         }
1527         catch(AUD_Exception&)
1528         {
1529                 PyErr_SetString(AUDError, "Couldn't retrieve the minimum volume of the sound!");
1530                 return NULL;
1531         }
1532 }
1533
1534 static int
1535 Handle_set_volume_minimum(Handle *self, PyObject* args, void* nothing)
1536 {
1537         float volume;
1538
1539         if(!PyArg_Parse(args, "f", &volume))
1540                 return -1;
1541
1542         Device* dev = (Device*)self->device;
1543
1544         try
1545         {
1546                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
1547                 if(device)
1548                 {
1549                         device->setVolumeMinimum(self->handle, volume);
1550                         return 0;
1551                 }
1552                 else
1553                         PyErr_SetString(AUDError, "Device is not a 3D device!");
1554         }
1555         catch(AUD_Exception&)
1556         {
1557                 PyErr_SetString(AUDError, "Couldn't set the minimum source volume!");
1558         }
1559
1560         return -1;
1561 }
1562
1563 PyDoc_STRVAR(M_aud_Handle_volume_maximum_doc,
1564                          "The maximum volume of the source.");
1565
1566 static PyObject *
1567 Handle_get_volume_maximum(Handle *self, void* nothing)
1568 {
1569         Device* dev = (Device*)self->device;
1570
1571         try
1572         {
1573                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
1574                 if(device)
1575                 {
1576                         return Py_BuildValue("f", device->getVolumeMaximum(self->handle));
1577                 }
1578                 else
1579                 {
1580                         PyErr_SetString(AUDError, "Device is not a 3D device!");
1581                         return NULL;
1582                 }
1583         }
1584         catch(AUD_Exception&)
1585         {
1586                 PyErr_SetString(AUDError, "Couldn't retrieve the maximum volume of the sound!");
1587                 return NULL;
1588         }
1589 }
1590
1591 static int
1592 Handle_set_volume_maximum(Handle *self, PyObject* args, void* nothing)
1593 {
1594         float volume;
1595
1596         if(!PyArg_Parse(args, "f", &volume))
1597                 return -1;
1598
1599         Device* dev = (Device*)self->device;
1600
1601         try
1602         {
1603                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
1604                 if(device)
1605                 {
1606                         device->setVolumeMaximum(self->handle, volume);
1607                         return 0;
1608                 }
1609                 else
1610                         PyErr_SetString(AUDError, "Device is not a 3D device!");
1611         }
1612         catch(AUD_Exception&)
1613         {
1614                 PyErr_SetString(AUDError, "Couldn't set the maximum source volume!");
1615         }
1616
1617         return -1;
1618 }
1619
1620 PyDoc_STRVAR(M_aud_Handle_distance_reference_doc,
1621                          "The reference distance of the source.");
1622
1623 static PyObject *
1624 Handle_get_distance_reference(Handle *self, void* nothing)
1625 {
1626         Device* dev = (Device*)self->device;
1627
1628         try
1629         {
1630                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
1631                 if(device)
1632                 {
1633                         return Py_BuildValue("f", device->getDistanceReference(self->handle));
1634                 }
1635                 else
1636                 {
1637                         PyErr_SetString(AUDError, "Device is not a 3D device!");
1638                         return NULL;
1639                 }
1640         }
1641         catch(AUD_Exception&)
1642         {
1643                 PyErr_SetString(AUDError, "Couldn't retrieve the reference distance of the sound!");
1644                 return NULL;
1645         }
1646 }
1647
1648 static int
1649 Handle_set_distance_reference(Handle *self, PyObject* args, void* nothing)
1650 {
1651         float distance;
1652
1653         if(!PyArg_Parse(args, "f", &distance))
1654                 return -1;
1655
1656         Device* dev = (Device*)self->device;
1657
1658         try
1659         {
1660                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
1661                 if(device)
1662                 {
1663                         device->setDistanceReference(self->handle, distance);
1664                         return 0;
1665                 }
1666                 else
1667                         PyErr_SetString(AUDError, "Device is not a 3D device!");
1668         }
1669         catch(AUD_Exception&)
1670         {
1671                 PyErr_SetString(AUDError, "Couldn't set the reference distance!");
1672         }
1673
1674         return -1;
1675 }
1676
1677 PyDoc_STRVAR(M_aud_Handle_distance_maximum_doc,
1678                          "The maximum distance of the source.");
1679
1680 static PyObject *
1681 Handle_get_distance_maximum(Handle *self, void* nothing)
1682 {
1683         Device* dev = (Device*)self->device;
1684
1685         try
1686         {
1687                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
1688                 if(device)
1689                 {
1690                         return Py_BuildValue("f", device->getDistanceMaximum(self->handle));
1691                 }
1692                 else
1693                 {
1694                         PyErr_SetString(AUDError, "Device is not a 3D device!");
1695                         return NULL;
1696                 }
1697         }
1698         catch(AUD_Exception&)
1699         {
1700                 PyErr_SetString(AUDError, "Couldn't retrieve the maximum distance of the sound!");
1701                 return NULL;
1702         }
1703 }
1704
1705 static int
1706 Handle_set_distance_maximum(Handle *self, PyObject* args, void* nothing)
1707 {
1708         float distance;
1709
1710         if(!PyArg_Parse(args, "f", &distance))
1711                 return -1;
1712
1713         Device* dev = (Device*)self->device;
1714
1715         try
1716         {
1717                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
1718                 if(device)
1719                 {
1720                         device->setDistanceMaximum(self->handle, distance);
1721                         return 0;
1722                 }
1723                 else
1724                         PyErr_SetString(AUDError, "Device is not a 3D device!");
1725         }
1726         catch(AUD_Exception&)
1727         {
1728                 PyErr_SetString(AUDError, "Couldn't set the maximum distance!");
1729         }
1730
1731         return -1;
1732 }
1733
1734 PyDoc_STRVAR(M_aud_Handle_attenuation_doc,
1735                          "The attenuation of the source.");
1736
1737 static PyObject *
1738 Handle_get_attenuation(Handle *self, void* nothing)
1739 {
1740         Device* dev = (Device*)self->device;
1741
1742         try
1743         {
1744                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
1745                 if(device)
1746                 {
1747                         return Py_BuildValue("f", device->getAttenuation(self->handle));
1748                 }
1749                 else
1750                 {
1751                         PyErr_SetString(AUDError, "Device is not a 3D device!");
1752                         return NULL;
1753                 }
1754         }
1755         catch(AUD_Exception&)
1756         {
1757                 PyErr_SetString(AUDError, "Couldn't retrieve the attenuation of the sound!");
1758                 return NULL;
1759         }
1760 }
1761
1762 static int
1763 Handle_set_attenuation(Handle *self, PyObject* args, void* nothing)
1764 {
1765         float factor;
1766
1767         if(!PyArg_Parse(args, "f", &factor))
1768                 return -1;
1769
1770         Device* dev = (Device*)self->device;
1771
1772         try
1773         {
1774                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
1775                 if(device)
1776                 {
1777                         device->setAttenuation(self->handle, factor);
1778                         return 0;
1779                 }
1780                 else
1781                         PyErr_SetString(AUDError, "Device is not a 3D device!");
1782         }
1783         catch(AUD_Exception&)
1784         {
1785                 PyErr_SetString(AUDError, "Couldn't set the attenuation!");
1786         }
1787
1788         return -1;
1789 }
1790
1791 PyDoc_STRVAR(M_aud_Handle_cone_angle_inner_doc,
1792                          "The cone inner angle of the source.");
1793
1794 static PyObject *
1795 Handle_get_cone_angle_inner(Handle *self, void* nothing)
1796 {
1797         Device* dev = (Device*)self->device;
1798
1799         try
1800         {
1801                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
1802                 if(device)
1803                 {
1804                         return Py_BuildValue("f", device->getConeAngleInner(self->handle));
1805                 }
1806                 else
1807                 {
1808                         PyErr_SetString(AUDError, "Device is not a 3D device!");
1809                         return NULL;
1810                 }
1811         }
1812         catch(AUD_Exception&)
1813         {
1814                 PyErr_SetString(AUDError, "Couldn't retrieve the cone inner angle of the sound!");
1815                 return NULL;
1816         }
1817 }
1818
1819 static int
1820 Handle_set_cone_angle_inner(Handle *self, PyObject* args, void* nothing)
1821 {
1822         float angle;
1823
1824         if(!PyArg_Parse(args, "f", &angle))
1825                 return -1;
1826
1827         Device* dev = (Device*)self->device;
1828
1829         try
1830         {
1831                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
1832                 if(device)
1833                 {
1834                         device->setConeAngleInner(self->handle, angle);
1835                         return 0;
1836                 }
1837                 else
1838                         PyErr_SetString(AUDError, "Device is not a 3D device!");
1839         }
1840         catch(AUD_Exception&)
1841         {
1842                 PyErr_SetString(AUDError, "Couldn't set the cone inner angle!");
1843         }
1844
1845         return -1;
1846 }
1847
1848 PyDoc_STRVAR(M_aud_Handle_cone_angle_outer_doc,
1849                          "The cone outer angle of the source.");
1850
1851 static PyObject *
1852 Handle_get_cone_angle_outer(Handle *self, void* nothing)
1853 {
1854         Device* dev = (Device*)self->device;
1855
1856         try
1857         {
1858                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
1859                 if(device)
1860                 {
1861                         return Py_BuildValue("f", device->getConeAngleOuter(self->handle));
1862                 }
1863                 else
1864                 {
1865                         PyErr_SetString(AUDError, "Device is not a 3D device!");
1866                         return NULL;
1867                 }
1868         }
1869         catch(AUD_Exception&)
1870         {
1871                 PyErr_SetString(AUDError, "Couldn't retrieve the cone outer angle of the sound!");
1872                 return NULL;
1873         }
1874 }
1875
1876 static int
1877 Handle_set_cone_angle_outer(Handle *self, PyObject* args, void* nothing)
1878 {
1879         float angle;
1880
1881         if(!PyArg_Parse(args, "f", &angle))
1882                 return -1;
1883
1884         Device* dev = (Device*)self->device;
1885
1886         try
1887         {
1888                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
1889                 if(device)
1890                 {
1891                         device->setConeAngleOuter(self->handle, angle);
1892                         return 0;
1893                 }
1894                 else
1895                         PyErr_SetString(AUDError, "Device is not a 3D device!");
1896         }
1897         catch(AUD_Exception&)
1898         {
1899                 PyErr_SetString(AUDError, "Couldn't set the cone outer angle!");
1900         }
1901
1902         return -1;
1903 }
1904
1905 PyDoc_STRVAR(M_aud_Handle_cone_volume_outer_doc,
1906                          "The cone outer volume of the source.");
1907
1908 static PyObject *
1909 Handle_get_cone_volume_outer(Handle *self, void* nothing)
1910 {
1911         Device* dev = (Device*)self->device;
1912
1913         try
1914         {
1915                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
1916                 if(device)
1917                 {
1918                         return Py_BuildValue("f", device->getConeVolumeOuter(self->handle));
1919                 }
1920                 else
1921                 {
1922                         PyErr_SetString(AUDError, "Device is not a 3D device!");
1923                         return NULL;
1924                 }
1925         }
1926         catch(AUD_Exception&)
1927         {
1928                 PyErr_SetString(AUDError, "Couldn't retrieve the cone outer volume of the sound!");
1929                 return NULL;
1930         }
1931 }
1932
1933 static int
1934 Handle_set_cone_volume_outer(Handle *self, PyObject* args, void* nothing)
1935 {
1936         float volume;
1937
1938         if(!PyArg_Parse(args, "f", &volume))
1939                 return -1;
1940
1941         Device* dev = (Device*)self->device;
1942
1943         try
1944         {
1945                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
1946                 if(device)
1947                 {
1948                         device->setConeVolumeOuter(self->handle, volume);
1949                         return 0;
1950                 }
1951                 else
1952                         PyErr_SetString(AUDError, "Device is not a 3D device!");
1953         }
1954         catch(AUD_Exception&)
1955         {
1956                 PyErr_SetString(AUDError, "Couldn't set the cone outer volume!");
1957         }
1958
1959         return -1;
1960 }
1961
1962 static PyGetSetDef Handle_properties[] = {
1963         {(char*)"position", (getter)Handle_get_position, (setter)Handle_set_position,
1964          M_aud_Handle_position_doc, NULL },
1965         {(char*)"keep", (getter)Handle_get_keep, (setter)Handle_set_keep,
1966          M_aud_Handle_keep_doc, NULL },
1967         {(char*)"status", (getter)Handle_get_status, NULL,
1968          M_aud_Handle_status_doc, NULL },
1969         {(char*)"volume", (getter)Handle_get_volume, (setter)Handle_set_volume,
1970          M_aud_Handle_volume_doc, NULL },
1971         {(char*)"pitch", (getter)Handle_get_pitch, (setter)Handle_set_pitch,
1972          M_aud_Handle_pitch_doc, NULL },
1973         {(char*)"loop_count", (getter)Handle_get_loop_count, (setter)Handle_set_loop_count,
1974          M_aud_Handle_loop_count_doc, NULL },
1975         {(char*)"location", (getter)Handle_get_location, (setter)Handle_set_location,
1976          M_aud_Handle_location_doc, NULL },
1977         {(char*)"velocity", (getter)Handle_get_velocity, (setter)Handle_set_velocity,
1978          M_aud_Handle_velocity_doc, NULL },
1979         {(char*)"orientation", (getter)Handle_get_orientation, (setter)Handle_set_orientation,
1980          M_aud_Handle_orientation_doc, NULL },
1981         {(char*)"relative", (getter)Handle_get_relative, (setter)Handle_set_relative,
1982          M_aud_Handle_relative_doc, NULL },
1983         {(char*)"volume_minimum", (getter)Handle_get_volume_minimum, (setter)Handle_set_volume_minimum,
1984          M_aud_Handle_volume_minimum_doc, NULL },
1985         {(char*)"volume_maximum", (getter)Handle_get_volume_maximum, (setter)Handle_set_volume_maximum,
1986          M_aud_Handle_volume_maximum_doc, NULL },
1987         {(char*)"distance_reference", (getter)Handle_get_distance_reference, (setter)Handle_set_distance_reference,
1988          M_aud_Handle_distance_reference_doc, NULL },
1989         {(char*)"distance_maximum", (getter)Handle_get_distance_maximum, (setter)Handle_set_distance_maximum,
1990          M_aud_Handle_distance_maximum_doc, NULL },
1991         {(char*)"attenuation", (getter)Handle_get_attenuation, (setter)Handle_set_attenuation,
1992          M_aud_Handle_attenuation_doc, NULL },
1993         {(char*)"cone_angle_inner", (getter)Handle_get_cone_angle_inner, (setter)Handle_set_cone_angle_inner,
1994          M_aud_Handle_cone_angle_inner_doc, NULL },
1995         {(char*)"cone_angle_outer", (getter)Handle_get_cone_angle_outer, (setter)Handle_set_cone_angle_outer,
1996          M_aud_Handle_cone_angle_outer_doc, NULL },
1997         {(char*)"cone_volume_outer", (getter)Handle_get_cone_volume_outer, (setter)Handle_set_cone_volume_outer,
1998          M_aud_Handle_cone_volume_outer_doc, NULL },
1999         {NULL}  /* Sentinel */
2000 };
2001
2002 PyDoc_STRVAR(M_aud_Handle_doc,
2003                          "Handle objects are playback handles that can be used to control "
2004                          "playback of a sound. If a sound is played back multiple times "
2005                          "then there are as many handles.");
2006
2007 static PyTypeObject HandleType = {
2008         PyVarObject_HEAD_INIT(NULL, 0)
2009         "aud.Handle",              /* tp_name */
2010         sizeof(Handle),            /* tp_basicsize */
2011         0,                         /* tp_itemsize */
2012         (destructor)Handle_dealloc,/* tp_dealloc */
2013         0,                         /* tp_print */
2014         0,                         /* tp_getattr */
2015         0,                         /* tp_setattr */
2016         0,                         /* tp_reserved */
2017         0,                         /* tp_repr */
2018         0,                         /* tp_as_number */
2019         0,                         /* tp_as_sequence */
2020         0,                         /* tp_as_mapping */
2021         0,                         /* tp_hash  */
2022         0,                         /* tp_call */
2023         0,                         /* tp_str */
2024         0,                         /* tp_getattro */
2025         0,                         /* tp_setattro */
2026         0,                         /* tp_as_buffer */
2027         Py_TPFLAGS_DEFAULT,        /* tp_flags */
2028         M_aud_Handle_doc,          /* tp_doc */
2029         0,                                 /* tp_traverse */
2030         0,                                 /* tp_clear */
2031         0,                                 /* tp_richcompare */
2032         0,                                 /* tp_weaklistoffset */
2033         0,                                 /* tp_iter */
2034         0,                                 /* tp_iternext */
2035         Handle_methods,            /* tp_methods */
2036         0,                         /* tp_members */
2037         Handle_properties,         /* tp_getset */
2038         0,                         /* tp_base */
2039         0,                         /* tp_dict */
2040         0,                         /* tp_descr_get */
2041         0,                         /* tp_descr_set */
2042         0,                         /* tp_dictoffset */
2043         0,                         /* tp_init */
2044         0,                         /* tp_alloc */
2045         0,                         /* tp_new */
2046 };
2047
2048 // ========== Device ==================================================
2049
2050 static void
2051 Device_dealloc(Device* self)
2052 {
2053         if(self->device)
2054                 delete self->device;
2055         Py_TYPE(self)->tp_free((PyObject*)self);
2056 }
2057
2058 PyDoc_STRVAR(M_aud_Device_play_doc,
2059                          "play(sound[, keep])\n\n"
2060                          "Plays a sound.\n\n"
2061                          ":arg sound: The sound to play.\n"
2062                          ":type sound: aud.Sound\n"
2063                          ":arg keep: Whether the sound should be kept paused in the device when its end is reached.\n"
2064                          ":type keep: boolean\n"
2065                          ":return: The playback handle.\n"
2066                          ":rtype: aud.Handle");
2067
2068 static PyObject *
2069 Device_play(Device *self, PyObject *args, PyObject *kwds)
2070 {
2071         PyObject* object;
2072         PyObject* keepo = NULL;
2073
2074         bool keep = false;
2075
2076         static const char *kwlist[] = {"sound", "keep", NULL};
2077
2078         if(!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", const_cast<char**>(kwlist), &object, &keepo))
2079                 return NULL;
2080
2081         if(!PyObject_TypeCheck(object, &SoundType))
2082         {
2083                 PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Sound!");
2084                 return NULL;
2085         }
2086
2087         if(keepo != NULL)
2088         {
2089                 if(!PyBool_Check(keepo))
2090                 {
2091                         PyErr_SetString(PyExc_TypeError, "keep is not a boolean!");
2092                         return NULL;
2093                 }
2094
2095                 keep = keepo == Py_True;
2096         }
2097
2098         Sound* sound = (Sound*)object;
2099         Handle *handle;
2100
2101         handle = (Handle*)HandleType.tp_alloc(&HandleType, 0);
2102         if(handle != NULL)
2103         {
2104                 handle->device = (PyObject*)self;
2105                 Py_INCREF(self);
2106
2107                 try
2108                 {
2109                         handle->handle = self->device->play(sound->factory, keep);
2110                 }
2111                 catch(AUD_Exception&)
2112                 {
2113                         Py_DECREF(handle);
2114                         PyErr_SetString(AUDError, "Couldn't play the sound!");
2115                         return NULL;
2116                 }
2117         }
2118
2119         return (PyObject *)handle;
2120 }
2121
2122 PyDoc_STRVAR(M_aud_Device_lock_doc,
2123                          "lock()\n\n"
2124                          "Locks the device so that it's guaranteed, that no samples are "
2125                          "read from the streams until the unlock is called. The device has "
2126                          "to be unlocked as often as locked to be able to continue "
2127                          "playback. Make sure the time between locking and unlocking is as "
2128                          "short as possible to avoid clicks.");
2129
2130 static PyObject *
2131 Device_lock(Device *self)
2132 {
2133         try
2134         {
2135                 self->device->lock();
2136                 Py_RETURN_NONE;
2137         }
2138         catch(AUD_Exception&)
2139         {
2140                 PyErr_SetString(AUDError, "Couldn't lock the device!");
2141                 return NULL;
2142         }
2143 }
2144
2145 PyDoc_STRVAR(M_aud_Device_unlock_doc,
2146                          "unlock()\n\n"
2147                          "Unlocks the device after a lock call, see lock() for details.");
2148
2149 static PyObject *
2150 Device_unlock(Device *self)
2151 {
2152         try
2153         {
2154                 self->device->unlock();
2155                 Py_RETURN_NONE;
2156         }
2157         catch(AUD_Exception&)
2158         {
2159                 PyErr_SetString(AUDError, "Couldn't unlock the device!");
2160                 return NULL;
2161         }
2162 }
2163
2164 PyDoc_STRVAR(M_aud_Device_OpenAL_doc,
2165                          "OpenAL([frequency[, buffer_size]])\n\n"
2166                          "Creates an OpenAL device.\n\n"
2167                          ":arg frequency: The prefered sampling frequency.\n"
2168                          ":type frequency: integer\n"
2169                          ":arg buffer_size: The size of a playback buffer, "
2170                          "must be at least 128.\n"
2171                          ":type buffer_size: integer\n"
2172                          ":return: The created aud.Device object.\n"
2173                          ":rtype: aud.Device");
2174
2175 static PyObject *
2176 Device_OpenAL(PyTypeObject *type, PyObject *args, PyObject *kwds);
2177
2178 PyDoc_STRVAR(M_aud_Device_SDL_doc,
2179                          "SDL([frequency[, buffer_size]])\n\n"
2180                          "Creates an SDL device.\n\n"
2181                          ":arg frequency: The sampling frequency.\n"
2182                          ":type frequency: integer\n"
2183                          ":arg buffer_size: The size of the playback buffer, "
2184                          "must be at least 128.\n"
2185                          ":type buffer_size: integer\n"
2186                          ":return: The created aud.Device object.\n"
2187                          ":rtype: aud.Device");
2188
2189 static PyObject *
2190 Device_SDL(PyTypeObject *type, PyObject *args, PyObject *kwds);
2191
2192 PyDoc_STRVAR(M_aud_Device_Jack_doc,
2193                          "Jack([channels[, buffer_size]])\n\n"
2194                          "Creates a Jack device.\n\n"
2195                          ":arg channels: The count of channels.\n"
2196                          ":type channels: integer\n"
2197                          ":arg buffer_size: The size of the playback buffer, "
2198                          "must be at least 128.\n"
2199                          ":type buffer_size: integer\n"
2200                          ":return: The created aud.Device object.\n"
2201                          ":rtype: aud.Device");
2202
2203 static PyObject *
2204 Device_Jack(PyTypeObject *type, PyObject *args, PyObject *kwds);
2205
2206 PyDoc_STRVAR(M_aud_Device_Null_doc,
2207                          "Null()\n\n"
2208                          "Creates a Null device.\n\n"
2209                          ":return: The created aud.Device object.\n"
2210                          ":rtype: aud.Device");
2211
2212 static PyObject *
2213 Device_Null(PyTypeObject *type);
2214
2215 static PyMethodDef Device_methods[] = {
2216         {"play", (PyCFunction)Device_play, METH_VARARGS | METH_KEYWORDS,
2217          M_aud_Device_play_doc
2218         },
2219         {"lock", (PyCFunction)Device_lock, METH_NOARGS,
2220          M_aud_Device_lock_doc
2221         },
2222         {"unlock", (PyCFunction)Device_unlock, METH_NOARGS,
2223          M_aud_Device_unlock_doc
2224         },
2225         {"OpenAL", (PyCFunction)Device_OpenAL, METH_VARARGS | METH_STATIC | METH_KEYWORDS,
2226          M_aud_Device_OpenAL_doc
2227         },
2228         {"SDL", (PyCFunction)Device_SDL, METH_VARARGS | METH_STATIC | METH_KEYWORDS,
2229          M_aud_Device_SDL_doc
2230         },
2231         {"Jack", (PyCFunction)Device_Jack, METH_VARARGS | METH_STATIC | METH_KEYWORDS,
2232          M_aud_Device_Jack_doc
2233         },
2234         {"Null", (PyCFunction)Device_Null, METH_NOARGS | METH_STATIC,
2235          M_aud_Device_Null_doc
2236         },
2237         {NULL}  /* Sentinel */
2238 };
2239
2240 PyDoc_STRVAR(M_aud_Device_rate_doc,
2241                          "The sampling rate of the device in Hz.");
2242
2243 static PyObject *
2244 Device_get_rate(Device *self, void* nothing)
2245 {
2246         try
2247         {
2248                 AUD_DeviceSpecs specs = self->device->getSpecs();
2249                 return Py_BuildValue("i", specs.rate);
2250         }
2251         catch(AUD_Exception&)
2252         {
2253                 PyErr_SetString(AUDError, "Couldn't retrieve device stats!");
2254                 return NULL;
2255         }
2256 }
2257
2258 PyDoc_STRVAR(M_aud_Device_format_doc,
2259                          "The native sample format of the device.");
2260
2261 static PyObject *
2262 Device_get_format(Device *self, void* nothing)
2263 {
2264         try
2265         {
2266                 AUD_DeviceSpecs specs = self->device->getSpecs();
2267                 return Py_BuildValue("i", specs.format);
2268         }
2269         catch(AUD_Exception&)
2270         {
2271                 PyErr_SetString(AUDError, "Couldn't retrieve device stats!");
2272                 return NULL;
2273         }
2274 }
2275
2276 PyDoc_STRVAR(M_aud_Device_channels_doc,
2277                          "The channel count of the device.");
2278
2279 static PyObject *
2280 Device_get_channels(Device *self, void* nothing)
2281 {
2282         try
2283         {
2284                 AUD_DeviceSpecs specs = self->device->getSpecs();
2285                 return Py_BuildValue("i", specs.channels);
2286         }
2287         catch(AUD_Exception&)
2288         {
2289                 PyErr_SetString(AUDError, "Couldn't retrieve device stats!");
2290                 return NULL;
2291         }
2292 }
2293
2294 PyDoc_STRVAR(M_aud_Device_volume_doc,
2295                          "The overall volume of the device.");
2296
2297 static PyObject *
2298 Device_get_volume(Device *self, void* nothing)
2299 {
2300         try
2301         {
2302                 return Py_BuildValue("f", self->device->getVolume());
2303         }
2304         catch(AUD_Exception&)
2305         {
2306                 PyErr_SetString(AUDError, "Couldn't retrieve device volume!");
2307                 return NULL;
2308         }
2309 }
2310
2311 static int
2312 Device_set_volume(Device *self, PyObject* args, void* nothing)
2313 {
2314         float volume;
2315
2316         if(!PyArg_Parse(args, "f", &volume))
2317                 return -1;
2318
2319         try
2320         {
2321                 self->device->setVolume(volume);
2322                 return 0;
2323         }
2324         catch(AUD_Exception&)
2325         {
2326                 PyErr_SetString(AUDError, "Couldn't set device volume!");
2327                 return -1;
2328         }
2329 }
2330
2331 PyDoc_STRVAR(M_aud_Device_listener_location_doc,
2332                          "The listeners's location in 3D space, a 3D tuple of floats.");
2333
2334 static PyObject *
2335 Device_get_listener_location(Device *self, void* nothing)
2336 {
2337         try
2338         {
2339                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
2340                 if(device)
2341                 {
2342                         AUD_Vector3 v = device->getListenerLocation();
2343                         return Py_BuildValue("(fff)", v.x(), v.y(), v.z());
2344                 }
2345                 else
2346                 {
2347                         PyErr_SetString(AUDError, "Device is not a 3D device!");
2348                 }
2349         }
2350         catch(AUD_Exception&)
2351         {
2352                 PyErr_SetString(AUDError, "Couldn't retrieve the location!");
2353         }
2354
2355         return NULL;
2356 }
2357
2358 static int
2359 Device_set_listener_location(Device *self, PyObject* args, void* nothing)
2360 {
2361         float x, y, z;
2362
2363         if(!PyArg_Parse(args, "(fff)", &x, &y, &z))
2364                 return -1;
2365
2366         try
2367         {
2368                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
2369                 if(device)
2370                 {
2371                         AUD_Vector3 location(x, y, z);
2372                         device->setListenerLocation(location);
2373                         return 0;
2374                 }
2375                 else
2376                         PyErr_SetString(AUDError, "Device is not a 3D device!");
2377         }
2378         catch(AUD_Exception&)
2379         {
2380                 PyErr_SetString(AUDError, "Couldn't set the location!");
2381         }
2382
2383         return -1;
2384 }
2385
2386 PyDoc_STRVAR(M_aud_Device_listener_velocity_doc,
2387                          "The listener's velocity in 3D space, a 3D tuple of floats.");
2388
2389 static PyObject *
2390 Device_get_listener_velocity(Device *self, void* nothing)
2391 {
2392         try
2393         {
2394                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
2395                 if(device)
2396                 {
2397                         AUD_Vector3 v = device->getListenerVelocity();
2398                         return Py_BuildValue("(fff)", v.x(), v.y(), v.z());
2399                 }
2400                 else
2401                 {
2402                         PyErr_SetString(AUDError, "Device is not a 3D device!");
2403                 }
2404         }
2405         catch(AUD_Exception&)
2406         {
2407                 PyErr_SetString(AUDError, "Couldn't retrieve the velocity!");
2408         }
2409
2410         return NULL;
2411 }
2412
2413 static int
2414 Device_set_listener_velocity(Device *self, PyObject* args, void* nothing)
2415 {
2416         float x, y, z;
2417
2418         if(!PyArg_Parse(args, "(fff)", &x, &y, &z))
2419                 return -1;
2420
2421         try
2422         {
2423                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
2424                 if(device)
2425                 {
2426                         AUD_Vector3 velocity(x, y, z);
2427                         device->setListenerVelocity(velocity);
2428                         return 0;
2429                 }
2430                 else
2431                         PyErr_SetString(AUDError, "Device is not a 3D device!");
2432         }
2433         catch(AUD_Exception&)
2434         {
2435                 PyErr_SetString(AUDError, "Couldn't set the velocity!");
2436         }
2437
2438         return -1;
2439 }
2440
2441 PyDoc_STRVAR(M_aud_Device_listener_orientation_doc,
2442                          "The listener's orientation in 3D space as quaternion, a 4 float tuple.");
2443
2444 static PyObject *
2445 Device_get_listener_orientation(Device *self, void* nothing)
2446 {
2447         try
2448         {
2449                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
2450                 if(device)
2451                 {
2452                         AUD_Quaternion o = device->getListenerOrientation();
2453                         return Py_BuildValue("(ffff)", o.w(), o.x(), o.y(), o.z());
2454                 }
2455                 else
2456                 {
2457                         PyErr_SetString(AUDError, "Device is not a 3D device!");
2458                 }
2459         }
2460         catch(AUD_Exception&)
2461         {
2462                 PyErr_SetString(AUDError, "Couldn't retrieve the orientation!");
2463         }
2464
2465         return NULL;
2466 }
2467
2468 static int
2469 Device_set_listener_orientation(Device *self, PyObject* args, void* nothing)
2470 {
2471         float w, x, y, z;
2472
2473         if(!PyArg_Parse(args, "(ffff)", &w, &x, &y, &z))
2474                 return -1;
2475
2476         try
2477         {
2478                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
2479                 if(device)
2480                 {
2481                         AUD_Quaternion orientation(w, x, y, z);
2482                         device->setListenerOrientation(orientation);
2483                         return 0;
2484                 }
2485                 else
2486                         PyErr_SetString(AUDError, "Device is not a 3D device!");
2487         }
2488         catch(AUD_Exception&)
2489         {
2490                 PyErr_SetString(AUDError, "Couldn't set the orientation!");
2491         }
2492
2493         return -1;
2494 }
2495
2496 PyDoc_STRVAR(M_aud_Device_speed_of_sound_doc,
2497                          "The speed of sound of the device.");
2498
2499 static PyObject *
2500 Device_get_speed_of_sound(Device *self, void* nothing)
2501 {
2502         try
2503         {
2504                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
2505                 if(device)
2506                 {
2507                         return Py_BuildValue("f", device->getSpeedOfSound());
2508                 }
2509                 else
2510                 {
2511                         PyErr_SetString(AUDError, "Device is not a 3D device!");
2512                         return NULL;
2513                 }
2514         }
2515         catch(AUD_Exception&)
2516         {
2517                 PyErr_SetString(AUDError, "Couldn't retrieve device speed of sound!");
2518                 return NULL;
2519         }
2520 }
2521
2522 static int
2523 Device_set_speed_of_sound(Device *self, PyObject* args, void* nothing)
2524 {
2525         float speed;
2526
2527         if(!PyArg_Parse(args, "f", &speed))
2528                 return -1;
2529
2530         try
2531         {
2532                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
2533                 if(device)
2534                 {
2535                         device->setSpeedOfSound(speed);
2536                         return 0;
2537                 }
2538                 else
2539                         PyErr_SetString(AUDError, "Device is not a 3D device!");
2540         }
2541         catch(AUD_Exception&)
2542         {
2543                 PyErr_SetString(AUDError, "Couldn't set device speed of sound!");
2544         }
2545
2546         return -1;
2547 }
2548
2549 PyDoc_STRVAR(M_aud_Device_doppler_factor_doc,
2550                          "The doppler factor of the device.");
2551
2552 static PyObject *
2553 Device_get_doppler_factor(Device *self, void* nothing)
2554 {
2555         try
2556         {
2557                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
2558                 if(device)
2559                 {
2560                         return Py_BuildValue("f", device->getDopplerFactor());
2561                 }
2562                 else
2563                 {
2564                         PyErr_SetString(AUDError, "Device is not a 3D device!");
2565                         return NULL;
2566                 }
2567         }
2568         catch(AUD_Exception&)
2569         {
2570                 PyErr_SetString(AUDError, "Couldn't retrieve device doppler factor!");
2571                 return NULL;
2572         }
2573 }
2574
2575 static int
2576 Device_set_doppler_factor(Device *self, PyObject* args, void* nothing)
2577 {
2578         float factor;
2579
2580         if(!PyArg_Parse(args, "f", &factor))
2581                 return -1;
2582
2583         try
2584         {
2585                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
2586                 if(device)
2587                 {
2588                         device->setDopplerFactor(factor);
2589                         return 0;
2590                 }
2591                 else
2592                         PyErr_SetString(AUDError, "Device is not a 3D device!");
2593         }
2594         catch(AUD_Exception&)
2595         {
2596                 PyErr_SetString(AUDError, "Couldn't set device doppler factor!");
2597         }
2598
2599         return -1;
2600 }
2601
2602 PyDoc_STRVAR(M_aud_Device_distance_model_doc,
2603                          "The distance model of the device.");
2604
2605 static PyObject *
2606 Device_get_distance_model(Device *self, void* nothing)
2607 {
2608         try
2609         {
2610                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
2611                 if(device)
2612                 {
2613                         return Py_BuildValue("i", int(device->getDistanceModel()));
2614                 }
2615                 else
2616                 {
2617                         PyErr_SetString(AUDError, "Device is not a 3D device!");
2618                         return NULL;
2619                 }
2620         }
2621         catch(AUD_Exception&)
2622         {
2623                 PyErr_SetString(AUDError, "Couldn't retrieve device distance model!");
2624                 return NULL;
2625         }
2626 }
2627
2628 static int
2629 Device_set_distance_model(Device *self, PyObject* args, void* nothing)
2630 {
2631         int model;
2632
2633         if(!PyArg_Parse(args, "i", &model))
2634                 return -1;
2635
2636         try
2637         {
2638                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
2639                 if(device)
2640                 {
2641                         device->setDistanceModel(AUD_DistanceModel(model));
2642                         return 0;
2643                 }
2644                 else
2645                         PyErr_SetString(AUDError, "Device is not a 3D device!");
2646         }
2647         catch(AUD_Exception&)
2648         {
2649                 PyErr_SetString(AUDError, "Couldn't set device distance model!");
2650         }
2651
2652         return -1;
2653 }
2654
2655 static PyGetSetDef Device_properties[] = {
2656         {(char*)"rate", (getter)Device_get_rate, NULL,
2657          M_aud_Device_rate_doc, NULL },
2658         {(char*)"format", (getter)Device_get_format, NULL,
2659          M_aud_Device_format_doc, NULL },
2660         {(char*)"channels", (getter)Device_get_channels, NULL,
2661          M_aud_Device_channels_doc, NULL },
2662         {(char*)"volume", (getter)Device_get_volume, (setter)Device_set_volume,
2663          M_aud_Device_volume_doc, NULL },
2664         {(char*)"listener_location", (getter)Device_get_listener_location, (setter)Device_set_listener_location,
2665          M_aud_Device_listener_location_doc, NULL },
2666         {(char*)"listener_velocity", (getter)Device_get_listener_velocity, (setter)Device_set_listener_velocity,
2667          M_aud_Device_listener_velocity_doc, NULL },
2668         {(char*)"listener_orientation", (getter)Device_get_listener_orientation, (setter)Device_set_listener_orientation,
2669          M_aud_Device_listener_orientation_doc, NULL },
2670         {(char*)"speed_of_sound", (getter)Device_get_speed_of_sound, (setter)Device_set_speed_of_sound,
2671          M_aud_Device_speed_of_sound_doc, NULL },
2672         {(char*)"doppler_factor", (getter)Device_get_doppler_factor, (setter)Device_set_doppler_factor,
2673          M_aud_Device_doppler_factor_doc, NULL },
2674         {(char*)"distance_model", (getter)Device_get_distance_model, (setter)Device_set_distance_model,
2675          M_aud_Device_distance_model_doc, NULL },
2676         {NULL}  /* Sentinel */
2677 };
2678
2679 PyDoc_STRVAR(M_aud_Device_doc,
2680                          "Device objects represent an audio output backend like OpenAL or "
2681                          "SDL, but might also represent a file output or RAM buffer "
2682                          "output.");
2683
2684 static PyTypeObject DeviceType = {
2685         PyVarObject_HEAD_INIT(NULL, 0)
2686         "aud.Device",              /* tp_name */
2687         sizeof(Device),            /* tp_basicsize */
2688         0,                         /* tp_itemsize */
2689         (destructor)Device_dealloc,/* tp_dealloc */
2690         0,                         /* tp_print */
2691         0,                         /* tp_getattr */
2692         0,                         /* tp_setattr */
2693         0,                         /* tp_reserved */
2694         0,                         /* tp_repr */
2695         0,                         /* tp_as_number */
2696         0,                         /* tp_as_sequence */
2697         0,                         /* tp_as_mapping */
2698         0,                         /* tp_hash  */
2699         0,                         /* tp_call */
2700         0,                         /* tp_str */
2701         0,                         /* tp_getattro */
2702         0,                         /* tp_setattro */
2703         0,                         /* tp_as_buffer */
2704         Py_TPFLAGS_DEFAULT,        /* tp_flags */
2705         M_aud_Device_doc,          /* tp_doc */
2706         0,                                 /* tp_traverse */
2707         0,                                 /* tp_clear */
2708         0,                                 /* tp_richcompare */
2709         0,                                 /* tp_weaklistoffset */
2710         0,                                 /* tp_iter */
2711         0,                                 /* tp_iternext */
2712         Device_methods,            /* tp_methods */
2713         0,                         /* tp_members */
2714         Device_properties,         /* tp_getset */
2715         0,                         /* tp_base */
2716         0,                         /* tp_dict */
2717         0,                         /* tp_descr_get */
2718         0,                         /* tp_descr_set */
2719         0,                         /* tp_dictoffset */
2720         0,                         /* tp_init */
2721         0,                         /* tp_alloc */
2722         0,                         /* tp_new */
2723 };
2724
2725 static PyObject *
2726 Device_OpenAL(PyTypeObject *type, PyObject *args, PyObject *kwds)
2727 {
2728 #ifdef WITH_OPENAL
2729         int buffersize = AUD_DEFAULT_BUFFER_SIZE;
2730         int frequency = AUD_RATE_44100;
2731
2732         static const char *kwlist[] = {"frequency", "buffer_size", NULL};
2733
2734         if(!PyArg_ParseTupleAndKeywords(args, kwds, "|ii", const_cast<char**>(kwlist), &frequency, &buffersize))
2735                 return NULL;
2736
2737         if(buffersize < 128)
2738         {
2739                 PyErr_SetString(PyExc_ValueError, "buffer_size must be greater than 127!");
2740                 return NULL;
2741         }
2742
2743         Device *self;
2744
2745         self = (Device*)DeviceType.tp_alloc(&DeviceType, 0);
2746         if(self != NULL)
2747         {
2748                 try
2749                 {
2750                         AUD_DeviceSpecs specs;
2751                         specs.rate = static_cast<AUD_SampleRate>(frequency);
2752                         specs.channels = AUD_CHANNELS_STEREO;
2753                         specs.format = AUD_FORMAT_S16;
2754                         self->device = new AUD_OpenALDevice(specs, buffersize);
2755                 }
2756                 catch(AUD_Exception&)
2757                 {
2758                         Py_DECREF(self);
2759                         PyErr_SetString(AUDError, "OpenAL device couldn't be created!");
2760                         return NULL;
2761                 }
2762         }
2763
2764         return (PyObject *)self;
2765 #else
2766         PyErr_SetString(AUDError, "OpenAL device couldn't be created!");
2767         return NULL;
2768 #endif
2769 }
2770
2771 static PyObject *
2772 Device_SDL(PyTypeObject *type, PyObject *args, PyObject *kwds)
2773 {
2774 #ifdef WITH_SDL
2775         int buffersize = AUD_DEFAULT_BUFFER_SIZE;
2776         int frequency = AUD_RATE_44100;
2777
2778         static const char *kwlist[] = {"frequency", "buffer_size", NULL};
2779
2780         if(!PyArg_ParseTupleAndKeywords(args, kwds, "|ii", const_cast<char**>(kwlist), &frequency, &buffersize))
2781                 return NULL;
2782
2783         if(buffersize < 128)
2784         {
2785                 PyErr_SetString(PyExc_ValueError, "buffer_size must be greater than 127!");
2786                 return NULL;
2787         }
2788
2789         Device *self;
2790
2791         self = (Device*)DeviceType.tp_alloc(&DeviceType, 0);
2792         if(self != NULL)
2793         {
2794                 try
2795                 {
2796                         AUD_DeviceSpecs specs;
2797                         specs.rate = static_cast<AUD_SampleRate>(frequency);
2798                         specs.channels = AUD_CHANNELS_STEREO;
2799                         specs.format = AUD_FORMAT_S16;
2800                         self->device = new AUD_SDLDevice(specs, buffersize);
2801                 }
2802                 catch(AUD_Exception&)
2803                 {
2804                         Py_DECREF(self);
2805                         PyErr_SetString(AUDError, "SDL device couldn't be created!");
2806                         return NULL;
2807                 }
2808         }
2809
2810         return (PyObject *)self;
2811 #else
2812         PyErr_SetString(AUDError, "SDL device couldn't be created!");
2813         return NULL;
2814 #endif
2815 }
2816
2817 static PyObject *
2818 Device_Jack(PyTypeObject *type, PyObject *args, PyObject *kwds)
2819 {
2820 #ifdef WITH_JACK
2821         int buffersize = AUD_DEFAULT_BUFFER_SIZE;
2822         int channels = AUD_CHANNELS_STEREO;
2823
2824         static const char *kwlist[] = {"channels", "buffer_size", NULL};
2825
2826         if(!PyArg_ParseTupleAndKeywords(args, kwds, "|ii", const_cast<char**>(kwlist), &channels, &buffersize))
2827                 return NULL;
2828
2829         if(buffersize < 128)
2830         {
2831                 PyErr_SetString(PyExc_ValueError, "buffer_size must be greater than 127!");
2832                 return NULL;
2833         }
2834
2835         Device *self;
2836
2837         self = (Device*)DeviceType.tp_alloc(&DeviceType, 0);
2838         if(self != NULL)
2839         {
2840                 try
2841                 {
2842                         AUD_DeviceSpecs specs;
2843                         specs.rate = AUD_RATE_44100;
2844                         specs.channels = static_cast<AUD_Channels>(channels);
2845                         specs.format = AUD_FORMAT_FLOAT32;
2846                         self->device = new AUD_JackDevice(specs, buffersize);
2847                 }
2848                 catch(AUD_Exception&)
2849                 {
2850                         Py_DECREF(self);
2851                         PyErr_SetString(AUDError, "Jack device couldn't be created!");
2852                         return NULL;
2853                 }
2854         }
2855
2856         return (PyObject *)self;
2857 #else
2858         PyErr_SetString(AUDError, "Jack device couldn't be created!");
2859         return NULL;
2860 #endif
2861 }
2862
2863 static PyObject *
2864 Device_Null(PyTypeObject *type)
2865 {
2866         Device *self;
2867
2868         self = (Device*)DeviceType.tp_alloc(&DeviceType, 0);
2869         if(self != NULL)
2870         {
2871                 try
2872                 {
2873                         self->device = new AUD_NULLDevice();
2874                 }
2875                 catch(AUD_Exception&)
2876                 {
2877                         Py_DECREF(self);
2878                         PyErr_SetString(AUDError, "Null device couldn't be created!");
2879                         return NULL;
2880                 }
2881         }
2882
2883         return (PyObject *)self;
2884 }
2885
2886 PyObject *
2887 Device_empty()
2888 {
2889         return DeviceType.tp_alloc(&DeviceType, 0);
2890 }
2891
2892 // ====================================================================
2893
2894 PyDoc_STRVAR(M_aud_doc,
2895                          "This module provides access to the audaspace audio library.");
2896
2897 static struct PyModuleDef audmodule = {
2898         PyModuleDef_HEAD_INIT,
2899         "aud",     /* name of module */
2900         M_aud_doc, /* module documentation */
2901         -1,        /* size of per-interpreter state of the module,
2902                                   or -1 if the module keeps state in global variables. */
2903    NULL, NULL, NULL, NULL, NULL
2904 };
2905
2906 PyMODINIT_FUNC
2907 PyInit_aud(void)
2908 {
2909         PyObject* m;
2910
2911         if(PyType_Ready(&SoundType) < 0)
2912                 return NULL;
2913
2914         if(PyType_Ready(&DeviceType) < 0)
2915                 return NULL;
2916
2917         if(PyType_Ready(&HandleType) < 0)
2918                 return NULL;
2919
2920         m = PyModule_Create(&audmodule);
2921         if(m == NULL)
2922                 return NULL;
2923
2924         Py_INCREF(&SoundType);
2925         PyModule_AddObject(m, "Sound", (PyObject*)&SoundType);
2926
2927         Py_INCREF(&DeviceType);
2928         PyModule_AddObject(m, "Device", (PyObject*)&DeviceType);
2929
2930         Py_INCREF(&HandleType);
2931         PyModule_AddObject(m, "Handle", (PyObject*)&HandleType);
2932
2933         AUDError = PyErr_NewException("aud.error", NULL, NULL);
2934         Py_INCREF(AUDError);
2935         PyModule_AddObject(m, "error", AUDError);
2936
2937         // format constants
2938         PY_MODULE_ADD_CONSTANT(m, AUD_FORMAT_FLOAT32);
2939         PY_MODULE_ADD_CONSTANT(m, AUD_FORMAT_FLOAT64);
2940         PY_MODULE_ADD_CONSTANT(m, AUD_FORMAT_INVALID);
2941         PY_MODULE_ADD_CONSTANT(m, AUD_FORMAT_S16);
2942         PY_MODULE_ADD_CONSTANT(m, AUD_FORMAT_S24);
2943         PY_MODULE_ADD_CONSTANT(m, AUD_FORMAT_S32);
2944         PY_MODULE_ADD_CONSTANT(m, AUD_FORMAT_U8);
2945         // status constants
2946         PY_MODULE_ADD_CONSTANT(m, AUD_STATUS_INVALID);
2947         PY_MODULE_ADD_CONSTANT(m, AUD_STATUS_PAUSED);
2948         PY_MODULE_ADD_CONSTANT(m, AUD_STATUS_PLAYING);
2949         // distance model constants
2950         PY_MODULE_ADD_CONSTANT(m, AUD_DISTANCE_MODEL_EXPONENT);
2951         PY_MODULE_ADD_CONSTANT(m, AUD_DISTANCE_MODEL_EXPONENT_CLAMPED);
2952         PY_MODULE_ADD_CONSTANT(m, AUD_DISTANCE_MODEL_INVERSE);
2953         PY_MODULE_ADD_CONSTANT(m, AUD_DISTANCE_MODEL_INVERSE_CLAMPED);
2954         PY_MODULE_ADD_CONSTANT(m, AUD_DISTANCE_MODEL_LINEAR);
2955         PY_MODULE_ADD_CONSTANT(m, AUD_DISTANCE_MODEL_LINEAR_CLAMPED);
2956         PY_MODULE_ADD_CONSTANT(m, AUD_DISTANCE_MODEL_INVALID);
2957
2958         return m;
2959 }