Blender  V2.59
AUD_PyAPI.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: AUD_PyAPI.cpp 36174 2011-04-15 01:32:37Z campbellbarton $
00003  *
00004  * ***** BEGIN GPL LICENSE BLOCK *****
00005  *
00006  * Copyright 2009-2011 Jörg Hermann Müller
00007  *
00008  * This file is part of AudaSpace.
00009  *
00010  * Audaspace is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version.
00014  *
00015  * AudaSpace is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License
00021  * along with Audaspace; if not, write to the Free Software Foundation,
00022  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00023  *
00024  * ***** END GPL LICENSE BLOCK *****
00025  */
00026 
00032 #include "AUD_PyAPI.h"
00033 #include "structmember.h"
00034 
00035 #include "AUD_I3DDevice.h"
00036 #include "AUD_NULLDevice.h"
00037 #include "AUD_DelayFactory.h"
00038 #include "AUD_DoubleFactory.h"
00039 #include "AUD_FaderFactory.h"
00040 #include "AUD_HighpassFactory.h"
00041 #include "AUD_LimiterFactory.h"
00042 #include "AUD_LoopFactory.h"
00043 #include "AUD_LowpassFactory.h"
00044 #include "AUD_PingPongFactory.h"
00045 #include "AUD_PitchFactory.h"
00046 #include "AUD_ReverseFactory.h"
00047 #include "AUD_SinusFactory.h"
00048 #include "AUD_FileFactory.h"
00049 #include "AUD_SquareFactory.h"
00050 #include "AUD_StreamBufferFactory.h"
00051 #include "AUD_SuperposeFactory.h"
00052 #include "AUD_VolumeFactory.h"
00053 #include "AUD_IIRFilterFactory.h"
00054 
00055 #ifdef WITH_SDL
00056 #include "AUD_SDLDevice.h"
00057 #endif
00058 
00059 #ifdef WITH_OPENAL
00060 #include "AUD_OpenALDevice.h"
00061 #endif
00062 
00063 #ifdef WITH_JACK
00064 #include "AUD_JackDevice.h"
00065 #endif
00066 
00067 // ====================================================================
00068 
00069 typedef enum
00070 {
00071         AUD_DEVICE_NULL = 0,
00072         AUD_DEVICE_OPENAL,
00073         AUD_DEVICE_SDL,
00074         AUD_DEVICE_JACK,
00075         AUD_DEVICE_READ,
00076 } AUD_DeviceTypes;
00077 
00078 // ====================================================================
00079 
00080 #define PY_MODULE_ADD_CONSTANT(module, name) PyModule_AddIntConstant(module, #name, name)
00081 
00082 // ====================================================================
00083 
00084 static PyObject* AUDError;
00085 
00086 static const char* device_not_3d_error = "Device is not a 3D device!";
00087 
00088 // ====================================================================
00089 
00090 static void
00091 Factory_dealloc(Factory* self)
00092 {
00093         if(self->factory)
00094                 delete self->factory;
00095         Py_XDECREF(self->child_list);
00096         Py_TYPE(self)->tp_free((PyObject*)self);
00097 }
00098 
00099 static PyObject *
00100 Factory_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
00101 {
00102         Factory *self;
00103 
00104         self = (Factory*)type->tp_alloc(type, 0);
00105         if(self != NULL)
00106         {
00107                 static const char *kwlist[] = {"filename", NULL};
00108                 const char* filename = NULL;
00109 
00110                 if(!PyArg_ParseTupleAndKeywords(args, kwds, "s:Factory", const_cast<char**>(kwlist), &filename))
00111                 {
00112                         Py_DECREF(self);
00113                         return NULL;
00114                 }
00115 
00116                 try
00117                 {
00118                         self->factory = new AUD_FileFactory(filename);
00119                 }
00120                 catch(AUD_Exception& e)
00121                 {
00122                         Py_DECREF(self);
00123                         PyErr_SetString(AUDError, e.str);
00124                         return NULL;
00125                 }
00126         }
00127 
00128         return (PyObject *)self;
00129 }
00130 
00131 PyDoc_STRVAR(M_aud_Factory_sine_doc,
00132                          "sine(frequency, rate=44100)\n\n"
00133                          "Creates a sine factory which plays a sine wave.\n\n"
00134                          ":arg frequency: The frequency of the sine wave in Hz.\n"
00135                          ":type frequency: float\n"
00136                          ":arg rate: The sampling rate in Hz. It's recommended to set this "
00137                          "value to the playback device's samling rate to avoid resamping.\n"
00138                          ":type rate: int\n"
00139                          ":return: The created :class:`Factory` object.\n"
00140                          ":rtype: :class:`Factory`");
00141 
00142 static PyObject *
00143 Factory_sine(PyTypeObject* type, PyObject* args)
00144 {
00145         float frequency;
00146         int rate = 44100;
00147 
00148         if(!PyArg_ParseTuple(args, "f|i:sine", &frequency, &rate))
00149                 return NULL;
00150 
00151         Factory *self;
00152 
00153         self = (Factory*)type->tp_alloc(type, 0);
00154         if(self != NULL)
00155         {
00156                 try
00157                 {
00158                         self->factory = new AUD_SinusFactory(frequency, (AUD_SampleRate)rate);
00159                 }
00160                 catch(AUD_Exception& e)
00161                 {
00162                         Py_DECREF(self);
00163                         PyErr_SetString(AUDError, e.str);
00164                         return NULL;
00165                 }
00166         }
00167 
00168         return (PyObject *)self;
00169 }
00170 
00171 PyDoc_STRVAR(M_aud_Factory_file_doc,
00172                          "file(filename)\n\n"
00173                          "Creates a factory object of a sound file.\n\n"
00174                          ":arg filename: Path of the file.\n"
00175                          ":type filename: string\n"
00176                          ":return: The created :class:`Factory` object.\n"
00177                          ":rtype: :class:`Factory`\n\n"
00178                          ".. warning:: If the file doesn't exist or can't be read you will "
00179                          "not get an exception immediately, but when you try to start "
00180                          "playback of that factory.");
00181 
00182 static PyObject *
00183 Factory_file(PyTypeObject* type, PyObject* args)
00184 {
00185         const char* filename = NULL;
00186 
00187         if(!PyArg_ParseTuple(args, "s:file", &filename))
00188                 return NULL;
00189 
00190         Factory *self;
00191 
00192         self = (Factory*)type->tp_alloc(type, 0);
00193         if(self != NULL)
00194         {
00195                 try
00196                 {
00197                         self->factory = new AUD_FileFactory(filename);
00198                 }
00199                 catch(AUD_Exception& e)
00200                 {
00201                         Py_DECREF(self);
00202                         PyErr_SetString(AUDError, e.str);
00203                         return NULL;
00204                 }
00205         }
00206 
00207         return (PyObject *)self;
00208 }
00209 
00210 PyDoc_STRVAR(M_aud_Factory_lowpass_doc,
00211                          "lowpass(frequency, Q=0.5)\n\n"
00212                          "Creates a second order lowpass filter based on the transfer "
00213                          "function H(s) = 1 / (s^2 + s/Q + 1)\n\n"
00214                          ":arg frequency: The cut off trequency of the lowpass.\n"
00215                          ":type frequency: float\n"
00216                          ":arg Q: Q factor of the lowpass.\n"
00217                          ":type Q: float\n"
00218                          ":return: The created :class:`Factory` object.\n"
00219                          ":rtype: :class:`Factory`");
00220 
00221 static PyObject *
00222 Factory_lowpass(Factory* self, PyObject* args)
00223 {
00224         float frequency;
00225         float Q = 0.5;
00226 
00227         if(!PyArg_ParseTuple(args, "f|f:lowpass", &frequency, &Q))
00228                 return NULL;
00229 
00230         PyTypeObject* type = ((PyObject*)self)->ob_type;
00231         Factory *parent = (Factory*)type->tp_alloc(type, 0);
00232 
00233         if(parent != NULL)
00234         {
00235                 Py_INCREF(self);
00236                 parent->child_list = (PyObject*)self;
00237 
00238                 try
00239                 {
00240                         parent->factory = new AUD_LowpassFactory(self->factory, frequency, Q);
00241                 }
00242                 catch(AUD_Exception& e)
00243                 {
00244                         Py_DECREF(parent);
00245                         PyErr_SetString(AUDError, e.str);
00246                         return NULL;
00247                 }
00248         }
00249 
00250         return (PyObject *)parent;
00251 }
00252 
00253 PyDoc_STRVAR(M_aud_Factory_delay_doc,
00254                          "delay(time)\n\n"
00255                          "Delays by playing adding silence in front of the other factory's "
00256                          "data.\n\n"
00257                          ":arg time: How many seconds of silence should be added before "
00258                          "the factory.\n"
00259                          ":type time: float\n"
00260                          ":return: The created :class:`Factory` object.\n"
00261                          ":rtype: :class:`Factory`");
00262 
00263 static PyObject *
00264 Factory_delay(Factory* self, PyObject* args)
00265 {
00266         float delay;
00267 
00268         if(!PyArg_ParseTuple(args, "f:delay", &delay))
00269                 return NULL;
00270 
00271         PyTypeObject* type = ((PyObject*)self)->ob_type;
00272         Factory *parent = (Factory*)type->tp_alloc(type, 0);
00273 
00274         if(parent != NULL)
00275         {
00276                 Py_INCREF(self);
00277                 parent->child_list = (PyObject*)self;
00278 
00279                 try
00280                 {
00281                         parent->factory = new AUD_DelayFactory(self->factory, delay);
00282                 }
00283                 catch(AUD_Exception& e)
00284                 {
00285                         Py_DECREF(parent);
00286                         PyErr_SetString(AUDError, e.str);
00287                         return NULL;
00288                 }
00289         }
00290 
00291         return (PyObject *)parent;
00292 }
00293 
00294 PyDoc_STRVAR(M_aud_Factory_join_doc,
00295                          "join(factory)\n\n"
00296                          "Plays two factories in sequence.\n\n"
00297                          ":arg factory: The factory to play second.\n"
00298                          ":type factory: :class:`Factory`\n"
00299                          ":return: The created :class:`Factory` object.\n"
00300                          ":rtype: :class:`Factory`\n\n"
00301                          ".. note:: The two factories have to have the same specifications "
00302                          "(channels and samplerate).");
00303 
00304 static PyObject *
00305 Factory_join(Factory* self, PyObject* object)
00306 {
00307         PyTypeObject* type = ((PyObject*)self)->ob_type;
00308 
00309         if(!PyObject_TypeCheck(object, type))
00310         {
00311                 PyErr_SetString(PyExc_TypeError, "Object has to be of type Factory!");
00312                 return NULL;
00313         }
00314 
00315         Factory *parent;
00316         Factory *child = (Factory*)object;
00317 
00318         parent = (Factory*)type->tp_alloc(type, 0);
00319         if(parent != NULL)
00320         {
00321                 parent->child_list = Py_BuildValue("(OO)", self, object);
00322 
00323                 try
00324                 {
00325                         parent->factory = new AUD_DoubleFactory(self->factory, child->factory);
00326                 }
00327                 catch(AUD_Exception& e)
00328                 {
00329                         Py_DECREF(parent);
00330                         PyErr_SetString(AUDError, e.str);
00331                         return NULL;
00332                 }
00333         }
00334 
00335         return (PyObject *)parent;
00336 }
00337 
00338 PyDoc_STRVAR(M_aud_Factory_highpass_doc,
00339                          "highpass(frequency, Q=0.5)\n\n"
00340                          "Creates a second order highpass filter based on the transfer "
00341                          "function H(s) = s^2 / (s^2 + s/Q + 1)\n\n"
00342                          ":arg frequency: The cut off trequency of the highpass.\n"
00343                          ":type frequency: float\n"
00344                          ":arg Q: Q factor of the lowpass.\n"
00345                          ":type Q: float\n"
00346                          ":return: The created :class:`Factory` object.\n"
00347                          ":rtype: :class:`Factory`");
00348 
00349 static PyObject *
00350 Factory_highpass(Factory* self, PyObject* args)
00351 {
00352         float frequency;
00353         float Q = 0.5;
00354 
00355         if(!PyArg_ParseTuple(args, "f|f:highpass", &frequency, &Q))
00356                 return NULL;
00357 
00358         PyTypeObject* type = ((PyObject*)self)->ob_type;
00359         Factory *parent = (Factory*)type->tp_alloc(type, 0);
00360 
00361         if(parent != NULL)
00362         {
00363                 Py_INCREF(self);
00364                 parent->child_list = (PyObject*)self;
00365 
00366                 try
00367                 {
00368                         parent->factory = new AUD_HighpassFactory(self->factory, frequency, Q);
00369                 }
00370                 catch(AUD_Exception& e)
00371                 {
00372                         Py_DECREF(parent);
00373                         PyErr_SetString(AUDError, e.str);
00374                         return NULL;
00375                 }
00376         }
00377 
00378         return (PyObject *)parent;
00379 }
00380 
00381 PyDoc_STRVAR(M_aud_Factory_limit_doc,
00382                          "limit(start, end)\n\n"
00383                          "Limits a factory within a specific start and end time.\n\n"
00384                          ":arg start: Start time in seconds.\n"
00385                          ":type start: float\n"
00386                          ":arg end: End time in seconds.\n"
00387                          ":type end: float\n"
00388                          ":return: The created :class:`Factory` object.\n"
00389                          ":rtype: :class:`Factory`");
00390 
00391 static PyObject *
00392 Factory_limit(Factory* self, PyObject* args)
00393 {
00394         float start, end;
00395 
00396         if(!PyArg_ParseTuple(args, "ff:limit", &start, &end))
00397                 return NULL;
00398 
00399         PyTypeObject* type = ((PyObject*)self)->ob_type;
00400         Factory *parent = (Factory*)type->tp_alloc(type, 0);
00401 
00402         if(parent != NULL)
00403         {
00404                 Py_INCREF(self);
00405                 parent->child_list = (PyObject*)self;
00406 
00407                 try
00408                 {
00409                         parent->factory = new AUD_LimiterFactory(self->factory, start, end);
00410                 }
00411                 catch(AUD_Exception& e)
00412                 {
00413                         Py_DECREF(parent);
00414                         PyErr_SetString(AUDError, e.str);
00415                         return NULL;
00416                 }
00417         }
00418 
00419         return (PyObject *)parent;
00420 }
00421 
00422 PyDoc_STRVAR(M_aud_Factory_pitch_doc,
00423                          "pitch(factor)\n\n"
00424                          "Changes the pitch of a factory with a specific factor.\n\n"
00425                          ":arg factor: The factor to change the pitch with.\n"
00426                          ":type factor: float\n"
00427                          ":return: The created :class:`Factory` object.\n"
00428                          ":rtype: :class:`Factory`\n\n"
00429                          ".. note:: This is done by changing the sample rate of the "
00430                          "underlying factory, which has to be an integer, so the factor "
00431                          "value rounded and the factor may not be 100 % accurate.\n\n"
00432                          ".. note:: This is a filter function, you might consider using "
00433                          ":attr:`Handle.pitch` instead.");
00434 
00435 static PyObject *
00436 Factory_pitch(Factory* self, PyObject* args)
00437 {
00438         float factor;
00439 
00440         if(!PyArg_ParseTuple(args, "f:pitch", &factor))
00441                 return NULL;
00442 
00443         PyTypeObject* type = ((PyObject*)self)->ob_type;
00444         Factory *parent = (Factory*)type->tp_alloc(type, 0);
00445 
00446         if(parent != NULL)
00447         {
00448                 Py_INCREF(self);
00449                 parent->child_list = (PyObject*)self;
00450 
00451                 try
00452                 {
00453                         parent->factory = new AUD_PitchFactory(self->factory, factor);
00454                 }
00455                 catch(AUD_Exception& e)
00456                 {
00457                         Py_DECREF(parent);
00458                         PyErr_SetString(AUDError, e.str);
00459                         return NULL;
00460                 }
00461         }
00462 
00463         return (PyObject *)parent;
00464 }
00465 
00466 PyDoc_STRVAR(M_aud_Factory_volume_doc,
00467                          "volume(volume)\n\n"
00468                          "Changes the volume of a factory.\n\n"
00469                          ":arg volume: The new volume..\n"
00470                          ":type volume: float\n"
00471                          ":return: The created :class:`Factory` object.\n"
00472                          ":rtype: :class:`Factory`\n\n"
00473                          ".. note:: Should be in the range [0, 1] to avoid clipping.\n\n"
00474                          ".. note:: This is a filter function, you might consider using "
00475                          ":attr:`Handle.volume` instead.");
00476 
00477 static PyObject *
00478 Factory_volume(Factory* self, PyObject* args)
00479 {
00480         float volume;
00481 
00482         if(!PyArg_ParseTuple(args, "f:volume", &volume))
00483                 return NULL;
00484 
00485         PyTypeObject* type = ((PyObject*)self)->ob_type;
00486         Factory *parent = (Factory*)type->tp_alloc(type, 0);
00487 
00488         if(parent != NULL)
00489         {
00490                 Py_INCREF(self);
00491                 parent->child_list = (PyObject*)self;
00492 
00493                 try
00494                 {
00495                         parent->factory = new AUD_VolumeFactory(self->factory, volume);
00496                 }
00497                 catch(AUD_Exception& e)
00498                 {
00499                         Py_DECREF(parent);
00500                         PyErr_SetString(AUDError, e.str);
00501                         return NULL;
00502                 }
00503         }
00504 
00505         return (PyObject *)parent;
00506 }
00507 
00508 PyDoc_STRVAR(M_aud_Factory_fadein_doc,
00509                          "fadein(start, length)\n\n"
00510                          "Fades a factory in by raising the volume linearly in the given "
00511                          "time interval.\n\n"
00512                          ":arg start: Time in seconds when the fading should start.\n"
00513                          ":type start: float\n"
00514                          ":arg length: Time in seconds how long the fading should last.\n"
00515                          ":type length: float\n"
00516                          ":return: The created :class:`Factory` object.\n"
00517                          ":rtype: :class:`Factory`\n\n"
00518                          ".. note:: Before the fade starts it plays silence.");
00519 
00520 static PyObject *
00521 Factory_fadein(Factory* self, PyObject* args)
00522 {
00523         float start, length;
00524 
00525         if(!PyArg_ParseTuple(args, "ff:fadein", &start, &length))
00526                 return NULL;
00527 
00528         PyTypeObject* type = ((PyObject*)self)->ob_type;
00529         Factory *parent = (Factory*)type->tp_alloc(type, 0);
00530 
00531         if(parent != NULL)
00532         {
00533                 Py_INCREF(self);
00534                 parent->child_list = (PyObject*)self;
00535 
00536                 try
00537                 {
00538                         parent->factory = new AUD_FaderFactory(self->factory, AUD_FADE_IN, start, length);
00539                 }
00540                 catch(AUD_Exception& e)
00541                 {
00542                         Py_DECREF(parent);
00543                         PyErr_SetString(AUDError, e.str);
00544                         return NULL;
00545                 }
00546         }
00547 
00548         return (PyObject *)parent;
00549 }
00550 
00551 PyDoc_STRVAR(M_aud_Factory_fadeout_doc,
00552                          "fadeout(start, length)\n\n"
00553                          "Fades a factory in by lowering the volume linearly in the given "
00554                          "time interval.\n\n"
00555                          ":arg start: Time in seconds when the fading should start.\n"
00556                          ":type start: float\n"
00557                          ":arg length: Time in seconds how long the fading should last.\n"
00558                          ":type length: float\n"
00559                          ":return: The created :class:`Factory` object.\n"
00560                          ":rtype: :class:`Factory`\n\n"
00561                          ".. note:: After the fade this factory plays silence, so that "
00562                          "the length of the factory is not altered.");
00563 
00564 static PyObject *
00565 Factory_fadeout(Factory* self, PyObject* args)
00566 {
00567         float start, length;
00568 
00569         if(!PyArg_ParseTuple(args, "ff:fadeout", &start, &length))
00570                 return NULL;
00571 
00572         PyTypeObject* type = ((PyObject*)self)->ob_type;
00573         Factory *parent = (Factory*)type->tp_alloc(type, 0);
00574 
00575         if(parent != NULL)
00576         {
00577                 Py_INCREF(self);
00578                 parent->child_list = (PyObject*)self;
00579 
00580                 try
00581                 {
00582                         parent->factory = new AUD_FaderFactory(self->factory, AUD_FADE_OUT, start, length);
00583                 }
00584                 catch(AUD_Exception& e)
00585                 {
00586                         Py_DECREF(parent);
00587                         PyErr_SetString(AUDError, e.str);
00588                         return NULL;
00589                 }
00590         }
00591 
00592         return (PyObject *)parent;
00593 }
00594 
00595 PyDoc_STRVAR(M_aud_Factory_loop_doc,
00596                          "loop(count)\n\n"
00597                          "Loops a factory.\n\n"
00598                          ":arg count: How often the factory should be looped. "
00599                          "Negative values mean endlessly.\n"
00600                          ":type count: integer\n"
00601                          ":return: The created :class:`Factory` object.\n"
00602                          ":rtype: :class:`Factory`\n\n"
00603                          ".. note:: This is a filter function, you might consider using "
00604                          ":attr:`Handle.loop_count` instead.");
00605 
00606 static PyObject *
00607 Factory_loop(Factory* self, PyObject* args)
00608 {
00609         int loop;
00610 
00611         if(!PyArg_ParseTuple(args, "i:loop", &loop))
00612                 return NULL;
00613 
00614         PyTypeObject* type = ((PyObject*)self)->ob_type;
00615         Factory *parent = (Factory*)type->tp_alloc(type, 0);
00616 
00617         if(parent != NULL)
00618         {
00619                 Py_INCREF(self);
00620                 parent->child_list = (PyObject*)self;
00621 
00622                 try
00623                 {
00624                         parent->factory = new AUD_LoopFactory(self->factory, loop);
00625                 }
00626                 catch(AUD_Exception& e)
00627                 {
00628                         Py_DECREF(parent);
00629                         PyErr_SetString(AUDError, e.str);
00630                         return NULL;
00631                 }
00632         }
00633 
00634         return (PyObject *)parent;
00635 }
00636 
00637 PyDoc_STRVAR(M_aud_Factory_mix_doc,
00638                          "mix(factory)\n\n"
00639                          "Mixes two factories.\n\n"
00640                          ":arg factory: The factory to mix over the other.\n"
00641                          ":type factory: :class:`Factory`\n"
00642                          ":return: The created :class:`Factory` object.\n"
00643                          ":rtype: :class:`Factory`\n\n"
00644                          ".. note:: The two factories have to have the same specifications "
00645                          "(channels and samplerate).");
00646 
00647 static PyObject *
00648 Factory_mix(Factory* self, PyObject* object)
00649 {
00650         PyTypeObject* type = ((PyObject*)self)->ob_type;
00651 
00652         if(!PyObject_TypeCheck(object, type))
00653         {
00654                 PyErr_SetString(PyExc_TypeError, "Object is not of type Factory!");
00655                 return NULL;
00656         }
00657 
00658         Factory *parent = (Factory*)type->tp_alloc(type, 0);
00659         Factory *child = (Factory*)object;
00660 
00661         if(parent != NULL)
00662         {
00663                 parent->child_list = Py_BuildValue("(OO)", self, object);
00664 
00665                 try
00666                 {
00667                         parent->factory = new AUD_SuperposeFactory(self->factory, child->factory);
00668                 }
00669                 catch(AUD_Exception& e)
00670                 {
00671                         Py_DECREF(parent);
00672                         PyErr_SetString(AUDError, e.str);
00673                         return NULL;
00674                 }
00675         }
00676 
00677         return (PyObject *)parent;
00678 }
00679 
00680 PyDoc_STRVAR(M_aud_Factory_pingpong_doc,
00681                          "pingpong()\n\n"
00682                          "Plays a factory forward and then backward.\n"
00683                          "This is like joining a factory with its reverse.\n\n"
00684                          ":return: The created :class:`Factory` object.\n"
00685                          ":rtype: :class:`Factory`");
00686 
00687 static PyObject *
00688 Factory_pingpong(Factory* self)
00689 {
00690         PyTypeObject* type = ((PyObject*)self)->ob_type;
00691         Factory *parent = (Factory*)type->tp_alloc(type, 0);
00692 
00693         if(parent != NULL)
00694         {
00695                 Py_INCREF(self);
00696                 parent->child_list = (PyObject*)self;
00697 
00698                 try
00699                 {
00700                         parent->factory = new AUD_PingPongFactory(self->factory);
00701                 }
00702                 catch(AUD_Exception& e)
00703                 {
00704                         Py_DECREF(parent);
00705                         PyErr_SetString(AUDError, e.str);
00706                         return NULL;
00707                 }
00708         }
00709 
00710         return (PyObject *)parent;
00711 }
00712 
00713 PyDoc_STRVAR(M_aud_Factory_reverse_doc,
00714                          "reverse()\n\n"
00715                          "Plays a factory reversed.\n\n"
00716                          ":return: The created :class:`Factory` object.\n"
00717                          ":rtype: :class:`Factory`\n\n"
00718                          ".. note:: The factory has to have a finite length and has to be "
00719                          "seekable. It's recommended to use this only with factories     with "
00720                          "fast and accurate seeking, which is not true for encoded audio "
00721                          "files, such ones should be buffered using :meth:`buffer` before "
00722                          "being played reversed.\n\n"
00723                          ".. warning:: If seeking is not accurate in the underlying factory "
00724                          "you'll likely hear skips/jumps/cracks.");
00725 
00726 static PyObject *
00727 Factory_reverse(Factory* self)
00728 {
00729         PyTypeObject* type = ((PyObject*)self)->ob_type;
00730         Factory *parent = (Factory*)type->tp_alloc(type, 0);
00731 
00732         if(parent != NULL)
00733         {
00734                 Py_INCREF(self);
00735                 parent->child_list = (PyObject*)self;
00736 
00737                 try
00738                 {
00739                         parent->factory = new AUD_ReverseFactory(self->factory);
00740                 }
00741                 catch(AUD_Exception& e)
00742                 {
00743                         Py_DECREF(parent);
00744                         PyErr_SetString(AUDError, e.str);
00745                         return NULL;
00746                 }
00747         }
00748 
00749         return (PyObject *)parent;
00750 }
00751 
00752 PyDoc_STRVAR(M_aud_Factory_buffer_doc,
00753                          "buffer()\n\n"
00754                          "Buffers a factory into RAM.\n"
00755                          "This saves CPU usage needed for decoding and file access if the "
00756                          "underlying factory reads from a file on the harddisk, but it "
00757                          "consumes a lot of memory.\n\n"
00758                          ":return: The created :class:`Factory` object.\n"
00759                          ":rtype: :class:`Factory`\n\n"
00760                          ".. note:: Only known-length factories can be buffered.\n\n"
00761                          ".. warning:: Raw PCM data needs a lot of space, only buffer "
00762                          "short factories.");
00763 
00764 static PyObject *
00765 Factory_buffer(Factory* self)
00766 {
00767         PyTypeObject* type = ((PyObject*)self)->ob_type;
00768         Factory *parent = (Factory*)type->tp_alloc(type, 0);
00769 
00770         if(parent != NULL)
00771         {
00772                 try
00773                 {
00774                         parent->factory = new AUD_StreamBufferFactory(self->factory);
00775                 }
00776                 catch(AUD_Exception& e)
00777                 {
00778                         Py_DECREF(parent);
00779                         PyErr_SetString(AUDError, e.str);
00780                         return NULL;
00781                 }
00782         }
00783 
00784         return (PyObject *)parent;
00785 }
00786 
00787 PyDoc_STRVAR(M_aud_Factory_square_doc,
00788                          "square(threshold = 0)\n\n"
00789                          "Makes a square wave out of an audio wave by setting all samples "
00790                          "with a amplitude >= threshold to 1, all <= -threshold to -1 and "
00791                          "all between to 0.\n\n"
00792                          ":arg threshold: Threshold value over which an amplitude counts "
00793                          "non-zero.\n"
00794                          ":type threshold: float\n"
00795                          ":return: The created :class:`Factory` object.\n"
00796                          ":rtype: :class:`Factory`");
00797 
00798 static PyObject *
00799 Factory_square(Factory* self, PyObject* args)
00800 {
00801         float threshold = 0;
00802 
00803         if(!PyArg_ParseTuple(args, "|f:square", &threshold))
00804                 return NULL;
00805 
00806         PyTypeObject* type = ((PyObject*)self)->ob_type;
00807         Factory *parent = (Factory*)type->tp_alloc(type, 0);
00808 
00809         if(parent != NULL)
00810         {
00811                 Py_INCREF(self);
00812                 parent->child_list = (PyObject*)self;
00813 
00814                 try
00815                 {
00816                         parent->factory = new AUD_SquareFactory(self->factory, threshold);
00817                 }
00818                 catch(AUD_Exception& e)
00819                 {
00820                         Py_DECREF(parent);
00821                         PyErr_SetString(AUDError, e.str);
00822                         return NULL;
00823                 }
00824         }
00825 
00826         return (PyObject *)parent;
00827 }
00828 
00829 PyDoc_STRVAR(M_aud_Factory_filter_doc,
00830                          "filter(b, a = (1))\n\n"
00831                          "Filters a factory with the supplied IIR filter coefficients.\n"
00832                          "Without the second parameter you'll get a FIR filter.\n"
00833                          "If the first value of the a sequence is 0 it will be set to 1 "
00834                          "automatically.\n"
00835                          "If the first value of the a sequence is neither 0 nor 1, all "
00836                          "filter coefficients will be scaled by this value so that it is 1 "
00837                          "in the end, you don't have to scale yourself.\n\n"
00838                          ":arg b: The nominator filter coefficients.\n"
00839                          ":type b: sequence of float\n"
00840                          ":arg a: The denominator filter coefficients.\n"
00841                          ":type a: sequence of float\n"
00842                          ":return: The created :class:`Factory` object.\n"
00843                          ":rtype: :class:`Factory`");
00844 
00845 static PyObject *
00846 Factory_filter(Factory* self, PyObject* args)
00847 {
00848         PyObject* py_b;
00849         PyObject* py_a = NULL;
00850 
00851         if(!PyArg_ParseTuple(args, "O|O:filter", &py_b, &py_a))
00852                 return NULL;
00853 
00854         if(!PySequence_Check(py_b) || (py_a != NULL && !PySequence_Check(py_a)))
00855         {
00856                 PyErr_SetString(PyExc_TypeError, "Parameter is not a sequence!");
00857                 return NULL;
00858         }
00859 
00860         if(!PySequence_Size(py_b) || (py_a != NULL && !PySequence_Size(py_a)))
00861         {
00862                 PyErr_SetString(PyExc_ValueError, "The sequence has to contain at least one value!");
00863                 return NULL;
00864         }
00865 
00866         std::vector<float> a, b;
00867         PyObject* py_value;
00868         float value;
00869         int result;
00870 
00871         for(int i = 0; i < PySequence_Size(py_b); i++)
00872         {
00873                 py_value = PySequence_GetItem(py_b, i);
00874                 result = PyArg_Parse(py_value, "f:filter", &value);
00875                 Py_DECREF(py_value);
00876 
00877                 if(!result)
00878                         return NULL;
00879 
00880                 b.push_back(value);
00881         }
00882 
00883         if(py_a)
00884         {
00885                 for(int i = 0; i < PySequence_Size(py_a); i++)
00886                 {
00887                         py_value = PySequence_GetItem(py_a, i);
00888                         result = PyArg_Parse(py_value, "f:filter", &value);
00889                         Py_DECREF(py_value);
00890 
00891                         if(!result)
00892                                 return NULL;
00893 
00894                         a.push_back(value);
00895                 }
00896 
00897                 if(a[0] == 0)
00898                         a[0] = 1;
00899         }
00900         else
00901                 a.push_back(1);
00902 
00903         PyTypeObject* type = ((PyObject*)self)->ob_type;
00904         Factory *parent = (Factory*)type->tp_alloc(type, 0);
00905 
00906         if(parent != NULL)
00907         {
00908                 Py_INCREF(self);
00909                 parent->child_list = (PyObject*)self;
00910 
00911                 try
00912                 {
00913                         parent->factory = new AUD_IIRFilterFactory(self->factory, b, a);
00914                 }
00915                 catch(AUD_Exception& e)
00916                 {
00917                         Py_DECREF(parent);
00918                         PyErr_SetString(AUDError, e.str);
00919                         return NULL;
00920                 }
00921         }
00922 
00923         return (PyObject *)parent;
00924 }
00925 
00926 static PyMethodDef Factory_methods[] = {
00927         {"sine", (PyCFunction)Factory_sine, METH_VARARGS | METH_CLASS,
00928          M_aud_Factory_sine_doc
00929         },
00930         {"file", (PyCFunction)Factory_file, METH_VARARGS | METH_CLASS,
00931          M_aud_Factory_file_doc
00932         },
00933         {"lowpass", (PyCFunction)Factory_lowpass, METH_VARARGS,
00934          M_aud_Factory_lowpass_doc
00935         },
00936         {"delay", (PyCFunction)Factory_delay, METH_VARARGS,
00937          M_aud_Factory_delay_doc
00938         },
00939         {"join", (PyCFunction)Factory_join, METH_O,
00940          M_aud_Factory_join_doc
00941         },
00942         {"highpass", (PyCFunction)Factory_highpass, METH_VARARGS,
00943          M_aud_Factory_highpass_doc
00944         },
00945         {"limit", (PyCFunction)Factory_limit, METH_VARARGS,
00946          M_aud_Factory_limit_doc
00947         },
00948         {"pitch", (PyCFunction)Factory_pitch, METH_VARARGS,
00949          M_aud_Factory_pitch_doc
00950         },
00951         {"volume", (PyCFunction)Factory_volume, METH_VARARGS,
00952          M_aud_Factory_volume_doc
00953         },
00954         {"fadein", (PyCFunction)Factory_fadein, METH_VARARGS,
00955          M_aud_Factory_fadein_doc
00956         },
00957         {"fadeout", (PyCFunction)Factory_fadeout, METH_VARARGS,
00958          M_aud_Factory_fadeout_doc
00959         },
00960         {"loop", (PyCFunction)Factory_loop, METH_VARARGS,
00961          M_aud_Factory_loop_doc
00962         },
00963         {"mix", (PyCFunction)Factory_mix, METH_O,
00964          M_aud_Factory_mix_doc
00965         },
00966         {"pingpong", (PyCFunction)Factory_pingpong, METH_NOARGS,
00967          M_aud_Factory_pingpong_doc
00968         },
00969         {"reverse", (PyCFunction)Factory_reverse, METH_NOARGS,
00970          M_aud_Factory_reverse_doc
00971         },
00972         {"buffer", (PyCFunction)Factory_buffer, METH_NOARGS,
00973          M_aud_Factory_buffer_doc
00974         },
00975         {"square", (PyCFunction)Factory_square, METH_VARARGS,
00976          M_aud_Factory_square_doc
00977         },
00978         {"filter", (PyCFunction)Factory_filter, METH_VARARGS,
00979          M_aud_Factory_filter_doc
00980         },
00981         {NULL}  /* Sentinel */
00982 };
00983 
00984 PyDoc_STRVAR(M_aud_Factory_doc,
00985                          "Factory objects are immutable and represent a sound that can be "
00986                          "played simultaneously multiple times. They are called factories "
00987                          "because they create reader objects internally that are used for "
00988                          "playback.");
00989 
00990 static PyTypeObject FactoryType = {
00991         PyVarObject_HEAD_INIT(NULL, 0)
00992         "aud.Factory",               /* tp_name */
00993         sizeof(Factory),             /* tp_basicsize */
00994         0,                         /* tp_itemsize */
00995         (destructor)Factory_dealloc, /* tp_dealloc */
00996         0,                         /* tp_print */
00997         0,                         /* tp_getattr */
00998         0,                         /* tp_setattr */
00999         0,                         /* tp_reserved */
01000         0,                         /* tp_repr */
01001         0,                         /* tp_as_number */
01002         0,                         /* tp_as_sequence */
01003         0,                         /* tp_as_mapping */
01004         0,                         /* tp_hash  */
01005         0,                         /* tp_call */
01006         0,                         /* tp_str */
01007         0,                         /* tp_getattro */
01008         0,                         /* tp_setattro */
01009         0,                         /* tp_as_buffer */
01010         Py_TPFLAGS_DEFAULT,        /* tp_flags */
01011         M_aud_Factory_doc,           /* tp_doc */
01012         0,                                 /* tp_traverse */
01013         0,                                 /* tp_clear */
01014         0,                                 /* tp_richcompare */
01015         0,                                 /* tp_weaklistoffset */
01016         0,                                 /* tp_iter */
01017         0,                                 /* tp_iternext */
01018         Factory_methods,             /* tp_methods */
01019         0,                         /* tp_members */
01020         0,                         /* tp_getset */
01021         0,                         /* tp_base */
01022         0,                         /* tp_dict */
01023         0,                         /* tp_descr_get */
01024         0,                         /* tp_descr_set */
01025         0,                         /* tp_dictoffset */
01026         0,                         /* tp_init */
01027         0,                         /* tp_alloc */
01028         Factory_new,                 /* tp_new */
01029 };
01030 
01031 // ========== Handle ==================================================
01032 
01033 static void
01034 Handle_dealloc(Handle* self)
01035 {
01036         Py_XDECREF(self->device);
01037         Py_TYPE(self)->tp_free((PyObject*)self);
01038 }
01039 
01040 PyDoc_STRVAR(M_aud_Handle_pause_doc,
01041                          "pause()\n\n"
01042                          "Pauses playback.\n\n"
01043                          ":return: Whether the action succeeded.\n"
01044                          ":rtype: bool");
01045 
01046 static PyObject *
01047 Handle_pause(Handle *self)
01048 {
01049         Device* device = (Device*)self->device;
01050 
01051         try
01052         {
01053                 return PyBool_FromLong((long)device->device->pause(self->handle));
01054         }
01055         catch(AUD_Exception& e)
01056         {
01057                 PyErr_SetString(AUDError, e.str);
01058                 return NULL;
01059         }
01060 }
01061 
01062 PyDoc_STRVAR(M_aud_Handle_resume_doc,
01063                          "resume()\n\n"
01064                          "Resumes playback.\n\n"
01065                          ":return: Whether the action succeeded.\n"
01066                          ":rtype: bool");
01067 
01068 static PyObject *
01069 Handle_resume(Handle *self)
01070 {
01071         Device* device = (Device*)self->device;
01072 
01073         try
01074         {
01075                 return PyBool_FromLong((long)device->device->resume(self->handle));
01076         }
01077         catch(AUD_Exception& e)
01078         {
01079                 PyErr_SetString(AUDError, e.str);
01080                 return NULL;
01081         }
01082 }
01083 
01084 PyDoc_STRVAR(M_aud_Handle_stop_doc,
01085                          "stop()\n\n"
01086                          "Stops playback.\n\n"
01087                          ":return: Whether the action succeeded.\n"
01088                          ":rtype: bool\n\n"
01089                          ".. note:: This makes the handle invalid.");
01090 
01091 static PyObject *
01092 Handle_stop(Handle *self)
01093 {
01094         Device* device = (Device*)self->device;
01095 
01096         try
01097         {
01098                 return PyBool_FromLong((long)device->device->stop(self->handle));
01099         }
01100         catch(AUD_Exception& e)
01101         {
01102                 PyErr_SetString(AUDError, e.str);
01103                 return NULL;
01104         }
01105 }
01106 
01107 static PyMethodDef Handle_methods[] = {
01108         {"pause", (PyCFunction)Handle_pause, METH_NOARGS,
01109          M_aud_Handle_pause_doc
01110         },
01111         {"resume", (PyCFunction)Handle_resume, METH_NOARGS,
01112          M_aud_Handle_resume_doc
01113         },
01114         {"stop", (PyCFunction)Handle_stop, METH_NOARGS,
01115          M_aud_Handle_stop_doc
01116         },
01117         {NULL}  /* Sentinel */
01118 };
01119 
01120 PyDoc_STRVAR(M_aud_Handle_position_doc,
01121                          "The playback position of the sound in seconds.");
01122 
01123 static PyObject *
01124 Handle_get_position(Handle *self, void* nothing)
01125 {
01126         Device* device = (Device*)self->device;
01127 
01128         try
01129         {
01130                 return Py_BuildValue("f", device->device->getPosition(self->handle));
01131         }
01132         catch(AUD_Exception& e)
01133         {
01134                 PyErr_SetString(AUDError, e.str);
01135                 return NULL;
01136         }
01137 }
01138 
01139 static int
01140 Handle_set_position(Handle *self, PyObject* args, void* nothing)
01141 {
01142         float position;
01143 
01144         if(!PyArg_Parse(args, "f:position", &position))
01145                 return -1;
01146 
01147         Device* device = (Device*)self->device;
01148 
01149         try
01150         {
01151                 if(device->device->seek(self->handle, position))
01152                         return 0;
01153                 PyErr_SetString(AUDError, "Couldn't seek the sound!");
01154         }
01155         catch(AUD_Exception& e)
01156         {
01157                 PyErr_SetString(AUDError, e.str);
01158         }
01159 
01160         return -1;
01161 }
01162 
01163 PyDoc_STRVAR(M_aud_Handle_keep_doc,
01164                          "Whether the sound should be kept paused in the device when its "
01165                          "end is reached.\n"
01166                          "This can be used to seek the sound to some position and start "
01167                          "playback again.\n\n"
01168                          ".. warning:: If this is set to true and you forget stopping this "
01169                          "equals a memory leak as the handle exists until the device is "
01170                          "destroyed.");
01171 
01172 static PyObject *
01173 Handle_get_keep(Handle *self, void* nothing)
01174 {
01175         Device* device = (Device*)self->device;
01176 
01177         try
01178         {
01179                 return PyBool_FromLong((long)device->device->getKeep(self->handle));
01180         }
01181         catch(AUD_Exception& e)
01182         {
01183                 PyErr_SetString(AUDError, e.str);
01184                 return NULL;
01185         }
01186 }
01187 
01188 static int
01189 Handle_set_keep(Handle *self, PyObject* args, void* nothing)
01190 {
01191         if(!PyBool_Check(args))
01192         {
01193                 PyErr_SetString(PyExc_TypeError, "keep is not a boolean!");
01194                 return -1;
01195         }
01196 
01197         bool keep = args == Py_True;
01198         Device* device = (Device*)self->device;
01199 
01200         try
01201         {
01202                 if(device->device->setKeep(self->handle, keep))
01203                         return 0;
01204                 PyErr_SetString(AUDError, "Couldn't set keep of the sound!");
01205         }
01206         catch(AUD_Exception& e)
01207         {
01208                 PyErr_SetString(AUDError, e.str);
01209         }
01210 
01211         return -1;
01212 }
01213 
01214 PyDoc_STRVAR(M_aud_Handle_status_doc,
01215                          "Whether the sound is playing, paused or stopped (=invalid).");
01216 
01217 static PyObject *
01218 Handle_get_status(Handle *self, void* nothing)
01219 {
01220         Device* device = (Device*)self->device;
01221 
01222         try
01223         {
01224                 return PyBool_FromLong((long)device->device->getStatus(self->handle));
01225         }
01226         catch(AUD_Exception& e)
01227         {
01228                 PyErr_SetString(AUDError, e.str);
01229                 return NULL;
01230         }
01231 }
01232 
01233 PyDoc_STRVAR(M_aud_Handle_volume_doc,
01234                          "The volume of the sound.");
01235 
01236 static PyObject *
01237 Handle_get_volume(Handle *self, void* nothing)
01238 {
01239         Device* device = (Device*)self->device;
01240 
01241         try
01242         {
01243                 return Py_BuildValue("f", device->device->getVolume(self->handle));
01244         }
01245         catch(AUD_Exception& e)
01246         {
01247                 PyErr_SetString(AUDError, e.str);
01248                 return NULL;
01249         }
01250 }
01251 
01252 static int
01253 Handle_set_volume(Handle *self, PyObject* args, void* nothing)
01254 {
01255         float volume;
01256 
01257         if(!PyArg_Parse(args, "f:volume", &volume))
01258                 return -1;
01259 
01260         Device* device = (Device*)self->device;
01261 
01262         try
01263         {
01264                 if(device->device->setVolume(self->handle, volume))
01265                         return 0;
01266                 PyErr_SetString(AUDError, "Couldn't set the sound volume!");
01267         }
01268         catch(AUD_Exception& e)
01269         {
01270                 PyErr_SetString(AUDError, e.str);
01271         }
01272 
01273         return -1;
01274 }
01275 
01276 PyDoc_STRVAR(M_aud_Handle_pitch_doc,
01277                          "The pitch of the sound.");
01278 
01279 static PyObject *
01280 Handle_get_pitch(Handle *self, void* nothing)
01281 {
01282         Device* device = (Device*)self->device;
01283 
01284         try
01285         {
01286                 return Py_BuildValue("f", device->device->getPitch(self->handle));
01287         }
01288         catch(AUD_Exception& e)
01289         {
01290                 PyErr_SetString(AUDError, e.str);
01291                 return NULL;
01292         }
01293 }
01294 
01295 static int
01296 Handle_set_pitch(Handle *self, PyObject* args, void* nothing)
01297 {
01298         float pitch;
01299 
01300         if(!PyArg_Parse(args, "f:pitch", &pitch))
01301                 return -1;
01302 
01303         Device* device = (Device*)self->device;
01304 
01305         try
01306         {
01307                 if(device->device->setPitch(self->handle, pitch))
01308                         return 0;
01309                 PyErr_SetString(AUDError, "Couldn't set the sound pitch!");
01310         }
01311         catch(AUD_Exception& e)
01312         {
01313                 PyErr_SetString(AUDError, e.str);
01314         }
01315 
01316         return -1;
01317 }
01318 
01319 PyDoc_STRVAR(M_aud_Handle_loop_count_doc,
01320                          "The (remaining) loop count of the sound. A negative value indicates infinity.");
01321 
01322 static PyObject *
01323 Handle_get_loop_count(Handle *self, void* nothing)
01324 {
01325         Device* device = (Device*)self->device;
01326 
01327         try
01328         {
01329                 return Py_BuildValue("i", device->device->getLoopCount(self->handle));
01330         }
01331         catch(AUD_Exception& e)
01332         {
01333                 PyErr_SetString(AUDError, e.str);
01334                 return NULL;
01335         }
01336 }
01337 
01338 static int
01339 Handle_set_loop_count(Handle *self, PyObject* args, void* nothing)
01340 {
01341         int loops;
01342 
01343         if(!PyArg_Parse(args, "i:loop_count", &loops))
01344                 return -1;
01345 
01346         Device* device = (Device*)self->device;
01347 
01348         try
01349         {
01350                 if(device->device->setLoopCount(self->handle, loops))
01351                         return 0;
01352                 PyErr_SetString(AUDError, "Couldn't set the loop count!");
01353         }
01354         catch(AUD_Exception& e)
01355         {
01356                 PyErr_SetString(AUDError, e.str);
01357         }
01358 
01359         return -1;
01360 }
01361 
01362 PyDoc_STRVAR(M_aud_Handle_location_doc,
01363                          "The source's location in 3D space, a 3D tuple of floats.");
01364 
01365 static PyObject *
01366 Handle_get_location(Handle *self, void* nothing)
01367 {
01368         Device* dev = (Device*)self->device;
01369 
01370         try
01371         {
01372                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
01373                 if(device)
01374                 {
01375                         AUD_Vector3 v = device->getSourceLocation(self->handle);
01376                         return Py_BuildValue("(fff)", v.x(), v.y(), v.z());
01377                 }
01378                 else
01379                 {
01380                         PyErr_SetString(AUDError, device_not_3d_error);
01381                 }
01382         }
01383         catch(AUD_Exception& e)
01384         {
01385                 PyErr_SetString(AUDError, e.str);
01386         }
01387 
01388         return NULL;
01389 }
01390 
01391 static int
01392 Handle_set_location(Handle *self, PyObject* args, void* nothing)
01393 {
01394         float x, y, z;
01395 
01396         if(!PyArg_Parse(args, "(fff):location", &x, &y, &z))
01397                 return -1;
01398 
01399         Device* dev = (Device*)self->device;
01400 
01401         try
01402         {
01403                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
01404                 if(device)
01405                 {
01406                         AUD_Vector3 location(x, y, z);
01407                         if(device->setSourceLocation(self->handle, location))
01408                                 return 0;
01409                         PyErr_SetString(AUDError, "Location couldn't be set!");
01410                 }
01411                 else
01412                         PyErr_SetString(AUDError, device_not_3d_error);
01413         }
01414         catch(AUD_Exception& e)
01415         {
01416                 PyErr_SetString(AUDError, e.str);
01417         }
01418 
01419         return -1;
01420 }
01421 
01422 PyDoc_STRVAR(M_aud_Handle_velocity_doc,
01423                          "The source's velocity in 3D space, a 3D tuple of floats.");
01424 
01425 static PyObject *
01426 Handle_get_velocity(Handle *self, void* nothing)
01427 {
01428         Device* dev = (Device*)self->device;
01429 
01430         try
01431         {
01432                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
01433                 if(device)
01434                 {
01435                         AUD_Vector3 v = device->getSourceVelocity(self->handle);
01436                         return Py_BuildValue("(fff)", v.x(), v.y(), v.z());
01437                 }
01438                 else
01439                 {
01440                         PyErr_SetString(AUDError, device_not_3d_error);
01441                 }
01442         }
01443         catch(AUD_Exception& e)
01444         {
01445                 PyErr_SetString(AUDError, e.str);
01446         }
01447 
01448         return NULL;
01449 }
01450 
01451 static int
01452 Handle_set_velocity(Handle *self, PyObject* args, void* nothing)
01453 {
01454         float x, y, z;
01455 
01456         if(!PyArg_Parse(args, "(fff):velocity", &x, &y, &z))
01457                 return -1;
01458 
01459         Device* dev = (Device*)self->device;
01460 
01461         try
01462         {
01463                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
01464                 if(device)
01465                 {
01466                         AUD_Vector3 velocity(x, y, z);
01467                         if(device->setSourceVelocity(self->handle, velocity))
01468                                 return 0;
01469                         PyErr_SetString(AUDError, "Couldn't set the velocity!");
01470                 }
01471                 else
01472                         PyErr_SetString(AUDError, device_not_3d_error);
01473         }
01474         catch(AUD_Exception& e)
01475         {
01476                 PyErr_SetString(AUDError, e.str);
01477         }
01478 
01479         return -1;
01480 }
01481 
01482 PyDoc_STRVAR(M_aud_Handle_orientation_doc,
01483                          "The source's orientation in 3D space as quaternion, a 4 float tuple.");
01484 
01485 static PyObject *
01486 Handle_get_orientation(Handle *self, void* nothing)
01487 {
01488         Device* dev = (Device*)self->device;
01489 
01490         try
01491         {
01492                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
01493                 if(device)
01494                 {
01495                         AUD_Quaternion o = device->getSourceOrientation(self->handle);
01496                         return Py_BuildValue("(ffff)", o.w(), o.x(), o.y(), o.z());
01497                 }
01498                 else
01499                 {
01500                         PyErr_SetString(AUDError, device_not_3d_error);
01501                 }
01502         }
01503         catch(AUD_Exception& e)
01504         {
01505                 PyErr_SetString(AUDError, e.str);
01506         }
01507 
01508         return NULL;
01509 }
01510 
01511 static int
01512 Handle_set_orientation(Handle *self, PyObject* args, void* nothing)
01513 {
01514         float w, x, y, z;
01515 
01516         if(!PyArg_Parse(args, "(ffff):orientation", &w, &x, &y, &z))
01517                 return -1;
01518 
01519         Device* dev = (Device*)self->device;
01520 
01521         try
01522         {
01523                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
01524                 if(device)
01525                 {
01526                         AUD_Quaternion orientation(w, x, y, z);
01527                         if(device->setSourceOrientation(self->handle, orientation))
01528                                 return 0;
01529                         PyErr_SetString(AUDError, "Couldn't set the orientation!");
01530                 }
01531                 else
01532                         PyErr_SetString(AUDError, device_not_3d_error);
01533         }
01534         catch(AUD_Exception& e)
01535         {
01536                 PyErr_SetString(AUDError, e.str);
01537         }
01538 
01539         return -1;
01540 }
01541 
01542 PyDoc_STRVAR(M_aud_Handle_relative_doc,
01543                          "Whether the source's location, velocity and orientation is relative or absolute to the listener.");
01544 
01545 static PyObject *
01546 Handle_get_relative(Handle *self, void* nothing)
01547 {
01548         Device* dev = (Device*)self->device;
01549 
01550         try
01551         {
01552                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
01553                 if(device)
01554                 {
01555                         return PyBool_FromLong((long)device->isRelative(self->handle));
01556                 }
01557                 else
01558                 {
01559                         PyErr_SetString(AUDError, device_not_3d_error);
01560                 }
01561         }
01562         catch(AUD_Exception& e)
01563         {
01564                 PyErr_SetString(AUDError, e.str);
01565         }
01566 
01567         return NULL;
01568 }
01569 
01570 static int
01571 Handle_set_relative(Handle *self, PyObject* args, void* nothing)
01572 {
01573         if(!PyBool_Check(args))
01574         {
01575                 PyErr_SetString(PyExc_TypeError, "Value is not a boolean!");
01576                 return -1;
01577         }
01578 
01579         bool relative = (args == Py_True);
01580         Device* dev = (Device*)self->device;
01581 
01582         try
01583         {
01584                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
01585                 if(device)
01586                 {
01587                         if(device->setRelative(self->handle, relative))
01588                                 return 0;
01589                         PyErr_SetString(AUDError, "Couldn't set the relativeness!");
01590                 }
01591                 else
01592                         PyErr_SetString(AUDError, device_not_3d_error);
01593         }
01594         catch(AUD_Exception& e)
01595         {
01596                 PyErr_SetString(AUDError, e.str);
01597         }
01598 
01599         return -1;
01600 }
01601 
01602 PyDoc_STRVAR(M_aud_Handle_volume_minimum_doc,
01603                          "The minimum volume of the source.\n\n"
01604                          ".. seealso:: :attr:`Device.distance_model`");
01605 
01606 static PyObject *
01607 Handle_get_volume_minimum(Handle *self, void* nothing)
01608 {
01609         Device* dev = (Device*)self->device;
01610 
01611         try
01612         {
01613                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
01614                 if(device)
01615                 {
01616                         return Py_BuildValue("f", device->getVolumeMinimum(self->handle));
01617                 }
01618                 else
01619                 {
01620                         PyErr_SetString(AUDError, device_not_3d_error);
01621                         return NULL;
01622                 }
01623         }
01624         catch(AUD_Exception& e)
01625         {
01626                 PyErr_SetString(AUDError, e.str);
01627                 return NULL;
01628         }
01629 }
01630 
01631 static int
01632 Handle_set_volume_minimum(Handle *self, PyObject* args, void* nothing)
01633 {
01634         float volume;
01635 
01636         if(!PyArg_Parse(args, "f:volume_minimum", &volume))
01637                 return -1;
01638 
01639         Device* dev = (Device*)self->device;
01640 
01641         try
01642         {
01643                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
01644                 if(device)
01645                 {
01646                         if(device->setVolumeMinimum(self->handle, volume))
01647                                 return 0;
01648                         PyErr_SetString(AUDError, "Couldn't set the minimum volume!");
01649                 }
01650                 else
01651                         PyErr_SetString(AUDError, device_not_3d_error);
01652         }
01653         catch(AUD_Exception& e)
01654         {
01655                 PyErr_SetString(AUDError, e.str);
01656         }
01657 
01658         return -1;
01659 }
01660 
01661 PyDoc_STRVAR(M_aud_Handle_volume_maximum_doc,
01662                          "The maximum volume of the source.\n\n"
01663                          ".. seealso:: :attr:`Device.distance_model`");
01664 
01665 static PyObject *
01666 Handle_get_volume_maximum(Handle *self, void* nothing)
01667 {
01668         Device* dev = (Device*)self->device;
01669 
01670         try
01671         {
01672                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
01673                 if(device)
01674                 {
01675                         return Py_BuildValue("f", device->getVolumeMaximum(self->handle));
01676                 }
01677                 else
01678                 {
01679                         PyErr_SetString(AUDError, device_not_3d_error);
01680                         return NULL;
01681                 }
01682         }
01683         catch(AUD_Exception& e)
01684         {
01685                 PyErr_SetString(AUDError, e.str);
01686                 return NULL;
01687         }
01688 }
01689 
01690 static int
01691 Handle_set_volume_maximum(Handle *self, PyObject* args, void* nothing)
01692 {
01693         float volume;
01694 
01695         if(!PyArg_Parse(args, "f:volume_maximum", &volume))
01696                 return -1;
01697 
01698         Device* dev = (Device*)self->device;
01699 
01700         try
01701         {
01702                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
01703                 if(device)
01704                 {
01705                         if(device->setVolumeMaximum(self->handle, volume))
01706                                 return 0;
01707                         PyErr_SetString(AUDError, "Couldn't set the maximum volume!");
01708                 }
01709                 else
01710                         PyErr_SetString(AUDError, device_not_3d_error);
01711         }
01712         catch(AUD_Exception& e)
01713         {
01714                 PyErr_SetString(AUDError, e.str);
01715         }
01716 
01717         return -1;
01718 }
01719 
01720 PyDoc_STRVAR(M_aud_Handle_distance_reference_doc,
01721                          "The reference distance of the source.\n"
01722                          "At this distance the volume will be exactly :attr:`volume`.\n\n"
01723                          ".. seealso:: :attr:`Device.distance_model`");
01724 
01725 static PyObject *
01726 Handle_get_distance_reference(Handle *self, void* nothing)
01727 {
01728         Device* dev = (Device*)self->device;
01729 
01730         try
01731         {
01732                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
01733                 if(device)
01734                 {
01735                         return Py_BuildValue("f", device->getDistanceReference(self->handle));
01736                 }
01737                 else
01738                 {
01739                         PyErr_SetString(AUDError, device_not_3d_error);
01740                         return NULL;
01741                 }
01742         }
01743         catch(AUD_Exception& e)
01744         {
01745                 PyErr_SetString(AUDError, e.str);
01746                 return NULL;
01747         }
01748 }
01749 
01750 static int
01751 Handle_set_distance_reference(Handle *self, PyObject* args, void* nothing)
01752 {
01753         float distance;
01754 
01755         if(!PyArg_Parse(args, "f:distance_reference", &distance))
01756                 return -1;
01757 
01758         Device* dev = (Device*)self->device;
01759 
01760         try
01761         {
01762                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
01763                 if(device)
01764                 {
01765                         if(device->setDistanceReference(self->handle, distance))
01766                                 return 0;
01767                         PyErr_SetString(AUDError, "Couldn't set the reference distance!");
01768                 }
01769                 else
01770                         PyErr_SetString(AUDError, device_not_3d_error);
01771         }
01772         catch(AUD_Exception& e)
01773         {
01774                 PyErr_SetString(AUDError, e.str);
01775         }
01776 
01777         return -1;
01778 }
01779 
01780 PyDoc_STRVAR(M_aud_Handle_distance_maximum_doc,
01781                          "The maximum distance of the source.\n"
01782                          "If the listener is further away the source volume will be 0.\n\n"
01783                          ".. seealso:: :attr:`Device.distance_model`");
01784 
01785 static PyObject *
01786 Handle_get_distance_maximum(Handle *self, void* nothing)
01787 {
01788         Device* dev = (Device*)self->device;
01789 
01790         try
01791         {
01792                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
01793                 if(device)
01794                 {
01795                         return Py_BuildValue("f", device->getDistanceMaximum(self->handle));
01796                 }
01797                 else
01798                 {
01799                         PyErr_SetString(AUDError, device_not_3d_error);
01800                         return NULL;
01801                 }
01802         }
01803         catch(AUD_Exception& e)
01804         {
01805                 PyErr_SetString(AUDError, e.str);
01806                 return NULL;
01807         }
01808 }
01809 
01810 static int
01811 Handle_set_distance_maximum(Handle *self, PyObject* args, void* nothing)
01812 {
01813         float distance;
01814 
01815         if(!PyArg_Parse(args, "f:distance_maximum", &distance))
01816                 return -1;
01817 
01818         Device* dev = (Device*)self->device;
01819 
01820         try
01821         {
01822                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
01823                 if(device)
01824                 {
01825                         if(device->setDistanceMaximum(self->handle, distance))
01826                                 return 0;
01827                         PyErr_SetString(AUDError, "Couldn't set the maximum distance!");
01828                 }
01829                 else
01830                         PyErr_SetString(AUDError, device_not_3d_error);
01831         }
01832         catch(AUD_Exception& e)
01833         {
01834                 PyErr_SetString(AUDError, e.str);
01835         }
01836 
01837         return -1;
01838 }
01839 
01840 PyDoc_STRVAR(M_aud_Handle_attenuation_doc,
01841                          "This factor is used for distance based attenuation of the "
01842                          "source.\n\n"
01843                          ".. seealso:: :attr:`Device.distance_model`");
01844 
01845 static PyObject *
01846 Handle_get_attenuation(Handle *self, void* nothing)
01847 {
01848         Device* dev = (Device*)self->device;
01849 
01850         try
01851         {
01852                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
01853                 if(device)
01854                 {
01855                         return Py_BuildValue("f", device->getAttenuation(self->handle));
01856                 }
01857                 else
01858                 {
01859                         PyErr_SetString(AUDError, device_not_3d_error);
01860                         return NULL;
01861                 }
01862         }
01863         catch(AUD_Exception& e)
01864         {
01865                 PyErr_SetString(AUDError, e.str);
01866                 return NULL;
01867         }
01868 }
01869 
01870 static int
01871 Handle_set_attenuation(Handle *self, PyObject* args, void* nothing)
01872 {
01873         float factor;
01874 
01875         if(!PyArg_Parse(args, "f:attenuation", &factor))
01876                 return -1;
01877 
01878         Device* dev = (Device*)self->device;
01879 
01880         try
01881         {
01882                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
01883                 if(device)
01884                 {
01885                         if(device->setAttenuation(self->handle, factor))
01886                                 return 0;
01887                         PyErr_SetString(AUDError, "Couldn't set the attenuation!");
01888                 }
01889                 else
01890                         PyErr_SetString(AUDError, device_not_3d_error);
01891         }
01892         catch(AUD_Exception& e)
01893         {
01894                 PyErr_SetString(AUDError, e.str);
01895         }
01896 
01897         return -1;
01898 }
01899 
01900 PyDoc_STRVAR(M_aud_Handle_cone_angle_inner_doc,
01901                          "The opening angle of the inner cone of the source. If the cone "
01902                          "values of a source are set there are two (audible) cones with "
01903                          "the apex at the :attr:`location` of the source and with infinite "
01904                          "height, heading in the direction of the source's "
01905                          ":attr:`orientation`.\n"
01906                          "In the inner cone the volume is normal. Outside the outer cone "
01907                          "the volume will be :attr:`cone_volume_outer` and in the area "
01908                          "between the volume will be interpolated linearly.");
01909 
01910 static PyObject *
01911 Handle_get_cone_angle_inner(Handle *self, void* nothing)
01912 {
01913         Device* dev = (Device*)self->device;
01914 
01915         try
01916         {
01917                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
01918                 if(device)
01919                 {
01920                         return Py_BuildValue("f", device->getConeAngleInner(self->handle));
01921                 }
01922                 else
01923                 {
01924                         PyErr_SetString(AUDError, device_not_3d_error);
01925                         return NULL;
01926                 }
01927         }
01928         catch(AUD_Exception& e)
01929         {
01930                 PyErr_SetString(AUDError, e.str);
01931                 return NULL;
01932         }
01933 }
01934 
01935 static int
01936 Handle_set_cone_angle_inner(Handle *self, PyObject* args, void* nothing)
01937 {
01938         float angle;
01939 
01940         if(!PyArg_Parse(args, "f:cone_angle_inner", &angle))
01941                 return -1;
01942 
01943         Device* dev = (Device*)self->device;
01944 
01945         try
01946         {
01947                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
01948                 if(device)
01949                 {
01950                         if(device->setConeAngleInner(self->handle, angle))
01951                                 return 0;
01952                         PyErr_SetString(AUDError, "Couldn't set the cone inner angle!");
01953                 }
01954                 else
01955                         PyErr_SetString(AUDError, device_not_3d_error);
01956         }
01957         catch(AUD_Exception& e)
01958         {
01959                 PyErr_SetString(AUDError, e.str);
01960         }
01961 
01962         return -1;
01963 }
01964 
01965 PyDoc_STRVAR(M_aud_Handle_cone_angle_outer_doc,
01966                          "The opening angle of the outer cone of the source.\n\n"
01967                          ".. seealso:: :attr:`cone_angle_inner`");
01968 
01969 static PyObject *
01970 Handle_get_cone_angle_outer(Handle *self, void* nothing)
01971 {
01972         Device* dev = (Device*)self->device;
01973 
01974         try
01975         {
01976                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
01977                 if(device)
01978                 {
01979                         return Py_BuildValue("f", device->getConeAngleOuter(self->handle));
01980                 }
01981                 else
01982                 {
01983                         PyErr_SetString(AUDError, device_not_3d_error);
01984                         return NULL;
01985                 }
01986         }
01987         catch(AUD_Exception& e)
01988         {
01989                 PyErr_SetString(AUDError, e.str);
01990                 return NULL;
01991         }
01992 }
01993 
01994 static int
01995 Handle_set_cone_angle_outer(Handle *self, PyObject* args, void* nothing)
01996 {
01997         float angle;
01998 
01999         if(!PyArg_Parse(args, "f:cone_angle_outer", &angle))
02000                 return -1;
02001 
02002         Device* dev = (Device*)self->device;
02003 
02004         try
02005         {
02006                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
02007                 if(device)
02008                 {
02009                         if(device->setConeAngleOuter(self->handle, angle))
02010                                 return 0;
02011                         PyErr_SetString(AUDError, "Couldn't set the cone outer angle!");
02012                 }
02013                 else
02014                         PyErr_SetString(AUDError, device_not_3d_error);
02015         }
02016         catch(AUD_Exception& e)
02017         {
02018                 PyErr_SetString(AUDError, e.str);
02019         }
02020 
02021         return -1;
02022 }
02023 
02024 PyDoc_STRVAR(M_aud_Handle_cone_volume_outer_doc,
02025                          "The volume outside the outer cone of the source.\n\n"
02026                          ".. seealso:: :attr:`cone_angle_inner`");
02027 
02028 static PyObject *
02029 Handle_get_cone_volume_outer(Handle *self, void* nothing)
02030 {
02031         Device* dev = (Device*)self->device;
02032 
02033         try
02034         {
02035                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
02036                 if(device)
02037                 {
02038                         return Py_BuildValue("f", device->getConeVolumeOuter(self->handle));
02039                 }
02040                 else
02041                 {
02042                         PyErr_SetString(AUDError, device_not_3d_error);
02043                         return NULL;
02044                 }
02045         }
02046         catch(AUD_Exception& e)
02047         {
02048                 PyErr_SetString(AUDError, e.str);
02049                 return NULL;
02050         }
02051 }
02052 
02053 static int
02054 Handle_set_cone_volume_outer(Handle *self, PyObject* args, void* nothing)
02055 {
02056         float volume;
02057 
02058         if(!PyArg_Parse(args, "f:cone_volume_outer", &volume))
02059                 return -1;
02060 
02061         Device* dev = (Device*)self->device;
02062 
02063         try
02064         {
02065                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
02066                 if(device)
02067                 {
02068                         if(device->setConeVolumeOuter(self->handle, volume))
02069                                 return 0;
02070                         PyErr_SetString(AUDError, "Couldn't set the cone outer volume!");
02071                 }
02072                 else
02073                         PyErr_SetString(AUDError, device_not_3d_error);
02074         }
02075         catch(AUD_Exception& e)
02076         {
02077                 PyErr_SetString(AUDError, e.str);
02078         }
02079 
02080         return -1;
02081 }
02082 
02083 static PyGetSetDef Handle_properties[] = {
02084         {(char*)"position", (getter)Handle_get_position, (setter)Handle_set_position,
02085          M_aud_Handle_position_doc, NULL },
02086         {(char*)"keep", (getter)Handle_get_keep, (setter)Handle_set_keep,
02087          M_aud_Handle_keep_doc, NULL },
02088         {(char*)"status", (getter)Handle_get_status, NULL,
02089          M_aud_Handle_status_doc, NULL },
02090         {(char*)"volume", (getter)Handle_get_volume, (setter)Handle_set_volume,
02091          M_aud_Handle_volume_doc, NULL },
02092         {(char*)"pitch", (getter)Handle_get_pitch, (setter)Handle_set_pitch,
02093          M_aud_Handle_pitch_doc, NULL },
02094         {(char*)"loop_count", (getter)Handle_get_loop_count, (setter)Handle_set_loop_count,
02095          M_aud_Handle_loop_count_doc, NULL },
02096         {(char*)"location", (getter)Handle_get_location, (setter)Handle_set_location,
02097          M_aud_Handle_location_doc, NULL },
02098         {(char*)"velocity", (getter)Handle_get_velocity, (setter)Handle_set_velocity,
02099          M_aud_Handle_velocity_doc, NULL },
02100         {(char*)"orientation", (getter)Handle_get_orientation, (setter)Handle_set_orientation,
02101          M_aud_Handle_orientation_doc, NULL },
02102         {(char*)"relative", (getter)Handle_get_relative, (setter)Handle_set_relative,
02103          M_aud_Handle_relative_doc, NULL },
02104         {(char*)"volume_minimum", (getter)Handle_get_volume_minimum, (setter)Handle_set_volume_minimum,
02105          M_aud_Handle_volume_minimum_doc, NULL },
02106         {(char*)"volume_maximum", (getter)Handle_get_volume_maximum, (setter)Handle_set_volume_maximum,
02107          M_aud_Handle_volume_maximum_doc, NULL },
02108         {(char*)"distance_reference", (getter)Handle_get_distance_reference, (setter)Handle_set_distance_reference,
02109          M_aud_Handle_distance_reference_doc, NULL },
02110         {(char*)"distance_maximum", (getter)Handle_get_distance_maximum, (setter)Handle_set_distance_maximum,
02111          M_aud_Handle_distance_maximum_doc, NULL },
02112         {(char*)"attenuation", (getter)Handle_get_attenuation, (setter)Handle_set_attenuation,
02113          M_aud_Handle_attenuation_doc, NULL },
02114         {(char*)"cone_angle_inner", (getter)Handle_get_cone_angle_inner, (setter)Handle_set_cone_angle_inner,
02115          M_aud_Handle_cone_angle_inner_doc, NULL },
02116         {(char*)"cone_angle_outer", (getter)Handle_get_cone_angle_outer, (setter)Handle_set_cone_angle_outer,
02117          M_aud_Handle_cone_angle_outer_doc, NULL },
02118         {(char*)"cone_volume_outer", (getter)Handle_get_cone_volume_outer, (setter)Handle_set_cone_volume_outer,
02119          M_aud_Handle_cone_volume_outer_doc, NULL },
02120         {NULL}  /* Sentinel */
02121 };
02122 
02123 PyDoc_STRVAR(M_aud_Handle_doc,
02124                          "Handle objects are playback handles that can be used to control "
02125                          "playback of a sound. If a sound is played back multiple times "
02126                          "then there are as many handles.");
02127 
02128 static PyTypeObject HandleType = {
02129         PyVarObject_HEAD_INIT(NULL, 0)
02130         "aud.Handle",              /* tp_name */
02131         sizeof(Handle),            /* tp_basicsize */
02132         0,                         /* tp_itemsize */
02133         (destructor)Handle_dealloc,/* tp_dealloc */
02134         0,                         /* tp_print */
02135         0,                         /* tp_getattr */
02136         0,                         /* tp_setattr */
02137         0,                         /* tp_reserved */
02138         0,                         /* tp_repr */
02139         0,                         /* tp_as_number */
02140         0,                         /* tp_as_sequence */
02141         0,                         /* tp_as_mapping */
02142         0,                         /* tp_hash  */
02143         0,                         /* tp_call */
02144         0,                         /* tp_str */
02145         0,                         /* tp_getattro */
02146         0,                         /* tp_setattro */
02147         0,                         /* tp_as_buffer */
02148         Py_TPFLAGS_DEFAULT,        /* tp_flags */
02149         M_aud_Handle_doc,          /* tp_doc */
02150         0,                                 /* tp_traverse */
02151         0,                                 /* tp_clear */
02152         0,                                 /* tp_richcompare */
02153         0,                                 /* tp_weaklistoffset */
02154         0,                                 /* tp_iter */
02155         0,                                 /* tp_iternext */
02156         Handle_methods,            /* tp_methods */
02157         0,                         /* tp_members */
02158         Handle_properties,         /* tp_getset */
02159         0,                         /* tp_base */
02160         0,                         /* tp_dict */
02161         0,                         /* tp_descr_get */
02162         0,                         /* tp_descr_set */
02163         0,                         /* tp_dictoffset */
02164         0,                         /* tp_init */
02165         0,                         /* tp_alloc */
02166         0,                         /* tp_new */
02167 };
02168 
02169 // ========== Device ==================================================
02170 
02171 static void
02172 Device_dealloc(Device* self)
02173 {
02174         if(self->device)
02175                 delete self->device;
02176         Py_TYPE(self)->tp_free((PyObject*)self);
02177 }
02178 
02179 static PyObject *
02180 Device_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
02181 {
02182         Device *self;
02183 
02184         static const char *kwlist[] = {"type", "rate", "channels", "format", "buffer_size", "name", NULL};
02185         int device;
02186         int rate = AUD_RATE_44100;
02187         int channels = AUD_CHANNELS_STEREO;
02188         int format = AUD_FORMAT_FLOAT32;
02189         int buffersize = AUD_DEFAULT_BUFFER_SIZE;
02190         const char* name = "Audaspace";
02191 
02192         if(!PyArg_ParseTupleAndKeywords(args, kwds, "i|iiiis:Device", const_cast<char**>(kwlist),
02193                                                                         &device, &rate, &channels, &format, &buffersize, &name))
02194                 return NULL;
02195 
02196         if(buffersize < 128)
02197         {
02198                 PyErr_SetString(PyExc_ValueError, "buffer_size must be greater than 127!");
02199                 return NULL;
02200         }
02201 
02202         self = (Device*)type->tp_alloc(type, 0);
02203         if(self != NULL)
02204         {
02205                 AUD_DeviceSpecs specs;
02206                 specs.channels = (AUD_Channels)channels;
02207                 specs.format = (AUD_SampleFormat)format;
02208                 specs.rate = (AUD_SampleRate)rate;
02209 
02210                 self->device = NULL;
02211 
02212                 try
02213                 {
02214                         switch(device)
02215                         {
02216                         case AUD_DEVICE_NULL:
02217                                 (void)specs; /* quiet warning when others disabled */
02218                                 self->device = new AUD_NULLDevice();
02219                                 break;
02220                         case AUD_DEVICE_OPENAL:
02221 #ifdef WITH_OPENAL
02222                                 self->device = new AUD_OpenALDevice(specs, buffersize);
02223 #endif
02224                                 break;
02225                         case AUD_DEVICE_SDL:
02226 #ifdef WITH_SDL
02227                                 self->device = new AUD_SDLDevice(specs, buffersize);
02228 #endif
02229                                 break;
02230                         case AUD_DEVICE_JACK:
02231 #ifdef WITH_JACK
02232                                 self->device = new AUD_JackDevice(name, specs, buffersize);
02233 #endif
02234                                 break;
02235                         case AUD_DEVICE_READ:
02236                                 break;
02237                         }
02238 
02239                 }
02240                 catch(AUD_Exception& e)
02241                 {
02242                         Py_DECREF(self);
02243                         PyErr_SetString(AUDError, e.str);
02244                         return NULL;
02245                 }
02246 
02247                 if(!self->device)
02248                 {
02249                         Py_DECREF(self);
02250                         PyErr_SetString(AUDError, "Unsupported device type!");
02251                         return NULL;
02252                 }
02253         }
02254 
02255         return (PyObject *)self;
02256 }
02257 
02258 PyDoc_STRVAR(M_aud_Device_play_doc,
02259                          "play(factory, keep=False)\n\n"
02260                          "Plays a factory.\n\n"
02261                          ":arg factory: The factory to play.\n"
02262                          ":type factory: :class:`Factory`\n"
02263                          ":arg keep: See :attr:`Handle.keep`.\n"
02264                          ":type keep: bool\n"
02265                          ":return: The playback handle with which playback can be "
02266                          "controlled with.\n"
02267                          ":rtype: :class:`Handle`");
02268 
02269 static PyObject *
02270 Device_play(Device *self, PyObject *args, PyObject *kwds)
02271 {
02272         PyObject* object;
02273         PyObject* keepo = NULL;
02274 
02275         bool keep = false;
02276 
02277         static const char *kwlist[] = {"factory", "keep", NULL};
02278 
02279         if(!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:play", const_cast<char**>(kwlist), &object, &keepo))
02280                 return NULL;
02281 
02282         if(!PyObject_TypeCheck(object, &FactoryType))
02283         {
02284                 PyErr_SetString(PyExc_TypeError, "Object is not of type Factory!");
02285                 return NULL;
02286         }
02287 
02288         if(keepo != NULL)
02289         {
02290                 if(!PyBool_Check(keepo))
02291                 {
02292                         PyErr_SetString(PyExc_TypeError, "keep is not a boolean!");
02293                         return NULL;
02294                 }
02295 
02296                 keep = keepo == Py_True;
02297         }
02298 
02299         Factory* sound = (Factory*)object;
02300         Handle *handle;
02301 
02302         handle = (Handle*)HandleType.tp_alloc(&HandleType, 0);
02303         if(handle != NULL)
02304         {
02305                 handle->device = (PyObject*)self;
02306                 Py_INCREF(self);
02307 
02308                 try
02309                 {
02310                         handle->handle = self->device->play(sound->factory, keep);
02311                 }
02312                 catch(AUD_Exception& e)
02313                 {
02314                         Py_DECREF(handle);
02315                         PyErr_SetString(AUDError, e.str);
02316                         return NULL;
02317                 }
02318         }
02319 
02320         return (PyObject *)handle;
02321 }
02322 
02323 PyDoc_STRVAR(M_aud_Device_lock_doc,
02324                          "lock()\n\n"
02325                          "Locks the device so that it's guaranteed, that no samples are "
02326                          "read from the streams until :meth:`unlock` is called.\n"
02327                          "This is useful if you want to do start/stop/pause/resume some "
02328                          "sounds at the same time.\n\n"
02329                          ".. note:: The device has to be unlocked as often as locked to be "
02330                          "able to continue playback.\n\n"
02331                          ".. warning:: Make sure the time between locking and unlocking is "
02332                          "as short as possible to avoid clicks.");
02333 
02334 static PyObject *
02335 Device_lock(Device *self)
02336 {
02337         try
02338         {
02339                 self->device->lock();
02340                 Py_RETURN_NONE;
02341         }
02342         catch(AUD_Exception& e)
02343         {
02344                 PyErr_SetString(AUDError, e.str);
02345                 return NULL;
02346         }
02347 }
02348 
02349 PyDoc_STRVAR(M_aud_Device_unlock_doc,
02350                          "unlock()\n\n"
02351                          "Unlocks the device after a lock call, see :meth:`lock` for "
02352                          "details.");
02353 
02354 static PyObject *
02355 Device_unlock(Device *self)
02356 {
02357         try
02358         {
02359                 self->device->unlock();
02360                 Py_RETURN_NONE;
02361         }
02362         catch(AUD_Exception& e)
02363         {
02364                 PyErr_SetString(AUDError, e.str);
02365                 return NULL;
02366         }
02367 }
02368 
02369 static PyMethodDef Device_methods[] = {
02370         {"play", (PyCFunction)Device_play, METH_VARARGS | METH_KEYWORDS,
02371          M_aud_Device_play_doc
02372         },
02373         {"lock", (PyCFunction)Device_lock, METH_NOARGS,
02374          M_aud_Device_lock_doc
02375         },
02376         {"unlock", (PyCFunction)Device_unlock, METH_NOARGS,
02377          M_aud_Device_unlock_doc
02378         },
02379         {NULL}  /* Sentinel */
02380 };
02381 
02382 PyDoc_STRVAR(M_aud_Device_rate_doc,
02383                          "The sampling rate of the device in Hz.");
02384 
02385 static PyObject *
02386 Device_get_rate(Device *self, void* nothing)
02387 {
02388         try
02389         {
02390                 AUD_DeviceSpecs specs = self->device->getSpecs();
02391                 return Py_BuildValue("i", specs.rate);
02392         }
02393         catch(AUD_Exception& e)
02394         {
02395                 PyErr_SetString(AUDError, e.str);
02396                 return NULL;
02397         }
02398 }
02399 
02400 PyDoc_STRVAR(M_aud_Device_format_doc,
02401                          "The native sample format of the device.");
02402 
02403 static PyObject *
02404 Device_get_format(Device *self, void* nothing)
02405 {
02406         try
02407         {
02408                 AUD_DeviceSpecs specs = self->device->getSpecs();
02409                 return Py_BuildValue("i", specs.format);
02410         }
02411         catch(AUD_Exception& e)
02412         {
02413                 PyErr_SetString(AUDError, e.str);
02414                 return NULL;
02415         }
02416 }
02417 
02418 PyDoc_STRVAR(M_aud_Device_channels_doc,
02419                          "The channel count of the device.");
02420 
02421 static PyObject *
02422 Device_get_channels(Device *self, void* nothing)
02423 {
02424         try
02425         {
02426                 AUD_DeviceSpecs specs = self->device->getSpecs();
02427                 return Py_BuildValue("i", specs.channels);
02428         }
02429         catch(AUD_Exception& e)
02430         {
02431                 PyErr_SetString(AUDError, e.str);
02432                 return NULL;
02433         }
02434 }
02435 
02436 PyDoc_STRVAR(M_aud_Device_volume_doc,
02437                          "The overall volume of the device.");
02438 
02439 static PyObject *
02440 Device_get_volume(Device *self, void* nothing)
02441 {
02442         try
02443         {
02444                 return Py_BuildValue("f", self->device->getVolume());
02445         }
02446         catch(AUD_Exception& e)
02447         {
02448                 PyErr_SetString(AUDError, e.str);
02449                 return NULL;
02450         }
02451 }
02452 
02453 static int
02454 Device_set_volume(Device *self, PyObject* args, void* nothing)
02455 {
02456         float volume;
02457 
02458         if(!PyArg_Parse(args, "f:volume", &volume))
02459                 return -1;
02460 
02461         try
02462         {
02463                 self->device->setVolume(volume);
02464                 return 0;
02465         }
02466         catch(AUD_Exception& e)
02467         {
02468                 PyErr_SetString(AUDError, e.str);
02469                 return -1;
02470         }
02471 }
02472 
02473 PyDoc_STRVAR(M_aud_Device_listener_location_doc,
02474                          "The listeners's location in 3D space, a 3D tuple of floats.");
02475 
02476 static PyObject *
02477 Device_get_listener_location(Device *self, void* nothing)
02478 {
02479         try
02480         {
02481                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
02482                 if(device)
02483                 {
02484                         AUD_Vector3 v = device->getListenerLocation();
02485                         return Py_BuildValue("(fff)", v.x(), v.y(), v.z());
02486                 }
02487                 else
02488                 {
02489                         PyErr_SetString(AUDError, device_not_3d_error);
02490                 }
02491         }
02492         catch(AUD_Exception& e)
02493         {
02494                 PyErr_SetString(AUDError, e.str);
02495         }
02496 
02497         return NULL;
02498 }
02499 
02500 static int
02501 Device_set_listener_location(Device *self, PyObject* args, void* nothing)
02502 {
02503         float x, y, z;
02504 
02505         if(!PyArg_Parse(args, "(fff):listener_location", &x, &y, &z))
02506                 return -1;
02507 
02508         try
02509         {
02510                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
02511                 if(device)
02512                 {
02513                         AUD_Vector3 location(x, y, z);
02514                         device->setListenerLocation(location);
02515                         return 0;
02516                 }
02517                 else
02518                         PyErr_SetString(AUDError, device_not_3d_error);
02519         }
02520         catch(AUD_Exception& e)
02521         {
02522                 PyErr_SetString(AUDError, e.str);
02523         }
02524 
02525         return -1;
02526 }
02527 
02528 PyDoc_STRVAR(M_aud_Device_listener_velocity_doc,
02529                          "The listener's velocity in 3D space, a 3D tuple of floats.");
02530 
02531 static PyObject *
02532 Device_get_listener_velocity(Device *self, void* nothing)
02533 {
02534         try
02535         {
02536                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
02537                 if(device)
02538                 {
02539                         AUD_Vector3 v = device->getListenerVelocity();
02540                         return Py_BuildValue("(fff)", v.x(), v.y(), v.z());
02541                 }
02542                 else
02543                 {
02544                         PyErr_SetString(AUDError, device_not_3d_error);
02545                 }
02546         }
02547         catch(AUD_Exception& e)
02548         {
02549                 PyErr_SetString(AUDError, e.str);
02550         }
02551 
02552         return NULL;
02553 }
02554 
02555 static int
02556 Device_set_listener_velocity(Device *self, PyObject* args, void* nothing)
02557 {
02558         float x, y, z;
02559 
02560         if(!PyArg_Parse(args, "(fff):listener_velocity", &x, &y, &z))
02561                 return -1;
02562 
02563         try
02564         {
02565                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
02566                 if(device)
02567                 {
02568                         AUD_Vector3 velocity(x, y, z);
02569                         device->setListenerVelocity(velocity);
02570                         return 0;
02571                 }
02572                 else
02573                         PyErr_SetString(AUDError, device_not_3d_error);
02574         }
02575         catch(AUD_Exception& e)
02576         {
02577                 PyErr_SetString(AUDError, e.str);
02578         }
02579 
02580         return -1;
02581 }
02582 
02583 PyDoc_STRVAR(M_aud_Device_listener_orientation_doc,
02584                          "The listener's orientation in 3D space as quaternion, a 4 float tuple.");
02585 
02586 static PyObject *
02587 Device_get_listener_orientation(Device *self, void* nothing)
02588 {
02589         try
02590         {
02591                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
02592                 if(device)
02593                 {
02594                         AUD_Quaternion o = device->getListenerOrientation();
02595                         return Py_BuildValue("(ffff)", o.w(), o.x(), o.y(), o.z());
02596                 }
02597                 else
02598                 {
02599                         PyErr_SetString(AUDError, device_not_3d_error);
02600                 }
02601         }
02602         catch(AUD_Exception& e)
02603         {
02604                 PyErr_SetString(AUDError, e.str);
02605         }
02606 
02607         return NULL;
02608 }
02609 
02610 static int
02611 Device_set_listener_orientation(Device *self, PyObject* args, void* nothing)
02612 {
02613         float w, x, y, z;
02614 
02615         if(!PyArg_Parse(args, "(ffff):listener_orientation", &w, &x, &y, &z))
02616                 return -1;
02617 
02618         try
02619         {
02620                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
02621                 if(device)
02622                 {
02623                         AUD_Quaternion orientation(w, x, y, z);
02624                         device->setListenerOrientation(orientation);
02625                         return 0;
02626                 }
02627                 else
02628                         PyErr_SetString(AUDError, device_not_3d_error);
02629         }
02630         catch(AUD_Exception& e)
02631         {
02632                 PyErr_SetString(AUDError, e.str);
02633         }
02634 
02635         return -1;
02636 }
02637 
02638 PyDoc_STRVAR(M_aud_Device_speed_of_sound_doc,
02639                          "The speed of sound of the device.\n"
02640                          "The speed of sound in air is typically 343 m/s.");
02641 
02642 static PyObject *
02643 Device_get_speed_of_sound(Device *self, void* nothing)
02644 {
02645         try
02646         {
02647                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
02648                 if(device)
02649                 {
02650                         return Py_BuildValue("f", device->getSpeedOfSound());
02651                 }
02652                 else
02653                 {
02654                         PyErr_SetString(AUDError, device_not_3d_error);
02655                         return NULL;
02656                 }
02657         }
02658         catch(AUD_Exception& e)
02659         {
02660                 PyErr_SetString(AUDError, e.str);
02661                 return NULL;
02662         }
02663 }
02664 
02665 static int
02666 Device_set_speed_of_sound(Device *self, PyObject* args, void* nothing)
02667 {
02668         float speed;
02669 
02670         if(!PyArg_Parse(args, "f:speed_of_sound", &speed))
02671                 return -1;
02672 
02673         try
02674         {
02675                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
02676                 if(device)
02677                 {
02678                         device->setSpeedOfSound(speed);
02679                         return 0;
02680                 }
02681                 else
02682                         PyErr_SetString(AUDError, device_not_3d_error);
02683         }
02684         catch(AUD_Exception& e)
02685         {
02686                 PyErr_SetString(AUDError, e.str);
02687         }
02688 
02689         return -1;
02690 }
02691 
02692 PyDoc_STRVAR(M_aud_Device_doppler_factor_doc,
02693                          "The doppler factor of the device.\n"
02694                          "This factor is a scaling factor for the velocity vectors in "
02695                          "doppler calculation. So a value bigger than 1 will exaggerate "
02696                          "the effect as it raises the velocity.");
02697 
02698 static PyObject *
02699 Device_get_doppler_factor(Device *self, void* nothing)
02700 {
02701         try
02702         {
02703                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
02704                 if(device)
02705                 {
02706                         return Py_BuildValue("f", device->getDopplerFactor());
02707                 }
02708                 else
02709                 {
02710                         PyErr_SetString(AUDError, device_not_3d_error);
02711                         return NULL;
02712                 }
02713         }
02714         catch(AUD_Exception& e)
02715         {
02716                 PyErr_SetString(AUDError, e.str);
02717                 return NULL;
02718         }
02719 }
02720 
02721 static int
02722 Device_set_doppler_factor(Device *self, PyObject* args, void* nothing)
02723 {
02724         float factor;
02725 
02726         if(!PyArg_Parse(args, "f:doppler_factor", &factor))
02727                 return -1;
02728 
02729         try
02730         {
02731                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
02732                 if(device)
02733                 {
02734                         device->setDopplerFactor(factor);
02735                         return 0;
02736                 }
02737                 else
02738                         PyErr_SetString(AUDError, device_not_3d_error);
02739         }
02740         catch(AUD_Exception& e)
02741         {
02742                 PyErr_SetString(AUDError, e.str);
02743         }
02744 
02745         return -1;
02746 }
02747 
02748 PyDoc_STRVAR(M_aud_Device_distance_model_doc,
02749                          "The distance model of the device.\n\n"
02750                          ".. seealso:: http://connect.creativelabs.com/openal/Documentation/OpenAL%201.1%20Specification.htm#_Toc199835864");
02751 
02752 static PyObject *
02753 Device_get_distance_model(Device *self, void* nothing)
02754 {
02755         try
02756         {
02757                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
02758                 if(device)
02759                 {
02760                         return Py_BuildValue("i", int(device->getDistanceModel()));
02761                 }
02762                 else
02763                 {
02764                         PyErr_SetString(AUDError, device_not_3d_error);
02765                         return NULL;
02766                 }
02767         }
02768         catch(AUD_Exception& e)
02769         {
02770                 PyErr_SetString(AUDError, e.str);
02771                 return NULL;
02772         }
02773 }
02774 
02775 static int
02776 Device_set_distance_model(Device *self, PyObject* args, void* nothing)
02777 {
02778         int model;
02779 
02780         if(!PyArg_Parse(args, "i:distance_model", &model))
02781                 return -1;
02782 
02783         try
02784         {
02785                 AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
02786                 if(device)
02787                 {
02788                         device->setDistanceModel(AUD_DistanceModel(model));
02789                         return 0;
02790                 }
02791                 else
02792                         PyErr_SetString(AUDError, device_not_3d_error);
02793         }
02794         catch(AUD_Exception& e)
02795         {
02796                 PyErr_SetString(AUDError, e.str);
02797         }
02798 
02799         return -1;
02800 }
02801 
02802 static PyGetSetDef Device_properties[] = {
02803         {(char*)"rate", (getter)Device_get_rate, NULL,
02804          M_aud_Device_rate_doc, NULL },
02805         {(char*)"format", (getter)Device_get_format, NULL,
02806          M_aud_Device_format_doc, NULL },
02807         {(char*)"channels", (getter)Device_get_channels, NULL,
02808          M_aud_Device_channels_doc, NULL },
02809         {(char*)"volume", (getter)Device_get_volume, (setter)Device_set_volume,
02810          M_aud_Device_volume_doc, NULL },
02811         {(char*)"listener_location", (getter)Device_get_listener_location, (setter)Device_set_listener_location,
02812          M_aud_Device_listener_location_doc, NULL },
02813         {(char*)"listener_velocity", (getter)Device_get_listener_velocity, (setter)Device_set_listener_velocity,
02814          M_aud_Device_listener_velocity_doc, NULL },
02815         {(char*)"listener_orientation", (getter)Device_get_listener_orientation, (setter)Device_set_listener_orientation,
02816          M_aud_Device_listener_orientation_doc, NULL },
02817         {(char*)"speed_of_sound", (getter)Device_get_speed_of_sound, (setter)Device_set_speed_of_sound,
02818          M_aud_Device_speed_of_sound_doc, NULL },
02819         {(char*)"doppler_factor", (getter)Device_get_doppler_factor, (setter)Device_set_doppler_factor,
02820          M_aud_Device_doppler_factor_doc, NULL },
02821         {(char*)"distance_model", (getter)Device_get_distance_model, (setter)Device_set_distance_model,
02822          M_aud_Device_distance_model_doc, NULL },
02823         {NULL}  /* Sentinel */
02824 };
02825 
02826 PyDoc_STRVAR(M_aud_Device_doc,
02827                          "Device objects represent an audio output backend like OpenAL or "
02828                          "SDL, but might also represent a file output or RAM buffer "
02829                          "output.");
02830 
02831 static PyTypeObject DeviceType = {
02832         PyVarObject_HEAD_INIT(NULL, 0)
02833         "aud.Device",              /* tp_name */
02834         sizeof(Device),            /* tp_basicsize */
02835         0,                         /* tp_itemsize */
02836         (destructor)Device_dealloc,/* tp_dealloc */
02837         0,                         /* tp_print */
02838         0,                         /* tp_getattr */
02839         0,                         /* tp_setattr */
02840         0,                         /* tp_reserved */
02841         0,                         /* tp_repr */
02842         0,                         /* tp_as_number */
02843         0,                         /* tp_as_sequence */
02844         0,                         /* tp_as_mapping */
02845         0,                         /* tp_hash  */
02846         0,                         /* tp_call */
02847         0,                         /* tp_str */
02848         0,                         /* tp_getattro */
02849         0,                         /* tp_setattro */
02850         0,                         /* tp_as_buffer */
02851         Py_TPFLAGS_DEFAULT,        /* tp_flags */
02852         M_aud_Device_doc,          /* tp_doc */
02853         0,                                 /* tp_traverse */
02854         0,                                 /* tp_clear */
02855         0,                                 /* tp_richcompare */
02856         0,                                 /* tp_weaklistoffset */
02857         0,                                 /* tp_iter */
02858         0,                                 /* tp_iternext */
02859         Device_methods,            /* tp_methods */
02860         0,                         /* tp_members */
02861         Device_properties,         /* tp_getset */
02862         0,                         /* tp_base */
02863         0,                         /* tp_dict */
02864         0,                         /* tp_descr_get */
02865         0,                         /* tp_descr_set */
02866         0,                         /* tp_dictoffset */
02867         0,                         /* tp_init */
02868         0,                         /* tp_alloc */
02869         Device_new,                /* tp_new */
02870 };
02871 
02872 PyObject *
02873 Device_empty()
02874 {
02875         return DeviceType.tp_alloc(&DeviceType, 0);
02876 }
02877 
02878 // ====================================================================
02879 
02880 PyDoc_STRVAR(M_aud_doc,
02881                          "This module provides access to the audaspace audio library.");
02882 
02883 static struct PyModuleDef audmodule = {
02884         PyModuleDef_HEAD_INIT,
02885         "aud",     /* name of module */
02886         M_aud_doc, /* module documentation */
02887         -1,        /* size of per-interpreter state of the module,
02888                                   or -1 if the module keeps state in global variables. */
02889    NULL, NULL, NULL, NULL, NULL
02890 };
02891 
02892 PyMODINIT_FUNC
02893 PyInit_aud(void)
02894 {
02895         PyObject* m;
02896 
02897         if(PyType_Ready(&FactoryType) < 0)
02898                 return NULL;
02899 
02900         if(PyType_Ready(&DeviceType) < 0)
02901                 return NULL;
02902 
02903         if(PyType_Ready(&HandleType) < 0)
02904                 return NULL;
02905 
02906         m = PyModule_Create(&audmodule);
02907         if(m == NULL)
02908                 return NULL;
02909 
02910         Py_INCREF(&FactoryType);
02911         PyModule_AddObject(m, "Factory", (PyObject*)&FactoryType);
02912 
02913         Py_INCREF(&DeviceType);
02914         PyModule_AddObject(m, "Device", (PyObject*)&DeviceType);
02915 
02916         Py_INCREF(&HandleType);
02917         PyModule_AddObject(m, "Handle", (PyObject*)&HandleType);
02918 
02919         AUDError = PyErr_NewException("aud.error", NULL, NULL);
02920         Py_INCREF(AUDError);
02921         PyModule_AddObject(m, "error", AUDError);
02922 
02923         // device constants
02924         PY_MODULE_ADD_CONSTANT(m, AUD_DEVICE_NULL);
02925         PY_MODULE_ADD_CONSTANT(m, AUD_DEVICE_OPENAL);
02926         PY_MODULE_ADD_CONSTANT(m, AUD_DEVICE_SDL);
02927         PY_MODULE_ADD_CONSTANT(m, AUD_DEVICE_JACK);
02928         //PY_MODULE_ADD_CONSTANT(m, AUD_DEVICE_READ);
02929         // format constants
02930         PY_MODULE_ADD_CONSTANT(m, AUD_FORMAT_FLOAT32);
02931         PY_MODULE_ADD_CONSTANT(m, AUD_FORMAT_FLOAT64);
02932         PY_MODULE_ADD_CONSTANT(m, AUD_FORMAT_INVALID);
02933         PY_MODULE_ADD_CONSTANT(m, AUD_FORMAT_S16);
02934         PY_MODULE_ADD_CONSTANT(m, AUD_FORMAT_S24);
02935         PY_MODULE_ADD_CONSTANT(m, AUD_FORMAT_S32);
02936         PY_MODULE_ADD_CONSTANT(m, AUD_FORMAT_U8);
02937         // status constants
02938         PY_MODULE_ADD_CONSTANT(m, AUD_STATUS_INVALID);
02939         PY_MODULE_ADD_CONSTANT(m, AUD_STATUS_PAUSED);
02940         PY_MODULE_ADD_CONSTANT(m, AUD_STATUS_PLAYING);
02941         // distance model constants
02942         PY_MODULE_ADD_CONSTANT(m, AUD_DISTANCE_MODEL_EXPONENT);
02943         PY_MODULE_ADD_CONSTANT(m, AUD_DISTANCE_MODEL_EXPONENT_CLAMPED);
02944         PY_MODULE_ADD_CONSTANT(m, AUD_DISTANCE_MODEL_INVERSE);
02945         PY_MODULE_ADD_CONSTANT(m, AUD_DISTANCE_MODEL_INVERSE_CLAMPED);
02946         PY_MODULE_ADD_CONSTANT(m, AUD_DISTANCE_MODEL_LINEAR);
02947         PY_MODULE_ADD_CONSTANT(m, AUD_DISTANCE_MODEL_LINEAR_CLAMPED);
02948         PY_MODULE_ADD_CONSTANT(m, AUD_DISTANCE_MODEL_INVALID);
02949 
02950         return m;
02951 }