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