| 
							- /************************************************************************/
 - /*  PyRtAudio: a python wrapper around RtAudio
 -     Copyright (c) 2011 Antoine Lefebvre
 - 
 -     Permission is hereby granted, free of charge, to any person
 -     obtaining a copy of this software and associated documentation files
 -     (the "Software"), to deal in the Software without restriction,
 -     including without limitation the rights to use, copy, modify, merge,
 -     publish, distribute, sublicense, and/or sell copies of the Software,
 -     and to permit persons to whom the Software is furnished to do so,
 -     subject to the following conditions:
 - 
 -     The above copyright notice and this permission notice shall be
 -     included in all copies or substantial portions of the Software.
 - 
 -     Any person wishing to distribute modifications to the Software is
 -     asked to send the modifications to the original developer so that
 -     they can be incorporated into the canonical version.  This is,
 -     however, not a binding provision of this license.
 - 
 -     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 -     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 -     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 -     IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
 -     ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
 -     CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 -     WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 - */
 - /************************************************************************/
 - 
 - // This software is in the development stage
 - // Do not expect compatibility with future versions.
 - // Comments, suggestions, new features, bug fixes, etc. are welcome
 - 
 - #include <Python.h>
 - 
 - #include "RtAudio.h" 
 - 
 - extern "C" {
 - 
 -     typedef struct 
 -     {
 -         PyObject_HEAD;
 -         RtAudio *dac;
 -         RtAudioFormat _format;
 -         int _bufferSize;
 -         unsigned int inputChannels;
 -         PyObject *callback_func;
 -     } PyRtAudio;
 - 
 -     static PyObject *RtAudioError;
 - 
 -     static int callback(void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames,
 -         double streamTime, RtAudioStreamStatus status, void *data )
 -     {
 -         PyRtAudio* self = (PyRtAudio*) data;
 - 
 -         if (status == RTAUDIO_OUTPUT_UNDERFLOW)
 -             printf("underflow.\n");
 - 
 -         if (self == NULL) return -1;
 - 
 -         float* in = (float *) inputBuffer;
 -         float* out = (float *) outputBuffer;
 - 
 -         PyObject *py_callback_func = self->callback_func;
 - 
 -         int retval = 0;
 - 
 -         if (py_callback_func) {
 -             PyGILState_STATE gstate = PyGILState_Ensure();
 - 
 -             PyObject* iBuffer = PyBuffer_FromMemory(in, sizeof(float) * self->inputChannels * nBufferFrames);
 -             PyObject* oBuffer = PyBuffer_FromReadWriteMemory(out, sizeof(float) * nBufferFrames);
 -             PyObject *arglist =  Py_BuildValue("(O,O)", oBuffer, iBuffer);
 - 
 -             if (arglist == NULL) {
 -                 printf("error.\n");
 -                 PyErr_Print();
 -                 PyGILState_Release(gstate);
 -                 return 2;
 -             }
 - 
 -             // Calling the callback
 -             PyObject *result = PyEval_CallObject(py_callback_func, arglist);
 - 
 -             if (PyErr_Occurred() != NULL) {
 -                 PyErr_Print();
 -             }
 -             else if PyInt_Check(result) {
 -               retval = PyInt_AsLong(result);
 -             }
 -             
 -             Py_DECREF(arglist);
 -             Py_DECREF(oBuffer);
 -             Py_DECREF(iBuffer);
 -             Py_XDECREF(result);
 - 
 -             PyGILState_Release(gstate);            
 -         }
 - 
 -         return retval;
 -     }
 - 
 - 
 - 
 -     static void RtAudio_dealloc(PyRtAudio *self)
 -     {
 -         printf("RtAudio_dealloc.\n");
 -         if (self == NULL) return;
 - 
 -         if (self->dac) {
 -             self->dac->closeStream();
 -             Py_CLEAR(self->callback_func);
 -             delete self->dac;
 -         }
 - 
 -         self->ob_type->tp_free((PyObject *) self);
 -     }
 - 
 - 
 -     static PyObject* RtAudio_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 -     {
 -         printf("RtAudio_new.\n");
 -         PyRtAudio *self;
 -         char *api = NULL;
 - 
 -         if(!PyArg_ParseTuple(args, "|s", &api))
 -             return NULL;
 - 
 -         self = (PyRtAudio *) type->tp_alloc(type, 0);
 - 
 -         if(self == NULL) return NULL;
 - 
 -         self->dac = NULL;
 -         self->callback_func = NULL;
 - 
 -         try {
 -             if (api == NULL)
 -                 self->dac = new RtAudio;
 -             else if(!strcmp(api, "jack"))
 -                 self->dac = new RtAudio(RtAudio::UNIX_JACK);
 -             else if(!strcmp(api, "alsa"))
 -                 self->dac = new RtAudio(RtAudio::LINUX_ALSA);
 -             else if(!strcmp(api, "oss"))
 -                 self->dac = new RtAudio(RtAudio::LINUX_ALSA);
 -             else if(!strcmp(api, "core"))
 -                 self->dac = new RtAudio(RtAudio::MACOSX_CORE);
 -             else if(!strcmp(api, "asio"))
 -                 self->dac = new RtAudio(RtAudio::WINDOWS_ASIO);
 -             else if(!strcmp(api, "directsound"))
 -                 self->dac = new RtAudio(RtAudio::WINDOWS_DS);
 -         }
 -         catch (RtError &error) {
 -             PyErr_SetString(RtAudioError, error.getMessage().c_str());
 -             Py_INCREF(RtAudioError);
 -             return NULL;
 -         }
 - 
 -         self->dac->showWarnings(false);
 - 
 -         //Py_XINCREF(self);
 -         return (PyObject *) self;
 -     }
 - 
 -     static int RtAudio_init(PyRtAudio *self, PyObject *args, PyObject *kwds)
 -     {
 -         printf("RtAudio_init.\n");
 -         //if (self == NULL) return 0;
 -         return 0;
 -     }
 - 
 -     // This functions does not yet support all the features of the RtAudio::openStream method.
 -     // Please send your patches if you improves this.
 -     static PyObject* RtAudio_openStream(PyRtAudio *self, PyObject *args)
 -     {
 -         if (self == NULL) return NULL;
 - 
 -         if (self->dac == NULL) {
 -             printf("the dac is null.\n");
 -             Py_RETURN_NONE;
 -         }
 - 
 -         PyObject *oParamsObj;
 -         PyObject *iParamsObj;
 -         int fs;
 -         unsigned int bf;
 -         PyObject *pycallback;
 - 
 -         if (!PyArg_ParseTuple(args, "OOiiO", &oParamsObj, &iParamsObj, &fs, &bf, &pycallback)) 
 -             return NULL;
 - 
 -         RtAudio::StreamParameters oParams;
 -         oParams.deviceId = 1;
 -         oParams.nChannels = 1;
 -         oParams.firstChannel = 0;
 - 
 -         if (PyDict_Check(oParamsObj)) {
 -             if (PyDict_Contains(oParamsObj, PyString_FromString("deviceId"))) {
 -                 PyObject *value = PyDict_GetItem(oParamsObj, PyString_FromString("deviceId"));
 -                 oParams.deviceId = PyInt_AsLong(value);
 -             }
 -             if (PyDict_Contains(oParamsObj, PyString_FromString("nChannels"))) {
 -                 PyObject *value = PyDict_GetItem(oParamsObj, PyString_FromString("nChannels"));
 -                 oParams.nChannels = PyInt_AsLong(value);
 -             }
 -             if (PyDict_Contains(oParamsObj, PyString_FromString("firstChannel"))) {
 -                 PyObject *value = PyDict_GetItem(oParamsObj, PyString_FromString("firstChannel"));
 -                 oParams.firstChannel = PyInt_AsLong(value);
 -             }
 -         }
 -         else {
 -             printf("First argument must be a dictionary. Default values will be used.\n");
 -         }
 - 
 -         RtAudio::StreamParameters iParams;
 -         iParams.deviceId = 1;
 -         iParams.nChannels = 2;
 -         iParams.firstChannel = 0;
 - 
 -         if (PyDict_Check(iParamsObj)) {
 -             if (PyDict_Contains(iParamsObj, PyString_FromString("deviceId"))) {
 -                 PyObject *value = PyDict_GetItem(iParamsObj, PyString_FromString("deviceId"));
 -                 iParams.deviceId = PyInt_AsLong(value);
 -             }
 -             if (PyDict_Contains(iParamsObj, PyString_FromString("nChannels"))) {
 -                 PyObject *value = PyDict_GetItem(iParamsObj, PyString_FromString("nChannels"));
 -                 iParams.nChannels = PyInt_AsLong(value);
 -             }
 -             if (PyDict_Contains(iParamsObj, PyString_FromString("firstChannel"))) {
 -                 PyObject *value = PyDict_GetItem(iParamsObj, PyString_FromString("firstChannel"));
 -                 iParams.firstChannel = PyInt_AsLong(value);
 -             }
 -         }
 -         else {
 -             printf("Second argument must be a dictionary. Default values will be used.\n");
 -         }
 - 
 - 
 -         if (!PyCallable_Check(pycallback)) {
 -             PyErr_SetString(PyExc_TypeError, "Need a callable object!");
 -             Py_XINCREF(PyExc_TypeError);
 -             return NULL;
 -         }
 - 
 -         // sanity check the callback ?
 - 
 - 
 -         Py_INCREF(pycallback);         /* Add a reference to new callback */
 -         self->callback_func = pycallback; /*Remember new callback */
 - 
 -         // add support for other format
 -         self->_format = RTAUDIO_FLOAT32;
 - 
 -         // add support for other options
 -         RtAudio::StreamOptions options;
 -         options.flags = RTAUDIO_NONINTERLEAVED;
 - 
 -         try {
 -             if (self->dac->isStreamOpen())
 -                 self->dac->closeStream();
 -             self->dac->openStream(&oParams, &iParams, self->_format, fs, &bf, &callback, self, &options);
 -         }
 -         catch ( RtError& error ) {
 -             PyErr_SetString(RtAudioError, error.getMessage().c_str());
 -             Py_INCREF(RtAudioError);
 -             return NULL;
 -         }
 - 
 -         self->inputChannels = iParams.nChannels;
 - 
 -         Py_RETURN_NONE;
 -     }
 - 
 -     static PyObject* RtAudio_closeStream(PyRtAudio *self, PyObject *args)
 -     {
 -         printf("RtAudio_closeStream.\n");
 -         if (self == NULL || self->dac == NULL) return NULL;
 - 
 -         try {
 -             self->dac->closeStream();
 -             Py_CLEAR(self->callback_func);
 -         }
 -         catch(RtError &error) {
 -             PyErr_SetString(RtAudioError, error.getMessage().c_str());
 -             Py_INCREF(RtAudioError);
 -             return NULL;
 -         }
 - 
 -         Py_RETURN_NONE;
 -     }
 - 
 -     static PyObject* RtAudio_startStream(PyRtAudio *self, PyObject *args)
 -     {
 -         if (self == NULL || self->dac == NULL) return NULL;
 - 
 -         try {
 -             self->dac->startStream();
 -         }
 -         catch(RtError &error) {
 -             PyErr_SetString(RtAudioError, error.getMessage().c_str());
 -             Py_INCREF(RtAudioError);
 -             return NULL;
 -         }
 - 
 -         Py_RETURN_NONE;
 -     }
 - 
 - 
 -     static PyObject* RtAudio_stopStream(PyRtAudio *self, PyObject *args)
 -     {
 -         printf("RtAudio_stopStream.\n");
 -         if (self == NULL || self->dac == NULL) return NULL;
 - 
 -         try {
 -             self->dac->stopStream();
 -         }
 -         catch(RtError &error) {
 -             PyErr_SetString(RtAudioError, error.getMessage().c_str());
 -             Py_INCREF(RtAudioError);
 -             return NULL;
 -         }
 - 
 -         Py_RETURN_NONE;
 -     }
 - 
 -     static PyObject* RtAudio_abortStream(PyRtAudio *self, PyObject *args)
 -     {
 -         printf("RtAudio_abortStream.\n");
 -         if (self == NULL || self->dac == NULL) return NULL;
 - 
 -         try {
 -             self->dac->abortStream();
 -         }
 -         catch(RtError &error) {
 -             PyErr_SetString(RtAudioError, error.getMessage().c_str());
 -             Py_INCREF(RtAudioError);
 -             return NULL;
 -         }
 -         Py_RETURN_NONE;
 -     }
 - 
 -     static PyObject* RtAudio_isStreamRunning(PyRtAudio *self, PyObject *args)
 -     {
 -        if (self == NULL || self->dac == NULL) return NULL;
 - 
 -        if (self->dac == NULL) {
 -             Py_RETURN_FALSE;
 -         }
 -         if (self->dac->isStreamRunning())
 -             Py_RETURN_TRUE;
 -         else
 -             Py_RETURN_FALSE;
 -     }
 - 
 -     static PyObject* RtAudio_isStreamOpen(PyRtAudio *self, PyObject *args)
 -     {
 -         if (self == NULL || self->dac == NULL) return NULL;
 - 
 -         if (self->dac == NULL) {
 -             Py_RETURN_FALSE;
 -         }
 -         if (self->dac->isStreamOpen())
 -             Py_RETURN_TRUE;
 -         else
 -             Py_RETURN_FALSE;
 - 
 -     }
 - 
 -     static PyObject* RtAudio_getDeviceCount(PyRtAudio *self, PyObject *args)
 -     {
 -         if (self == NULL || self->dac == NULL) return NULL;
 - 
 -         return PyInt_FromLong(self->dac->getDeviceCount());
 -     }
 - 
 -     static PyObject* RtAudio_getDeviceInfo(PyRtAudio *self, PyObject *args)
 -     {
 -         if (self == NULL || self->dac == NULL) return NULL;
 - 
 -         int device;
 -         if (!PyArg_ParseTuple(args, "i", &device))
 -             return NULL;
 - 
 -         try {
 -             RtAudio::DeviceInfo info = self->dac->getDeviceInfo(device);
 - 
 -             PyObject* info_dict = PyDict_New();
 - 
 -             if (info.probed) {
 -                 Py_INCREF(Py_True);
 -                 PyDict_SetItemString(info_dict, "probed", Py_True);
 -             }
 -             else {
 -                 Py_INCREF(Py_False);
 -                 PyDict_SetItemString(info_dict, "probed", Py_False);
 -             }
 -             PyObject* obj;
 - 
 -             obj = PyString_FromString(info.name.c_str());
 -             PyDict_SetItemString(info_dict, "name", obj);
 - 
 -             obj = PyInt_FromLong(info.outputChannels);
 -             PyDict_SetItemString(info_dict, "outputChannels", obj);
 - 
 -             obj = PyInt_FromLong(info.inputChannels);
 -             PyDict_SetItemString(info_dict, "inputChannels", obj);
 - 
 -             obj = PyInt_FromLong(info.duplexChannels);
 -             PyDict_SetItemString(info_dict, "duplexChannels", obj);
 - 
 -             if (info.isDefaultOutput) {
 -                 Py_INCREF(Py_True);
 -                 PyDict_SetItemString(info_dict, "isDefaultOutput", Py_True);
 -             }
 -             else {
 -                 Py_INCREF(Py_False);
 -                 PyDict_SetItemString(info_dict, "isDefaultOutput", Py_False);
 -             }
 - 
 -             if (info.isDefaultInput) {
 -                 Py_INCREF(Py_True);
 -                 PyDict_SetItemString(info_dict, "isDefaultInput", Py_True);
 -             }
 -             else {
 -                 Py_INCREF(Py_False);
 -                 PyDict_SetItemString(info_dict, "isDefaultInput", Py_False);
 -             }
 - 
 -             return info_dict;
 - 
 -         }
 -         catch(RtError &error) {
 -             PyErr_SetString(RtAudioError, error.getMessage().c_str());
 -             Py_INCREF(RtAudioError);
 -             return NULL;
 -         }
 -     }
 - 
 -     static PyObject* RtAudio_getDefaultOutputDevice(PyRtAudio *self, PyObject *args)
 -     {
 -         if (self == NULL || self->dac == NULL) return NULL;
 -         return PyInt_FromLong(self->dac->getDefaultOutputDevice());
 -     }
 - 
 -     static PyObject* RtAudio_getDefaultInputDevice(PyRtAudio *self, PyObject *args)
 -     {
 -         if (self == NULL || self->dac == NULL) return NULL;
 -         return PyInt_FromLong(self->dac->getDefaultInputDevice());
 -     }
 - 
 -     static PyObject* RtAudio_getStreamTime(PyRtAudio *self, PyObject *args)
 -     {
 -         if (self == NULL || self->dac == NULL) return NULL;
 -         return PyFloat_FromDouble( self->dac->getStreamTime() );
 -     }
 - 
 -     static PyObject* RtAudio_getStreamLatency(PyRtAudio *self, PyObject *args)
 -     {
 -         if (self == NULL || self->dac == NULL) return NULL;
 -         return PyInt_FromLong( self->dac->getStreamLatency() );
 -     }
 - 
 -     static PyObject* RtAudio_getStreamSampleRate(PyRtAudio *self, PyObject *args)
 -     {
 -         if (self == NULL || self->dac == NULL) return NULL;
 -         return PyInt_FromLong( self->dac->getStreamSampleRate() );
 -     }
 - 
 -     static PyObject* RtAudio_showWarnings(PyRtAudio *self, PyObject *args)
 -     {
 -         if (self == NULL || self->dac == NULL) return NULL;
 - 
 -         PyObject *obj;
 -         if (!PyArg_ParseTuple(args, "O", &obj))
 -             return NULL;
 - 
 -         if (!PyBool_Check(obj))
 -             return NULL;
 - 
 -         if (obj == Py_True)
 -             self->dac->showWarnings(true);
 -         else if (obj == Py_False)
 -             self->dac->showWarnings(false);
 -         else {
 -             printf("not true nor false\n");
 -         }
 -         Py_RETURN_NONE;
 -     }
 - 
 - 
 -     static PyMethodDef RtAudio_methods[] = 
 -     {
 -         // TO BE DONE: getCurrentApi(void)
 -         {"getDeviceCount", (PyCFunction) RtAudio_getDeviceCount, METH_NOARGS,
 -         "A public function that queries for the number of audio devices available."},
 -         {"getDeviceInfo", (PyCFunction) RtAudio_getDeviceInfo, METH_VARARGS,
 -         "Return a dictionary with information for a specified device number."},
 -         {"getDefaultOutputDevice", (PyCFunction) RtAudio_getDefaultOutputDevice, METH_NOARGS,
 -         "A function that returns the index of the default output device."},
 -         {"getDefaultInputDevice", (PyCFunction) RtAudio_getDefaultInputDevice, METH_NOARGS,
 -         "A function that returns the index of the default input device."},
 -         {"openStream", (PyCFunction) RtAudio_openStream, METH_VARARGS,
 -         "A public method for opening a stream with the specified parameters."},
 -         {"closeStream", (PyCFunction) RtAudio_closeStream, METH_NOARGS,
 -         "A function that closes a stream and frees any associated stream memory. "},
 -         {"startStream", (PyCFunction) RtAudio_startStream, METH_NOARGS,
 -         "A function that starts a stream. "},
 -         {"stopStream", (PyCFunction) RtAudio_stopStream, METH_NOARGS,
 -         "Stop a stream, allowing any samples remaining in the output queue to be played. "},
 -         {"abortStream", (PyCFunction) RtAudio_abortStream, METH_NOARGS,
 -         "Stop a stream, discarding any samples remaining in the input/output queue."},
 -         {"isStreamOpen", (PyCFunction) RtAudio_isStreamOpen, METH_NOARGS,
 -         "Returns true if a stream is open and false if not."},
 -         {"isStreamRunning", (PyCFunction) RtAudio_isStreamRunning, METH_NOARGS,
 -         "Returns true if the stream is running and false if it is stopped or not open."},
 -         {"getStreamTime", (PyCFunction) RtAudio_getStreamTime, METH_NOARGS,
 -         "Returns the number of elapsed seconds since the stream was started."},
 -         {"getStreamLatency", (PyCFunction) RtAudio_getStreamLatency, METH_NOARGS,
 -         "Returns the internal stream latency in sample frames."},
 -         {"getStreamSampleRate", (PyCFunction) RtAudio_getStreamSampleRate, METH_NOARGS,
 -         "Returns actual sample rate in use by the stream."},
 -         {"showWarnings", (PyCFunction) RtAudio_showWarnings, METH_VARARGS,
 -         "Specify whether warning messages should be printed to stderr."},
 -         // TO BE DONE: getCompiledApi (std::vector< RtAudio::Api > &apis) throw ()
 -         {NULL}
 -     };
 - 
 - 
 -     static PyTypeObject RtAudio_type = {
 -         PyObject_HEAD_INIT(NULL)
 -         0,                         /*ob_size*/
 -         "rtaudio.RtAudio",             /*tp_name*/
 -         sizeof(RtAudio), /*tp_basicsize*/
 -         0,                         /*tp_itemsize*/
 -         (destructor) RtAudio_dealloc,                         /*tp_dealloc*/
 -         0,                         /*tp_print*/
 -         0,                         /*tp_getattr*/
 -         0,                         /*tp_setattr*/
 -         0,                         /*tp_compare*/
 -         0,                         /*tp_repr*/
 -         0,                         /*tp_as_number*/
 -         0,                         /*tp_as_sequence*/
 -         0,                         /*tp_as_mapping*/
 -         0,                         /*tp_hash */
 -         0,                         /*tp_call*/
 -         0,                         /*tp_str*/
 -         0,                         /*tp_getattro*/
 -         0,                         /*tp_setattro*/
 -         0,                         /*tp_as_buffer*/
 -         Py_TPFLAGS_DEFAULT,        /*tp_flags*/
 -         "Audio input device",           /* tp_doc */
 -         0,               /* tp_traverse */
 -         0,               /* tp_clear */
 -         0,               /* tp_richcompare */
 -         0,               /* tp_weaklistoffset */
 -         0,               /* tp_iter */
 -         0,               /* tp_iternext */
 -         RtAudio_methods,             /* tp_methods */
 -         0,              /* tp_members */
 -         0,                         /* tp_getset */
 -         0,                         /* tp_base */
 -         0,                         /* tp_dict */
 -         0,                         /* tp_descr_get */
 -         0,                         /* tp_descr_set */
 -         0,                         /* tp_dictoffset */
 -         (initproc)RtAudio_init,      /* tp_init */
 -         0,                         /* tp_alloc */
 -         RtAudio_new,                 /* tp_new */
 -         0, /* Low-level free-memory routine */
 - 	    0, /* For PyObject_IS_GC */
 - 	    0, // PyObject *tp_bases;
 - 	    0, // PyObject *tp_mro; /* method resolution order */
 - 	    0, //PyObject *tp_cache;
 - 	    0, //PyObject *tp_subclasses;
 - 	    0, //PyObject *tp_weaklist;
 - 	    0, //destructor tp_del;
 -         //0,	/* Type attribute cache version tag. Added in version 2.6 */
 -     };
 - 
 - 
 - 
 - #ifndef PyMODINIT_FUNC	/* declarations for DLL import/export */
 - #define PyMODINIT_FUNC void
 - #endif
 -     PyMODINIT_FUNC
 -     initrtaudio(void) 
 -     {
 -         PyEval_InitThreads();
 - 
 -         if (PyType_Ready(&RtAudio_type) < 0)
 -             return;
 - 
 -         PyObject* module = Py_InitModule3("rtaudio", NULL, "RtAudio wrapper.");
 -         if (module == NULL)
 -             return;
 - 
 -         Py_INCREF(&RtAudio_type);
 -         PyModule_AddObject(module, "RtAudio", (PyObject *)&RtAudio_type);
 - 
 -         RtAudioError = PyErr_NewException("rtaudio.RtError", NULL, NULL);
 -         Py_INCREF(RtAudioError);
 -         PyModule_AddObject(module, "RtError", RtAudioError);
 -     }
 - }
 
 
  |