LCOV - code coverage report
Current view: | top level - Modules - ossaudiodev.c (source / functions) |  |  | Hit | Total | Coverage
Test: | CPython 3.12 LCOV report [commit 5e6661bce9] |  | Lines: | 140 | 520 | 26.9 %
Date: | 2023-03-20 08:15:36 |  | Functions: | 2 | 44 | 4.5 %
|  |  | Branches: | 127 | 467 | 27.2 %

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

Generated by: LCOV version 1.14