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