symbian-qemu-0.9.1-12/python-2.6.1/Modules/linuxaudiodev.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 /* Hey Emacs, this is -*-C-*- 
       
     2  ******************************************************************************
       
     3  * linuxaudiodev.c -- Linux audio device for python.
       
     4  * 
       
     5  * Author          : Peter Bosch
       
     6  * Created On      : Thu Mar  2 21:10:33 2000
       
     7  * Status          : Unknown, Use with caution!
       
     8  * 
       
     9  * Unless other notices are present in any part of this file
       
    10  * explicitly claiming copyrights for other people and/or 
       
    11  * organizations, the contents of this file is fully copyright 
       
    12  * (C) 2000 Peter Bosch, all rights reserved.
       
    13  ******************************************************************************
       
    14  */
       
    15 
       
    16 #include "Python.h"
       
    17 #include "structmember.h"
       
    18 
       
    19 #ifdef HAVE_FCNTL_H
       
    20 #include <fcntl.h>
       
    21 #else
       
    22 #define O_RDONLY 00
       
    23 #define O_WRONLY 01
       
    24 #endif
       
    25 
       
    26 
       
    27 #include <sys/ioctl.h>
       
    28 #if defined(linux)
       
    29 #include <linux/soundcard.h>
       
    30 
       
    31 #ifndef HAVE_STDINT_H
       
    32 typedef unsigned long uint32_t;
       
    33 #endif
       
    34 
       
    35 #elif defined(__FreeBSD__)
       
    36 #include <machine/soundcard.h>
       
    37 
       
    38 #ifndef SNDCTL_DSP_CHANNELS
       
    39 #define SNDCTL_DSP_CHANNELS SOUND_PCM_WRITE_CHANNELS
       
    40 #endif
       
    41 
       
    42 #endif
       
    43 
       
    44 typedef struct {
       
    45     PyObject_HEAD
       
    46     int		x_fd;		/* The open file */
       
    47     int         x_mode;           /* file mode */
       
    48     int		x_icount;	/* Input count */
       
    49     int		x_ocount;	/* Output count */
       
    50     uint32_t	x_afmts;	/* Audio formats supported by hardware*/
       
    51 } lad_t;
       
    52 
       
    53 /* XXX several format defined in soundcard.h are not supported,
       
    54    including _NE (native endian) options and S32 options
       
    55 */
       
    56 
       
    57 static struct {
       
    58     int		a_bps;
       
    59     uint32_t	a_fmt;
       
    60     char       *a_name;
       
    61 } audio_types[] = {
       
    62     {  8, 	AFMT_MU_LAW, "logarithmic mu-law 8-bit audio" },
       
    63     {  8, 	AFMT_A_LAW,  "logarithmic A-law 8-bit audio" },
       
    64     {  8,	AFMT_U8,     "linear unsigned 8-bit audio" },
       
    65     {  8, 	AFMT_S8,     "linear signed 8-bit audio" },
       
    66     { 16, 	AFMT_U16_BE, "linear unsigned 16-bit big-endian audio" },
       
    67     { 16, 	AFMT_U16_LE, "linear unsigned 16-bit little-endian audio" },
       
    68     { 16, 	AFMT_S16_BE, "linear signed 16-bit big-endian audio" },
       
    69     { 16, 	AFMT_S16_LE, "linear signed 16-bit little-endian audio" },
       
    70     { 16, 	AFMT_S16_NE, "linear signed 16-bit native-endian audio" },
       
    71 };
       
    72 
       
    73 static int n_audio_types = sizeof(audio_types) / sizeof(audio_types[0]);
       
    74 
       
    75 static PyTypeObject Ladtype;
       
    76 
       
    77 static PyObject *LinuxAudioError;
       
    78 
       
    79 static lad_t *
       
    80 newladobject(PyObject *arg)
       
    81 {
       
    82     lad_t *xp;
       
    83     int fd, afmts, imode;
       
    84     char *basedev = NULL;
       
    85     char *mode = NULL;
       
    86 
       
    87     /* Two ways to call linuxaudiodev.open():
       
    88          open(device, mode) (for consistency with builtin open())
       
    89          open(mode)         (for backwards compatibility)
       
    90        because the *first* argument is optional, parsing args is
       
    91        a wee bit tricky. */
       
    92     if (!PyArg_ParseTuple(arg, "s|s:open", &basedev, &mode))
       
    93        return NULL;
       
    94     if (mode == NULL) {                 /* only one arg supplied */
       
    95        mode = basedev;
       
    96        basedev = NULL;
       
    97     }
       
    98 
       
    99     if (strcmp(mode, "r") == 0)
       
   100         imode = O_RDONLY;
       
   101     else if (strcmp(mode, "w") == 0)
       
   102         imode = O_WRONLY;
       
   103     else {
       
   104         PyErr_SetString(LinuxAudioError, "mode should be 'r' or 'w'");
       
   105         return NULL;
       
   106     }
       
   107 
       
   108     /* Open the correct device.  The base device name comes from the
       
   109      * AUDIODEV environment variable first, then /dev/dsp.  The
       
   110      * control device tacks "ctl" onto the base device name.
       
   111      * 
       
   112      * Note that the only difference between /dev/audio and /dev/dsp
       
   113      * is that the former uses logarithmic mu-law encoding and the
       
   114      * latter uses 8-bit unsigned encoding.
       
   115      */
       
   116 
       
   117     if (basedev == NULL) {              /* called with one arg */
       
   118        basedev = getenv("AUDIODEV");
       
   119        if (basedev == NULL)             /* $AUDIODEV not set */
       
   120           basedev = "/dev/dsp";
       
   121     }
       
   122 
       
   123     if ((fd = open(basedev, imode)) == -1) {
       
   124         PyErr_SetFromErrnoWithFilename(LinuxAudioError, basedev);
       
   125         return NULL;
       
   126     }
       
   127     if (imode == O_WRONLY && ioctl(fd, SNDCTL_DSP_NONBLOCK, NULL) == -1) {
       
   128         PyErr_SetFromErrnoWithFilename(LinuxAudioError, basedev);
       
   129         return NULL;
       
   130     }
       
   131     if (ioctl(fd, SNDCTL_DSP_GETFMTS, &afmts) == -1) {
       
   132         PyErr_SetFromErrnoWithFilename(LinuxAudioError, basedev);
       
   133         return NULL;
       
   134     }
       
   135     /* Create and initialize the object */
       
   136     if ((xp = PyObject_New(lad_t, &Ladtype)) == NULL) {
       
   137         close(fd);
       
   138         return NULL;
       
   139     }
       
   140     xp->x_fd = fd;
       
   141     xp->x_mode = imode;
       
   142     xp->x_icount = xp->x_ocount = 0;
       
   143     xp->x_afmts  = afmts;
       
   144     return xp;
       
   145 }
       
   146 
       
   147 static void
       
   148 lad_dealloc(lad_t *xp)
       
   149 {
       
   150     /* if already closed, don't reclose it */
       
   151     if (xp->x_fd != -1)
       
   152 	close(xp->x_fd);
       
   153     PyObject_Del(xp);
       
   154 }
       
   155 
       
   156 static PyObject *
       
   157 lad_read(lad_t *self, PyObject *args)
       
   158 {
       
   159     int size, count;
       
   160     char *cp;
       
   161     PyObject *rv;
       
   162 	
       
   163     if (!PyArg_ParseTuple(args, "i:read", &size))
       
   164         return NULL;
       
   165     rv = PyString_FromStringAndSize(NULL, size);
       
   166     if (rv == NULL)
       
   167         return NULL;
       
   168     cp = PyString_AS_STRING(rv);
       
   169     if ((count = read(self->x_fd, cp, size)) < 0) {
       
   170         PyErr_SetFromErrno(LinuxAudioError);
       
   171         Py_DECREF(rv);
       
   172         return NULL;
       
   173     }
       
   174     self->x_icount += count;
       
   175     _PyString_Resize(&rv, count);
       
   176     return rv;
       
   177 }
       
   178 
       
   179 static PyObject *
       
   180 lad_write(lad_t *self, PyObject *args)
       
   181 {
       
   182     char *cp;
       
   183     int rv, size;
       
   184     fd_set write_set_fds;
       
   185     struct timeval tv;
       
   186     int select_retval;
       
   187     
       
   188     if (!PyArg_ParseTuple(args, "s#:write", &cp, &size)) 
       
   189 	return NULL;
       
   190 
       
   191     /* use select to wait for audio device to be available */
       
   192     FD_ZERO(&write_set_fds);
       
   193     FD_SET(self->x_fd, &write_set_fds);
       
   194     tv.tv_sec = 4; /* timeout values */
       
   195     tv.tv_usec = 0; 
       
   196 
       
   197     while (size > 0) {
       
   198       select_retval = select(self->x_fd+1, NULL, &write_set_fds, NULL, &tv);
       
   199       tv.tv_sec = 1; tv.tv_usec = 0; /* willing to wait this long next time*/
       
   200       if (select_retval) {
       
   201         if ((rv = write(self->x_fd, cp, size)) == -1) {
       
   202 	  if (errno != EAGAIN) {
       
   203 	    PyErr_SetFromErrno(LinuxAudioError);
       
   204 	    return NULL;
       
   205 	  } else {
       
   206 	    errno = 0; /* EAGAIN: buffer is full, try again */
       
   207 	  }
       
   208         } else {
       
   209 	  self->x_ocount += rv;
       
   210 	  size -= rv;
       
   211 	  cp += rv;
       
   212 	}
       
   213       } else {
       
   214 	/* printf("Not able to write to linux audio device within %ld seconds\n", tv.tv_sec); */
       
   215 	PyErr_SetFromErrno(LinuxAudioError);
       
   216 	return NULL;
       
   217       }
       
   218     }
       
   219     Py_INCREF(Py_None);
       
   220     return Py_None;
       
   221 }
       
   222 
       
   223 static PyObject *
       
   224 lad_close(lad_t *self, PyObject *unused)
       
   225 {
       
   226     if (self->x_fd >= 0) {
       
   227         close(self->x_fd);
       
   228         self->x_fd = -1;
       
   229     }
       
   230     Py_RETURN_NONE;
       
   231 }
       
   232 
       
   233 static PyObject *
       
   234 lad_fileno(lad_t *self, PyObject *unused)
       
   235 {
       
   236     return PyInt_FromLong(self->x_fd);
       
   237 }
       
   238 
       
   239 static PyObject *
       
   240 lad_setparameters(lad_t *self, PyObject *args)
       
   241 {
       
   242     int rate, ssize, nchannels, n, fmt, emulate=0;
       
   243 
       
   244     if (!PyArg_ParseTuple(args, "iiii|i:setparameters",
       
   245                           &rate, &ssize, &nchannels, &fmt, &emulate))
       
   246         return NULL;
       
   247   
       
   248     if (rate < 0) {
       
   249 	PyErr_Format(PyExc_ValueError, "expected rate >= 0, not %d",
       
   250 		     rate); 
       
   251 	return NULL;
       
   252     }
       
   253     if (ssize < 0) {
       
   254 	PyErr_Format(PyExc_ValueError, "expected sample size >= 0, not %d",
       
   255 		     ssize);
       
   256 	return NULL;
       
   257     }
       
   258     if (nchannels != 1 && nchannels != 2) {
       
   259 	PyErr_Format(PyExc_ValueError, "nchannels must be 1 or 2, not %d",
       
   260 		     nchannels);
       
   261 	return NULL;
       
   262     }
       
   263 
       
   264     for (n = 0; n < n_audio_types; n++)
       
   265         if (fmt == audio_types[n].a_fmt)
       
   266             break;
       
   267     if (n == n_audio_types) {
       
   268 	PyErr_Format(PyExc_ValueError, "unknown audio encoding: %d", fmt);
       
   269 	return NULL;
       
   270     }
       
   271     if (audio_types[n].a_bps != ssize) {
       
   272 	PyErr_Format(PyExc_ValueError, 
       
   273 		     "for %s, expected sample size %d, not %d",
       
   274 		     audio_types[n].a_name, audio_types[n].a_bps, ssize);
       
   275 	return NULL;
       
   276     }
       
   277 
       
   278     if (emulate == 0) {
       
   279 	if ((self->x_afmts & audio_types[n].a_fmt) == 0) {
       
   280 	    PyErr_Format(PyExc_ValueError, 
       
   281 			 "%s format not supported by device",
       
   282 			 audio_types[n].a_name);
       
   283 	    return NULL;
       
   284 	}
       
   285     }
       
   286     if (ioctl(self->x_fd, SNDCTL_DSP_SETFMT, 
       
   287 	      &audio_types[n].a_fmt) == -1) {
       
   288         PyErr_SetFromErrno(LinuxAudioError);
       
   289         return NULL;
       
   290     }
       
   291     if (ioctl(self->x_fd, SNDCTL_DSP_CHANNELS, &nchannels) == -1) {
       
   292         PyErr_SetFromErrno(LinuxAudioError);
       
   293         return NULL;
       
   294     }
       
   295     if (ioctl(self->x_fd, SNDCTL_DSP_SPEED, &rate) == -1) {
       
   296         PyErr_SetFromErrno(LinuxAudioError);
       
   297         return NULL;
       
   298     }
       
   299 
       
   300     Py_INCREF(Py_None);
       
   301     return Py_None;
       
   302 }
       
   303 
       
   304 static int
       
   305 _ssize(lad_t *self, int *nchannels, int *ssize)
       
   306 {
       
   307     int fmt;
       
   308 
       
   309     fmt = 0;
       
   310     if (ioctl(self->x_fd, SNDCTL_DSP_SETFMT, &fmt) < 0) 
       
   311         return -errno;
       
   312 
       
   313     switch (fmt) {
       
   314     case AFMT_MU_LAW:
       
   315     case AFMT_A_LAW:
       
   316     case AFMT_U8:
       
   317     case AFMT_S8:
       
   318         *ssize = sizeof(char);
       
   319         break;
       
   320     case AFMT_S16_LE:
       
   321     case AFMT_S16_BE:
       
   322     case AFMT_U16_LE:
       
   323     case AFMT_U16_BE:
       
   324         *ssize = sizeof(short);
       
   325         break;
       
   326     case AFMT_MPEG:
       
   327     case AFMT_IMA_ADPCM:
       
   328     default:
       
   329         return -EOPNOTSUPP;
       
   330     }
       
   331     if (ioctl(self->x_fd, SNDCTL_DSP_CHANNELS, nchannels) < 0)
       
   332         return -errno;
       
   333     return 0;
       
   334 }
       
   335 
       
   336 
       
   337 /* bufsize returns the size of the hardware audio buffer in number 
       
   338    of samples */
       
   339 static PyObject *
       
   340 lad_bufsize(lad_t *self, PyObject *unused)
       
   341 {
       
   342     audio_buf_info ai;
       
   343     int nchannels=0, ssize=0;
       
   344 
       
   345     if (_ssize(self, &nchannels, &ssize) < 0 || !ssize || !nchannels) {
       
   346         PyErr_SetFromErrno(LinuxAudioError);
       
   347         return NULL;
       
   348     }
       
   349     if (ioctl(self->x_fd, SNDCTL_DSP_GETOSPACE, &ai) < 0) {
       
   350         PyErr_SetFromErrno(LinuxAudioError);
       
   351         return NULL;
       
   352     }
       
   353     return PyInt_FromLong((ai.fragstotal * ai.fragsize) / (nchannels * ssize));
       
   354 }
       
   355 
       
   356 /* obufcount returns the number of samples that are available in the 
       
   357    hardware for playing */
       
   358 static PyObject *
       
   359 lad_obufcount(lad_t *self, PyObject *unused)
       
   360 {
       
   361     audio_buf_info ai;
       
   362     int nchannels=0, ssize=0;
       
   363 
       
   364     if (_ssize(self, &nchannels, &ssize) < 0 || !ssize || !nchannels) {
       
   365         PyErr_SetFromErrno(LinuxAudioError);
       
   366         return NULL;
       
   367     }
       
   368     if (ioctl(self->x_fd, SNDCTL_DSP_GETOSPACE, &ai) < 0) {
       
   369         PyErr_SetFromErrno(LinuxAudioError);
       
   370         return NULL;
       
   371     }
       
   372     return PyInt_FromLong((ai.fragstotal * ai.fragsize - ai.bytes) / 
       
   373                           (ssize * nchannels));
       
   374 }
       
   375 
       
   376 /* obufcount returns the number of samples that can be played without
       
   377    blocking */
       
   378 static PyObject *
       
   379 lad_obuffree(lad_t *self, PyObject *unused)
       
   380 {
       
   381     audio_buf_info ai;
       
   382     int nchannels=0, ssize=0;
       
   383 
       
   384     if (_ssize(self, &nchannels, &ssize) < 0 || !ssize || !nchannels) {
       
   385         PyErr_SetFromErrno(LinuxAudioError);
       
   386         return NULL;
       
   387     }
       
   388     if (ioctl(self->x_fd, SNDCTL_DSP_GETOSPACE, &ai) < 0) {
       
   389         PyErr_SetFromErrno(LinuxAudioError);
       
   390         return NULL;
       
   391     }
       
   392     return PyInt_FromLong(ai.bytes / (ssize * nchannels));
       
   393 }
       
   394 
       
   395 /* Flush the device */
       
   396 static PyObject *
       
   397 lad_flush(lad_t *self, PyObject *unused)
       
   398 {
       
   399     if (ioctl(self->x_fd, SNDCTL_DSP_SYNC, NULL) == -1) {
       
   400         PyErr_SetFromErrno(LinuxAudioError);
       
   401         return NULL;
       
   402     }
       
   403     Py_RETURN_NONE;
       
   404 }
       
   405 
       
   406 static PyObject *
       
   407 lad_getptr(lad_t *self, PyObject *unused)
       
   408 {
       
   409     count_info info;
       
   410     int req;
       
   411 
       
   412     if (self->x_mode == O_RDONLY)
       
   413 	req = SNDCTL_DSP_GETIPTR;
       
   414     else
       
   415 	req = SNDCTL_DSP_GETOPTR;
       
   416     if (ioctl(self->x_fd, req, &info) == -1) {
       
   417         PyErr_SetFromErrno(LinuxAudioError);
       
   418         return NULL;
       
   419     }
       
   420     return Py_BuildValue("iii", info.bytes, info.blocks, info.ptr);
       
   421 }
       
   422 
       
   423 static PyMethodDef lad_methods[] = {
       
   424     { "read",		(PyCFunction)lad_read, METH_VARARGS },
       
   425     { "write",		(PyCFunction)lad_write, METH_VARARGS },
       
   426     { "setparameters",	(PyCFunction)lad_setparameters, METH_VARARGS },
       
   427     { "bufsize",	(PyCFunction)lad_bufsize, METH_VARARGS },
       
   428     { "obufcount",	(PyCFunction)lad_obufcount, METH_NOARGS },
       
   429     { "obuffree",	(PyCFunction)lad_obuffree, METH_NOARGS },
       
   430     { "flush",		(PyCFunction)lad_flush, METH_NOARGS },
       
   431     { "close",		(PyCFunction)lad_close, METH_NOARGS },
       
   432     { "fileno",     	(PyCFunction)lad_fileno, METH_NOARGS },
       
   433     { "getptr",         (PyCFunction)lad_getptr, METH_NOARGS },
       
   434     { NULL,		NULL}		/* sentinel */
       
   435 };
       
   436 
       
   437 static PyObject *
       
   438 lad_getattr(lad_t *xp, char *name)
       
   439 {
       
   440     return Py_FindMethod(lad_methods, (PyObject *)xp, name);
       
   441 }
       
   442 
       
   443 static PyTypeObject Ladtype = {
       
   444     PyVarObject_HEAD_INIT(&PyType_Type, 0)
       
   445     "linuxaudiodev.linux_audio_device", /*tp_name*/
       
   446     sizeof(lad_t),		/*tp_size*/
       
   447     0,				/*tp_itemsize*/
       
   448     /* methods */
       
   449     (destructor)lad_dealloc,	/*tp_dealloc*/
       
   450     0,				/*tp_print*/
       
   451     (getattrfunc)lad_getattr,	/*tp_getattr*/
       
   452     0,				/*tp_setattr*/
       
   453     0,				/*tp_compare*/
       
   454     0,				/*tp_repr*/
       
   455 };
       
   456 
       
   457 static PyObject *
       
   458 ladopen(PyObject *self, PyObject *args)
       
   459 {
       
   460     return (PyObject *)newladobject(args);
       
   461 }
       
   462 
       
   463 static PyMethodDef linuxaudiodev_methods[] = {
       
   464     { "open", ladopen, METH_VARARGS },
       
   465     { 0, 0 },
       
   466 };
       
   467 
       
   468 void
       
   469 initlinuxaudiodev(void)
       
   470 {
       
   471     PyObject *m;
       
   472     
       
   473     if (PyErr_WarnPy3k("the linuxaudiodev module has been removed in "
       
   474                     "Python 3.0; use the ossaudiodev module instead", 2) < 0)
       
   475         return;
       
   476   
       
   477     m = Py_InitModule("linuxaudiodev", linuxaudiodev_methods);
       
   478     if (m == NULL)
       
   479 	return;
       
   480 
       
   481     LinuxAudioError = PyErr_NewException("linuxaudiodev.error", NULL, NULL);
       
   482     if (LinuxAudioError)
       
   483 	PyModule_AddObject(m, "error", LinuxAudioError);
       
   484 
       
   485     if (PyModule_AddIntConstant(m, "AFMT_MU_LAW", (long)AFMT_MU_LAW) == -1)
       
   486 	return;
       
   487     if (PyModule_AddIntConstant(m, "AFMT_A_LAW", (long)AFMT_A_LAW) == -1)
       
   488 	return;
       
   489     if (PyModule_AddIntConstant(m, "AFMT_U8", (long)AFMT_U8) == -1)
       
   490 	return;
       
   491     if (PyModule_AddIntConstant(m, "AFMT_S8", (long)AFMT_S8) == -1)
       
   492 	return;
       
   493     if (PyModule_AddIntConstant(m, "AFMT_U16_BE", (long)AFMT_U16_BE) == -1)
       
   494 	return;
       
   495     if (PyModule_AddIntConstant(m, "AFMT_U16_LE", (long)AFMT_U16_LE) == -1)
       
   496 	return;
       
   497     if (PyModule_AddIntConstant(m, "AFMT_S16_BE", (long)AFMT_S16_BE) == -1)
       
   498 	return;
       
   499     if (PyModule_AddIntConstant(m, "AFMT_S16_LE", (long)AFMT_S16_LE) == -1)
       
   500 	return;
       
   501     if (PyModule_AddIntConstant(m, "AFMT_S16_NE", (long)AFMT_S16_NE) == -1)
       
   502 	return;
       
   503 
       
   504     return;
       
   505 }