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