LCOV - code coverage report
Current view: top level - libreoffice/workdir/unxlngi6.pro/UnpackedTarball/python3/Modules - ossaudiodev.c (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 538 0.0 %
Date: 2012-12-17 Functions: 0 43 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * ossaudiodev -- Python interface to the OSS (Open Sound System) API.
       3             :  *                This is the standard audio API for Linux and some
       4             :  *                flavours of BSD [XXX which ones?]; it is also available
       5             :  *                for a wide range of commercial Unices.
       6             :  *
       7             :  * Originally written by Peter Bosch, March 2000, as linuxaudiodev.
       8             :  *
       9             :  * Renamed to ossaudiodev and rearranged/revised/hacked up
      10             :  * by Greg Ward <gward@python.net>, November 2002.
      11             :  * Mixer interface by Nicholas FitzRoy-Dale <wzdd@lardcave.net>, Dec 2002.
      12             :  *
      13             :  * (c) 2000 Peter Bosch.  All Rights Reserved.
      14             :  * (c) 2002 Gregory P. Ward.  All Rights Reserved.
      15             :  * (c) 2002 Python Software Foundation.  All Rights Reserved.
      16             :  *
      17             :  * XXX need a license statement
      18             :  *
      19             :  * $Id$
      20             :  */
      21             : 
      22             : #include "Python.h"
      23             : #include "structmember.h"
      24             : 
      25             : #ifdef HAVE_FCNTL_H
      26             : #include <fcntl.h>
      27             : #else
      28             : #define O_RDONLY 00
      29             : #define O_WRONLY 01
      30             : #endif
      31             : 
      32             : #include <sys/ioctl.h>
      33             : #include <sys/soundcard.h>
      34             : 
      35             : #if defined(linux)
      36             : 
      37             : #ifndef HAVE_STDINT_H
      38             : typedef unsigned long uint32_t;
      39             : #endif
      40             : 
      41             : #elif defined(__FreeBSD__)
      42             : 
      43             : # ifndef SNDCTL_DSP_CHANNELS
      44             : #  define SNDCTL_DSP_CHANNELS SOUND_PCM_WRITE_CHANNELS
      45             : # endif
      46             : 
      47             : #endif
      48             : 
      49             : typedef struct {
      50             :     PyObject_HEAD
      51             :     char    *devicename;              /* name of the device file */
      52             :     int      fd;                      /* file descriptor */
      53             :     int      mode;                    /* file mode (O_RDONLY, etc.) */
      54             :     int      icount;                  /* input count */
      55             :     int      ocount;                  /* output count */
      56             :     uint32_t afmts;                   /* audio formats supported by hardware */
      57             : } oss_audio_t;
      58             : 
      59             : typedef struct {
      60             :     PyObject_HEAD
      61             :     int      fd;                      /* The open mixer device */
      62             : } oss_mixer_t;
      63             : 
      64             : 
      65             : static PyTypeObject OSSAudioType;
      66             : static PyTypeObject OSSMixerType;
      67             : 
      68             : static PyObject *OSSAudioError;
      69             : 
      70             : 
      71             : /* ----------------------------------------------------------------------
      72             :  * DSP object initialization/deallocation
      73             :  */
      74             : 
      75             : static oss_audio_t *
      76           0 : newossobject(PyObject *arg)
      77             : {
      78             :     oss_audio_t *self;
      79             :     int fd, afmts, imode;
      80           0 :     char *devicename = NULL;
      81           0 :     char *mode = NULL;
      82             : 
      83             :     /* Two ways to call open():
      84             :          open(device, mode) (for consistency with builtin open())
      85             :          open(mode)         (for backwards compatibility)
      86             :        because the *first* argument is optional, parsing args is
      87             :        a wee bit tricky. */
      88           0 :     if (!PyArg_ParseTuple(arg, "s|s:open", &devicename, &mode))
      89           0 :        return NULL;
      90           0 :     if (mode == NULL) {                 /* only one arg supplied */
      91           0 :        mode = devicename;
      92           0 :        devicename = NULL;
      93             :     }
      94             : 
      95           0 :     if (strcmp(mode, "r") == 0)
      96           0 :         imode = O_RDONLY;
      97           0 :     else if (strcmp(mode, "w") == 0)
      98           0 :         imode = O_WRONLY;
      99           0 :     else if (strcmp(mode, "rw") == 0)
     100           0 :         imode = O_RDWR;
     101             :     else {
     102           0 :         PyErr_SetString(OSSAudioError, "mode must be 'r', 'w', or 'rw'");
     103           0 :         return NULL;
     104             :     }
     105             : 
     106             :     /* Open the correct device: either the 'device' argument,
     107             :        or the AUDIODEV environment variable, or "/dev/dsp". */
     108           0 :     if (devicename == NULL) {              /* called with one arg */
     109           0 :        devicename = getenv("AUDIODEV");
     110           0 :        if (devicename == NULL)             /* $AUDIODEV not set */
     111           0 :           devicename = "/dev/dsp";
     112             :     }
     113             : 
     114             :     /* Open with O_NONBLOCK to avoid hanging on devices that only allow
     115             :        one open at a time.  This does *not* affect later I/O; OSS
     116             :        provides a special ioctl() for non-blocking read/write, which is
     117             :        exposed via oss_nonblock() below. */
     118           0 :     if ((fd = open(devicename, imode|O_NONBLOCK)) == -1) {
     119           0 :         PyErr_SetFromErrnoWithFilename(PyExc_IOError, devicename);
     120           0 :         return NULL;
     121             :     }
     122             : 
     123             :     /* And (try to) put it back in blocking mode so we get the
     124             :        expected write() semantics. */
     125           0 :     if (fcntl(fd, F_SETFL, 0) == -1) {
     126           0 :         close(fd);
     127           0 :         PyErr_SetFromErrnoWithFilename(PyExc_IOError, devicename);
     128           0 :         return NULL;
     129             :     }
     130             : 
     131           0 :     if (ioctl(fd, SNDCTL_DSP_GETFMTS, &afmts) == -1) {
     132           0 :         close(fd);
     133           0 :         PyErr_SetFromErrnoWithFilename(PyExc_IOError, devicename);
     134           0 :         return NULL;
     135             :     }
     136             :     /* Create and initialize the object */
     137           0 :     if ((self = PyObject_New(oss_audio_t, &OSSAudioType)) == NULL) {
     138           0 :         close(fd);
     139           0 :         return NULL;
     140             :     }
     141           0 :     self->devicename = devicename;
     142           0 :     self->fd = fd;
     143           0 :     self->mode = imode;
     144           0 :     self->icount = self->ocount = 0;
     145           0 :     self->afmts  = afmts;
     146           0 :     return self;
     147             : }
     148             : 
     149             : static void
     150           0 : oss_dealloc(oss_audio_t *self)
     151             : {
     152             :     /* if already closed, don't reclose it */
     153           0 :     if (self->fd != -1)
     154           0 :         close(self->fd);
     155           0 :     PyObject_Del(self);
     156           0 : }
     157             : 
     158             : 
     159             : /* ----------------------------------------------------------------------
     160             :  * Mixer object initialization/deallocation
     161             :  */
     162             : 
     163             : static oss_mixer_t *
     164           0 : newossmixerobject(PyObject *arg)
     165             : {
     166           0 :     char *devicename = NULL;
     167             :     int fd;
     168             :     oss_mixer_t *self;
     169             : 
     170           0 :     if (!PyArg_ParseTuple(arg, "|s", &devicename)) {
     171           0 :         return NULL;
     172             :     }
     173             : 
     174           0 :     if (devicename == NULL) {
     175           0 :         devicename = getenv("MIXERDEV");
     176           0 :         if (devicename == NULL)            /* MIXERDEV not set */
     177           0 :             devicename = "/dev/mixer";
     178             :     }
     179             : 
     180           0 :     if ((fd = open(devicename, O_RDWR)) == -1) {
     181           0 :         PyErr_SetFromErrnoWithFilename(PyExc_IOError, devicename);
     182           0 :         return NULL;
     183             :     }
     184             : 
     185           0 :     if ((self = PyObject_New(oss_mixer_t, &OSSMixerType)) == NULL) {
     186           0 :         close(fd);
     187           0 :         return NULL;
     188             :     }
     189             : 
     190           0 :     self->fd = fd;
     191             : 
     192           0 :     return self;
     193             : }
     194             : 
     195             : static void
     196           0 : oss_mixer_dealloc(oss_mixer_t *self)
     197             : {
     198             :     /* if already closed, don't reclose it */
     199           0 :     if (self->fd != -1)
     200           0 :         close(self->fd);
     201           0 :     PyObject_Del(self);
     202           0 : }
     203             : 
     204             : 
     205             : /* Methods to wrap the OSS ioctls.  The calling convention is pretty
     206             :    simple:
     207             :      nonblock()        -> ioctl(fd, SNDCTL_DSP_NONBLOCK)
     208             :      fmt = setfmt(fmt) -> ioctl(fd, SNDCTL_DSP_SETFMT, &fmt)
     209             :      etc.
     210             : */
     211             : 
     212             : 
     213             : /* ----------------------------------------------------------------------
     214             :  * Helper functions
     215             :  */
     216             : 
     217             : /* Check if a given file descriptor is valid (i.e. hasn't been closed).
     218             :  * If true, return 1. Otherwise, raise ValueError and return 0.
     219             :  */
     220           0 : static int _is_fd_valid(int fd)
     221             : {
     222             :     /* the FD is set to -1 in oss_close()/oss_mixer_close() */
     223           0 :     if (fd >= 0) {
     224           0 :         return 1;
     225             :     } else {
     226           0 :         PyErr_SetString(PyExc_ValueError,
     227             :                         "Operation on closed OSS device.");
     228           0 :         return 0;
     229             :     }
     230             : }
     231             : 
     232             : /* _do_ioctl_1() is a private helper function used for the OSS ioctls --
     233             :    SNDCTL_DSP_{SETFMT,CHANNELS,SPEED} -- that that are called from C
     234             :    like this:
     235             :      ioctl(fd, SNDCTL_DSP_cmd, &arg)
     236             : 
     237             :    where arg is the value to set, and on return the driver sets arg to
     238             :    the value that was actually set.  Mapping this to Python is obvious:
     239             :      arg = dsp.xxx(arg)
     240             : */
     241             : static PyObject *
     242           0 : _do_ioctl_1(int fd, PyObject *args, char *fname, int cmd)
     243             : {
     244           0 :     char argfmt[33] = "i:";
     245             :     int arg;
     246             : 
     247             :     assert(strlen(fname) <= 30);
     248           0 :     strcat(argfmt, fname);
     249           0 :     if (!PyArg_ParseTuple(args, argfmt, &arg))
     250           0 :         return NULL;
     251             : 
     252           0 :     if (ioctl(fd, cmd, &arg) == -1)
     253           0 :         return PyErr_SetFromErrno(PyExc_IOError);
     254           0 :     return PyLong_FromLong(arg);
     255             : }
     256             : 
     257             : 
     258             : /* _do_ioctl_1_internal() is a wrapper for ioctls that take no inputs
     259             :    but return an output -- ie. we need to pass a pointer to a local C
     260             :    variable so the driver can write its output there, but from Python
     261             :    all we see is the return value.  For example,
     262             :    SOUND_MIXER_READ_DEVMASK returns a bitmask of available mixer
     263             :    devices, but does not use the value of the parameter passed-in in any
     264             :    way.
     265             : */
     266             : static PyObject *
     267           0 : _do_ioctl_1_internal(int fd, PyObject *args, char *fname, int cmd)
     268             : {
     269           0 :     char argfmt[32] = ":";
     270           0 :     int arg = 0;
     271             : 
     272             :     assert(strlen(fname) <= 30);
     273           0 :     strcat(argfmt, fname);
     274           0 :     if (!PyArg_ParseTuple(args, argfmt, &arg))
     275           0 :         return NULL;
     276             : 
     277           0 :     if (ioctl(fd, cmd, &arg) == -1)
     278           0 :         return PyErr_SetFromErrno(PyExc_IOError);
     279           0 :     return PyLong_FromLong(arg);
     280             : }
     281             : 
     282             : 
     283             : 
     284             : /* _do_ioctl_0() is a private helper for the no-argument ioctls:
     285             :    SNDCTL_DSP_{SYNC,RESET,POST}. */
     286             : static PyObject *
     287           0 : _do_ioctl_0(int fd, PyObject *args, char *fname, int cmd)
     288             : {
     289           0 :     char argfmt[32] = ":";
     290             :     int rv;
     291             : 
     292             :     assert(strlen(fname) <= 30);
     293           0 :     strcat(argfmt, fname);
     294           0 :     if (!PyArg_ParseTuple(args, argfmt))
     295           0 :         return NULL;
     296             : 
     297             :     /* According to hannu@opensound.com, all three of the ioctls that
     298             :        use this function can block, so release the GIL.  This is
     299             :        especially important for SYNC, which can block for several
     300             :        seconds. */
     301           0 :     Py_BEGIN_ALLOW_THREADS
     302           0 :     rv = ioctl(fd, cmd, 0);
     303           0 :     Py_END_ALLOW_THREADS
     304             : 
     305           0 :     if (rv == -1)
     306           0 :         return PyErr_SetFromErrno(PyExc_IOError);
     307           0 :     Py_INCREF(Py_None);
     308           0 :     return Py_None;
     309             : }
     310             : 
     311             : 
     312             : /* ----------------------------------------------------------------------
     313             :  * Methods of DSP objects (OSSAudioType)
     314             :  */
     315             : 
     316             : static PyObject *
     317           0 : oss_nonblock(oss_audio_t *self, PyObject *unused)
     318             : {
     319           0 :     if (!_is_fd_valid(self->fd))
     320           0 :         return NULL;
     321             : 
     322             :     /* Hmmm: it doesn't appear to be possible to return to blocking
     323             :        mode once we're in non-blocking mode! */
     324           0 :     if (ioctl(self->fd, SNDCTL_DSP_NONBLOCK, NULL) == -1)
     325           0 :         return PyErr_SetFromErrno(PyExc_IOError);
     326           0 :     Py_INCREF(Py_None);
     327           0 :     return Py_None;
     328             : }
     329             : 
     330             : static PyObject *
     331           0 : oss_setfmt(oss_audio_t *self, PyObject *args)
     332             : {
     333           0 :     if (!_is_fd_valid(self->fd))
     334           0 :         return NULL;
     335             : 
     336           0 :     return _do_ioctl_1(self->fd, args, "setfmt", SNDCTL_DSP_SETFMT);
     337             : }
     338             : 
     339             : static PyObject *
     340           0 : oss_getfmts(oss_audio_t *self, PyObject *unused)
     341             : {
     342             :     int mask;
     343             : 
     344           0 :     if (!_is_fd_valid(self->fd))
     345           0 :         return NULL;
     346             : 
     347           0 :     if (ioctl(self->fd, SNDCTL_DSP_GETFMTS, &mask) == -1)
     348           0 :         return PyErr_SetFromErrno(PyExc_IOError);
     349           0 :     return PyLong_FromLong(mask);
     350             : }
     351             : 
     352             : static PyObject *
     353           0 : oss_channels(oss_audio_t *self, PyObject *args)
     354             : {
     355           0 :     if (!_is_fd_valid(self->fd))
     356           0 :         return NULL;
     357             : 
     358           0 :     return _do_ioctl_1(self->fd, args, "channels", SNDCTL_DSP_CHANNELS);
     359             : }
     360             : 
     361             : static PyObject *
     362           0 : oss_speed(oss_audio_t *self, PyObject *args)
     363             : {
     364           0 :     if (!_is_fd_valid(self->fd))
     365           0 :         return NULL;
     366             : 
     367           0 :     return _do_ioctl_1(self->fd, args, "speed", SNDCTL_DSP_SPEED);
     368             : }
     369             : 
     370             : static PyObject *
     371           0 : oss_sync(oss_audio_t *self, PyObject *args)
     372             : {
     373           0 :     if (!_is_fd_valid(self->fd))
     374           0 :         return NULL;
     375             : 
     376           0 :     return _do_ioctl_0(self->fd, args, "sync", SNDCTL_DSP_SYNC);
     377             : }
     378             : 
     379             : static PyObject *
     380           0 : oss_reset(oss_audio_t *self, PyObject *args)
     381             : {
     382           0 :     if (!_is_fd_valid(self->fd))
     383           0 :         return NULL;
     384             : 
     385           0 :     return _do_ioctl_0(self->fd, args, "reset", SNDCTL_DSP_RESET);
     386             : }
     387             : 
     388             : static PyObject *
     389           0 : oss_post(oss_audio_t *self, PyObject *args)
     390             : {
     391           0 :     if (!_is_fd_valid(self->fd))
     392           0 :         return NULL;
     393             : 
     394           0 :     return _do_ioctl_0(self->fd, args, "post", SNDCTL_DSP_POST);
     395             : }
     396             : 
     397             : 
     398             : /* Regular file methods: read(), write(), close(), etc. as well
     399             :    as one convenience method, writeall(). */
     400             : 
     401             : static PyObject *
     402           0 : oss_read(oss_audio_t *self, PyObject *args)
     403             : {
     404             :     int size, count;
     405             :     char *cp;
     406             :     PyObject *rv;
     407             : 
     408           0 :     if (!_is_fd_valid(self->fd))
     409           0 :         return NULL;
     410             : 
     411           0 :     if (!PyArg_ParseTuple(args, "i:read", &size))
     412           0 :         return NULL;
     413           0 :     rv = PyBytes_FromStringAndSize(NULL, size);
     414           0 :     if (rv == NULL)
     415           0 :         return NULL;
     416           0 :     cp = PyBytes_AS_STRING(rv);
     417             : 
     418           0 :     Py_BEGIN_ALLOW_THREADS
     419           0 :     count = read(self->fd, cp, size);
     420           0 :     Py_END_ALLOW_THREADS
     421             : 
     422           0 :     if (count < 0) {
     423           0 :         PyErr_SetFromErrno(PyExc_IOError);
     424           0 :         Py_DECREF(rv);
     425           0 :         return NULL;
     426             :     }
     427           0 :     self->icount += count;
     428           0 :     _PyBytes_Resize(&rv, count);
     429           0 :     return rv;
     430             : }
     431             : 
     432             : static PyObject *
     433           0 : oss_write(oss_audio_t *self, PyObject *args)
     434             : {
     435             :     char *cp;
     436             :     int rv, size;
     437             : 
     438           0 :     if (!_is_fd_valid(self->fd))
     439           0 :         return NULL;
     440             : 
     441           0 :     if (!PyArg_ParseTuple(args, "y#:write", &cp, &size)) {
     442           0 :         return NULL;
     443             :     }
     444             : 
     445           0 :     Py_BEGIN_ALLOW_THREADS
     446           0 :     rv = write(self->fd, cp, size);
     447           0 :     Py_END_ALLOW_THREADS
     448             : 
     449           0 :     if (rv == -1) {
     450           0 :         return PyErr_SetFromErrno(PyExc_IOError);
     451             :     } else {
     452           0 :         self->ocount += rv;
     453             :     }
     454           0 :     return PyLong_FromLong(rv);
     455             : }
     456             : 
     457             : static PyObject *
     458           0 : oss_writeall(oss_audio_t *self, PyObject *args)
     459             : {
     460             :     char *cp;
     461             :     int rv, size;
     462             :     fd_set write_set_fds;
     463             :     int select_rv;
     464             : 
     465             :     /* NB. writeall() is only useful in non-blocking mode: according to
     466             :        Guenter Geiger <geiger@xdv.org> on the linux-audio-dev list
     467             :        (http://eca.cx/lad/2002/11/0380.html), OSS guarantees that
     468             :        write() in blocking mode consumes the whole buffer.  In blocking
     469             :        mode, the behaviour of write() and writeall() from Python is
     470             :        indistinguishable. */
     471             : 
     472           0 :     if (!_is_fd_valid(self->fd))
     473           0 :         return NULL;
     474             : 
     475           0 :     if (!PyArg_ParseTuple(args, "y#:write", &cp, &size))
     476           0 :         return NULL;
     477             : 
     478           0 :     if (!_PyIsSelectable_fd(self->fd)) {
     479           0 :         PyErr_SetString(PyExc_ValueError,
     480             :                         "file descriptor out of range for select");
     481           0 :         return NULL;
     482             :     }
     483             :     /* use select to wait for audio device to be available */
     484           0 :     FD_ZERO(&write_set_fds);
     485           0 :     FD_SET(self->fd, &write_set_fds);
     486             : 
     487           0 :     while (size > 0) {
     488           0 :         Py_BEGIN_ALLOW_THREADS
     489           0 :         select_rv = select(self->fd+1, NULL, &write_set_fds, NULL, NULL);
     490           0 :         Py_END_ALLOW_THREADS
     491             :         assert(select_rv != 0);         /* no timeout, can't expire */
     492           0 :         if (select_rv == -1)
     493           0 :             return PyErr_SetFromErrno(PyExc_IOError);
     494             : 
     495           0 :         Py_BEGIN_ALLOW_THREADS
     496           0 :         rv = write(self->fd, cp, size);
     497           0 :         Py_END_ALLOW_THREADS
     498           0 :         if (rv == -1) {
     499           0 :             if (errno == EAGAIN) {      /* buffer is full, try again */
     500           0 :                 errno = 0;
     501           0 :                 continue;
     502             :             } else                      /* it's a real error */
     503           0 :                 return PyErr_SetFromErrno(PyExc_IOError);
     504             :         } else {                        /* wrote rv bytes */
     505           0 :             self->ocount += rv;
     506           0 :             size -= rv;
     507           0 :             cp += rv;
     508             :         }
     509             :     }
     510           0 :     Py_INCREF(Py_None);
     511           0 :     return Py_None;
     512             : }
     513             : 
     514             : static PyObject *
     515           0 : oss_close(oss_audio_t *self, PyObject *unused)
     516             : {
     517           0 :     if (self->fd >= 0) {
     518           0 :         Py_BEGIN_ALLOW_THREADS
     519           0 :         close(self->fd);
     520           0 :         Py_END_ALLOW_THREADS
     521           0 :         self->fd = -1;
     522             :     }
     523           0 :     Py_INCREF(Py_None);
     524           0 :     return Py_None;
     525             : }
     526             : 
     527             : static PyObject *
     528           0 : oss_self(PyObject *self, PyObject *unused)
     529             : {
     530           0 :     Py_INCREF(self);
     531           0 :     return self;
     532             : }
     533             : 
     534             : static PyObject *
     535           0 : oss_exit(PyObject *self, PyObject *unused)
     536             : {
     537             :     _Py_IDENTIFIER(close);
     538             : 
     539           0 :     PyObject *ret = _PyObject_CallMethodId(self, &PyId_close, NULL);
     540           0 :     if (!ret)
     541           0 :         return NULL;
     542           0 :     Py_DECREF(ret);
     543           0 :     Py_RETURN_NONE;
     544             : }
     545             : 
     546             : static PyObject *
     547           0 : oss_fileno(oss_audio_t *self, PyObject *unused)
     548             : {
     549           0 :     if (!_is_fd_valid(self->fd))
     550           0 :         return NULL;
     551             : 
     552           0 :     return PyLong_FromLong(self->fd);
     553             : }
     554             : 
     555             : 
     556             : /* Convenience methods: these generally wrap a couple of ioctls into one
     557             :    common task. */
     558             : 
     559             : static PyObject *
     560           0 : oss_setparameters(oss_audio_t *self, PyObject *args)
     561             : {
     562           0 :     int wanted_fmt, wanted_channels, wanted_rate, strict=0;
     563             :     int fmt, channels, rate;
     564             :     PyObject * rv;                    /* return tuple (fmt, channels, rate) */
     565             : 
     566           0 :     if (!_is_fd_valid(self->fd))
     567           0 :         return NULL;
     568             : 
     569           0 :     if (!PyArg_ParseTuple(args, "iii|i:setparameters",
     570             :                           &wanted_fmt, &wanted_channels, &wanted_rate,
     571             :                           &strict))
     572           0 :         return NULL;
     573             : 
     574           0 :     fmt = wanted_fmt;
     575           0 :     if (ioctl(self->fd, SNDCTL_DSP_SETFMT, &fmt) == -1) {
     576           0 :         return PyErr_SetFromErrno(PyExc_IOError);
     577             :     }
     578           0 :     if (strict && fmt != wanted_fmt) {
     579           0 :         return PyErr_Format
     580           0 :             (OSSAudioError,
     581             :              "unable to set requested format (wanted %d, got %d)",
     582             :              wanted_fmt, fmt);
     583             :     }
     584             : 
     585           0 :     channels = wanted_channels;
     586           0 :     if (ioctl(self->fd, SNDCTL_DSP_CHANNELS, &channels) == -1) {
     587           0 :         return PyErr_SetFromErrno(PyExc_IOError);
     588             :     }
     589           0 :     if (strict && channels != wanted_channels) {
     590           0 :         return PyErr_Format
     591           0 :             (OSSAudioError,
     592             :              "unable to set requested channels (wanted %d, got %d)",
     593             :              wanted_channels, channels);
     594             :     }
     595             : 
     596           0 :     rate = wanted_rate;
     597           0 :     if (ioctl(self->fd, SNDCTL_DSP_SPEED, &rate) == -1) {
     598           0 :         return PyErr_SetFromErrno(PyExc_IOError);
     599             :     }
     600           0 :     if (strict && rate != wanted_rate) {
     601           0 :         return PyErr_Format
     602           0 :             (OSSAudioError,
     603             :              "unable to set requested rate (wanted %d, got %d)",
     604             :              wanted_rate, rate);
     605             :     }
     606             : 
     607             :     /* Construct the return value: a (fmt, channels, rate) tuple that
     608             :        tells what the audio hardware was actually set to. */
     609           0 :     rv = PyTuple_New(3);
     610           0 :     if (rv == NULL)
     611           0 :         return NULL;
     612           0 :     PyTuple_SET_ITEM(rv, 0, PyLong_FromLong(fmt));
     613           0 :     PyTuple_SET_ITEM(rv, 1, PyLong_FromLong(channels));
     614           0 :     PyTuple_SET_ITEM(rv, 2, PyLong_FromLong(rate));
     615           0 :     return rv;
     616             : }
     617             : 
     618             : static int
     619           0 : _ssize(oss_audio_t *self, int *nchannels, int *ssize)
     620             : {
     621             :     int fmt;
     622             : 
     623           0 :     fmt = 0;
     624           0 :     if (ioctl(self->fd, SNDCTL_DSP_SETFMT, &fmt) < 0)
     625           0 :         return -errno;
     626             : 
     627           0 :     switch (fmt) {
     628             :     case AFMT_MU_LAW:
     629             :     case AFMT_A_LAW:
     630             :     case AFMT_U8:
     631             :     case AFMT_S8:
     632           0 :         *ssize = 1;                     /* 8 bit formats: 1 byte */
     633           0 :         break;
     634             :     case AFMT_S16_LE:
     635             :     case AFMT_S16_BE:
     636             :     case AFMT_U16_LE:
     637             :     case AFMT_U16_BE:
     638           0 :         *ssize = 2;                     /* 16 bit formats: 2 byte */
     639           0 :         break;
     640             :     case AFMT_MPEG:
     641             :     case AFMT_IMA_ADPCM:
     642             :     default:
     643           0 :         return -EOPNOTSUPP;
     644             :     }
     645           0 :     if (ioctl(self->fd, SNDCTL_DSP_CHANNELS, nchannels) < 0)
     646           0 :         return -errno;
     647           0 :     return 0;
     648             : }
     649             : 
     650             : 
     651             : /* bufsize returns the size of the hardware audio buffer in number
     652             :    of samples */
     653             : static PyObject *
     654           0 : oss_bufsize(oss_audio_t *self, PyObject *unused)
     655             : {
     656             :     audio_buf_info ai;
     657           0 :     int nchannels=0, ssize=0;
     658             : 
     659           0 :     if (!_is_fd_valid(self->fd))
     660           0 :         return NULL;
     661             : 
     662           0 :     if (_ssize(self, &nchannels, &ssize) < 0 || !nchannels || !ssize) {
     663           0 :         PyErr_SetFromErrno(PyExc_IOError);
     664           0 :         return NULL;
     665             :     }
     666           0 :     if (ioctl(self->fd, SNDCTL_DSP_GETOSPACE, &ai) < 0) {
     667           0 :         PyErr_SetFromErrno(PyExc_IOError);
     668           0 :         return NULL;
     669             :     }
     670           0 :     return PyLong_FromLong((ai.fragstotal * ai.fragsize) / (nchannels * ssize));
     671             : }
     672             : 
     673             : /* obufcount returns the number of samples that are available in the
     674             :    hardware for playing */
     675             : static PyObject *
     676           0 : oss_obufcount(oss_audio_t *self, PyObject *unused)
     677             : {
     678             :     audio_buf_info ai;
     679           0 :     int nchannels=0, ssize=0;
     680             : 
     681           0 :     if (!_is_fd_valid(self->fd))
     682           0 :         return NULL;
     683             : 
     684           0 :     if (_ssize(self, &nchannels, &ssize) < 0 || !nchannels || !ssize) {
     685           0 :         PyErr_SetFromErrno(PyExc_IOError);
     686           0 :         return NULL;
     687             :     }
     688           0 :     if (ioctl(self->fd, SNDCTL_DSP_GETOSPACE, &ai) < 0) {
     689           0 :         PyErr_SetFromErrno(PyExc_IOError);
     690           0 :         return NULL;
     691             :     }
     692           0 :     return PyLong_FromLong((ai.fragstotal * ai.fragsize - ai.bytes) /
     693           0 :                           (ssize * nchannels));
     694             : }
     695             : 
     696             : /* obufcount returns the number of samples that can be played without
     697             :    blocking */
     698             : static PyObject *
     699           0 : oss_obuffree(oss_audio_t *self, PyObject *unused)
     700             : {
     701             :     audio_buf_info ai;
     702           0 :     int nchannels=0, ssize=0;
     703             : 
     704           0 :     if (!_is_fd_valid(self->fd))
     705           0 :         return NULL;
     706             : 
     707           0 :     if (_ssize(self, &nchannels, &ssize) < 0 || !nchannels || !ssize) {
     708           0 :         PyErr_SetFromErrno(PyExc_IOError);
     709           0 :         return NULL;
     710             :     }
     711           0 :     if (ioctl(self->fd, SNDCTL_DSP_GETOSPACE, &ai) < 0) {
     712           0 :         PyErr_SetFromErrno(PyExc_IOError);
     713           0 :         return NULL;
     714             :     }
     715           0 :     return PyLong_FromLong(ai.bytes / (ssize * nchannels));
     716             : }
     717             : 
     718             : static PyObject *
     719           0 : oss_getptr(oss_audio_t *self, PyObject *unused)
     720             : {
     721             :     count_info info;
     722             :     int req;
     723             : 
     724           0 :     if (!_is_fd_valid(self->fd))
     725           0 :         return NULL;
     726             : 
     727           0 :     if (self->mode == O_RDONLY)
     728           0 :         req = SNDCTL_DSP_GETIPTR;
     729             :     else
     730           0 :         req = SNDCTL_DSP_GETOPTR;
     731           0 :     if (ioctl(self->fd, req, &info) == -1) {
     732           0 :         PyErr_SetFromErrno(PyExc_IOError);
     733           0 :         return NULL;
     734             :     }
     735           0 :     return Py_BuildValue("iii", info.bytes, info.blocks, info.ptr);
     736             : }
     737             : 
     738             : 
     739             : /* ----------------------------------------------------------------------
     740             :  * Methods of mixer objects (OSSMixerType)
     741             :  */
     742             : 
     743             : static PyObject *
     744           0 : oss_mixer_close(oss_mixer_t *self, PyObject *unused)
     745             : {
     746           0 :     if (self->fd >= 0) {
     747           0 :         close(self->fd);
     748           0 :         self->fd = -1;
     749             :     }
     750           0 :     Py_INCREF(Py_None);
     751           0 :     return Py_None;
     752             : }
     753             : 
     754             : static PyObject *
     755           0 : oss_mixer_fileno(oss_mixer_t *self, PyObject *unused)
     756             : {
     757           0 :     if (!_is_fd_valid(self->fd))
     758           0 :         return NULL;
     759             : 
     760           0 :     return PyLong_FromLong(self->fd);
     761             : }
     762             : 
     763             : /* Simple mixer interface methods */
     764             : 
     765             : static PyObject *
     766           0 : oss_mixer_controls(oss_mixer_t *self, PyObject *args)
     767             : {
     768           0 :     if (!_is_fd_valid(self->fd))
     769           0 :         return NULL;
     770             : 
     771           0 :     return _do_ioctl_1_internal(self->fd, args, "controls",
     772             :         SOUND_MIXER_READ_DEVMASK);
     773             : }
     774             : 
     775             : static PyObject *
     776           0 : oss_mixer_stereocontrols(oss_mixer_t *self, PyObject *args)
     777             : {
     778           0 :     if (!_is_fd_valid(self->fd))
     779           0 :         return NULL;
     780             : 
     781           0 :     return _do_ioctl_1_internal(self->fd, args, "stereocontrols",
     782             :         SOUND_MIXER_READ_STEREODEVS);
     783             : }
     784             : 
     785             : static PyObject *
     786           0 : oss_mixer_reccontrols(oss_mixer_t *self, PyObject *args)
     787             : {
     788           0 :     if (!_is_fd_valid(self->fd))
     789           0 :         return NULL;
     790             : 
     791           0 :     return _do_ioctl_1_internal(self->fd, args, "reccontrols",
     792             :         SOUND_MIXER_READ_RECMASK);
     793             : }
     794             : 
     795             : static PyObject *
     796           0 : oss_mixer_get(oss_mixer_t *self, PyObject *args)
     797             : {
     798             :     int channel, volume;
     799             : 
     800           0 :     if (!_is_fd_valid(self->fd))
     801           0 :         return NULL;
     802             : 
     803             :     /* Can't use _do_ioctl_1 because of encoded arg thingy. */
     804           0 :     if (!PyArg_ParseTuple(args, "i:get", &channel))
     805           0 :         return NULL;
     806             : 
     807           0 :     if (channel < 0 || channel > SOUND_MIXER_NRDEVICES) {
     808           0 :         PyErr_SetString(OSSAudioError, "Invalid mixer channel specified.");
     809           0 :         return NULL;
     810             :     }
     811             : 
     812           0 :     if (ioctl(self->fd, MIXER_READ(channel), &volume) == -1)
     813           0 :         return PyErr_SetFromErrno(PyExc_IOError);
     814             : 
     815           0 :     return Py_BuildValue("(ii)", volume & 0xff, (volume & 0xff00) >> 8);
     816             : }
     817             : 
     818             : static PyObject *
     819           0 : oss_mixer_set(oss_mixer_t *self, PyObject *args)
     820             : {
     821             :     int channel, volume, leftVol, rightVol;
     822             : 
     823           0 :     if (!_is_fd_valid(self->fd))
     824           0 :         return NULL;
     825             : 
     826             :     /* Can't use _do_ioctl_1 because of encoded arg thingy. */
     827           0 :     if (!PyArg_ParseTuple(args, "i(ii):set", &channel, &leftVol, &rightVol))
     828           0 :         return NULL;
     829             : 
     830           0 :     if (channel < 0 || channel > SOUND_MIXER_NRDEVICES) {
     831           0 :         PyErr_SetString(OSSAudioError, "Invalid mixer channel specified.");
     832           0 :         return NULL;
     833             :     }
     834             : 
     835           0 :     if (leftVol < 0 || rightVol < 0 || leftVol > 100 || rightVol > 100) {
     836           0 :         PyErr_SetString(OSSAudioError, "Volumes must be between 0 and 100.");
     837           0 :         return NULL;
     838             :     }
     839             : 
     840           0 :     volume = (rightVol << 8) | leftVol;
     841             : 
     842           0 :     if (ioctl(self->fd, MIXER_WRITE(channel), &volume) == -1)
     843           0 :         return PyErr_SetFromErrno(PyExc_IOError);
     844             : 
     845           0 :     return Py_BuildValue("(ii)", volume & 0xff, (volume & 0xff00) >> 8);
     846             : }
     847             : 
     848             : static PyObject *
     849           0 : oss_mixer_get_recsrc(oss_mixer_t *self, PyObject *args)
     850             : {
     851           0 :     if (!_is_fd_valid(self->fd))
     852           0 :         return NULL;
     853             : 
     854           0 :     return _do_ioctl_1_internal(self->fd, args, "get_recsrc",
     855             :         SOUND_MIXER_READ_RECSRC);
     856             : }
     857             : 
     858             : static PyObject *
     859           0 : oss_mixer_set_recsrc(oss_mixer_t *self, PyObject *args)
     860             : {
     861           0 :     if (!_is_fd_valid(self->fd))
     862           0 :         return NULL;
     863             : 
     864           0 :     return _do_ioctl_1(self->fd, args, "set_recsrc",
     865             :         SOUND_MIXER_WRITE_RECSRC);
     866             : }
     867             : 
     868             : 
     869             : /* ----------------------------------------------------------------------
     870             :  * Method tables and other bureaucracy
     871             :  */
     872             : 
     873             : static PyMethodDef oss_methods[] = {
     874             :     /* Regular file methods */
     875             :     { "read",           (PyCFunction)oss_read, METH_VARARGS },
     876             :     { "write",          (PyCFunction)oss_write, METH_VARARGS },
     877             :     { "writeall",       (PyCFunction)oss_writeall, METH_VARARGS },
     878             :     { "close",          (PyCFunction)oss_close, METH_NOARGS },
     879             :     { "fileno",         (PyCFunction)oss_fileno, METH_NOARGS },
     880             : 
     881             :     /* Simple ioctl wrappers */
     882             :     { "nonblock",       (PyCFunction)oss_nonblock, METH_NOARGS },
     883             :     { "setfmt",         (PyCFunction)oss_setfmt, METH_VARARGS },
     884             :     { "getfmts",        (PyCFunction)oss_getfmts, METH_NOARGS },
     885             :     { "channels",       (PyCFunction)oss_channels, METH_VARARGS },
     886             :     { "speed",          (PyCFunction)oss_speed, METH_VARARGS },
     887             :     { "sync",           (PyCFunction)oss_sync, METH_VARARGS },
     888             :     { "reset",          (PyCFunction)oss_reset, METH_VARARGS },
     889             :     { "post",           (PyCFunction)oss_post, METH_VARARGS },
     890             : 
     891             :     /* Convenience methods -- wrap a couple of ioctls together */
     892             :     { "setparameters",  (PyCFunction)oss_setparameters, METH_VARARGS },
     893             :     { "bufsize",        (PyCFunction)oss_bufsize, METH_NOARGS },
     894             :     { "obufcount",      (PyCFunction)oss_obufcount, METH_NOARGS },
     895             :     { "obuffree",       (PyCFunction)oss_obuffree, METH_NOARGS },
     896             :     { "getptr",         (PyCFunction)oss_getptr, METH_NOARGS },
     897             : 
     898             :     /* Aliases for backwards compatibility */
     899             :     { "flush",          (PyCFunction)oss_sync, METH_VARARGS },
     900             : 
     901             :     /* Support for the context manager protocol */
     902             :     { "__enter__",      oss_self, METH_NOARGS },
     903             :     { "__exit__",       oss_exit, METH_VARARGS },
     904             : 
     905             :     { NULL,             NULL}           /* sentinel */
     906             : };
     907             : 
     908             : static PyMethodDef oss_mixer_methods[] = {
     909             :     /* Regular file method - OSS mixers are ioctl-only interface */
     910             :     { "close",          (PyCFunction)oss_mixer_close, METH_NOARGS },
     911             :     { "fileno",         (PyCFunction)oss_mixer_fileno, METH_NOARGS },
     912             : 
     913             :     /* Support for the context manager protocol */
     914             :     { "__enter__",      oss_self, METH_NOARGS },
     915             :     { "__exit__",       oss_exit, METH_VARARGS },
     916             : 
     917             :     /* Simple ioctl wrappers */
     918             :     { "controls",       (PyCFunction)oss_mixer_controls, METH_VARARGS },
     919             :     { "stereocontrols", (PyCFunction)oss_mixer_stereocontrols, METH_VARARGS},
     920             :     { "reccontrols",    (PyCFunction)oss_mixer_reccontrols, METH_VARARGS},
     921             :     { "get",            (PyCFunction)oss_mixer_get, METH_VARARGS },
     922             :     { "set",            (PyCFunction)oss_mixer_set, METH_VARARGS },
     923             :     { "get_recsrc",     (PyCFunction)oss_mixer_get_recsrc, METH_VARARGS },
     924             :     { "set_recsrc",     (PyCFunction)oss_mixer_set_recsrc, METH_VARARGS },
     925             : 
     926             :     { NULL,             NULL}
     927             : };
     928             : 
     929             : static PyObject *
     930           0 : oss_getattro(oss_audio_t *self, PyObject *nameobj)
     931             : {
     932           0 :     char *name = "";
     933           0 :     PyObject * rval = NULL;
     934             : 
     935           0 :     if (PyUnicode_Check(nameobj))
     936           0 :         name = _PyUnicode_AsString(nameobj);
     937             : 
     938           0 :     if (strcmp(name, "closed") == 0) {
     939           0 :         rval = (self->fd == -1) ? Py_True : Py_False;
     940           0 :         Py_INCREF(rval);
     941             :     }
     942           0 :     else if (strcmp(name, "name") == 0) {
     943           0 :         rval = PyUnicode_FromString(self->devicename);
     944             :     }
     945           0 :     else if (strcmp(name, "mode") == 0) {
     946             :         /* No need for a "default" in this switch: from newossobject(),
     947             :            self->mode can only be one of these three values. */
     948           0 :         switch(self->mode) {
     949             :             case O_RDONLY:
     950           0 :                 rval = PyUnicode_FromString("r");
     951           0 :                 break;
     952             :             case O_RDWR:
     953           0 :                 rval = PyUnicode_FromString("rw");
     954           0 :                 break;
     955             :             case O_WRONLY:
     956           0 :                 rval = PyUnicode_FromString("w");
     957           0 :                 break;
     958             :         }
     959             :     }
     960             :     else {
     961           0 :         rval = PyObject_GenericGetAttr((PyObject *)self, nameobj);
     962             :     }
     963           0 :     return rval;
     964             : }
     965             : 
     966             : static PyTypeObject OSSAudioType = {
     967             :     PyVarObject_HEAD_INIT(&PyType_Type, 0)
     968             :     "ossaudiodev.oss_audio_device", /*tp_name*/
     969             :     sizeof(oss_audio_t),        /*tp_size*/
     970             :     0,                          /*tp_itemsize*/
     971             :     /* methods */
     972             :     (destructor)oss_dealloc,    /*tp_dealloc*/
     973             :     0,                          /*tp_print*/
     974             :     0,                          /*tp_getattr*/
     975             :     0,                          /*tp_setattr*/
     976             :     0,                          /*tp_reserved*/
     977             :     0,                          /*tp_repr*/
     978             :     0,                          /*tp_as_number*/
     979             :     0,                          /*tp_as_sequence*/
     980             :     0,                          /*tp_as_mapping*/
     981             :     0,                          /*tp_hash*/
     982             :     0,                          /*tp_call*/
     983             :     0,                          /*tp_str*/
     984             :     (getattrofunc)oss_getattro, /*tp_getattro*/
     985             :     0,                          /*tp_setattro*/
     986             :     0,                          /*tp_as_buffer*/
     987             :     Py_TPFLAGS_DEFAULT,         /*tp_flags*/
     988             :     0,                          /*tp_doc*/
     989             :     0,                          /*tp_traverse*/
     990             :     0,                          /*tp_clear*/
     991             :     0,                          /*tp_richcompare*/
     992             :     0,                          /*tp_weaklistoffset*/
     993             :     0,                          /*tp_iter*/
     994             :     0,                          /*tp_iternext*/
     995             :     oss_methods,                /*tp_methods*/
     996             : };
     997             : 
     998             : static PyTypeObject OSSMixerType = {
     999             :     PyVarObject_HEAD_INIT(&PyType_Type, 0)
    1000             :     "ossaudiodev.oss_mixer_device", /*tp_name*/
    1001             :     sizeof(oss_mixer_t),            /*tp_size*/
    1002             :     0,                              /*tp_itemsize*/
    1003             :     /* methods */
    1004             :     (destructor)oss_mixer_dealloc,  /*tp_dealloc*/
    1005             :     0,                              /*tp_print*/
    1006             :     0,                              /*tp_getattr*/
    1007             :     0,                              /*tp_setattr*/
    1008             :     0,                              /*tp_reserved*/
    1009             :     0,                              /*tp_repr*/
    1010             :     0,                              /*tp_as_number*/
    1011             :     0,                              /*tp_as_sequence*/
    1012             :     0,                              /*tp_as_mapping*/
    1013             :     0,                              /*tp_hash*/
    1014             :     0,                              /*tp_call*/
    1015             :     0,                              /*tp_str*/
    1016             :     0,                              /*tp_getattro*/
    1017             :     0,                              /*tp_setattro*/
    1018             :     0,                              /*tp_as_buffer*/
    1019             :     Py_TPFLAGS_DEFAULT,             /*tp_flags*/
    1020             :     0,                              /*tp_doc*/
    1021             :     0,                              /*tp_traverse*/
    1022             :     0,                              /*tp_clear*/
    1023             :     0,                              /*tp_richcompare*/
    1024             :     0,                              /*tp_weaklistoffset*/
    1025             :     0,                              /*tp_iter*/
    1026             :     0,                              /*tp_iternext*/
    1027             :     oss_mixer_methods,              /*tp_methods*/
    1028             : };
    1029             : 
    1030             : 
    1031             : static PyObject *
    1032           0 : ossopen(PyObject *self, PyObject *args)
    1033             : {
    1034           0 :     return (PyObject *)newossobject(args);
    1035             : }
    1036             : 
    1037             : static PyObject *
    1038           0 : ossopenmixer(PyObject *self, PyObject *args)
    1039             : {
    1040           0 :     return (PyObject *)newossmixerobject(args);
    1041             : }
    1042             : 
    1043             : static PyMethodDef ossaudiodev_methods[] = {
    1044             :     { "open", ossopen, METH_VARARGS },
    1045             :     { "openmixer", ossopenmixer, METH_VARARGS },
    1046             :     { 0, 0 },
    1047             : };
    1048             : 
    1049             : 
    1050             : #define _EXPORT_INT(mod, name) \
    1051             :   if (PyModule_AddIntConstant(mod, #name, (long) (name)) == -1) return NULL;
    1052             : 
    1053             : 
    1054             : static char *control_labels[] = SOUND_DEVICE_LABELS;
    1055             : static char *control_names[] = SOUND_DEVICE_NAMES;
    1056             : 
    1057             : 
    1058             : static int
    1059           0 : build_namelists (PyObject *module)
    1060             : {
    1061             :     PyObject *labels;
    1062             :     PyObject *names;
    1063             :     PyObject *s;
    1064             :     int num_controls;
    1065             :     int i;
    1066             : 
    1067           0 :     num_controls = Py_ARRAY_LENGTH(control_labels);
    1068             :     assert(num_controls == Py_ARRAY_LENGTH(control_names));
    1069             : 
    1070           0 :     labels = PyList_New(num_controls);
    1071           0 :     names = PyList_New(num_controls);
    1072           0 :     if (labels == NULL || names == NULL)
    1073             :         goto error2;
    1074           0 :     for (i = 0; i < num_controls; i++) {
    1075           0 :         s = PyUnicode_FromString(control_labels[i]);
    1076           0 :         if (s == NULL)
    1077           0 :             goto error2;
    1078           0 :         PyList_SET_ITEM(labels, i, s);
    1079             : 
    1080           0 :         s = PyUnicode_FromString(control_names[i]);
    1081           0 :         if (s == NULL)
    1082           0 :             goto error2;
    1083           0 :         PyList_SET_ITEM(names, i, s);
    1084             :     }
    1085             : 
    1086           0 :     if (PyModule_AddObject(module, "control_labels", labels) == -1)
    1087           0 :         goto error2;
    1088           0 :     if (PyModule_AddObject(module, "control_names", names) == -1)
    1089           0 :         goto error1;
    1090             : 
    1091           0 :     return 0;
    1092             : 
    1093             : error2:
    1094           0 :     Py_XDECREF(labels);
    1095             : error1:
    1096           0 :     Py_XDECREF(names);
    1097           0 :     return -1;
    1098             : }
    1099             : 
    1100             : 
    1101             : static struct PyModuleDef ossaudiodevmodule = {
    1102             :         PyModuleDef_HEAD_INIT,
    1103             :         "ossaudiodev",
    1104             :         NULL,
    1105             :         -1,
    1106             :         ossaudiodev_methods,
    1107             :         NULL,
    1108             :         NULL,
    1109             :         NULL,
    1110             :         NULL
    1111             : };
    1112             : 
    1113             : PyMODINIT_FUNC
    1114           0 : PyInit_ossaudiodev(void)
    1115             : {
    1116             :     PyObject *m;
    1117             : 
    1118           0 :     if (PyType_Ready(&OSSAudioType) < 0)
    1119           0 :         return NULL;
    1120             : 
    1121           0 :     if (PyType_Ready(&OSSMixerType) < 0)
    1122           0 :         return NULL;
    1123             : 
    1124           0 :     m = PyModule_Create(&ossaudiodevmodule);
    1125           0 :     if (m == NULL)
    1126           0 :         return NULL;
    1127             : 
    1128           0 :     OSSAudioError = PyErr_NewException("ossaudiodev.OSSAudioError",
    1129             :                                        NULL, NULL);
    1130           0 :     if (OSSAudioError) {
    1131             :         /* Each call to PyModule_AddObject decrefs it; compensate: */
    1132           0 :         Py_INCREF(OSSAudioError);
    1133           0 :         Py_INCREF(OSSAudioError);
    1134           0 :         PyModule_AddObject(m, "error", OSSAudioError);
    1135           0 :         PyModule_AddObject(m, "OSSAudioError", OSSAudioError);
    1136             :     }
    1137             : 
    1138             :     /* Build 'control_labels' and 'control_names' lists and add them
    1139             :        to the module. */
    1140           0 :     if (build_namelists(m) == -1)       /* XXX what to do here? */
    1141           0 :         return NULL;
    1142             : 
    1143             :     /* Expose the audio format numbers -- essential! */
    1144           0 :     _EXPORT_INT(m, AFMT_QUERY);
    1145           0 :     _EXPORT_INT(m, AFMT_MU_LAW);
    1146           0 :     _EXPORT_INT(m, AFMT_A_LAW);
    1147           0 :     _EXPORT_INT(m, AFMT_IMA_ADPCM);
    1148           0 :     _EXPORT_INT(m, AFMT_U8);
    1149           0 :     _EXPORT_INT(m, AFMT_S16_LE);
    1150           0 :     _EXPORT_INT(m, AFMT_S16_BE);
    1151           0 :     _EXPORT_INT(m, AFMT_S8);
    1152           0 :     _EXPORT_INT(m, AFMT_U16_LE);
    1153           0 :     _EXPORT_INT(m, AFMT_U16_BE);
    1154           0 :     _EXPORT_INT(m, AFMT_MPEG);
    1155             : #ifdef AFMT_AC3
    1156           0 :     _EXPORT_INT(m, AFMT_AC3);
    1157             : #endif
    1158             : #ifdef AFMT_S16_NE
    1159           0 :     _EXPORT_INT(m, AFMT_S16_NE);
    1160             : #endif
    1161             : #ifdef AFMT_U16_NE
    1162             :     _EXPORT_INT(m, AFMT_U16_NE);
    1163             : #endif
    1164             : #ifdef AFMT_S32_LE
    1165             :     _EXPORT_INT(m, AFMT_S32_LE);
    1166             : #endif
    1167             : #ifdef AFMT_S32_BE
    1168             :     _EXPORT_INT(m, AFMT_S32_BE);
    1169             : #endif
    1170             : #ifdef AFMT_MPEG
    1171           0 :     _EXPORT_INT(m, AFMT_MPEG);
    1172             : #endif
    1173             : 
    1174             :     /* Expose the sound mixer device numbers. */
    1175           0 :     _EXPORT_INT(m, SOUND_MIXER_NRDEVICES);
    1176           0 :     _EXPORT_INT(m, SOUND_MIXER_VOLUME);
    1177           0 :     _EXPORT_INT(m, SOUND_MIXER_BASS);
    1178           0 :     _EXPORT_INT(m, SOUND_MIXER_TREBLE);
    1179           0 :     _EXPORT_INT(m, SOUND_MIXER_SYNTH);
    1180           0 :     _EXPORT_INT(m, SOUND_MIXER_PCM);
    1181           0 :     _EXPORT_INT(m, SOUND_MIXER_SPEAKER);
    1182           0 :     _EXPORT_INT(m, SOUND_MIXER_LINE);
    1183           0 :     _EXPORT_INT(m, SOUND_MIXER_MIC);
    1184           0 :     _EXPORT_INT(m, SOUND_MIXER_CD);
    1185           0 :     _EXPORT_INT(m, SOUND_MIXER_IMIX);
    1186           0 :     _EXPORT_INT(m, SOUND_MIXER_ALTPCM);
    1187           0 :     _EXPORT_INT(m, SOUND_MIXER_RECLEV);
    1188           0 :     _EXPORT_INT(m, SOUND_MIXER_IGAIN);
    1189           0 :     _EXPORT_INT(m, SOUND_MIXER_OGAIN);
    1190           0 :     _EXPORT_INT(m, SOUND_MIXER_LINE1);
    1191           0 :     _EXPORT_INT(m, SOUND_MIXER_LINE2);
    1192           0 :     _EXPORT_INT(m, SOUND_MIXER_LINE3);
    1193             : #ifdef SOUND_MIXER_DIGITAL1
    1194           0 :     _EXPORT_INT(m, SOUND_MIXER_DIGITAL1);
    1195             : #endif
    1196             : #ifdef SOUND_MIXER_DIGITAL2
    1197           0 :     _EXPORT_INT(m, SOUND_MIXER_DIGITAL2);
    1198             : #endif
    1199             : #ifdef SOUND_MIXER_DIGITAL3
    1200           0 :     _EXPORT_INT(m, SOUND_MIXER_DIGITAL3);
    1201             : #endif
    1202             : #ifdef SOUND_MIXER_PHONEIN
    1203           0 :     _EXPORT_INT(m, SOUND_MIXER_PHONEIN);
    1204             : #endif
    1205             : #ifdef SOUND_MIXER_PHONEOUT
    1206           0 :     _EXPORT_INT(m, SOUND_MIXER_PHONEOUT);
    1207             : #endif
    1208             : #ifdef SOUND_MIXER_VIDEO
    1209           0 :     _EXPORT_INT(m, SOUND_MIXER_VIDEO);
    1210             : #endif
    1211             : #ifdef SOUND_MIXER_RADIO
    1212           0 :     _EXPORT_INT(m, SOUND_MIXER_RADIO);
    1213             : #endif
    1214             : #ifdef SOUND_MIXER_MONITOR
    1215           0 :     _EXPORT_INT(m, SOUND_MIXER_MONITOR);
    1216             : #endif
    1217             : 
    1218             :     /* Expose all the ioctl numbers for masochists who like to do this
    1219             :        stuff directly. */
    1220           0 :     _EXPORT_INT(m, SNDCTL_COPR_HALT);
    1221           0 :     _EXPORT_INT(m, SNDCTL_COPR_LOAD);
    1222           0 :     _EXPORT_INT(m, SNDCTL_COPR_RCODE);
    1223           0 :     _EXPORT_INT(m, SNDCTL_COPR_RCVMSG);
    1224           0 :     _EXPORT_INT(m, SNDCTL_COPR_RDATA);
    1225           0 :     _EXPORT_INT(m, SNDCTL_COPR_RESET);
    1226           0 :     _EXPORT_INT(m, SNDCTL_COPR_RUN);
    1227           0 :     _EXPORT_INT(m, SNDCTL_COPR_SENDMSG);
    1228           0 :     _EXPORT_INT(m, SNDCTL_COPR_WCODE);
    1229           0 :     _EXPORT_INT(m, SNDCTL_COPR_WDATA);
    1230             : #ifdef SNDCTL_DSP_BIND_CHANNEL
    1231           0 :     _EXPORT_INT(m, SNDCTL_DSP_BIND_CHANNEL);
    1232             : #endif
    1233           0 :     _EXPORT_INT(m, SNDCTL_DSP_CHANNELS);
    1234           0 :     _EXPORT_INT(m, SNDCTL_DSP_GETBLKSIZE);
    1235           0 :     _EXPORT_INT(m, SNDCTL_DSP_GETCAPS);
    1236             : #ifdef SNDCTL_DSP_GETCHANNELMASK
    1237           0 :     _EXPORT_INT(m, SNDCTL_DSP_GETCHANNELMASK);
    1238             : #endif
    1239           0 :     _EXPORT_INT(m, SNDCTL_DSP_GETFMTS);
    1240           0 :     _EXPORT_INT(m, SNDCTL_DSP_GETIPTR);
    1241           0 :     _EXPORT_INT(m, SNDCTL_DSP_GETISPACE);
    1242             : #ifdef SNDCTL_DSP_GETODELAY
    1243           0 :     _EXPORT_INT(m, SNDCTL_DSP_GETODELAY);
    1244             : #endif
    1245           0 :     _EXPORT_INT(m, SNDCTL_DSP_GETOPTR);
    1246           0 :     _EXPORT_INT(m, SNDCTL_DSP_GETOSPACE);
    1247             : #ifdef SNDCTL_DSP_GETSPDIF
    1248           0 :     _EXPORT_INT(m, SNDCTL_DSP_GETSPDIF);
    1249             : #endif
    1250           0 :     _EXPORT_INT(m, SNDCTL_DSP_GETTRIGGER);
    1251           0 :     _EXPORT_INT(m, SNDCTL_DSP_MAPINBUF);
    1252           0 :     _EXPORT_INT(m, SNDCTL_DSP_MAPOUTBUF);
    1253           0 :     _EXPORT_INT(m, SNDCTL_DSP_NONBLOCK);
    1254           0 :     _EXPORT_INT(m, SNDCTL_DSP_POST);
    1255             : #ifdef SNDCTL_DSP_PROFILE
    1256           0 :     _EXPORT_INT(m, SNDCTL_DSP_PROFILE);
    1257             : #endif
    1258           0 :     _EXPORT_INT(m, SNDCTL_DSP_RESET);
    1259           0 :     _EXPORT_INT(m, SNDCTL_DSP_SAMPLESIZE);
    1260           0 :     _EXPORT_INT(m, SNDCTL_DSP_SETDUPLEX);
    1261           0 :     _EXPORT_INT(m, SNDCTL_DSP_SETFMT);
    1262           0 :     _EXPORT_INT(m, SNDCTL_DSP_SETFRAGMENT);
    1263             : #ifdef SNDCTL_DSP_SETSPDIF
    1264           0 :     _EXPORT_INT(m, SNDCTL_DSP_SETSPDIF);
    1265             : #endif
    1266           0 :     _EXPORT_INT(m, SNDCTL_DSP_SETSYNCRO);
    1267           0 :     _EXPORT_INT(m, SNDCTL_DSP_SETTRIGGER);
    1268           0 :     _EXPORT_INT(m, SNDCTL_DSP_SPEED);
    1269           0 :     _EXPORT_INT(m, SNDCTL_DSP_STEREO);
    1270           0 :     _EXPORT_INT(m, SNDCTL_DSP_SUBDIVIDE);
    1271           0 :     _EXPORT_INT(m, SNDCTL_DSP_SYNC);
    1272           0 :     _EXPORT_INT(m, SNDCTL_FM_4OP_ENABLE);
    1273           0 :     _EXPORT_INT(m, SNDCTL_FM_LOAD_INSTR);
    1274           0 :     _EXPORT_INT(m, SNDCTL_MIDI_INFO);
    1275           0 :     _EXPORT_INT(m, SNDCTL_MIDI_MPUCMD);
    1276           0 :     _EXPORT_INT(m, SNDCTL_MIDI_MPUMODE);
    1277           0 :     _EXPORT_INT(m, SNDCTL_MIDI_PRETIME);
    1278           0 :     _EXPORT_INT(m, SNDCTL_SEQ_CTRLRATE);
    1279           0 :     _EXPORT_INT(m, SNDCTL_SEQ_GETINCOUNT);
    1280           0 :     _EXPORT_INT(m, SNDCTL_SEQ_GETOUTCOUNT);
    1281             : #ifdef SNDCTL_SEQ_GETTIME
    1282           0 :     _EXPORT_INT(m, SNDCTL_SEQ_GETTIME);
    1283             : #endif
    1284           0 :     _EXPORT_INT(m, SNDCTL_SEQ_NRMIDIS);
    1285           0 :     _EXPORT_INT(m, SNDCTL_SEQ_NRSYNTHS);
    1286           0 :     _EXPORT_INT(m, SNDCTL_SEQ_OUTOFBAND);
    1287           0 :     _EXPORT_INT(m, SNDCTL_SEQ_PANIC);
    1288           0 :     _EXPORT_INT(m, SNDCTL_SEQ_PERCMODE);
    1289           0 :     _EXPORT_INT(m, SNDCTL_SEQ_RESET);
    1290           0 :     _EXPORT_INT(m, SNDCTL_SEQ_RESETSAMPLES);
    1291           0 :     _EXPORT_INT(m, SNDCTL_SEQ_SYNC);
    1292           0 :     _EXPORT_INT(m, SNDCTL_SEQ_TESTMIDI);
    1293           0 :     _EXPORT_INT(m, SNDCTL_SEQ_THRESHOLD);
    1294             : #ifdef SNDCTL_SYNTH_CONTROL
    1295           0 :     _EXPORT_INT(m, SNDCTL_SYNTH_CONTROL);
    1296             : #endif
    1297             : #ifdef SNDCTL_SYNTH_ID
    1298           0 :     _EXPORT_INT(m, SNDCTL_SYNTH_ID);
    1299             : #endif
    1300           0 :     _EXPORT_INT(m, SNDCTL_SYNTH_INFO);
    1301           0 :     _EXPORT_INT(m, SNDCTL_SYNTH_MEMAVL);
    1302             : #ifdef SNDCTL_SYNTH_REMOVESAMPLE
    1303           0 :     _EXPORT_INT(m, SNDCTL_SYNTH_REMOVESAMPLE);
    1304             : #endif
    1305           0 :     _EXPORT_INT(m, SNDCTL_TMR_CONTINUE);
    1306           0 :     _EXPORT_INT(m, SNDCTL_TMR_METRONOME);
    1307           0 :     _EXPORT_INT(m, SNDCTL_TMR_SELECT);
    1308           0 :     _EXPORT_INT(m, SNDCTL_TMR_SOURCE);
    1309           0 :     _EXPORT_INT(m, SNDCTL_TMR_START);
    1310           0 :     _EXPORT_INT(m, SNDCTL_TMR_STOP);
    1311           0 :     _EXPORT_INT(m, SNDCTL_TMR_TEMPO);
    1312           0 :     _EXPORT_INT(m, SNDCTL_TMR_TIMEBASE);
    1313           0 :     return m;
    1314             : }

Generated by: LCOV version 1.10