symbian-qemu-0.9.1-12/python-2.6.1/Modules/sunaudiodev.c
changeset 1 2fb8b9db1c86
--- /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 <fcntl.h>
+#endif
+
+#include <stropts.h>
+#include <sys/ioctl.h>
+#ifdef SOLARIS
+#include <sys/audioio.h>
+#else
+#include <sun/audioio.h>
+#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);
+}