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