symbian-qemu-0.9.1-12/python-2.6.1/Modules/sunaudiodev.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 
       
     2 /* Sad objects */
       
     3 
       
     4 #include "Python.h"
       
     5 #include "structmember.h"
       
     6 
       
     7 #ifdef HAVE_SYS_AUDIOIO_H
       
     8 #define SOLARIS
       
     9 #endif
       
    10 
       
    11 #ifdef HAVE_FCNTL_H
       
    12 #include <fcntl.h>
       
    13 #endif
       
    14 
       
    15 #include <stropts.h>
       
    16 #include <sys/ioctl.h>
       
    17 #ifdef SOLARIS
       
    18 #include <sys/audioio.h>
       
    19 #else
       
    20 #include <sun/audioio.h>
       
    21 #endif
       
    22 
       
    23 /* #define offsetof(str,mem) ((int)(((str *)0)->mem)) */
       
    24 
       
    25 typedef struct {
       
    26 	PyObject_HEAD
       
    27 	int	x_fd;		/* The open file */
       
    28 	int	x_icount;	/* # samples read */
       
    29 	int	x_ocount;	/* # samples written */
       
    30 	int	x_isctl;	/* True if control device */
       
    31 	
       
    32 } sadobject;
       
    33 
       
    34 typedef struct {
       
    35 	PyObject_HEAD
       
    36 	audio_info_t ai;
       
    37 } sadstatusobject;
       
    38 
       
    39 static PyTypeObject Sadtype;
       
    40 static PyTypeObject Sadstatustype;
       
    41 static sadstatusobject *sads_alloc(void);	/* Forward */
       
    42 
       
    43 static PyObject *SunAudioError;
       
    44 
       
    45 #define is_sadobject(v)		(Py_TYPE(v) == &Sadtype)
       
    46 #define is_sadstatusobject(v)	(Py_TYPE(v) == &Sadstatustype)
       
    47 
       
    48 
       
    49 static sadobject *
       
    50 newsadobject(PyObject *args)
       
    51 {
       
    52 	sadobject *xp;
       
    53 	int fd;
       
    54 	char *mode;
       
    55 	int imode;
       
    56 	char* basedev;
       
    57 	char* ctldev;
       
    58 	char* opendev;
       
    59 
       
    60 	/* Check arg for r/w/rw */
       
    61 	if (!PyArg_ParseTuple(args, "s", &mode))
       
    62 		return NULL;
       
    63 	if (strcmp(mode, "r") == 0)
       
    64 		imode = 0;
       
    65 	else if (strcmp(mode, "w") == 0)
       
    66 		imode = 1;
       
    67 	else if (strcmp(mode, "rw") == 0)
       
    68 		imode = 2;
       
    69 	else if (strcmp(mode, "control") == 0)
       
    70 		imode = -1;
       
    71 	else {
       
    72 		PyErr_SetString(SunAudioError,
       
    73 			  "Mode should be one of 'r', 'w', 'rw' or 'control'");
       
    74 		return NULL;
       
    75 	}
       
    76 	
       
    77 	/* Open the correct device.  The base device name comes from the
       
    78 	 * AUDIODEV environment variable first, then /dev/audio.  The
       
    79 	 * control device tacks "ctl" onto the base device name.
       
    80 	 */
       
    81 	basedev = getenv("AUDIODEV");
       
    82 	if (!basedev)
       
    83 		basedev = "/dev/audio";
       
    84 	ctldev = PyMem_NEW(char, strlen(basedev) + 4);
       
    85 	if (!ctldev) {
       
    86 		PyErr_NoMemory();
       
    87 		return NULL;
       
    88 	}
       
    89 	strcpy(ctldev, basedev);
       
    90 	strcat(ctldev, "ctl");
       
    91 
       
    92 	if (imode < 0) {
       
    93 		opendev = ctldev;
       
    94 		fd = open(ctldev, 2);
       
    95 	}
       
    96 	else {
       
    97 		opendev = basedev;
       
    98 		fd = open(basedev, imode);
       
    99 	}
       
   100 	if (fd < 0) {
       
   101 		PyErr_SetFromErrnoWithFilename(SunAudioError, opendev);
       
   102 		PyMem_DEL(ctldev);
       
   103 		return NULL;
       
   104 	}
       
   105 	PyMem_DEL(ctldev);
       
   106 
       
   107 	/* Create and initialize the object */
       
   108 	xp = PyObject_New(sadobject, &Sadtype);
       
   109 	if (xp == NULL) {
       
   110 		close(fd);
       
   111 		return NULL;
       
   112 	}
       
   113 	xp->x_fd = fd;
       
   114 	xp->x_icount = xp->x_ocount = 0;
       
   115 	xp->x_isctl = (imode < 0);
       
   116 	
       
   117 	return xp;
       
   118 }
       
   119 
       
   120 /* Sad methods */
       
   121 
       
   122 static void
       
   123 sad_dealloc(sadobject *xp)
       
   124 {
       
   125         close(xp->x_fd);
       
   126 	PyObject_Del(xp);
       
   127 }
       
   128 
       
   129 static PyObject *
       
   130 sad_read(sadobject *self, PyObject *args)
       
   131 {
       
   132         int size, count;
       
   133 	char *cp;
       
   134 	PyObject *rv;
       
   135 	
       
   136         if (!PyArg_ParseTuple(args, "i:read", &size))
       
   137 		return NULL;
       
   138 	rv = PyString_FromStringAndSize(NULL, size);
       
   139 	if (rv == NULL)
       
   140 		return NULL;
       
   141 
       
   142 	if (!(cp = PyString_AsString(rv)))
       
   143 		goto finally;
       
   144 
       
   145 	count = read(self->x_fd, cp, size);
       
   146 	if (count < 0) {
       
   147 		PyErr_SetFromErrno(SunAudioError);
       
   148 		goto finally;
       
   149 	}
       
   150 #if 0
       
   151 	/* TBD: why print this message if you can handle the condition?
       
   152 	 * assume it's debugging info which we can just as well get rid
       
   153 	 * of.  in any case this message should *not* be using printf!
       
   154 	 */
       
   155 	if (count != size)
       
   156 		printf("sunaudio: funny read rv %d wtd %d\n", count, size);
       
   157 #endif
       
   158 	self->x_icount += count;
       
   159 	return rv;
       
   160 
       
   161   finally:
       
   162 	Py_DECREF(rv);
       
   163 	return NULL;
       
   164 }
       
   165 
       
   166 static PyObject *
       
   167 sad_write(sadobject *self, PyObject *args)
       
   168 {
       
   169         char *cp;
       
   170 	int count, size;
       
   171 	
       
   172         if (!PyArg_ParseTuple(args, "s#:write", &cp, &size))
       
   173 		return NULL;
       
   174 
       
   175 	count = write(self->x_fd, cp, size);
       
   176 	if (count < 0) {
       
   177 		PyErr_SetFromErrno(SunAudioError);
       
   178 		return NULL;
       
   179 	}
       
   180 #if 0
       
   181 	if (count != size)
       
   182 		printf("sunaudio: funny write rv %d wanted %d\n", count, size);
       
   183 #endif
       
   184 	self->x_ocount += count;
       
   185 	
       
   186 	Py_INCREF(Py_None);
       
   187 	return Py_None;
       
   188 }
       
   189 
       
   190 static PyObject *
       
   191 sad_getinfo(sadobject *self)
       
   192 {
       
   193 	sadstatusobject *rv;
       
   194 
       
   195 	if (!(rv = sads_alloc()))
       
   196 		return NULL;
       
   197 
       
   198 	if (ioctl(self->x_fd, AUDIO_GETINFO, &rv->ai) < 0) {
       
   199 		PyErr_SetFromErrno(SunAudioError);
       
   200 		Py_DECREF(rv);
       
   201 		return NULL;
       
   202 	}
       
   203 	return (PyObject *)rv;
       
   204 }
       
   205 
       
   206 static PyObject *
       
   207 sad_setinfo(sadobject *self, sadstatusobject *arg)
       
   208 {
       
   209 	if (!is_sadstatusobject(arg)) {
       
   210 		PyErr_SetString(PyExc_TypeError,
       
   211 				"Must be sun audio status object");
       
   212 		return NULL;
       
   213 	}
       
   214 	if (ioctl(self->x_fd, AUDIO_SETINFO, &arg->ai) < 0) {
       
   215 		PyErr_SetFromErrno(SunAudioError);
       
   216 		return NULL;
       
   217 	}
       
   218 	Py_INCREF(Py_None);
       
   219 	return Py_None;
       
   220 }
       
   221 
       
   222 static PyObject *
       
   223 sad_ibufcount(sadobject *self)
       
   224 {
       
   225 	audio_info_t ai;
       
   226     
       
   227 	if (ioctl(self->x_fd, AUDIO_GETINFO, &ai) < 0) {
       
   228 		PyErr_SetFromErrno(SunAudioError);
       
   229 		return NULL;
       
   230 	}
       
   231 	return PyInt_FromLong(ai.record.samples - self->x_icount);
       
   232 }
       
   233 
       
   234 static PyObject *
       
   235 sad_obufcount(sadobject *self)
       
   236 {
       
   237 	audio_info_t ai;
       
   238     
       
   239 	if (ioctl(self->x_fd, AUDIO_GETINFO, &ai) < 0) {
       
   240 		PyErr_SetFromErrno(SunAudioError);
       
   241 		return NULL;
       
   242 	}
       
   243 	/* x_ocount is in bytes, whereas play.samples is in frames */
       
   244 	/* we want frames */
       
   245 	return PyInt_FromLong(self->x_ocount / (ai.play.channels *
       
   246 						ai.play.precision / 8) -
       
   247 			      ai.play.samples);
       
   248 }
       
   249 
       
   250 static PyObject *
       
   251 sad_drain(sadobject *self)
       
   252 {
       
   253 	if (ioctl(self->x_fd, AUDIO_DRAIN, 0) < 0) {
       
   254 		PyErr_SetFromErrno(SunAudioError);
       
   255 		return NULL;
       
   256 	}
       
   257 	Py_INCREF(Py_None);
       
   258 	return Py_None;
       
   259 }
       
   260 
       
   261 #ifdef SOLARIS
       
   262 static PyObject *
       
   263 sad_getdev(sadobject *self)
       
   264 {
       
   265 	struct audio_device ad;
       
   266 
       
   267 	if (ioctl(self->x_fd, AUDIO_GETDEV, &ad) < 0) {
       
   268 		PyErr_SetFromErrno(SunAudioError);
       
   269 		return NULL;
       
   270 	}
       
   271 	return Py_BuildValue("(sss)", ad.name, ad.version, ad.config);
       
   272 }
       
   273 #endif
       
   274 
       
   275 static PyObject *
       
   276 sad_flush(sadobject *self)
       
   277 {
       
   278 	if (ioctl(self->x_fd, I_FLUSH, FLUSHW) < 0) {
       
   279 		PyErr_SetFromErrno(SunAudioError);
       
   280 		return NULL;
       
   281 	}
       
   282 	Py_INCREF(Py_None);
       
   283 	return Py_None;
       
   284 }
       
   285 
       
   286 static PyObject *
       
   287 sad_close(sadobject *self)
       
   288 {
       
   289     
       
   290 	if (self->x_fd >= 0) {
       
   291 		close(self->x_fd);
       
   292 		self->x_fd = -1;
       
   293 	}
       
   294 	Py_INCREF(Py_None);
       
   295 	return Py_None;
       
   296 }
       
   297 
       
   298 static PyObject *
       
   299 sad_fileno(sadobject *self)
       
   300 {
       
   301 	return PyInt_FromLong(self->x_fd);
       
   302 }
       
   303 
       
   304 
       
   305 static PyMethodDef sad_methods[] = {
       
   306         { "read",	(PyCFunction)sad_read, METH_VARARGS },
       
   307         { "write",	(PyCFunction)sad_write, METH_VARARGS },
       
   308         { "ibufcount",	(PyCFunction)sad_ibufcount, METH_NOARGS },
       
   309         { "obufcount",	(PyCFunction)sad_obufcount, METH_NOARGS },
       
   310 #define CTL_METHODS 4
       
   311         { "getinfo",	(PyCFunction)sad_getinfo, METH_NOARGS },
       
   312         { "setinfo",	(PyCFunction)sad_setinfo, METH_O},
       
   313         { "drain",	(PyCFunction)sad_drain, METH_NOARGS },
       
   314         { "flush",	(PyCFunction)sad_flush, METH_NOARGS },
       
   315 #ifdef SOLARIS
       
   316 	{ "getdev",	(PyCFunction)sad_getdev, METH_NOARGS },
       
   317 #endif
       
   318         { "close",	(PyCFunction)sad_close, METH_NOARGS },
       
   319 	{ "fileno",     (PyCFunction)sad_fileno, METH_NOARGS },
       
   320 	{NULL,		NULL}		/* sentinel */
       
   321 };
       
   322 
       
   323 static PyObject *
       
   324 sad_getattr(sadobject *xp, char *name)
       
   325 {
       
   326 	if (xp->x_isctl)
       
   327 		return Py_FindMethod(sad_methods+CTL_METHODS,
       
   328 				     (PyObject *)xp, name);
       
   329 	else
       
   330 		return Py_FindMethod(sad_methods, (PyObject *)xp, name);
       
   331 }
       
   332 
       
   333 /* ----------------------------------------------------------------- */
       
   334 
       
   335 static sadstatusobject *
       
   336 sads_alloc(void) {
       
   337 	return PyObject_New(sadstatusobject, &Sadstatustype);
       
   338 }
       
   339 
       
   340 static void
       
   341 sads_dealloc(sadstatusobject *xp)
       
   342 {
       
   343 	PyMem_DEL(xp);
       
   344 }
       
   345 
       
   346 #define OFF(x) offsetof(audio_info_t,x)
       
   347 static struct memberlist sads_ml[] = {
       
   348 	{ "i_sample_rate",	T_UINT,		OFF(record.sample_rate) },
       
   349 	{ "i_channels",		T_UINT,		OFF(record.channels) },
       
   350 	{ "i_precision",	T_UINT,		OFF(record.precision) },
       
   351 	{ "i_encoding",		T_UINT,		OFF(record.encoding) },
       
   352 	{ "i_gain",		T_UINT,		OFF(record.gain) },
       
   353 	{ "i_port",		T_UINT,		OFF(record.port) },
       
   354 	{ "i_samples",		T_UINT,		OFF(record.samples) },
       
   355 	{ "i_eof",		T_UINT,		OFF(record.eof) },
       
   356 	{ "i_pause",		T_UBYTE,	OFF(record.pause) },
       
   357 	{ "i_error",		T_UBYTE,	OFF(record.error) },
       
   358 	{ "i_waiting",		T_UBYTE,	OFF(record.waiting) },
       
   359 	{ "i_open",		T_UBYTE,	OFF(record.open) ,	 RO},
       
   360 	{ "i_active",		T_UBYTE,	OFF(record.active) ,	 RO},
       
   361 #ifdef SOLARIS
       
   362 	{ "i_buffer_size",	T_UINT,		OFF(record.buffer_size) },
       
   363 	{ "i_balance",		T_UBYTE,	OFF(record.balance) },
       
   364 	{ "i_avail_ports",	T_UINT,		OFF(record.avail_ports) },
       
   365 #endif
       
   366 
       
   367 	{ "o_sample_rate",	T_UINT,		OFF(play.sample_rate) },
       
   368 	{ "o_channels",		T_UINT,		OFF(play.channels) },
       
   369 	{ "o_precision",	T_UINT,		OFF(play.precision) },
       
   370 	{ "o_encoding",		T_UINT,		OFF(play.encoding) },
       
   371 	{ "o_gain",		T_UINT,		OFF(play.gain) },
       
   372 	{ "o_port",		T_UINT,		OFF(play.port) },
       
   373 	{ "o_samples",		T_UINT,		OFF(play.samples) },
       
   374 	{ "o_eof",		T_UINT,		OFF(play.eof) },
       
   375 	{ "o_pause",		T_UBYTE,	OFF(play.pause) },
       
   376 	{ "o_error",		T_UBYTE,	OFF(play.error) },
       
   377 	{ "o_waiting",		T_UBYTE,	OFF(play.waiting) },
       
   378 	{ "o_open",		T_UBYTE,	OFF(play.open) ,	 RO},
       
   379 	{ "o_active",		T_UBYTE,	OFF(play.active) ,	 RO},
       
   380 #ifdef SOLARIS
       
   381 	{ "o_buffer_size",	T_UINT,		OFF(play.buffer_size) },
       
   382 	{ "o_balance",		T_UBYTE,	OFF(play.balance) },
       
   383 	{ "o_avail_ports",	T_UINT,		OFF(play.avail_ports) },
       
   384 #endif
       
   385 
       
   386 	{ "monitor_gain",	T_UINT,		OFF(monitor_gain) },
       
   387         { NULL,                 0,              0},
       
   388 };
       
   389 
       
   390 static PyObject *
       
   391 sads_getattr(sadstatusobject *xp, char *name)
       
   392 {
       
   393 	return PyMember_Get((char *)&xp->ai, sads_ml, name);
       
   394 }
       
   395 
       
   396 static int
       
   397 sads_setattr(sadstatusobject *xp, char *name, PyObject *v)
       
   398 {
       
   399 
       
   400 	if (v == NULL) {
       
   401 		PyErr_SetString(PyExc_TypeError,
       
   402 				"can't delete sun audio status attributes");
       
   403 		return -1;
       
   404 	}
       
   405 	return PyMember_Set((char *)&xp->ai, sads_ml, name, v);
       
   406 }
       
   407 
       
   408 /* ------------------------------------------------------------------- */
       
   409 
       
   410 
       
   411 static PyTypeObject Sadtype = {
       
   412 	PyVarObject_HEAD_INIT(&PyType_Type, 0)
       
   413 	"sunaudiodev.sun_audio_device",	/*tp_name*/
       
   414 	sizeof(sadobject),		/*tp_size*/
       
   415 	0,				/*tp_itemsize*/
       
   416 	/* methods */
       
   417 	(destructor)sad_dealloc,	/*tp_dealloc*/
       
   418 	0,				/*tp_print*/
       
   419 	(getattrfunc)sad_getattr,	/*tp_getattr*/
       
   420 	0,				/*tp_setattr*/
       
   421 	0,				/*tp_compare*/
       
   422 	0,				/*tp_repr*/
       
   423 };
       
   424 
       
   425 static PyTypeObject Sadstatustype = {
       
   426 	PyVarObject_HEAD_INIT(&PyType_Type, 0)
       
   427 	"sunaudiodev.sun_audio_device_status", /*tp_name*/
       
   428 	sizeof(sadstatusobject),	/*tp_size*/
       
   429 	0,				/*tp_itemsize*/
       
   430 	/* methods */
       
   431 	(destructor)sads_dealloc,	/*tp_dealloc*/
       
   432 	0,				/*tp_print*/
       
   433 	(getattrfunc)sads_getattr,	/*tp_getattr*/
       
   434 	(setattrfunc)sads_setattr,	/*tp_setattr*/
       
   435 	0,				/*tp_compare*/
       
   436 	0,				/*tp_repr*/
       
   437 };
       
   438 /* ------------------------------------------------------------------- */
       
   439 
       
   440 static PyObject *
       
   441 sadopen(PyObject *self, PyObject *args)
       
   442 {
       
   443 	return (PyObject *)newsadobject(args);
       
   444 }
       
   445     
       
   446 static PyMethodDef sunaudiodev_methods[] = {
       
   447     { "open", sadopen, METH_VARARGS },
       
   448     { 0, 0 },
       
   449 };
       
   450 
       
   451 void
       
   452 initsunaudiodev(void)
       
   453 {
       
   454 	PyObject *m, *d;
       
   455 	
       
   456 	if (PyErr_WarnPy3k("the sunaudiodev module has been removed in "
       
   457 	                   "Python 3.0", 2) < 0)
       
   458 	    return;
       
   459 
       
   460 	m = Py_InitModule("sunaudiodev", sunaudiodev_methods);
       
   461 	if (m == NULL)
       
   462 		return;
       
   463 	d = PyModule_GetDict(m);
       
   464 	SunAudioError = PyErr_NewException("sunaudiodev.error", NULL, NULL);
       
   465 	if (SunAudioError)
       
   466 		PyDict_SetItemString(d, "error", SunAudioError);
       
   467 }