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