diff -r ffa851df0825 -r 2fb8b9db1c86 symbian-qemu-0.9.1-12/python-2.6.1/Modules/sunaudiodev.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/symbian-qemu-0.9.1-12/python-2.6.1/Modules/sunaudiodev.c Fri Jul 31 15:01:17 2009 +0100 @@ -0,0 +1,467 @@ + +/* Sad objects */ + +#include "Python.h" +#include "structmember.h" + +#ifdef HAVE_SYS_AUDIOIO_H +#define SOLARIS +#endif + +#ifdef HAVE_FCNTL_H +#include +#endif + +#include +#include +#ifdef SOLARIS +#include +#else +#include +#endif + +/* #define offsetof(str,mem) ((int)(((str *)0)->mem)) */ + +typedef struct { + PyObject_HEAD + int x_fd; /* The open file */ + int x_icount; /* # samples read */ + int x_ocount; /* # samples written */ + int x_isctl; /* True if control device */ + +} sadobject; + +typedef struct { + PyObject_HEAD + audio_info_t ai; +} sadstatusobject; + +static PyTypeObject Sadtype; +static PyTypeObject Sadstatustype; +static sadstatusobject *sads_alloc(void); /* Forward */ + +static PyObject *SunAudioError; + +#define is_sadobject(v) (Py_TYPE(v) == &Sadtype) +#define is_sadstatusobject(v) (Py_TYPE(v) == &Sadstatustype) + + +static sadobject * +newsadobject(PyObject *args) +{ + sadobject *xp; + int fd; + char *mode; + int imode; + char* basedev; + char* ctldev; + char* opendev; + + /* Check arg for r/w/rw */ + if (!PyArg_ParseTuple(args, "s", &mode)) + return NULL; + if (strcmp(mode, "r") == 0) + imode = 0; + else if (strcmp(mode, "w") == 0) + imode = 1; + else if (strcmp(mode, "rw") == 0) + imode = 2; + else if (strcmp(mode, "control") == 0) + imode = -1; + else { + PyErr_SetString(SunAudioError, + "Mode should be one of 'r', 'w', 'rw' or 'control'"); + return NULL; + } + + /* Open the correct device. The base device name comes from the + * AUDIODEV environment variable first, then /dev/audio. The + * control device tacks "ctl" onto the base device name. + */ + basedev = getenv("AUDIODEV"); + if (!basedev) + basedev = "/dev/audio"; + ctldev = PyMem_NEW(char, strlen(basedev) + 4); + if (!ctldev) { + PyErr_NoMemory(); + return NULL; + } + strcpy(ctldev, basedev); + strcat(ctldev, "ctl"); + + if (imode < 0) { + opendev = ctldev; + fd = open(ctldev, 2); + } + else { + opendev = basedev; + fd = open(basedev, imode); + } + if (fd < 0) { + PyErr_SetFromErrnoWithFilename(SunAudioError, opendev); + PyMem_DEL(ctldev); + return NULL; + } + PyMem_DEL(ctldev); + + /* Create and initialize the object */ + xp = PyObject_New(sadobject, &Sadtype); + if (xp == NULL) { + close(fd); + return NULL; + } + xp->x_fd = fd; + xp->x_icount = xp->x_ocount = 0; + xp->x_isctl = (imode < 0); + + return xp; +} + +/* Sad methods */ + +static void +sad_dealloc(sadobject *xp) +{ + close(xp->x_fd); + PyObject_Del(xp); +} + +static PyObject * +sad_read(sadobject *self, PyObject *args) +{ + int size, count; + char *cp; + PyObject *rv; + + if (!PyArg_ParseTuple(args, "i:read", &size)) + return NULL; + rv = PyString_FromStringAndSize(NULL, size); + if (rv == NULL) + return NULL; + + if (!(cp = PyString_AsString(rv))) + goto finally; + + count = read(self->x_fd, cp, size); + if (count < 0) { + PyErr_SetFromErrno(SunAudioError); + goto finally; + } +#if 0 + /* TBD: why print this message if you can handle the condition? + * assume it's debugging info which we can just as well get rid + * of. in any case this message should *not* be using printf! + */ + if (count != size) + printf("sunaudio: funny read rv %d wtd %d\n", count, size); +#endif + self->x_icount += count; + return rv; + + finally: + Py_DECREF(rv); + return NULL; +} + +static PyObject * +sad_write(sadobject *self, PyObject *args) +{ + char *cp; + int count, size; + + if (!PyArg_ParseTuple(args, "s#:write", &cp, &size)) + return NULL; + + count = write(self->x_fd, cp, size); + if (count < 0) { + PyErr_SetFromErrno(SunAudioError); + return NULL; + } +#if 0 + if (count != size) + printf("sunaudio: funny write rv %d wanted %d\n", count, size); +#endif + self->x_ocount += count; + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +sad_getinfo(sadobject *self) +{ + sadstatusobject *rv; + + if (!(rv = sads_alloc())) + return NULL; + + if (ioctl(self->x_fd, AUDIO_GETINFO, &rv->ai) < 0) { + PyErr_SetFromErrno(SunAudioError); + Py_DECREF(rv); + return NULL; + } + return (PyObject *)rv; +} + +static PyObject * +sad_setinfo(sadobject *self, sadstatusobject *arg) +{ + if (!is_sadstatusobject(arg)) { + PyErr_SetString(PyExc_TypeError, + "Must be sun audio status object"); + return NULL; + } + if (ioctl(self->x_fd, AUDIO_SETINFO, &arg->ai) < 0) { + PyErr_SetFromErrno(SunAudioError); + return NULL; + } + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +sad_ibufcount(sadobject *self) +{ + audio_info_t ai; + + if (ioctl(self->x_fd, AUDIO_GETINFO, &ai) < 0) { + PyErr_SetFromErrno(SunAudioError); + return NULL; + } + return PyInt_FromLong(ai.record.samples - self->x_icount); +} + +static PyObject * +sad_obufcount(sadobject *self) +{ + audio_info_t ai; + + if (ioctl(self->x_fd, AUDIO_GETINFO, &ai) < 0) { + PyErr_SetFromErrno(SunAudioError); + return NULL; + } + /* x_ocount is in bytes, whereas play.samples is in frames */ + /* we want frames */ + return PyInt_FromLong(self->x_ocount / (ai.play.channels * + ai.play.precision / 8) - + ai.play.samples); +} + +static PyObject * +sad_drain(sadobject *self) +{ + if (ioctl(self->x_fd, AUDIO_DRAIN, 0) < 0) { + PyErr_SetFromErrno(SunAudioError); + return NULL; + } + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef SOLARIS +static PyObject * +sad_getdev(sadobject *self) +{ + struct audio_device ad; + + if (ioctl(self->x_fd, AUDIO_GETDEV, &ad) < 0) { + PyErr_SetFromErrno(SunAudioError); + return NULL; + } + return Py_BuildValue("(sss)", ad.name, ad.version, ad.config); +} +#endif + +static PyObject * +sad_flush(sadobject *self) +{ + if (ioctl(self->x_fd, I_FLUSH, FLUSHW) < 0) { + PyErr_SetFromErrno(SunAudioError); + return NULL; + } + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +sad_close(sadobject *self) +{ + + if (self->x_fd >= 0) { + close(self->x_fd); + self->x_fd = -1; + } + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +sad_fileno(sadobject *self) +{ + return PyInt_FromLong(self->x_fd); +} + + +static PyMethodDef sad_methods[] = { + { "read", (PyCFunction)sad_read, METH_VARARGS }, + { "write", (PyCFunction)sad_write, METH_VARARGS }, + { "ibufcount", (PyCFunction)sad_ibufcount, METH_NOARGS }, + { "obufcount", (PyCFunction)sad_obufcount, METH_NOARGS }, +#define CTL_METHODS 4 + { "getinfo", (PyCFunction)sad_getinfo, METH_NOARGS }, + { "setinfo", (PyCFunction)sad_setinfo, METH_O}, + { "drain", (PyCFunction)sad_drain, METH_NOARGS }, + { "flush", (PyCFunction)sad_flush, METH_NOARGS }, +#ifdef SOLARIS + { "getdev", (PyCFunction)sad_getdev, METH_NOARGS }, +#endif + { "close", (PyCFunction)sad_close, METH_NOARGS }, + { "fileno", (PyCFunction)sad_fileno, METH_NOARGS }, + {NULL, NULL} /* sentinel */ +}; + +static PyObject * +sad_getattr(sadobject *xp, char *name) +{ + if (xp->x_isctl) + return Py_FindMethod(sad_methods+CTL_METHODS, + (PyObject *)xp, name); + else + return Py_FindMethod(sad_methods, (PyObject *)xp, name); +} + +/* ----------------------------------------------------------------- */ + +static sadstatusobject * +sads_alloc(void) { + return PyObject_New(sadstatusobject, &Sadstatustype); +} + +static void +sads_dealloc(sadstatusobject *xp) +{ + PyMem_DEL(xp); +} + +#define OFF(x) offsetof(audio_info_t,x) +static struct memberlist sads_ml[] = { + { "i_sample_rate", T_UINT, OFF(record.sample_rate) }, + { "i_channels", T_UINT, OFF(record.channels) }, + { "i_precision", T_UINT, OFF(record.precision) }, + { "i_encoding", T_UINT, OFF(record.encoding) }, + { "i_gain", T_UINT, OFF(record.gain) }, + { "i_port", T_UINT, OFF(record.port) }, + { "i_samples", T_UINT, OFF(record.samples) }, + { "i_eof", T_UINT, OFF(record.eof) }, + { "i_pause", T_UBYTE, OFF(record.pause) }, + { "i_error", T_UBYTE, OFF(record.error) }, + { "i_waiting", T_UBYTE, OFF(record.waiting) }, + { "i_open", T_UBYTE, OFF(record.open) , RO}, + { "i_active", T_UBYTE, OFF(record.active) , RO}, +#ifdef SOLARIS + { "i_buffer_size", T_UINT, OFF(record.buffer_size) }, + { "i_balance", T_UBYTE, OFF(record.balance) }, + { "i_avail_ports", T_UINT, OFF(record.avail_ports) }, +#endif + + { "o_sample_rate", T_UINT, OFF(play.sample_rate) }, + { "o_channels", T_UINT, OFF(play.channels) }, + { "o_precision", T_UINT, OFF(play.precision) }, + { "o_encoding", T_UINT, OFF(play.encoding) }, + { "o_gain", T_UINT, OFF(play.gain) }, + { "o_port", T_UINT, OFF(play.port) }, + { "o_samples", T_UINT, OFF(play.samples) }, + { "o_eof", T_UINT, OFF(play.eof) }, + { "o_pause", T_UBYTE, OFF(play.pause) }, + { "o_error", T_UBYTE, OFF(play.error) }, + { "o_waiting", T_UBYTE, OFF(play.waiting) }, + { "o_open", T_UBYTE, OFF(play.open) , RO}, + { "o_active", T_UBYTE, OFF(play.active) , RO}, +#ifdef SOLARIS + { "o_buffer_size", T_UINT, OFF(play.buffer_size) }, + { "o_balance", T_UBYTE, OFF(play.balance) }, + { "o_avail_ports", T_UINT, OFF(play.avail_ports) }, +#endif + + { "monitor_gain", T_UINT, OFF(monitor_gain) }, + { NULL, 0, 0}, +}; + +static PyObject * +sads_getattr(sadstatusobject *xp, char *name) +{ + return PyMember_Get((char *)&xp->ai, sads_ml, name); +} + +static int +sads_setattr(sadstatusobject *xp, char *name, PyObject *v) +{ + + if (v == NULL) { + PyErr_SetString(PyExc_TypeError, + "can't delete sun audio status attributes"); + return -1; + } + return PyMember_Set((char *)&xp->ai, sads_ml, name, v); +} + +/* ------------------------------------------------------------------- */ + + +static PyTypeObject Sadtype = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "sunaudiodev.sun_audio_device", /*tp_name*/ + sizeof(sadobject), /*tp_size*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor)sad_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + (getattrfunc)sad_getattr, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ +}; + +static PyTypeObject Sadstatustype = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "sunaudiodev.sun_audio_device_status", /*tp_name*/ + sizeof(sadstatusobject), /*tp_size*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor)sads_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + (getattrfunc)sads_getattr, /*tp_getattr*/ + (setattrfunc)sads_setattr, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ +}; +/* ------------------------------------------------------------------- */ + +static PyObject * +sadopen(PyObject *self, PyObject *args) +{ + return (PyObject *)newsadobject(args); +} + +static PyMethodDef sunaudiodev_methods[] = { + { "open", sadopen, METH_VARARGS }, + { 0, 0 }, +}; + +void +initsunaudiodev(void) +{ + PyObject *m, *d; + + if (PyErr_WarnPy3k("the sunaudiodev module has been removed in " + "Python 3.0", 2) < 0) + return; + + m = Py_InitModule("sunaudiodev", sunaudiodev_methods); + if (m == NULL) + return; + d = PyModule_GetDict(m); + SunAudioError = PyErr_NewException("sunaudiodev.error", NULL, NULL); + if (SunAudioError) + PyDict_SetItemString(d, "error", SunAudioError); +}