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