LCOV - code coverage report
Current view: top level - Modules - ossaudiodev.c (source / functions) Hit Total Coverage
Test: CPython 3.12 LCOV report [commit acb105a7c1f] Lines: 142 523 27.2 %
Date: 2022-07-20 13:12:14 Functions: 2 44 4.5 %
Branches: 127 469 27.1 %

           Branch data     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                 :            :  * $Id$
      18                 :            :  */
      19                 :            : 
      20                 :            : #ifndef Py_BUILD_CORE_BUILTIN
      21                 :            : #  define Py_BUILD_CORE_MODULE 1
      22                 :            : #endif
      23                 :            : #define NEEDS_PY_IDENTIFIER
      24                 :            : 
      25                 :            : #define PY_SSIZE_T_CLEAN
      26                 :            : #include "Python.h"
      27                 :            : #include "pycore_fileutils.h"     // _Py_write()
      28                 :            : #include "structmember.h"         // PyMemberDef
      29                 :            : 
      30                 :            : #include <stdlib.h>               // getenv()
      31                 :            : #ifdef HAVE_FCNTL_H
      32                 :            : #include <fcntl.h>
      33                 :            : #else
      34                 :            : #define O_RDONLY 00
      35                 :            : #define O_WRONLY 01
      36                 :            : #endif
      37                 :            : 
      38                 :            : #include <sys/ioctl.h>
      39                 :            : #ifdef __ANDROID__
      40                 :            : #include <linux/soundcard.h>
      41                 :            : #else
      42                 :            : #include <sys/soundcard.h>
      43                 :            : #endif
      44                 :            : 
      45                 :            : #ifdef __linux__
      46                 :            : 
      47                 :            : #ifndef HAVE_STDINT_H
      48                 :            : typedef unsigned long uint32_t;
      49                 :            : #endif
      50                 :            : 
      51                 :            : #elif defined(__FreeBSD__)
      52                 :            : 
      53                 :            : # ifndef SNDCTL_DSP_CHANNELS
      54                 :            : #  define SNDCTL_DSP_CHANNELS SOUND_PCM_WRITE_CHANNELS
      55                 :            : # endif
      56                 :            : 
      57                 :            : #endif
      58                 :            : 
      59                 :            : typedef struct {
      60                 :            :     PyObject_HEAD
      61                 :            :     const char *devicename;           /* name of the device file */
      62                 :            :     int      fd;                      /* file descriptor */
      63                 :            :     int      mode;                    /* file mode (O_RDONLY, etc.) */
      64                 :            :     Py_ssize_t icount;                /* input count */
      65                 :            :     Py_ssize_t ocount;                /* output count */
      66                 :            :     uint32_t afmts;                   /* audio formats supported by hardware */
      67                 :            : } oss_audio_t;
      68                 :            : 
      69                 :            : typedef struct {
      70                 :            :     PyObject_HEAD
      71                 :            :     int      fd;                      /* The open mixer device */
      72                 :            : } oss_mixer_t;
      73                 :            : 
      74                 :            : 
      75                 :            : static PyTypeObject OSSAudioType;
      76                 :            : static PyTypeObject OSSMixerType;
      77                 :            : 
      78                 :            : static PyObject *OSSAudioError;
      79                 :            : 
      80                 :            : 
      81                 :            : /* ----------------------------------------------------------------------
      82                 :            :  * DSP object initialization/deallocation
      83                 :            :  */
      84                 :            : 
      85                 :            : static oss_audio_t *
      86                 :          0 : newossobject(PyObject *arg)
      87                 :            : {
      88                 :            :     oss_audio_t *self;
      89                 :            :     int fd, afmts, imode;
      90                 :          0 :     const char *devicename = NULL;
      91                 :          0 :     const char *mode = NULL;
      92                 :            : 
      93                 :            :     /* Two ways to call open():
      94                 :            :          open(device, mode) (for consistency with builtin open())
      95                 :            :          open(mode)         (for backwards compatibility)
      96                 :            :        because the *first* argument is optional, parsing args is
      97                 :            :        a wee bit tricky. */
      98         [ #  # ]:          0 :     if (!PyArg_ParseTuple(arg, "s|s:open", &devicename, &mode))
      99                 :          0 :        return NULL;
     100         [ #  # ]:          0 :     if (mode == NULL) {                 /* only one arg supplied */
     101                 :          0 :        mode = devicename;
     102                 :          0 :        devicename = NULL;
     103                 :            :     }
     104                 :            : 
     105         [ #  # ]:          0 :     if (strcmp(mode, "r") == 0)
     106                 :          0 :         imode = O_RDONLY;
     107         [ #  # ]:          0 :     else if (strcmp(mode, "w") == 0)
     108                 :          0 :         imode = O_WRONLY;
     109         [ #  # ]:          0 :     else if (strcmp(mode, "rw") == 0)
     110                 :          0 :         imode = O_RDWR;
     111                 :            :     else {
     112                 :          0 :         PyErr_SetString(OSSAudioError, "mode must be 'r', 'w', or 'rw'");
     113                 :          0 :         return NULL;
     114                 :            :     }
     115                 :            : 
     116                 :            :     /* Open the correct device: either the 'device' argument,
     117                 :            :        or the AUDIODEV environment variable, or "/dev/dsp". */
     118         [ #  # ]:          0 :     if (devicename == NULL) {              /* called with one arg */
     119                 :          0 :        devicename = getenv("AUDIODEV");
     120         [ #  # ]:          0 :        if (devicename == NULL)             /* $AUDIODEV not set */
     121                 :          0 :           devicename = "/dev/dsp";
     122                 :            :     }
     123                 :            : 
     124                 :            :     /* Open with O_NONBLOCK to avoid hanging on devices that only allow
     125                 :            :        one open at a time.  This does *not* affect later I/O; OSS
     126                 :            :        provides a special ioctl() for non-blocking read/write, which is
     127                 :            :        exposed via oss_nonblock() below. */
     128                 :          0 :     fd = _Py_open(devicename, imode|O_NONBLOCK);
     129         [ #  # ]:          0 :     if (fd == -1)
     130                 :          0 :         return NULL;
     131                 :            : 
     132                 :            :     /* And (try to) put it back in blocking mode so we get the
     133                 :            :        expected write() semantics. */
     134         [ #  # ]:          0 :     if (fcntl(fd, F_SETFL, 0) == -1) {
     135                 :          0 :         close(fd);
     136                 :          0 :         PyErr_SetFromErrnoWithFilename(PyExc_OSError, devicename);
     137                 :          0 :         return NULL;
     138                 :            :     }
     139                 :            : 
     140         [ #  # ]:          0 :     if (ioctl(fd, SNDCTL_DSP_GETFMTS, &afmts) == -1) {
     141                 :          0 :         close(fd);
     142                 :          0 :         PyErr_SetFromErrnoWithFilename(PyExc_OSError, devicename);
     143                 :          0 :         return NULL;
     144                 :            :     }
     145                 :            :     /* Create and initialize the object */
     146         [ #  # ]:          0 :     if ((self = PyObject_New(oss_audio_t, &OSSAudioType)) == NULL) {
     147                 :          0 :         close(fd);
     148                 :          0 :         return NULL;
     149                 :            :     }
     150                 :          0 :     self->devicename = devicename;
     151                 :          0 :     self->fd = fd;
     152                 :          0 :     self->mode = imode;
     153                 :          0 :     self->icount = self->ocount = 0;
     154                 :          0 :     self->afmts  = afmts;
     155                 :          0 :     return self;
     156                 :            : }
     157                 :            : 
     158                 :            : static void
     159                 :          0 : oss_dealloc(oss_audio_t *self)
     160                 :            : {
     161                 :            :     /* if already closed, don't reclose it */
     162         [ #  # ]:          0 :     if (self->fd != -1)
     163                 :          0 :         close(self->fd);
     164                 :          0 :     PyObject_Free(self);
     165                 :          0 : }
     166                 :            : 
     167                 :            : 
     168                 :            : /* ----------------------------------------------------------------------
     169                 :            :  * Mixer object initialization/deallocation
     170                 :            :  */
     171                 :            : 
     172                 :            : static oss_mixer_t *
     173                 :          0 : newossmixerobject(PyObject *arg)
     174                 :            : {
     175                 :          0 :     const char *devicename = NULL;
     176                 :            :     int fd;
     177                 :            :     oss_mixer_t *self;
     178                 :            : 
     179         [ #  # ]:          0 :     if (!PyArg_ParseTuple(arg, "|s", &devicename)) {
     180                 :          0 :         return NULL;
     181                 :            :     }
     182                 :            : 
     183         [ #  # ]:          0 :     if (devicename == NULL) {
     184                 :          0 :         devicename = getenv("MIXERDEV");
     185         [ #  # ]:          0 :         if (devicename == NULL)            /* MIXERDEV not set */
     186                 :          0 :             devicename = "/dev/mixer";
     187                 :            :     }
     188                 :            : 
     189                 :          0 :     fd = _Py_open(devicename, O_RDWR);
     190         [ #  # ]:          0 :     if (fd == -1)
     191                 :          0 :         return NULL;
     192                 :            : 
     193         [ #  # ]:          0 :     if ((self = PyObject_New(oss_mixer_t, &OSSMixerType)) == NULL) {
     194                 :          0 :         close(fd);
     195                 :          0 :         return NULL;
     196                 :            :     }
     197                 :            : 
     198                 :          0 :     self->fd = fd;
     199                 :            : 
     200                 :          0 :     return self;
     201                 :            : }
     202                 :            : 
     203                 :            : static void
     204                 :          0 : oss_mixer_dealloc(oss_mixer_t *self)
     205                 :            : {
     206                 :            :     /* if already closed, don't reclose it */
     207         [ #  # ]:          0 :     if (self->fd != -1)
     208                 :          0 :         close(self->fd);
     209                 :          0 :     PyObject_Free(self);
     210                 :          0 : }
     211                 :            : 
     212                 :            : 
     213                 :            : /* Methods to wrap the OSS ioctls.  The calling convention is pretty
     214                 :            :    simple:
     215                 :            :      nonblock()        -> ioctl(fd, SNDCTL_DSP_NONBLOCK)
     216                 :            :      fmt = setfmt(fmt) -> ioctl(fd, SNDCTL_DSP_SETFMT, &fmt)
     217                 :            :      etc.
     218                 :            : */
     219                 :            : 
     220                 :            : 
     221                 :            : /* ----------------------------------------------------------------------
     222                 :            :  * Helper functions
     223                 :            :  */
     224                 :            : 
     225                 :            : /* Check if a given file descriptor is valid (i.e. hasn't been closed).
     226                 :            :  * If true, return 1. Otherwise, raise ValueError and return 0.
     227                 :            :  */
     228                 :          0 : static int _is_fd_valid(int fd)
     229                 :            : {
     230                 :            :     /* the FD is set to -1 in oss_close()/oss_mixer_close() */
     231         [ #  # ]:          0 :     if (fd >= 0) {
     232                 :          0 :         return 1;
     233                 :            :     } else {
     234                 :          0 :         PyErr_SetString(PyExc_ValueError,
     235                 :            :                         "Operation on closed OSS device.");
     236                 :          0 :         return 0;
     237                 :            :     }
     238                 :            : }
     239                 :            : 
     240                 :            : /* _do_ioctl_1() is a private helper function used for the OSS ioctls --
     241                 :            :    SNDCTL_DSP_{SETFMT,CHANNELS,SPEED} -- that are called from C
     242                 :            :    like this:
     243                 :            :      ioctl(fd, SNDCTL_DSP_cmd, &arg)
     244                 :            : 
     245                 :            :    where arg is the value to set, and on return the driver sets arg to
     246                 :            :    the value that was actually set.  Mapping this to Python is obvious:
     247                 :            :      arg = dsp.xxx(arg)
     248                 :            : */
     249                 :            : static PyObject *
     250                 :          0 : _do_ioctl_1(int fd, PyObject *args, char *fname, unsigned long cmd)
     251                 :            : {
     252                 :          0 :     char argfmt[33] = "i:";
     253                 :            :     int arg;
     254                 :            : 
     255                 :            :     assert(strlen(fname) <= 30);
     256                 :          0 :     strncat(argfmt, fname, 30);
     257         [ #  # ]:          0 :     if (!PyArg_ParseTuple(args, argfmt, &arg))
     258                 :          0 :         return NULL;
     259                 :            : 
     260         [ #  # ]:          0 :     if (ioctl(fd, cmd, &arg) == -1)
     261                 :          0 :         return PyErr_SetFromErrno(PyExc_OSError);
     262                 :          0 :     return PyLong_FromLong(arg);
     263                 :            : }
     264                 :            : 
     265                 :            : 
     266                 :            : /* _do_ioctl_1_internal() is a wrapper for ioctls that take no inputs
     267                 :            :    but return an output -- ie. we need to pass a pointer to a local C
     268                 :            :    variable so the driver can write its output there, but from Python
     269                 :            :    all we see is the return value.  For example,
     270                 :            :    SOUND_MIXER_READ_DEVMASK returns a bitmask of available mixer
     271                 :            :    devices, but does not use the value of the parameter passed-in in any
     272                 :            :    way.
     273                 :            : */
     274                 :            : static PyObject *
     275                 :          0 : _do_ioctl_1_internal(int fd, PyObject *args, char *fname, unsigned long cmd)
     276                 :            : {
     277                 :          0 :     char argfmt[32] = ":";
     278                 :          0 :     int arg = 0;
     279                 :            : 
     280                 :            :     assert(strlen(fname) <= 30);
     281                 :          0 :     strncat(argfmt, fname, 30);
     282         [ #  # ]:          0 :     if (!PyArg_ParseTuple(args, argfmt, &arg))
     283                 :          0 :         return NULL;
     284                 :            : 
     285         [ #  # ]:          0 :     if (ioctl(fd, cmd, &arg) == -1)
     286                 :          0 :         return PyErr_SetFromErrno(PyExc_OSError);
     287                 :          0 :     return PyLong_FromLong(arg);
     288                 :            : }
     289                 :            : 
     290                 :            : 
     291                 :            : 
     292                 :            : /* _do_ioctl_0() is a private helper for the no-argument ioctls:
     293                 :            :    SNDCTL_DSP_{SYNC,RESET,POST}. */
     294                 :            : static PyObject *
     295                 :          0 : _do_ioctl_0(int fd, PyObject *args, char *fname, unsigned long cmd)
     296                 :            : {
     297                 :          0 :     char argfmt[32] = ":";
     298                 :            :     int rv;
     299                 :            : 
     300                 :            :     assert(strlen(fname) <= 30);
     301                 :          0 :     strncat(argfmt, fname, 30);
     302         [ #  # ]:          0 :     if (!PyArg_ParseTuple(args, argfmt))
     303                 :          0 :         return NULL;
     304                 :            : 
     305                 :            :     /* According to hannu@opensound.com, all three of the ioctls that
     306                 :            :        use this function can block, so release the GIL.  This is
     307                 :            :        especially important for SYNC, which can block for several
     308                 :            :        seconds. */
     309                 :          0 :     Py_BEGIN_ALLOW_THREADS
     310                 :          0 :     rv = ioctl(fd, cmd, 0);
     311                 :          0 :     Py_END_ALLOW_THREADS
     312                 :            : 
     313         [ #  # ]:          0 :     if (rv == -1)
     314                 :          0 :         return PyErr_SetFromErrno(PyExc_OSError);
     315                 :          0 :     Py_RETURN_NONE;
     316                 :            : }
     317                 :            : 
     318                 :            : 
     319                 :            : /* ----------------------------------------------------------------------
     320                 :            :  * Methods of DSP objects (OSSAudioType)
     321                 :            :  */
     322                 :            : 
     323                 :            : static PyObject *
     324                 :          0 : oss_nonblock(oss_audio_t *self, PyObject *unused)
     325                 :            : {
     326         [ #  # ]:          0 :     if (!_is_fd_valid(self->fd))
     327                 :          0 :         return NULL;
     328                 :            : 
     329                 :            :     /* Hmmm: it doesn't appear to be possible to return to blocking
     330                 :            :        mode once we're in non-blocking mode! */
     331         [ #  # ]:          0 :     if (ioctl(self->fd, SNDCTL_DSP_NONBLOCK, NULL) == -1)
     332                 :          0 :         return PyErr_SetFromErrno(PyExc_OSError);
     333                 :          0 :     Py_RETURN_NONE;
     334                 :            : }
     335                 :            : 
     336                 :            : static PyObject *
     337                 :          0 : oss_setfmt(oss_audio_t *self, PyObject *args)
     338                 :            : {
     339         [ #  # ]:          0 :     if (!_is_fd_valid(self->fd))
     340                 :          0 :         return NULL;
     341                 :            : 
     342                 :          0 :     return _do_ioctl_1(self->fd, args, "setfmt", SNDCTL_DSP_SETFMT);
     343                 :            : }
     344                 :            : 
     345                 :            : static PyObject *
     346                 :          0 : oss_getfmts(oss_audio_t *self, PyObject *unused)
     347                 :            : {
     348                 :            :     int mask;
     349                 :            : 
     350         [ #  # ]:          0 :     if (!_is_fd_valid(self->fd))
     351                 :          0 :         return NULL;
     352                 :            : 
     353         [ #  # ]:          0 :     if (ioctl(self->fd, SNDCTL_DSP_GETFMTS, &mask) == -1)
     354                 :          0 :         return PyErr_SetFromErrno(PyExc_OSError);
     355                 :          0 :     return PyLong_FromLong(mask);
     356                 :            : }
     357                 :            : 
     358                 :            : static PyObject *
     359                 :          0 : oss_channels(oss_audio_t *self, PyObject *args)
     360                 :            : {
     361         [ #  # ]:          0 :     if (!_is_fd_valid(self->fd))
     362                 :          0 :         return NULL;
     363                 :            : 
     364                 :          0 :     return _do_ioctl_1(self->fd, args, "channels", SNDCTL_DSP_CHANNELS);
     365                 :            : }
     366                 :            : 
     367                 :            : static PyObject *
     368                 :          0 : oss_speed(oss_audio_t *self, PyObject *args)
     369                 :            : {
     370         [ #  # ]:          0 :     if (!_is_fd_valid(self->fd))
     371                 :          0 :         return NULL;
     372                 :            : 
     373                 :          0 :     return _do_ioctl_1(self->fd, args, "speed", SNDCTL_DSP_SPEED);
     374                 :            : }
     375                 :            : 
     376                 :            : static PyObject *
     377                 :          0 : oss_sync(oss_audio_t *self, PyObject *args)
     378                 :            : {
     379         [ #  # ]:          0 :     if (!_is_fd_valid(self->fd))
     380                 :          0 :         return NULL;
     381                 :            : 
     382                 :          0 :     return _do_ioctl_0(self->fd, args, "sync", SNDCTL_DSP_SYNC);
     383                 :            : }
     384                 :            : 
     385                 :            : static PyObject *
     386                 :          0 : oss_reset(oss_audio_t *self, PyObject *args)
     387                 :            : {
     388         [ #  # ]:          0 :     if (!_is_fd_valid(self->fd))
     389                 :          0 :         return NULL;
     390                 :            : 
     391                 :          0 :     return _do_ioctl_0(self->fd, args, "reset", SNDCTL_DSP_RESET);
     392                 :            : }
     393                 :            : 
     394                 :            : static PyObject *
     395                 :          0 : oss_post(oss_audio_t *self, PyObject *args)
     396                 :            : {
     397         [ #  # ]:          0 :     if (!_is_fd_valid(self->fd))
     398                 :          0 :         return NULL;
     399                 :            : 
     400                 :          0 :     return _do_ioctl_0(self->fd, args, "post", SNDCTL_DSP_POST);
     401                 :            : }
     402                 :            : 
     403                 :            : 
     404                 :            : /* Regular file methods: read(), write(), close(), etc. as well
     405                 :            :    as one convenience method, writeall(). */
     406                 :            : 
     407                 :            : static PyObject *
     408                 :          0 : oss_read(oss_audio_t *self, PyObject *args)
     409                 :            : {
     410                 :            :     Py_ssize_t size, count;
     411                 :            :     PyObject *rv;
     412                 :            : 
     413         [ #  # ]:          0 :     if (!_is_fd_valid(self->fd))
     414                 :          0 :         return NULL;
     415                 :            : 
     416         [ #  # ]:          0 :     if (!PyArg_ParseTuple(args, "n:read", &size))
     417                 :          0 :         return NULL;
     418                 :            : 
     419                 :          0 :     rv = PyBytes_FromStringAndSize(NULL, size);
     420         [ #  # ]:          0 :     if (rv == NULL)
     421                 :          0 :         return NULL;
     422                 :            : 
     423                 :          0 :     count = _Py_read(self->fd, PyBytes_AS_STRING(rv), size);
     424         [ #  # ]:          0 :     if (count == -1) {
     425                 :          0 :         Py_DECREF(rv);
     426                 :          0 :         return NULL;
     427                 :            :     }
     428                 :            : 
     429                 :          0 :     self->icount += count;
     430                 :          0 :     _PyBytes_Resize(&rv, count);
     431                 :          0 :     return rv;
     432                 :            : }
     433                 :            : 
     434                 :            : static PyObject *
     435                 :          0 : oss_write(oss_audio_t *self, PyObject *args)
     436                 :            : {
     437                 :            :     Py_buffer data;
     438                 :            :     Py_ssize_t rv;
     439                 :            : 
     440         [ #  # ]:          0 :     if (!_is_fd_valid(self->fd))
     441                 :          0 :         return NULL;
     442                 :            : 
     443         [ #  # ]:          0 :     if (!PyArg_ParseTuple(args, "y*:write", &data)) {
     444                 :          0 :         return NULL;
     445                 :            :     }
     446                 :            : 
     447                 :          0 :     rv = _Py_write(self->fd, data.buf, data.len);
     448                 :          0 :     PyBuffer_Release(&data);
     449         [ #  # ]:          0 :     if (rv == -1)
     450                 :          0 :         return NULL;
     451                 :            : 
     452                 :          0 :     self->ocount += rv;
     453                 :          0 :     return PyLong_FromLong(rv);
     454                 :            : }
     455                 :            : 
     456                 :            : static PyObject *
     457                 :          0 : oss_writeall(oss_audio_t *self, PyObject *args)
     458                 :            : {
     459                 :            :     Py_buffer data;
     460                 :            :     const char *cp;
     461                 :            :     Py_ssize_t size;
     462                 :            :     Py_ssize_t rv;
     463                 :            :     fd_set write_set_fds;
     464                 :            :     int select_rv;
     465                 :            : 
     466                 :            :     /* NB. writeall() is only useful in non-blocking mode: according to
     467                 :            :        Guenter Geiger <geiger@xdv.org> on the linux-audio-dev list
     468                 :            :        (http://eca.cx/lad/2002/11/0380.html), OSS guarantees that
     469                 :            :        write() in blocking mode consumes the whole buffer.  In blocking
     470                 :            :        mode, the behaviour of write() and writeall() from Python is
     471                 :            :        indistinguishable. */
     472                 :            : 
     473         [ #  # ]:          0 :     if (!_is_fd_valid(self->fd))
     474                 :          0 :         return NULL;
     475                 :            : 
     476         [ #  # ]:          0 :     if (!PyArg_ParseTuple(args, "y*:writeall", &data))
     477                 :          0 :         return NULL;
     478                 :            : 
     479         [ #  # ]:          0 :     if (!_PyIsSelectable_fd(self->fd)) {
     480                 :          0 :         PyErr_SetString(PyExc_ValueError,
     481                 :            :                         "file descriptor out of range for select");
     482                 :          0 :         PyBuffer_Release(&data);
     483                 :          0 :         return NULL;
     484                 :            :     }
     485                 :            :     /* use select to wait for audio device to be available */
     486         [ #  # ]:          0 :     FD_ZERO(&write_set_fds);
     487                 :          0 :     FD_SET(self->fd, &write_set_fds);
     488                 :          0 :     cp = (const char *)data.buf;
     489                 :          0 :     size = data.len;
     490                 :            : 
     491         [ #  # ]:          0 :     while (size > 0) {
     492                 :          0 :         Py_BEGIN_ALLOW_THREADS
     493                 :          0 :         select_rv = select(self->fd+1, NULL, &write_set_fds, NULL, NULL);
     494                 :          0 :         Py_END_ALLOW_THREADS
     495                 :            : 
     496                 :            :         assert(select_rv != 0);   /* no timeout, can't expire */
     497         [ #  # ]:          0 :         if (select_rv == -1) {
     498                 :          0 :             PyBuffer_Release(&data);
     499                 :          0 :             return PyErr_SetFromErrno(PyExc_OSError);
     500                 :            :         }
     501                 :            : 
     502                 :          0 :         rv = _Py_write(self->fd, cp, Py_MIN(size, INT_MAX));
     503         [ #  # ]:          0 :         if (rv == -1) {
     504                 :            :             /* buffer is full, try again */
     505         [ #  # ]:          0 :             if (errno == EAGAIN) {
     506                 :          0 :                 PyErr_Clear();
     507                 :          0 :                 continue;
     508                 :            :             }
     509                 :            :             /* it's a real error */
     510                 :          0 :             PyBuffer_Release(&data);
     511                 :          0 :             return NULL;
     512                 :            :         }
     513                 :            : 
     514                 :            :         /* wrote rv bytes */
     515                 :          0 :         self->ocount += rv;
     516                 :          0 :         size -= rv;
     517                 :          0 :         cp += rv;
     518                 :            :     }
     519                 :          0 :     PyBuffer_Release(&data);
     520                 :          0 :     Py_RETURN_NONE;
     521                 :            : }
     522                 :            : 
     523                 :            : static PyObject *
     524                 :          0 : oss_close(oss_audio_t *self, PyObject *unused)
     525                 :            : {
     526         [ #  # ]:          0 :     if (self->fd >= 0) {
     527                 :          0 :         Py_BEGIN_ALLOW_THREADS
     528                 :          0 :         close(self->fd);
     529                 :          0 :         Py_END_ALLOW_THREADS
     530                 :          0 :         self->fd = -1;
     531                 :            :     }
     532                 :          0 :     Py_RETURN_NONE;
     533                 :            : }
     534                 :            : 
     535                 :            : static PyObject *
     536                 :          0 : oss_self(PyObject *self, PyObject *unused)
     537                 :            : {
     538                 :          0 :     Py_INCREF(self);
     539                 :          0 :     return self;
     540                 :            : }
     541                 :            : 
     542                 :            : static PyObject *
     543                 :          0 : oss_exit(PyObject *self, PyObject *unused)
     544                 :            : {
     545                 :            :     _Py_IDENTIFIER(close);
     546                 :            : 
     547                 :          0 :     PyObject *ret = _PyObject_CallMethodIdNoArgs(self, &PyId_close);
     548         [ #  # ]:          0 :     if (!ret)
     549                 :          0 :         return NULL;
     550                 :          0 :     Py_DECREF(ret);
     551                 :          0 :     Py_RETURN_NONE;
     552                 :            : }
     553                 :            : 
     554                 :            : static PyObject *
     555                 :          0 : oss_fileno(oss_audio_t *self, PyObject *unused)
     556                 :            : {
     557         [ #  # ]:          0 :     if (!_is_fd_valid(self->fd))
     558                 :          0 :         return NULL;
     559                 :            : 
     560                 :          0 :     return PyLong_FromLong(self->fd);
     561                 :            : }
     562                 :            : 
     563                 :            : 
     564                 :            : /* Convenience methods: these generally wrap a couple of ioctls into one
     565                 :            :    common task. */
     566                 :            : 
     567                 :            : static PyObject *
     568                 :          0 : oss_setparameters(oss_audio_t *self, PyObject *args)
     569                 :            : {
     570                 :          0 :     int wanted_fmt, wanted_channels, wanted_rate, strict=0;
     571                 :            :     int fmt, channels, rate;
     572                 :            : 
     573         [ #  # ]:          0 :     if (!_is_fd_valid(self->fd))
     574                 :          0 :         return NULL;
     575                 :            : 
     576         [ #  # ]:          0 :     if (!PyArg_ParseTuple(args, "iii|i:setparameters",
     577                 :            :                           &wanted_fmt, &wanted_channels, &wanted_rate,
     578                 :            :                           &strict))
     579                 :          0 :         return NULL;
     580                 :            : 
     581                 :          0 :     fmt = wanted_fmt;
     582         [ #  # ]:          0 :     if (ioctl(self->fd, SNDCTL_DSP_SETFMT, &fmt) == -1) {
     583                 :          0 :         return PyErr_SetFromErrno(PyExc_OSError);
     584                 :            :     }
     585   [ #  #  #  # ]:          0 :     if (strict && fmt != wanted_fmt) {
     586                 :          0 :         return PyErr_Format
     587                 :            :             (OSSAudioError,
     588                 :            :              "unable to set requested format (wanted %d, got %d)",
     589                 :            :              wanted_fmt, fmt);
     590                 :            :     }
     591                 :            : 
     592                 :          0 :     channels = wanted_channels;
     593         [ #  # ]:          0 :     if (ioctl(self->fd, SNDCTL_DSP_CHANNELS, &channels) == -1) {
     594                 :          0 :         return PyErr_SetFromErrno(PyExc_OSError);
     595                 :            :     }
     596   [ #  #  #  # ]:          0 :     if (strict && channels != wanted_channels) {
     597                 :          0 :         return PyErr_Format
     598                 :            :             (OSSAudioError,
     599                 :            :              "unable to set requested channels (wanted %d, got %d)",
     600                 :            :              wanted_channels, channels);
     601                 :            :     }
     602                 :            : 
     603                 :          0 :     rate = wanted_rate;
     604         [ #  # ]:          0 :     if (ioctl(self->fd, SNDCTL_DSP_SPEED, &rate) == -1) {
     605                 :          0 :         return PyErr_SetFromErrno(PyExc_OSError);
     606                 :            :     }
     607   [ #  #  #  # ]:          0 :     if (strict && rate != wanted_rate) {
     608                 :          0 :         return PyErr_Format
     609                 :            :             (OSSAudioError,
     610                 :            :              "unable to set requested rate (wanted %d, got %d)",
     611                 :            :              wanted_rate, rate);
     612                 :            :     }
     613                 :            : 
     614                 :            :     /* Construct the return value: a (fmt, channels, rate) tuple that
     615                 :            :        tells what the audio hardware was actually set to. */
     616                 :          0 :     return Py_BuildValue("(iii)", fmt, channels, rate);
     617                 :            : }
     618                 :            : 
     619                 :            : static int
     620                 :          0 : _ssize(oss_audio_t *self, int *nchannels, int *ssize)
     621                 :            : {
     622                 :            :     int fmt;
     623                 :            : 
     624                 :          0 :     fmt = 0;
     625         [ #  # ]:          0 :     if (ioctl(self->fd, SNDCTL_DSP_SETFMT, &fmt) < 0)
     626                 :          0 :         return -errno;
     627                 :            : 
     628      [ #  #  # ]:          0 :     switch (fmt) {
     629                 :          0 :     case AFMT_MU_LAW:
     630                 :            :     case AFMT_A_LAW:
     631                 :            :     case AFMT_U8:
     632                 :            :     case AFMT_S8:
     633                 :          0 :         *ssize = 1;                     /* 8 bit formats: 1 byte */
     634                 :          0 :         break;
     635                 :          0 :     case AFMT_S16_LE:
     636                 :            :     case AFMT_S16_BE:
     637                 :            :     case AFMT_U16_LE:
     638                 :            :     case AFMT_U16_BE:
     639                 :          0 :         *ssize = 2;                     /* 16 bit formats: 2 byte */
     640                 :          0 :         break;
     641                 :          0 :     case AFMT_MPEG:
     642                 :            :     case AFMT_IMA_ADPCM:
     643                 :            :     default:
     644                 :          0 :         return -EOPNOTSUPP;
     645                 :            :     }
     646         [ #  # ]:          0 :     if (ioctl(self->fd, SNDCTL_DSP_CHANNELS, nchannels) < 0)
     647                 :          0 :         return -errno;
     648                 :          0 :     return 0;
     649                 :            : }
     650                 :            : 
     651                 :            : 
     652                 :            : /* bufsize returns the size of the hardware audio buffer in number
     653                 :            :    of samples */
     654                 :            : static PyObject *
     655                 :          0 : oss_bufsize(oss_audio_t *self, PyObject *unused)
     656                 :            : {
     657                 :            :     audio_buf_info ai;
     658                 :          0 :     int nchannels=0, ssize=0;
     659                 :            : 
     660         [ #  # ]:          0 :     if (!_is_fd_valid(self->fd))
     661                 :          0 :         return NULL;
     662                 :            : 
     663   [ #  #  #  #  :          0 :     if (_ssize(self, &nchannels, &ssize) < 0 || !nchannels || !ssize) {
                   #  # ]
     664                 :          0 :         PyErr_SetFromErrno(PyExc_OSError);
     665                 :          0 :         return NULL;
     666                 :            :     }
     667         [ #  # ]:          0 :     if (ioctl(self->fd, SNDCTL_DSP_GETOSPACE, &ai) < 0) {
     668                 :          0 :         PyErr_SetFromErrno(PyExc_OSError);
     669                 :          0 :         return NULL;
     670                 :            :     }
     671                 :          0 :     return PyLong_FromLong((ai.fragstotal * ai.fragsize) / (nchannels * ssize));
     672                 :            : }
     673                 :            : 
     674                 :            : /* obufcount returns the number of samples that are available in the
     675                 :            :    hardware for playing */
     676                 :            : static PyObject *
     677                 :          0 : oss_obufcount(oss_audio_t *self, PyObject *unused)
     678                 :            : {
     679                 :            :     audio_buf_info ai;
     680                 :          0 :     int nchannels=0, ssize=0;
     681                 :            : 
     682         [ #  # ]:          0 :     if (!_is_fd_valid(self->fd))
     683                 :          0 :         return NULL;
     684                 :            : 
     685   [ #  #  #  #  :          0 :     if (_ssize(self, &nchannels, &ssize) < 0 || !nchannels || !ssize) {
                   #  # ]
     686                 :          0 :         PyErr_SetFromErrno(PyExc_OSError);
     687                 :          0 :         return NULL;
     688                 :            :     }
     689         [ #  # ]:          0 :     if (ioctl(self->fd, SNDCTL_DSP_GETOSPACE, &ai) < 0) {
     690                 :          0 :         PyErr_SetFromErrno(PyExc_OSError);
     691                 :          0 :         return NULL;
     692                 :            :     }
     693                 :          0 :     return PyLong_FromLong((ai.fragstotal * ai.fragsize - ai.bytes) /
     694                 :          0 :                           (ssize * nchannels));
     695                 :            : }
     696                 :            : 
     697                 :            : /* obufcount returns the number of samples that can be played without
     698                 :            :    blocking */
     699                 :            : static PyObject *
     700                 :          0 : oss_obuffree(oss_audio_t *self, PyObject *unused)
     701                 :            : {
     702                 :            :     audio_buf_info ai;
     703                 :          0 :     int nchannels=0, ssize=0;
     704                 :            : 
     705         [ #  # ]:          0 :     if (!_is_fd_valid(self->fd))
     706                 :          0 :         return NULL;
     707                 :            : 
     708   [ #  #  #  #  :          0 :     if (_ssize(self, &nchannels, &ssize) < 0 || !nchannels || !ssize) {
                   #  # ]
     709                 :          0 :         PyErr_SetFromErrno(PyExc_OSError);
     710                 :          0 :         return NULL;
     711                 :            :     }
     712         [ #  # ]:          0 :     if (ioctl(self->fd, SNDCTL_DSP_GETOSPACE, &ai) < 0) {
     713                 :          0 :         PyErr_SetFromErrno(PyExc_OSError);
     714                 :          0 :         return NULL;
     715                 :            :     }
     716                 :          0 :     return PyLong_FromLong(ai.bytes / (ssize * nchannels));
     717                 :            : }
     718                 :            : 
     719                 :            : static PyObject *
     720                 :          0 : oss_getptr(oss_audio_t *self, PyObject *unused)
     721                 :            : {
     722                 :            :     count_info info;
     723                 :            :     int req;
     724                 :            : 
     725         [ #  # ]:          0 :     if (!_is_fd_valid(self->fd))
     726                 :          0 :         return NULL;
     727                 :            : 
     728         [ #  # ]:          0 :     if (self->mode == O_RDONLY)
     729                 :          0 :         req = SNDCTL_DSP_GETIPTR;
     730                 :            :     else
     731                 :          0 :         req = SNDCTL_DSP_GETOPTR;
     732         [ #  # ]:          0 :     if (ioctl(self->fd, req, &info) == -1) {
     733                 :          0 :         PyErr_SetFromErrno(PyExc_OSError);
     734                 :          0 :         return NULL;
     735                 :            :     }
     736                 :          0 :     return Py_BuildValue("iii", info.bytes, info.blocks, info.ptr);
     737                 :            : }
     738                 :            : 
     739                 :            : 
     740                 :            : /* ----------------------------------------------------------------------
     741                 :            :  * Methods of mixer objects (OSSMixerType)
     742                 :            :  */
     743                 :            : 
     744                 :            : static PyObject *
     745                 :          0 : oss_mixer_close(oss_mixer_t *self, PyObject *unused)
     746                 :            : {
     747         [ #  # ]:          0 :     if (self->fd >= 0) {
     748                 :          0 :         close(self->fd);
     749                 :          0 :         self->fd = -1;
     750                 :            :     }
     751                 :          0 :     Py_RETURN_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_OSError);
     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_OSError);
     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 management 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 management 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 PyMemberDef oss_members[] = {
     930                 :            :     {"name", T_STRING, offsetof(oss_audio_t, devicename), READONLY, NULL},
     931                 :            :     {NULL}
     932                 :            : };
     933                 :            : 
     934                 :            : static PyObject *
     935                 :          0 : oss_closed_getter(oss_audio_t *self, void *closure)
     936                 :            : {
     937                 :          0 :     return PyBool_FromLong(self->fd == -1);
     938                 :            : }
     939                 :            : 
     940                 :            : static PyObject *
     941                 :          0 : oss_mode_getter(oss_audio_t *self, void *closure)
     942                 :            : {
     943   [ #  #  #  # ]:          0 :     switch(self->mode) {
     944                 :          0 :         case O_RDONLY:
     945                 :          0 :             return PyUnicode_FromString("r");
     946                 :            :             break;
     947                 :          0 :         case O_RDWR:
     948                 :          0 :             return PyUnicode_FromString("rw");
     949                 :            :             break;
     950                 :          0 :         case O_WRONLY:
     951                 :          0 :             return PyUnicode_FromString("w");
     952                 :            :             break;
     953                 :          0 :         default:
     954                 :            :             /* From newossobject(), self->mode can only be one
     955                 :            :                of these three values. */
     956                 :          0 :             Py_UNREACHABLE();
     957                 :            :     }
     958                 :            : }
     959                 :            : 
     960                 :            : static PyGetSetDef oss_getsetlist[] = {
     961                 :            :     {"closed", (getter)oss_closed_getter, (setter)NULL, NULL},
     962                 :            :     {"mode", (getter)oss_mode_getter, (setter)NULL, NULL},
     963                 :            :     {NULL},
     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_basicsize*/
     970                 :            :     0,                          /*tp_itemsize*/
     971                 :            :     /* methods */
     972                 :            :     (destructor)oss_dealloc,    /*tp_dealloc*/
     973                 :            :     0,                          /*tp_vectorcall_offset*/
     974                 :            :     0,                          /*tp_getattr*/
     975                 :            :     0,                          /*tp_setattr*/
     976                 :            :     0,                          /*tp_as_async*/
     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                 :            :     0,                          /*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                 :            :     oss_members,                /*tp_members*/
     997                 :            :     oss_getsetlist,             /*tp_getset*/
     998                 :            : };
     999                 :            : 
    1000                 :            : static PyTypeObject OSSMixerType = {
    1001                 :            :     PyVarObject_HEAD_INIT(&PyType_Type, 0)
    1002                 :            :     "ossaudiodev.oss_mixer_device", /*tp_name*/
    1003                 :            :     sizeof(oss_mixer_t),            /*tp_basicsize*/
    1004                 :            :     0,                              /*tp_itemsize*/
    1005                 :            :     /* methods */
    1006                 :            :     (destructor)oss_mixer_dealloc,  /*tp_dealloc*/
    1007                 :            :     0,                              /*tp_vectorcall_offset*/
    1008                 :            :     0,                              /*tp_getattr*/
    1009                 :            :     0,                              /*tp_setattr*/
    1010                 :            :     0,                              /*tp_as_async*/
    1011                 :            :     0,                              /*tp_repr*/
    1012                 :            :     0,                              /*tp_as_number*/
    1013                 :            :     0,                              /*tp_as_sequence*/
    1014                 :            :     0,                              /*tp_as_mapping*/
    1015                 :            :     0,                              /*tp_hash*/
    1016                 :            :     0,                              /*tp_call*/
    1017                 :            :     0,                              /*tp_str*/
    1018                 :            :     0,                              /*tp_getattro*/
    1019                 :            :     0,                              /*tp_setattro*/
    1020                 :            :     0,                              /*tp_as_buffer*/
    1021                 :            :     Py_TPFLAGS_DEFAULT,             /*tp_flags*/
    1022                 :            :     0,                              /*tp_doc*/
    1023                 :            :     0,                              /*tp_traverse*/
    1024                 :            :     0,                              /*tp_clear*/
    1025                 :            :     0,                              /*tp_richcompare*/
    1026                 :            :     0,                              /*tp_weaklistoffset*/
    1027                 :            :     0,                              /*tp_iter*/
    1028                 :            :     0,                              /*tp_iternext*/
    1029                 :            :     oss_mixer_methods,              /*tp_methods*/
    1030                 :            : };
    1031                 :            : 
    1032                 :            : 
    1033                 :            : static PyObject *
    1034                 :          0 : ossopen(PyObject *self, PyObject *args)
    1035                 :            : {
    1036                 :          0 :     return (PyObject *)newossobject(args);
    1037                 :            : }
    1038                 :            : 
    1039                 :            : static PyObject *
    1040                 :          0 : ossopenmixer(PyObject *self, PyObject *args)
    1041                 :            : {
    1042                 :          0 :     return (PyObject *)newossmixerobject(args);
    1043                 :            : }
    1044                 :            : 
    1045                 :            : static PyMethodDef ossaudiodev_methods[] = {
    1046                 :            :     { "open", ossopen, METH_VARARGS },
    1047                 :            :     { "openmixer", ossopenmixer, METH_VARARGS },
    1048                 :            :     { 0, 0 },
    1049                 :            : };
    1050                 :            : 
    1051                 :            : 
    1052                 :            : #define _EXPORT_INT(mod, name) \
    1053                 :            :   if (PyModule_AddIntConstant(mod, #name, (long) (name)) == -1) return NULL;
    1054                 :            : 
    1055                 :            : 
    1056                 :            : static char *control_labels[] = SOUND_DEVICE_LABELS;
    1057                 :            : static char *control_names[] = SOUND_DEVICE_NAMES;
    1058                 :            : 
    1059                 :            : 
    1060                 :            : static int
    1061                 :          1 : build_namelists (PyObject *module)
    1062                 :            : {
    1063                 :            :     PyObject *labels;
    1064                 :            :     PyObject *names;
    1065                 :            :     PyObject *s;
    1066                 :            :     int num_controls;
    1067                 :            :     int i;
    1068                 :            : 
    1069                 :          1 :     num_controls = Py_ARRAY_LENGTH(control_labels);
    1070                 :            :     assert(num_controls == Py_ARRAY_LENGTH(control_names));
    1071                 :            : 
    1072                 :          1 :     labels = PyList_New(num_controls);
    1073                 :          1 :     names = PyList_New(num_controls);
    1074   [ +  -  -  + ]:          1 :     if (labels == NULL || names == NULL)
    1075                 :          0 :         goto error2;
    1076         [ +  + ]:         26 :     for (i = 0; i < num_controls; i++) {
    1077                 :         25 :         s = PyUnicode_FromString(control_labels[i]);
    1078         [ -  + ]:         25 :         if (s == NULL)
    1079                 :          0 :             goto error2;
    1080                 :         25 :         PyList_SET_ITEM(labels, i, s);
    1081                 :            : 
    1082                 :         25 :         s = PyUnicode_FromString(control_names[i]);
    1083         [ -  + ]:         25 :         if (s == NULL)
    1084                 :          0 :             goto error2;
    1085                 :         25 :         PyList_SET_ITEM(names, i, s);
    1086                 :            :     }
    1087                 :            : 
    1088         [ -  + ]:          1 :     if (PyModule_AddObject(module, "control_labels", labels) == -1)
    1089                 :          0 :         goto error2;
    1090         [ -  + ]:          1 :     if (PyModule_AddObject(module, "control_names", names) == -1)
    1091                 :          0 :         goto error1;
    1092                 :            : 
    1093                 :          1 :     return 0;
    1094                 :            : 
    1095                 :          0 : error2:
    1096                 :          0 :     Py_XDECREF(labels);
    1097                 :          0 : error1:
    1098                 :          0 :     Py_XDECREF(names);
    1099                 :          0 :     return -1;
    1100                 :            : }
    1101                 :            : 
    1102                 :            : 
    1103                 :            : static struct PyModuleDef ossaudiodevmodule = {
    1104                 :            :         PyModuleDef_HEAD_INIT,
    1105                 :            :         "ossaudiodev",
    1106                 :            :         NULL,
    1107                 :            :         -1,
    1108                 :            :         ossaudiodev_methods,
    1109                 :            :         NULL,
    1110                 :            :         NULL,
    1111                 :            :         NULL,
    1112                 :            :         NULL
    1113                 :            : };
    1114                 :            : 
    1115                 :            : PyMODINIT_FUNC
    1116                 :          1 : PyInit_ossaudiodev(void)
    1117                 :            : {
    1118                 :            :     PyObject *m;
    1119                 :            : 
    1120         [ -  + ]:          1 :     if (PyErr_WarnEx(PyExc_DeprecationWarning,
    1121                 :            :                      "'ossaudiodev' is deprecated and slated for removal in "
    1122                 :            :                      "Python 3.13",
    1123                 :            :                      7)) {
    1124                 :          0 :         return NULL;
    1125                 :            :     }
    1126                 :            : 
    1127         [ -  + ]:          1 :     if (PyType_Ready(&OSSAudioType) < 0)
    1128                 :          0 :         return NULL;
    1129                 :            : 
    1130         [ -  + ]:          1 :     if (PyType_Ready(&OSSMixerType) < 0)
    1131                 :          0 :         return NULL;
    1132                 :            : 
    1133                 :          1 :     m = PyModule_Create(&ossaudiodevmodule);
    1134         [ -  + ]:          1 :     if (m == NULL)
    1135                 :          0 :         return NULL;
    1136                 :            : 
    1137                 :          1 :     OSSAudioError = PyErr_NewException("ossaudiodev.OSSAudioError",
    1138                 :            :                                        NULL, NULL);
    1139         [ +  - ]:          1 :     if (OSSAudioError) {
    1140                 :            :         /* Each call to PyModule_AddObject decrefs it; compensate: */
    1141                 :          1 :         Py_INCREF(OSSAudioError);
    1142                 :          1 :         Py_INCREF(OSSAudioError);
    1143                 :          1 :         PyModule_AddObject(m, "error", OSSAudioError);
    1144                 :          1 :         PyModule_AddObject(m, "OSSAudioError", OSSAudioError);
    1145                 :            :     }
    1146                 :            : 
    1147                 :            :     /* Build 'control_labels' and 'control_names' lists and add them
    1148                 :            :        to the module. */
    1149         [ -  + ]:          1 :     if (build_namelists(m) == -1)       /* XXX what to do here? */
    1150                 :          0 :         return NULL;
    1151                 :            : 
    1152                 :            :     /* Expose the audio format numbers -- essential! */
    1153         [ -  + ]:          1 :     _EXPORT_INT(m, AFMT_QUERY);
    1154         [ -  + ]:          1 :     _EXPORT_INT(m, AFMT_MU_LAW);
    1155         [ -  + ]:          1 :     _EXPORT_INT(m, AFMT_A_LAW);
    1156         [ -  + ]:          1 :     _EXPORT_INT(m, AFMT_IMA_ADPCM);
    1157         [ -  + ]:          1 :     _EXPORT_INT(m, AFMT_U8);
    1158         [ -  + ]:          1 :     _EXPORT_INT(m, AFMT_S16_LE);
    1159         [ -  + ]:          1 :     _EXPORT_INT(m, AFMT_S16_BE);
    1160         [ -  + ]:          1 :     _EXPORT_INT(m, AFMT_S8);
    1161         [ -  + ]:          1 :     _EXPORT_INT(m, AFMT_U16_LE);
    1162         [ -  + ]:          1 :     _EXPORT_INT(m, AFMT_U16_BE);
    1163         [ -  + ]:          1 :     _EXPORT_INT(m, AFMT_MPEG);
    1164                 :            : #ifdef AFMT_AC3
    1165         [ -  + ]:          1 :     _EXPORT_INT(m, AFMT_AC3);
    1166                 :            : #endif
    1167                 :            : #ifdef AFMT_S16_NE
    1168         [ -  + ]:          1 :     _EXPORT_INT(m, AFMT_S16_NE);
    1169                 :            : #endif
    1170                 :            : #ifdef AFMT_U16_NE
    1171                 :            :     _EXPORT_INT(m, AFMT_U16_NE);
    1172                 :            : #endif
    1173                 :            : #ifdef AFMT_S32_LE
    1174                 :            :     _EXPORT_INT(m, AFMT_S32_LE);
    1175                 :            : #endif
    1176                 :            : #ifdef AFMT_S32_BE
    1177                 :            :     _EXPORT_INT(m, AFMT_S32_BE);
    1178                 :            : #endif
    1179                 :            : #ifdef AFMT_MPEG
    1180         [ -  + ]:          1 :     _EXPORT_INT(m, AFMT_MPEG);
    1181                 :            : #endif
    1182                 :            : 
    1183                 :            :     /* Expose the sound mixer device numbers. */
    1184         [ -  + ]:          1 :     _EXPORT_INT(m, SOUND_MIXER_NRDEVICES);
    1185         [ -  + ]:          1 :     _EXPORT_INT(m, SOUND_MIXER_VOLUME);
    1186         [ -  + ]:          1 :     _EXPORT_INT(m, SOUND_MIXER_BASS);
    1187         [ -  + ]:          1 :     _EXPORT_INT(m, SOUND_MIXER_TREBLE);
    1188         [ -  + ]:          1 :     _EXPORT_INT(m, SOUND_MIXER_SYNTH);
    1189         [ -  + ]:          1 :     _EXPORT_INT(m, SOUND_MIXER_PCM);
    1190         [ -  + ]:          1 :     _EXPORT_INT(m, SOUND_MIXER_SPEAKER);
    1191         [ -  + ]:          1 :     _EXPORT_INT(m, SOUND_MIXER_LINE);
    1192         [ -  + ]:          1 :     _EXPORT_INT(m, SOUND_MIXER_MIC);
    1193         [ -  + ]:          1 :     _EXPORT_INT(m, SOUND_MIXER_CD);
    1194         [ -  + ]:          1 :     _EXPORT_INT(m, SOUND_MIXER_IMIX);
    1195         [ -  + ]:          1 :     _EXPORT_INT(m, SOUND_MIXER_ALTPCM);
    1196         [ -  + ]:          1 :     _EXPORT_INT(m, SOUND_MIXER_RECLEV);
    1197         [ -  + ]:          1 :     _EXPORT_INT(m, SOUND_MIXER_IGAIN);
    1198         [ -  + ]:          1 :     _EXPORT_INT(m, SOUND_MIXER_OGAIN);
    1199         [ -  + ]:          1 :     _EXPORT_INT(m, SOUND_MIXER_LINE1);
    1200         [ -  + ]:          1 :     _EXPORT_INT(m, SOUND_MIXER_LINE2);
    1201         [ -  + ]:          1 :     _EXPORT_INT(m, SOUND_MIXER_LINE3);
    1202                 :            : #ifdef SOUND_MIXER_DIGITAL1
    1203         [ -  + ]:          1 :     _EXPORT_INT(m, SOUND_MIXER_DIGITAL1);
    1204                 :            : #endif
    1205                 :            : #ifdef SOUND_MIXER_DIGITAL2
    1206         [ -  + ]:          1 :     _EXPORT_INT(m, SOUND_MIXER_DIGITAL2);
    1207                 :            : #endif
    1208                 :            : #ifdef SOUND_MIXER_DIGITAL3
    1209         [ -  + ]:          1 :     _EXPORT_INT(m, SOUND_MIXER_DIGITAL3);
    1210                 :            : #endif
    1211                 :            : #ifdef SOUND_MIXER_PHONEIN
    1212         [ -  + ]:          1 :     _EXPORT_INT(m, SOUND_MIXER_PHONEIN);
    1213                 :            : #endif
    1214                 :            : #ifdef SOUND_MIXER_PHONEOUT
    1215         [ -  + ]:          1 :     _EXPORT_INT(m, SOUND_MIXER_PHONEOUT);
    1216                 :            : #endif
    1217                 :            : #ifdef SOUND_MIXER_VIDEO
    1218         [ -  + ]:          1 :     _EXPORT_INT(m, SOUND_MIXER_VIDEO);
    1219                 :            : #endif
    1220                 :            : #ifdef SOUND_MIXER_RADIO
    1221         [ -  + ]:          1 :     _EXPORT_INT(m, SOUND_MIXER_RADIO);
    1222                 :            : #endif
    1223                 :            : #ifdef SOUND_MIXER_MONITOR
    1224         [ -  + ]:          1 :     _EXPORT_INT(m, SOUND_MIXER_MONITOR);
    1225                 :            : #endif
    1226                 :            : 
    1227                 :            :     /* Expose all the ioctl numbers for masochists who like to do this
    1228                 :            :        stuff directly. */
    1229                 :            : #ifdef SNDCTL_COPR_HALT
    1230         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_COPR_HALT);
    1231                 :            : #endif
    1232                 :            : #ifdef SNDCTL_COPR_LOAD
    1233         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_COPR_LOAD);
    1234                 :            : #endif
    1235                 :            : #ifdef SNDCTL_COPR_RCODE
    1236         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_COPR_RCODE);
    1237                 :            : #endif
    1238                 :            : #ifdef SNDCTL_COPR_RCVMSG
    1239         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_COPR_RCVMSG);
    1240                 :            : #endif
    1241                 :            : #ifdef SNDCTL_COPR_RDATA
    1242         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_COPR_RDATA);
    1243                 :            : #endif
    1244                 :            : #ifdef SNDCTL_COPR_RESET
    1245         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_COPR_RESET);
    1246                 :            : #endif
    1247                 :            : #ifdef SNDCTL_COPR_RUN
    1248         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_COPR_RUN);
    1249                 :            : #endif
    1250                 :            : #ifdef SNDCTL_COPR_SENDMSG
    1251         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_COPR_SENDMSG);
    1252                 :            : #endif
    1253                 :            : #ifdef SNDCTL_COPR_WCODE
    1254         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_COPR_WCODE);
    1255                 :            : #endif
    1256                 :            : #ifdef SNDCTL_COPR_WDATA
    1257         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_COPR_WDATA);
    1258                 :            : #endif
    1259                 :            : #ifdef SNDCTL_DSP_BIND_CHANNEL
    1260         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_DSP_BIND_CHANNEL);
    1261                 :            : #endif
    1262         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_DSP_CHANNELS);
    1263         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_DSP_GETBLKSIZE);
    1264         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_DSP_GETCAPS);
    1265                 :            : #ifdef SNDCTL_DSP_GETCHANNELMASK
    1266         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_DSP_GETCHANNELMASK);
    1267                 :            : #endif
    1268         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_DSP_GETFMTS);
    1269         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_DSP_GETIPTR);
    1270         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_DSP_GETISPACE);
    1271                 :            : #ifdef SNDCTL_DSP_GETODELAY
    1272         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_DSP_GETODELAY);
    1273                 :            : #endif
    1274         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_DSP_GETOPTR);
    1275         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_DSP_GETOSPACE);
    1276                 :            : #ifdef SNDCTL_DSP_GETSPDIF
    1277         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_DSP_GETSPDIF);
    1278                 :            : #endif
    1279         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_DSP_GETTRIGGER);
    1280                 :            : #ifdef SNDCTL_DSP_MAPINBUF
    1281         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_DSP_MAPINBUF);
    1282                 :            : #endif
    1283                 :            : #ifdef SNDCTL_DSP_MAPOUTBUF
    1284         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_DSP_MAPOUTBUF);
    1285                 :            : #endif
    1286         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_DSP_NONBLOCK);
    1287         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_DSP_POST);
    1288                 :            : #ifdef SNDCTL_DSP_PROFILE
    1289         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_DSP_PROFILE);
    1290                 :            : #endif
    1291         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_DSP_RESET);
    1292         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_DSP_SAMPLESIZE);
    1293         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_DSP_SETDUPLEX);
    1294         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_DSP_SETFMT);
    1295         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_DSP_SETFRAGMENT);
    1296                 :            : #ifdef SNDCTL_DSP_SETSPDIF
    1297         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_DSP_SETSPDIF);
    1298                 :            : #endif
    1299         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_DSP_SETSYNCRO);
    1300         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_DSP_SETTRIGGER);
    1301         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_DSP_SPEED);
    1302         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_DSP_STEREO);
    1303         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_DSP_SUBDIVIDE);
    1304         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_DSP_SYNC);
    1305                 :            : #ifdef SNDCTL_FM_4OP_ENABLE
    1306         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_FM_4OP_ENABLE);
    1307                 :            : #endif
    1308                 :            : #ifdef SNDCTL_FM_LOAD_INSTR
    1309         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_FM_LOAD_INSTR);
    1310                 :            : #endif
    1311                 :            : #ifdef SNDCTL_MIDI_INFO
    1312         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_MIDI_INFO);
    1313                 :            : #endif
    1314                 :            : #ifdef SNDCTL_MIDI_MPUCMD
    1315         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_MIDI_MPUCMD);
    1316                 :            : #endif
    1317                 :            : #ifdef SNDCTL_MIDI_MPUMODE
    1318         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_MIDI_MPUMODE);
    1319                 :            : #endif
    1320                 :            : #ifdef SNDCTL_MIDI_PRETIME
    1321         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_MIDI_PRETIME);
    1322                 :            : #endif
    1323                 :            : #ifdef SNDCTL_SEQ_CTRLRATE
    1324         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_SEQ_CTRLRATE);
    1325                 :            : #endif
    1326                 :            : #ifdef SNDCTL_SEQ_GETINCOUNT
    1327         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_SEQ_GETINCOUNT);
    1328                 :            : #endif
    1329                 :            : #ifdef SNDCTL_SEQ_GETOUTCOUNT
    1330         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_SEQ_GETOUTCOUNT);
    1331                 :            : #endif
    1332                 :            : #ifdef SNDCTL_SEQ_GETTIME
    1333         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_SEQ_GETTIME);
    1334                 :            : #endif
    1335                 :            : #ifdef SNDCTL_SEQ_NRMIDIS
    1336         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_SEQ_NRMIDIS);
    1337                 :            : #endif
    1338                 :            : #ifdef SNDCTL_SEQ_NRSYNTHS
    1339         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_SEQ_NRSYNTHS);
    1340                 :            : #endif
    1341                 :            : #ifdef SNDCTL_SEQ_OUTOFBAND
    1342         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_SEQ_OUTOFBAND);
    1343                 :            : #endif
    1344                 :            : #ifdef SNDCTL_SEQ_PANIC
    1345         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_SEQ_PANIC);
    1346                 :            : #endif
    1347                 :            : #ifdef SNDCTL_SEQ_PERCMODE
    1348         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_SEQ_PERCMODE);
    1349                 :            : #endif
    1350                 :            : #ifdef SNDCTL_SEQ_RESET
    1351         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_SEQ_RESET);
    1352                 :            : #endif
    1353                 :            : #ifdef SNDCTL_SEQ_RESETSAMPLES
    1354         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_SEQ_RESETSAMPLES);
    1355                 :            : #endif
    1356                 :            : #ifdef SNDCTL_SEQ_SYNC
    1357         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_SEQ_SYNC);
    1358                 :            : #endif
    1359                 :            : #ifdef SNDCTL_SEQ_TESTMIDI
    1360         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_SEQ_TESTMIDI);
    1361                 :            : #endif
    1362                 :            : #ifdef SNDCTL_SEQ_THRESHOLD
    1363         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_SEQ_THRESHOLD);
    1364                 :            : #endif
    1365                 :            : #ifdef SNDCTL_SYNTH_CONTROL
    1366         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_SYNTH_CONTROL);
    1367                 :            : #endif
    1368                 :            : #ifdef SNDCTL_SYNTH_ID
    1369         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_SYNTH_ID);
    1370                 :            : #endif
    1371                 :            : #ifdef SNDCTL_SYNTH_INFO
    1372         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_SYNTH_INFO);
    1373                 :            : #endif
    1374                 :            : #ifdef SNDCTL_SYNTH_MEMAVL
    1375         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_SYNTH_MEMAVL);
    1376                 :            : #endif
    1377                 :            : #ifdef SNDCTL_SYNTH_REMOVESAMPLE
    1378         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_SYNTH_REMOVESAMPLE);
    1379                 :            : #endif
    1380                 :            : #ifdef SNDCTL_TMR_CONTINUE
    1381         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_TMR_CONTINUE);
    1382                 :            : #endif
    1383                 :            : #ifdef SNDCTL_TMR_METRONOME
    1384         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_TMR_METRONOME);
    1385                 :            : #endif
    1386                 :            : #ifdef SNDCTL_TMR_SELECT
    1387         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_TMR_SELECT);
    1388                 :            : #endif
    1389                 :            : #ifdef SNDCTL_TMR_SOURCE
    1390         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_TMR_SOURCE);
    1391                 :            : #endif
    1392                 :            : #ifdef SNDCTL_TMR_START
    1393         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_TMR_START);
    1394                 :            : #endif
    1395                 :            : #ifdef SNDCTL_TMR_STOP
    1396         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_TMR_STOP);
    1397                 :            : #endif
    1398                 :            : #ifdef SNDCTL_TMR_TEMPO
    1399         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_TMR_TEMPO);
    1400                 :            : #endif
    1401                 :            : #ifdef SNDCTL_TMR_TIMEBASE
    1402         [ -  + ]:          1 :     _EXPORT_INT(m, SNDCTL_TMR_TIMEBASE);
    1403                 :            : #endif
    1404                 :          1 :     return m;
    1405                 :            : }

Generated by: LCOV version 1.14