17db96d56Sopenharmony_ci/* 27db96d56Sopenharmony_ci * ossaudiodev -- Python interface to the OSS (Open Sound System) API. 37db96d56Sopenharmony_ci * This is the standard audio API for Linux and some 47db96d56Sopenharmony_ci * flavours of BSD [XXX which ones?]; it is also available 57db96d56Sopenharmony_ci * for a wide range of commercial Unices. 67db96d56Sopenharmony_ci * 77db96d56Sopenharmony_ci * Originally written by Peter Bosch, March 2000, as linuxaudiodev. 87db96d56Sopenharmony_ci * 97db96d56Sopenharmony_ci * Renamed to ossaudiodev and rearranged/revised/hacked up 107db96d56Sopenharmony_ci * by Greg Ward <gward@python.net>, November 2002. 117db96d56Sopenharmony_ci * Mixer interface by Nicholas FitzRoy-Dale <wzdd@lardcave.net>, Dec 2002. 127db96d56Sopenharmony_ci * 137db96d56Sopenharmony_ci * (c) 2000 Peter Bosch. All Rights Reserved. 147db96d56Sopenharmony_ci * (c) 2002 Gregory P. Ward. All Rights Reserved. 157db96d56Sopenharmony_ci * (c) 2002 Python Software Foundation. All Rights Reserved. 167db96d56Sopenharmony_ci * 177db96d56Sopenharmony_ci * $Id$ 187db96d56Sopenharmony_ci */ 197db96d56Sopenharmony_ci 207db96d56Sopenharmony_ci#ifndef Py_BUILD_CORE_BUILTIN 217db96d56Sopenharmony_ci# define Py_BUILD_CORE_MODULE 1 227db96d56Sopenharmony_ci#endif 237db96d56Sopenharmony_ci#define NEEDS_PY_IDENTIFIER 247db96d56Sopenharmony_ci 257db96d56Sopenharmony_ci#define PY_SSIZE_T_CLEAN 267db96d56Sopenharmony_ci#include "Python.h" 277db96d56Sopenharmony_ci#include "pycore_fileutils.h" // _Py_write() 287db96d56Sopenharmony_ci#include "structmember.h" // PyMemberDef 297db96d56Sopenharmony_ci 307db96d56Sopenharmony_ci#include <stdlib.h> // getenv() 317db96d56Sopenharmony_ci#ifdef HAVE_FCNTL_H 327db96d56Sopenharmony_ci#include <fcntl.h> 337db96d56Sopenharmony_ci#else 347db96d56Sopenharmony_ci#define O_RDONLY 00 357db96d56Sopenharmony_ci#define O_WRONLY 01 367db96d56Sopenharmony_ci#endif 377db96d56Sopenharmony_ci 387db96d56Sopenharmony_ci#include <sys/ioctl.h> 397db96d56Sopenharmony_ci#ifdef __ANDROID__ 407db96d56Sopenharmony_ci#include <linux/soundcard.h> 417db96d56Sopenharmony_ci#else 427db96d56Sopenharmony_ci#include <sys/soundcard.h> 437db96d56Sopenharmony_ci#endif 447db96d56Sopenharmony_ci 457db96d56Sopenharmony_ci#ifdef __linux__ 467db96d56Sopenharmony_ci 477db96d56Sopenharmony_ci#ifndef HAVE_STDINT_H 487db96d56Sopenharmony_citypedef unsigned long uint32_t; 497db96d56Sopenharmony_ci#endif 507db96d56Sopenharmony_ci 517db96d56Sopenharmony_ci#elif defined(__FreeBSD__) 527db96d56Sopenharmony_ci 537db96d56Sopenharmony_ci# ifndef SNDCTL_DSP_CHANNELS 547db96d56Sopenharmony_ci# define SNDCTL_DSP_CHANNELS SOUND_PCM_WRITE_CHANNELS 557db96d56Sopenharmony_ci# endif 567db96d56Sopenharmony_ci 577db96d56Sopenharmony_ci#endif 587db96d56Sopenharmony_ci 597db96d56Sopenharmony_citypedef struct { 607db96d56Sopenharmony_ci PyObject_HEAD 617db96d56Sopenharmony_ci const char *devicename; /* name of the device file */ 627db96d56Sopenharmony_ci int fd; /* file descriptor */ 637db96d56Sopenharmony_ci int mode; /* file mode (O_RDONLY, etc.) */ 647db96d56Sopenharmony_ci Py_ssize_t icount; /* input count */ 657db96d56Sopenharmony_ci Py_ssize_t ocount; /* output count */ 667db96d56Sopenharmony_ci uint32_t afmts; /* audio formats supported by hardware */ 677db96d56Sopenharmony_ci} oss_audio_t; 687db96d56Sopenharmony_ci 697db96d56Sopenharmony_citypedef struct { 707db96d56Sopenharmony_ci PyObject_HEAD 717db96d56Sopenharmony_ci int fd; /* The open mixer device */ 727db96d56Sopenharmony_ci} oss_mixer_t; 737db96d56Sopenharmony_ci 747db96d56Sopenharmony_ci 757db96d56Sopenharmony_cistatic PyTypeObject OSSAudioType; 767db96d56Sopenharmony_cistatic PyTypeObject OSSMixerType; 777db96d56Sopenharmony_ci 787db96d56Sopenharmony_cistatic PyObject *OSSAudioError; 797db96d56Sopenharmony_ci 807db96d56Sopenharmony_ci 817db96d56Sopenharmony_ci/* ---------------------------------------------------------------------- 827db96d56Sopenharmony_ci * DSP object initialization/deallocation 837db96d56Sopenharmony_ci */ 847db96d56Sopenharmony_ci 857db96d56Sopenharmony_cistatic oss_audio_t * 867db96d56Sopenharmony_cinewossobject(PyObject *arg) 877db96d56Sopenharmony_ci{ 887db96d56Sopenharmony_ci oss_audio_t *self; 897db96d56Sopenharmony_ci int fd, afmts, imode; 907db96d56Sopenharmony_ci const char *devicename = NULL; 917db96d56Sopenharmony_ci const char *mode = NULL; 927db96d56Sopenharmony_ci 937db96d56Sopenharmony_ci /* Two ways to call open(): 947db96d56Sopenharmony_ci open(device, mode) (for consistency with builtin open()) 957db96d56Sopenharmony_ci open(mode) (for backwards compatibility) 967db96d56Sopenharmony_ci because the *first* argument is optional, parsing args is 977db96d56Sopenharmony_ci a wee bit tricky. */ 987db96d56Sopenharmony_ci if (!PyArg_ParseTuple(arg, "s|s:open", &devicename, &mode)) 997db96d56Sopenharmony_ci return NULL; 1007db96d56Sopenharmony_ci if (mode == NULL) { /* only one arg supplied */ 1017db96d56Sopenharmony_ci mode = devicename; 1027db96d56Sopenharmony_ci devicename = NULL; 1037db96d56Sopenharmony_ci } 1047db96d56Sopenharmony_ci 1057db96d56Sopenharmony_ci if (strcmp(mode, "r") == 0) 1067db96d56Sopenharmony_ci imode = O_RDONLY; 1077db96d56Sopenharmony_ci else if (strcmp(mode, "w") == 0) 1087db96d56Sopenharmony_ci imode = O_WRONLY; 1097db96d56Sopenharmony_ci else if (strcmp(mode, "rw") == 0) 1107db96d56Sopenharmony_ci imode = O_RDWR; 1117db96d56Sopenharmony_ci else { 1127db96d56Sopenharmony_ci PyErr_SetString(OSSAudioError, "mode must be 'r', 'w', or 'rw'"); 1137db96d56Sopenharmony_ci return NULL; 1147db96d56Sopenharmony_ci } 1157db96d56Sopenharmony_ci 1167db96d56Sopenharmony_ci /* Open the correct device: either the 'device' argument, 1177db96d56Sopenharmony_ci or the AUDIODEV environment variable, or "/dev/dsp". */ 1187db96d56Sopenharmony_ci if (devicename == NULL) { /* called with one arg */ 1197db96d56Sopenharmony_ci devicename = getenv("AUDIODEV"); 1207db96d56Sopenharmony_ci if (devicename == NULL) /* $AUDIODEV not set */ 1217db96d56Sopenharmony_ci devicename = "/dev/dsp"; 1227db96d56Sopenharmony_ci } 1237db96d56Sopenharmony_ci 1247db96d56Sopenharmony_ci /* Open with O_NONBLOCK to avoid hanging on devices that only allow 1257db96d56Sopenharmony_ci one open at a time. This does *not* affect later I/O; OSS 1267db96d56Sopenharmony_ci provides a special ioctl() for non-blocking read/write, which is 1277db96d56Sopenharmony_ci exposed via oss_nonblock() below. */ 1287db96d56Sopenharmony_ci fd = _Py_open(devicename, imode|O_NONBLOCK); 1297db96d56Sopenharmony_ci if (fd == -1) 1307db96d56Sopenharmony_ci return NULL; 1317db96d56Sopenharmony_ci 1327db96d56Sopenharmony_ci /* And (try to) put it back in blocking mode so we get the 1337db96d56Sopenharmony_ci expected write() semantics. */ 1347db96d56Sopenharmony_ci if (fcntl(fd, F_SETFL, 0) == -1) { 1357db96d56Sopenharmony_ci close(fd); 1367db96d56Sopenharmony_ci PyErr_SetFromErrnoWithFilename(PyExc_OSError, devicename); 1377db96d56Sopenharmony_ci return NULL; 1387db96d56Sopenharmony_ci } 1397db96d56Sopenharmony_ci 1407db96d56Sopenharmony_ci if (ioctl(fd, SNDCTL_DSP_GETFMTS, &afmts) == -1) { 1417db96d56Sopenharmony_ci close(fd); 1427db96d56Sopenharmony_ci PyErr_SetFromErrnoWithFilename(PyExc_OSError, devicename); 1437db96d56Sopenharmony_ci return NULL; 1447db96d56Sopenharmony_ci } 1457db96d56Sopenharmony_ci /* Create and initialize the object */ 1467db96d56Sopenharmony_ci if ((self = PyObject_New(oss_audio_t, &OSSAudioType)) == NULL) { 1477db96d56Sopenharmony_ci close(fd); 1487db96d56Sopenharmony_ci return NULL; 1497db96d56Sopenharmony_ci } 1507db96d56Sopenharmony_ci self->devicename = devicename; 1517db96d56Sopenharmony_ci self->fd = fd; 1527db96d56Sopenharmony_ci self->mode = imode; 1537db96d56Sopenharmony_ci self->icount = self->ocount = 0; 1547db96d56Sopenharmony_ci self->afmts = afmts; 1557db96d56Sopenharmony_ci return self; 1567db96d56Sopenharmony_ci} 1577db96d56Sopenharmony_ci 1587db96d56Sopenharmony_cistatic void 1597db96d56Sopenharmony_cioss_dealloc(oss_audio_t *self) 1607db96d56Sopenharmony_ci{ 1617db96d56Sopenharmony_ci /* if already closed, don't reclose it */ 1627db96d56Sopenharmony_ci if (self->fd != -1) 1637db96d56Sopenharmony_ci close(self->fd); 1647db96d56Sopenharmony_ci PyObject_Free(self); 1657db96d56Sopenharmony_ci} 1667db96d56Sopenharmony_ci 1677db96d56Sopenharmony_ci 1687db96d56Sopenharmony_ci/* ---------------------------------------------------------------------- 1697db96d56Sopenharmony_ci * Mixer object initialization/deallocation 1707db96d56Sopenharmony_ci */ 1717db96d56Sopenharmony_ci 1727db96d56Sopenharmony_cistatic oss_mixer_t * 1737db96d56Sopenharmony_cinewossmixerobject(PyObject *arg) 1747db96d56Sopenharmony_ci{ 1757db96d56Sopenharmony_ci const char *devicename = NULL; 1767db96d56Sopenharmony_ci int fd; 1777db96d56Sopenharmony_ci oss_mixer_t *self; 1787db96d56Sopenharmony_ci 1797db96d56Sopenharmony_ci if (!PyArg_ParseTuple(arg, "|s", &devicename)) { 1807db96d56Sopenharmony_ci return NULL; 1817db96d56Sopenharmony_ci } 1827db96d56Sopenharmony_ci 1837db96d56Sopenharmony_ci if (devicename == NULL) { 1847db96d56Sopenharmony_ci devicename = getenv("MIXERDEV"); 1857db96d56Sopenharmony_ci if (devicename == NULL) /* MIXERDEV not set */ 1867db96d56Sopenharmony_ci devicename = "/dev/mixer"; 1877db96d56Sopenharmony_ci } 1887db96d56Sopenharmony_ci 1897db96d56Sopenharmony_ci fd = _Py_open(devicename, O_RDWR); 1907db96d56Sopenharmony_ci if (fd == -1) 1917db96d56Sopenharmony_ci return NULL; 1927db96d56Sopenharmony_ci 1937db96d56Sopenharmony_ci if ((self = PyObject_New(oss_mixer_t, &OSSMixerType)) == NULL) { 1947db96d56Sopenharmony_ci close(fd); 1957db96d56Sopenharmony_ci return NULL; 1967db96d56Sopenharmony_ci } 1977db96d56Sopenharmony_ci 1987db96d56Sopenharmony_ci self->fd = fd; 1997db96d56Sopenharmony_ci 2007db96d56Sopenharmony_ci return self; 2017db96d56Sopenharmony_ci} 2027db96d56Sopenharmony_ci 2037db96d56Sopenharmony_cistatic void 2047db96d56Sopenharmony_cioss_mixer_dealloc(oss_mixer_t *self) 2057db96d56Sopenharmony_ci{ 2067db96d56Sopenharmony_ci /* if already closed, don't reclose it */ 2077db96d56Sopenharmony_ci if (self->fd != -1) 2087db96d56Sopenharmony_ci close(self->fd); 2097db96d56Sopenharmony_ci PyObject_Free(self); 2107db96d56Sopenharmony_ci} 2117db96d56Sopenharmony_ci 2127db96d56Sopenharmony_ci 2137db96d56Sopenharmony_ci/* Methods to wrap the OSS ioctls. The calling convention is pretty 2147db96d56Sopenharmony_ci simple: 2157db96d56Sopenharmony_ci nonblock() -> ioctl(fd, SNDCTL_DSP_NONBLOCK) 2167db96d56Sopenharmony_ci fmt = setfmt(fmt) -> ioctl(fd, SNDCTL_DSP_SETFMT, &fmt) 2177db96d56Sopenharmony_ci etc. 2187db96d56Sopenharmony_ci*/ 2197db96d56Sopenharmony_ci 2207db96d56Sopenharmony_ci 2217db96d56Sopenharmony_ci/* ---------------------------------------------------------------------- 2227db96d56Sopenharmony_ci * Helper functions 2237db96d56Sopenharmony_ci */ 2247db96d56Sopenharmony_ci 2257db96d56Sopenharmony_ci/* Check if a given file descriptor is valid (i.e. hasn't been closed). 2267db96d56Sopenharmony_ci * If true, return 1. Otherwise, raise ValueError and return 0. 2277db96d56Sopenharmony_ci */ 2287db96d56Sopenharmony_cistatic int _is_fd_valid(int fd) 2297db96d56Sopenharmony_ci{ 2307db96d56Sopenharmony_ci /* the FD is set to -1 in oss_close()/oss_mixer_close() */ 2317db96d56Sopenharmony_ci if (fd >= 0) { 2327db96d56Sopenharmony_ci return 1; 2337db96d56Sopenharmony_ci } else { 2347db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, 2357db96d56Sopenharmony_ci "Operation on closed OSS device."); 2367db96d56Sopenharmony_ci return 0; 2377db96d56Sopenharmony_ci } 2387db96d56Sopenharmony_ci} 2397db96d56Sopenharmony_ci 2407db96d56Sopenharmony_ci/* _do_ioctl_1() is a private helper function used for the OSS ioctls -- 2417db96d56Sopenharmony_ci SNDCTL_DSP_{SETFMT,CHANNELS,SPEED} -- that are called from C 2427db96d56Sopenharmony_ci like this: 2437db96d56Sopenharmony_ci ioctl(fd, SNDCTL_DSP_cmd, &arg) 2447db96d56Sopenharmony_ci 2457db96d56Sopenharmony_ci where arg is the value to set, and on return the driver sets arg to 2467db96d56Sopenharmony_ci the value that was actually set. Mapping this to Python is obvious: 2477db96d56Sopenharmony_ci arg = dsp.xxx(arg) 2487db96d56Sopenharmony_ci*/ 2497db96d56Sopenharmony_cistatic PyObject * 2507db96d56Sopenharmony_ci_do_ioctl_1(int fd, PyObject *args, char *fname, unsigned long cmd) 2517db96d56Sopenharmony_ci{ 2527db96d56Sopenharmony_ci char argfmt[33] = "i:"; 2537db96d56Sopenharmony_ci int arg; 2547db96d56Sopenharmony_ci 2557db96d56Sopenharmony_ci assert(strlen(fname) <= 30); 2567db96d56Sopenharmony_ci strncat(argfmt, fname, 30); 2577db96d56Sopenharmony_ci if (!PyArg_ParseTuple(args, argfmt, &arg)) 2587db96d56Sopenharmony_ci return NULL; 2597db96d56Sopenharmony_ci 2607db96d56Sopenharmony_ci if (ioctl(fd, cmd, &arg) == -1) 2617db96d56Sopenharmony_ci return PyErr_SetFromErrno(PyExc_OSError); 2627db96d56Sopenharmony_ci return PyLong_FromLong(arg); 2637db96d56Sopenharmony_ci} 2647db96d56Sopenharmony_ci 2657db96d56Sopenharmony_ci 2667db96d56Sopenharmony_ci/* _do_ioctl_1_internal() is a wrapper for ioctls that take no inputs 2677db96d56Sopenharmony_ci but return an output -- ie. we need to pass a pointer to a local C 2687db96d56Sopenharmony_ci variable so the driver can write its output there, but from Python 2697db96d56Sopenharmony_ci all we see is the return value. For example, 2707db96d56Sopenharmony_ci SOUND_MIXER_READ_DEVMASK returns a bitmask of available mixer 2717db96d56Sopenharmony_ci devices, but does not use the value of the parameter passed-in in any 2727db96d56Sopenharmony_ci way. 2737db96d56Sopenharmony_ci*/ 2747db96d56Sopenharmony_cistatic PyObject * 2757db96d56Sopenharmony_ci_do_ioctl_1_internal(int fd, PyObject *args, char *fname, unsigned long cmd) 2767db96d56Sopenharmony_ci{ 2777db96d56Sopenharmony_ci char argfmt[32] = ":"; 2787db96d56Sopenharmony_ci int arg = 0; 2797db96d56Sopenharmony_ci 2807db96d56Sopenharmony_ci assert(strlen(fname) <= 30); 2817db96d56Sopenharmony_ci strncat(argfmt, fname, 30); 2827db96d56Sopenharmony_ci if (!PyArg_ParseTuple(args, argfmt, &arg)) 2837db96d56Sopenharmony_ci return NULL; 2847db96d56Sopenharmony_ci 2857db96d56Sopenharmony_ci if (ioctl(fd, cmd, &arg) == -1) 2867db96d56Sopenharmony_ci return PyErr_SetFromErrno(PyExc_OSError); 2877db96d56Sopenharmony_ci return PyLong_FromLong(arg); 2887db96d56Sopenharmony_ci} 2897db96d56Sopenharmony_ci 2907db96d56Sopenharmony_ci 2917db96d56Sopenharmony_ci 2927db96d56Sopenharmony_ci/* _do_ioctl_0() is a private helper for the no-argument ioctls: 2937db96d56Sopenharmony_ci SNDCTL_DSP_{SYNC,RESET,POST}. */ 2947db96d56Sopenharmony_cistatic PyObject * 2957db96d56Sopenharmony_ci_do_ioctl_0(int fd, PyObject *args, char *fname, unsigned long cmd) 2967db96d56Sopenharmony_ci{ 2977db96d56Sopenharmony_ci char argfmt[32] = ":"; 2987db96d56Sopenharmony_ci int rv; 2997db96d56Sopenharmony_ci 3007db96d56Sopenharmony_ci assert(strlen(fname) <= 30); 3017db96d56Sopenharmony_ci strncat(argfmt, fname, 30); 3027db96d56Sopenharmony_ci if (!PyArg_ParseTuple(args, argfmt)) 3037db96d56Sopenharmony_ci return NULL; 3047db96d56Sopenharmony_ci 3057db96d56Sopenharmony_ci /* According to hannu@opensound.com, all three of the ioctls that 3067db96d56Sopenharmony_ci use this function can block, so release the GIL. This is 3077db96d56Sopenharmony_ci especially important for SYNC, which can block for several 3087db96d56Sopenharmony_ci seconds. */ 3097db96d56Sopenharmony_ci Py_BEGIN_ALLOW_THREADS 3107db96d56Sopenharmony_ci rv = ioctl(fd, cmd, 0); 3117db96d56Sopenharmony_ci Py_END_ALLOW_THREADS 3127db96d56Sopenharmony_ci 3137db96d56Sopenharmony_ci if (rv == -1) 3147db96d56Sopenharmony_ci return PyErr_SetFromErrno(PyExc_OSError); 3157db96d56Sopenharmony_ci Py_RETURN_NONE; 3167db96d56Sopenharmony_ci} 3177db96d56Sopenharmony_ci 3187db96d56Sopenharmony_ci 3197db96d56Sopenharmony_ci/* ---------------------------------------------------------------------- 3207db96d56Sopenharmony_ci * Methods of DSP objects (OSSAudioType) 3217db96d56Sopenharmony_ci */ 3227db96d56Sopenharmony_ci 3237db96d56Sopenharmony_cistatic PyObject * 3247db96d56Sopenharmony_cioss_nonblock(oss_audio_t *self, PyObject *unused) 3257db96d56Sopenharmony_ci{ 3267db96d56Sopenharmony_ci if (!_is_fd_valid(self->fd)) 3277db96d56Sopenharmony_ci return NULL; 3287db96d56Sopenharmony_ci 3297db96d56Sopenharmony_ci /* Hmmm: it doesn't appear to be possible to return to blocking 3307db96d56Sopenharmony_ci mode once we're in non-blocking mode! */ 3317db96d56Sopenharmony_ci if (ioctl(self->fd, SNDCTL_DSP_NONBLOCK, NULL) == -1) 3327db96d56Sopenharmony_ci return PyErr_SetFromErrno(PyExc_OSError); 3337db96d56Sopenharmony_ci Py_RETURN_NONE; 3347db96d56Sopenharmony_ci} 3357db96d56Sopenharmony_ci 3367db96d56Sopenharmony_cistatic PyObject * 3377db96d56Sopenharmony_cioss_setfmt(oss_audio_t *self, PyObject *args) 3387db96d56Sopenharmony_ci{ 3397db96d56Sopenharmony_ci if (!_is_fd_valid(self->fd)) 3407db96d56Sopenharmony_ci return NULL; 3417db96d56Sopenharmony_ci 3427db96d56Sopenharmony_ci return _do_ioctl_1(self->fd, args, "setfmt", SNDCTL_DSP_SETFMT); 3437db96d56Sopenharmony_ci} 3447db96d56Sopenharmony_ci 3457db96d56Sopenharmony_cistatic PyObject * 3467db96d56Sopenharmony_cioss_getfmts(oss_audio_t *self, PyObject *unused) 3477db96d56Sopenharmony_ci{ 3487db96d56Sopenharmony_ci int mask; 3497db96d56Sopenharmony_ci 3507db96d56Sopenharmony_ci if (!_is_fd_valid(self->fd)) 3517db96d56Sopenharmony_ci return NULL; 3527db96d56Sopenharmony_ci 3537db96d56Sopenharmony_ci if (ioctl(self->fd, SNDCTL_DSP_GETFMTS, &mask) == -1) 3547db96d56Sopenharmony_ci return PyErr_SetFromErrno(PyExc_OSError); 3557db96d56Sopenharmony_ci return PyLong_FromLong(mask); 3567db96d56Sopenharmony_ci} 3577db96d56Sopenharmony_ci 3587db96d56Sopenharmony_cistatic PyObject * 3597db96d56Sopenharmony_cioss_channels(oss_audio_t *self, PyObject *args) 3607db96d56Sopenharmony_ci{ 3617db96d56Sopenharmony_ci if (!_is_fd_valid(self->fd)) 3627db96d56Sopenharmony_ci return NULL; 3637db96d56Sopenharmony_ci 3647db96d56Sopenharmony_ci return _do_ioctl_1(self->fd, args, "channels", SNDCTL_DSP_CHANNELS); 3657db96d56Sopenharmony_ci} 3667db96d56Sopenharmony_ci 3677db96d56Sopenharmony_cistatic PyObject * 3687db96d56Sopenharmony_cioss_speed(oss_audio_t *self, PyObject *args) 3697db96d56Sopenharmony_ci{ 3707db96d56Sopenharmony_ci if (!_is_fd_valid(self->fd)) 3717db96d56Sopenharmony_ci return NULL; 3727db96d56Sopenharmony_ci 3737db96d56Sopenharmony_ci return _do_ioctl_1(self->fd, args, "speed", SNDCTL_DSP_SPEED); 3747db96d56Sopenharmony_ci} 3757db96d56Sopenharmony_ci 3767db96d56Sopenharmony_cistatic PyObject * 3777db96d56Sopenharmony_cioss_sync(oss_audio_t *self, PyObject *args) 3787db96d56Sopenharmony_ci{ 3797db96d56Sopenharmony_ci if (!_is_fd_valid(self->fd)) 3807db96d56Sopenharmony_ci return NULL; 3817db96d56Sopenharmony_ci 3827db96d56Sopenharmony_ci return _do_ioctl_0(self->fd, args, "sync", SNDCTL_DSP_SYNC); 3837db96d56Sopenharmony_ci} 3847db96d56Sopenharmony_ci 3857db96d56Sopenharmony_cistatic PyObject * 3867db96d56Sopenharmony_cioss_reset(oss_audio_t *self, PyObject *args) 3877db96d56Sopenharmony_ci{ 3887db96d56Sopenharmony_ci if (!_is_fd_valid(self->fd)) 3897db96d56Sopenharmony_ci return NULL; 3907db96d56Sopenharmony_ci 3917db96d56Sopenharmony_ci return _do_ioctl_0(self->fd, args, "reset", SNDCTL_DSP_RESET); 3927db96d56Sopenharmony_ci} 3937db96d56Sopenharmony_ci 3947db96d56Sopenharmony_cistatic PyObject * 3957db96d56Sopenharmony_cioss_post(oss_audio_t *self, PyObject *args) 3967db96d56Sopenharmony_ci{ 3977db96d56Sopenharmony_ci if (!_is_fd_valid(self->fd)) 3987db96d56Sopenharmony_ci return NULL; 3997db96d56Sopenharmony_ci 4007db96d56Sopenharmony_ci return _do_ioctl_0(self->fd, args, "post", SNDCTL_DSP_POST); 4017db96d56Sopenharmony_ci} 4027db96d56Sopenharmony_ci 4037db96d56Sopenharmony_ci 4047db96d56Sopenharmony_ci/* Regular file methods: read(), write(), close(), etc. as well 4057db96d56Sopenharmony_ci as one convenience method, writeall(). */ 4067db96d56Sopenharmony_ci 4077db96d56Sopenharmony_cistatic PyObject * 4087db96d56Sopenharmony_cioss_read(oss_audio_t *self, PyObject *args) 4097db96d56Sopenharmony_ci{ 4107db96d56Sopenharmony_ci Py_ssize_t size, count; 4117db96d56Sopenharmony_ci PyObject *rv; 4127db96d56Sopenharmony_ci 4137db96d56Sopenharmony_ci if (!_is_fd_valid(self->fd)) 4147db96d56Sopenharmony_ci return NULL; 4157db96d56Sopenharmony_ci 4167db96d56Sopenharmony_ci if (!PyArg_ParseTuple(args, "n:read", &size)) 4177db96d56Sopenharmony_ci return NULL; 4187db96d56Sopenharmony_ci 4197db96d56Sopenharmony_ci rv = PyBytes_FromStringAndSize(NULL, size); 4207db96d56Sopenharmony_ci if (rv == NULL) 4217db96d56Sopenharmony_ci return NULL; 4227db96d56Sopenharmony_ci 4237db96d56Sopenharmony_ci count = _Py_read(self->fd, PyBytes_AS_STRING(rv), size); 4247db96d56Sopenharmony_ci if (count == -1) { 4257db96d56Sopenharmony_ci Py_DECREF(rv); 4267db96d56Sopenharmony_ci return NULL; 4277db96d56Sopenharmony_ci } 4287db96d56Sopenharmony_ci 4297db96d56Sopenharmony_ci self->icount += count; 4307db96d56Sopenharmony_ci _PyBytes_Resize(&rv, count); 4317db96d56Sopenharmony_ci return rv; 4327db96d56Sopenharmony_ci} 4337db96d56Sopenharmony_ci 4347db96d56Sopenharmony_cistatic PyObject * 4357db96d56Sopenharmony_cioss_write(oss_audio_t *self, PyObject *args) 4367db96d56Sopenharmony_ci{ 4377db96d56Sopenharmony_ci Py_buffer data; 4387db96d56Sopenharmony_ci Py_ssize_t rv; 4397db96d56Sopenharmony_ci 4407db96d56Sopenharmony_ci if (!_is_fd_valid(self->fd)) 4417db96d56Sopenharmony_ci return NULL; 4427db96d56Sopenharmony_ci 4437db96d56Sopenharmony_ci if (!PyArg_ParseTuple(args, "y*:write", &data)) { 4447db96d56Sopenharmony_ci return NULL; 4457db96d56Sopenharmony_ci } 4467db96d56Sopenharmony_ci 4477db96d56Sopenharmony_ci rv = _Py_write(self->fd, data.buf, data.len); 4487db96d56Sopenharmony_ci PyBuffer_Release(&data); 4497db96d56Sopenharmony_ci if (rv == -1) 4507db96d56Sopenharmony_ci return NULL; 4517db96d56Sopenharmony_ci 4527db96d56Sopenharmony_ci self->ocount += rv; 4537db96d56Sopenharmony_ci return PyLong_FromLong(rv); 4547db96d56Sopenharmony_ci} 4557db96d56Sopenharmony_ci 4567db96d56Sopenharmony_cistatic PyObject * 4577db96d56Sopenharmony_cioss_writeall(oss_audio_t *self, PyObject *args) 4587db96d56Sopenharmony_ci{ 4597db96d56Sopenharmony_ci Py_buffer data; 4607db96d56Sopenharmony_ci const char *cp; 4617db96d56Sopenharmony_ci Py_ssize_t size; 4627db96d56Sopenharmony_ci Py_ssize_t rv; 4637db96d56Sopenharmony_ci fd_set write_set_fds; 4647db96d56Sopenharmony_ci int select_rv; 4657db96d56Sopenharmony_ci 4667db96d56Sopenharmony_ci /* NB. writeall() is only useful in non-blocking mode: according to 4677db96d56Sopenharmony_ci Guenter Geiger <geiger@xdv.org> on the linux-audio-dev list 4687db96d56Sopenharmony_ci (http://eca.cx/lad/2002/11/0380.html), OSS guarantees that 4697db96d56Sopenharmony_ci write() in blocking mode consumes the whole buffer. In blocking 4707db96d56Sopenharmony_ci mode, the behaviour of write() and writeall() from Python is 4717db96d56Sopenharmony_ci indistinguishable. */ 4727db96d56Sopenharmony_ci 4737db96d56Sopenharmony_ci if (!_is_fd_valid(self->fd)) 4747db96d56Sopenharmony_ci return NULL; 4757db96d56Sopenharmony_ci 4767db96d56Sopenharmony_ci if (!PyArg_ParseTuple(args, "y*:writeall", &data)) 4777db96d56Sopenharmony_ci return NULL; 4787db96d56Sopenharmony_ci 4797db96d56Sopenharmony_ci if (!_PyIsSelectable_fd(self->fd)) { 4807db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, 4817db96d56Sopenharmony_ci "file descriptor out of range for select"); 4827db96d56Sopenharmony_ci PyBuffer_Release(&data); 4837db96d56Sopenharmony_ci return NULL; 4847db96d56Sopenharmony_ci } 4857db96d56Sopenharmony_ci /* use select to wait for audio device to be available */ 4867db96d56Sopenharmony_ci FD_ZERO(&write_set_fds); 4877db96d56Sopenharmony_ci FD_SET(self->fd, &write_set_fds); 4887db96d56Sopenharmony_ci cp = (const char *)data.buf; 4897db96d56Sopenharmony_ci size = data.len; 4907db96d56Sopenharmony_ci 4917db96d56Sopenharmony_ci while (size > 0) { 4927db96d56Sopenharmony_ci Py_BEGIN_ALLOW_THREADS 4937db96d56Sopenharmony_ci select_rv = select(self->fd+1, NULL, &write_set_fds, NULL, NULL); 4947db96d56Sopenharmony_ci Py_END_ALLOW_THREADS 4957db96d56Sopenharmony_ci 4967db96d56Sopenharmony_ci assert(select_rv != 0); /* no timeout, can't expire */ 4977db96d56Sopenharmony_ci if (select_rv == -1) { 4987db96d56Sopenharmony_ci PyBuffer_Release(&data); 4997db96d56Sopenharmony_ci return PyErr_SetFromErrno(PyExc_OSError); 5007db96d56Sopenharmony_ci } 5017db96d56Sopenharmony_ci 5027db96d56Sopenharmony_ci rv = _Py_write(self->fd, cp, Py_MIN(size, INT_MAX)); 5037db96d56Sopenharmony_ci if (rv == -1) { 5047db96d56Sopenharmony_ci /* buffer is full, try again */ 5057db96d56Sopenharmony_ci if (errno == EAGAIN) { 5067db96d56Sopenharmony_ci PyErr_Clear(); 5077db96d56Sopenharmony_ci continue; 5087db96d56Sopenharmony_ci } 5097db96d56Sopenharmony_ci /* it's a real error */ 5107db96d56Sopenharmony_ci PyBuffer_Release(&data); 5117db96d56Sopenharmony_ci return NULL; 5127db96d56Sopenharmony_ci } 5137db96d56Sopenharmony_ci 5147db96d56Sopenharmony_ci /* wrote rv bytes */ 5157db96d56Sopenharmony_ci self->ocount += rv; 5167db96d56Sopenharmony_ci size -= rv; 5177db96d56Sopenharmony_ci cp += rv; 5187db96d56Sopenharmony_ci } 5197db96d56Sopenharmony_ci PyBuffer_Release(&data); 5207db96d56Sopenharmony_ci Py_RETURN_NONE; 5217db96d56Sopenharmony_ci} 5227db96d56Sopenharmony_ci 5237db96d56Sopenharmony_cistatic PyObject * 5247db96d56Sopenharmony_cioss_close(oss_audio_t *self, PyObject *unused) 5257db96d56Sopenharmony_ci{ 5267db96d56Sopenharmony_ci if (self->fd >= 0) { 5277db96d56Sopenharmony_ci Py_BEGIN_ALLOW_THREADS 5287db96d56Sopenharmony_ci close(self->fd); 5297db96d56Sopenharmony_ci Py_END_ALLOW_THREADS 5307db96d56Sopenharmony_ci self->fd = -1; 5317db96d56Sopenharmony_ci } 5327db96d56Sopenharmony_ci Py_RETURN_NONE; 5337db96d56Sopenharmony_ci} 5347db96d56Sopenharmony_ci 5357db96d56Sopenharmony_cistatic PyObject * 5367db96d56Sopenharmony_cioss_self(PyObject *self, PyObject *unused) 5377db96d56Sopenharmony_ci{ 5387db96d56Sopenharmony_ci Py_INCREF(self); 5397db96d56Sopenharmony_ci return self; 5407db96d56Sopenharmony_ci} 5417db96d56Sopenharmony_ci 5427db96d56Sopenharmony_cistatic PyObject * 5437db96d56Sopenharmony_cioss_exit(PyObject *self, PyObject *unused) 5447db96d56Sopenharmony_ci{ 5457db96d56Sopenharmony_ci _Py_IDENTIFIER(close); 5467db96d56Sopenharmony_ci 5477db96d56Sopenharmony_ci PyObject *ret = _PyObject_CallMethodIdNoArgs(self, &PyId_close); 5487db96d56Sopenharmony_ci if (!ret) 5497db96d56Sopenharmony_ci return NULL; 5507db96d56Sopenharmony_ci Py_DECREF(ret); 5517db96d56Sopenharmony_ci Py_RETURN_NONE; 5527db96d56Sopenharmony_ci} 5537db96d56Sopenharmony_ci 5547db96d56Sopenharmony_cistatic PyObject * 5557db96d56Sopenharmony_cioss_fileno(oss_audio_t *self, PyObject *unused) 5567db96d56Sopenharmony_ci{ 5577db96d56Sopenharmony_ci if (!_is_fd_valid(self->fd)) 5587db96d56Sopenharmony_ci return NULL; 5597db96d56Sopenharmony_ci 5607db96d56Sopenharmony_ci return PyLong_FromLong(self->fd); 5617db96d56Sopenharmony_ci} 5627db96d56Sopenharmony_ci 5637db96d56Sopenharmony_ci 5647db96d56Sopenharmony_ci/* Convenience methods: these generally wrap a couple of ioctls into one 5657db96d56Sopenharmony_ci common task. */ 5667db96d56Sopenharmony_ci 5677db96d56Sopenharmony_cistatic PyObject * 5687db96d56Sopenharmony_cioss_setparameters(oss_audio_t *self, PyObject *args) 5697db96d56Sopenharmony_ci{ 5707db96d56Sopenharmony_ci int wanted_fmt, wanted_channels, wanted_rate, strict=0; 5717db96d56Sopenharmony_ci int fmt, channels, rate; 5727db96d56Sopenharmony_ci 5737db96d56Sopenharmony_ci if (!_is_fd_valid(self->fd)) 5747db96d56Sopenharmony_ci return NULL; 5757db96d56Sopenharmony_ci 5767db96d56Sopenharmony_ci if (!PyArg_ParseTuple(args, "iii|i:setparameters", 5777db96d56Sopenharmony_ci &wanted_fmt, &wanted_channels, &wanted_rate, 5787db96d56Sopenharmony_ci &strict)) 5797db96d56Sopenharmony_ci return NULL; 5807db96d56Sopenharmony_ci 5817db96d56Sopenharmony_ci fmt = wanted_fmt; 5827db96d56Sopenharmony_ci if (ioctl(self->fd, SNDCTL_DSP_SETFMT, &fmt) == -1) { 5837db96d56Sopenharmony_ci return PyErr_SetFromErrno(PyExc_OSError); 5847db96d56Sopenharmony_ci } 5857db96d56Sopenharmony_ci if (strict && fmt != wanted_fmt) { 5867db96d56Sopenharmony_ci return PyErr_Format 5877db96d56Sopenharmony_ci (OSSAudioError, 5887db96d56Sopenharmony_ci "unable to set requested format (wanted %d, got %d)", 5897db96d56Sopenharmony_ci wanted_fmt, fmt); 5907db96d56Sopenharmony_ci } 5917db96d56Sopenharmony_ci 5927db96d56Sopenharmony_ci channels = wanted_channels; 5937db96d56Sopenharmony_ci if (ioctl(self->fd, SNDCTL_DSP_CHANNELS, &channels) == -1) { 5947db96d56Sopenharmony_ci return PyErr_SetFromErrno(PyExc_OSError); 5957db96d56Sopenharmony_ci } 5967db96d56Sopenharmony_ci if (strict && channels != wanted_channels) { 5977db96d56Sopenharmony_ci return PyErr_Format 5987db96d56Sopenharmony_ci (OSSAudioError, 5997db96d56Sopenharmony_ci "unable to set requested channels (wanted %d, got %d)", 6007db96d56Sopenharmony_ci wanted_channels, channels); 6017db96d56Sopenharmony_ci } 6027db96d56Sopenharmony_ci 6037db96d56Sopenharmony_ci rate = wanted_rate; 6047db96d56Sopenharmony_ci if (ioctl(self->fd, SNDCTL_DSP_SPEED, &rate) == -1) { 6057db96d56Sopenharmony_ci return PyErr_SetFromErrno(PyExc_OSError); 6067db96d56Sopenharmony_ci } 6077db96d56Sopenharmony_ci if (strict && rate != wanted_rate) { 6087db96d56Sopenharmony_ci return PyErr_Format 6097db96d56Sopenharmony_ci (OSSAudioError, 6107db96d56Sopenharmony_ci "unable to set requested rate (wanted %d, got %d)", 6117db96d56Sopenharmony_ci wanted_rate, rate); 6127db96d56Sopenharmony_ci } 6137db96d56Sopenharmony_ci 6147db96d56Sopenharmony_ci /* Construct the return value: a (fmt, channels, rate) tuple that 6157db96d56Sopenharmony_ci tells what the audio hardware was actually set to. */ 6167db96d56Sopenharmony_ci return Py_BuildValue("(iii)", fmt, channels, rate); 6177db96d56Sopenharmony_ci} 6187db96d56Sopenharmony_ci 6197db96d56Sopenharmony_cistatic int 6207db96d56Sopenharmony_ci_ssize(oss_audio_t *self, int *nchannels, int *ssize) 6217db96d56Sopenharmony_ci{ 6227db96d56Sopenharmony_ci int fmt; 6237db96d56Sopenharmony_ci 6247db96d56Sopenharmony_ci fmt = 0; 6257db96d56Sopenharmony_ci if (ioctl(self->fd, SNDCTL_DSP_SETFMT, &fmt) < 0) 6267db96d56Sopenharmony_ci return -errno; 6277db96d56Sopenharmony_ci 6287db96d56Sopenharmony_ci switch (fmt) { 6297db96d56Sopenharmony_ci case AFMT_MU_LAW: 6307db96d56Sopenharmony_ci case AFMT_A_LAW: 6317db96d56Sopenharmony_ci case AFMT_U8: 6327db96d56Sopenharmony_ci case AFMT_S8: 6337db96d56Sopenharmony_ci *ssize = 1; /* 8 bit formats: 1 byte */ 6347db96d56Sopenharmony_ci break; 6357db96d56Sopenharmony_ci case AFMT_S16_LE: 6367db96d56Sopenharmony_ci case AFMT_S16_BE: 6377db96d56Sopenharmony_ci case AFMT_U16_LE: 6387db96d56Sopenharmony_ci case AFMT_U16_BE: 6397db96d56Sopenharmony_ci *ssize = 2; /* 16 bit formats: 2 byte */ 6407db96d56Sopenharmony_ci break; 6417db96d56Sopenharmony_ci case AFMT_MPEG: 6427db96d56Sopenharmony_ci case AFMT_IMA_ADPCM: 6437db96d56Sopenharmony_ci default: 6447db96d56Sopenharmony_ci return -EOPNOTSUPP; 6457db96d56Sopenharmony_ci } 6467db96d56Sopenharmony_ci if (ioctl(self->fd, SNDCTL_DSP_CHANNELS, nchannels) < 0) 6477db96d56Sopenharmony_ci return -errno; 6487db96d56Sopenharmony_ci return 0; 6497db96d56Sopenharmony_ci} 6507db96d56Sopenharmony_ci 6517db96d56Sopenharmony_ci 6527db96d56Sopenharmony_ci/* bufsize returns the size of the hardware audio buffer in number 6537db96d56Sopenharmony_ci of samples */ 6547db96d56Sopenharmony_cistatic PyObject * 6557db96d56Sopenharmony_cioss_bufsize(oss_audio_t *self, PyObject *unused) 6567db96d56Sopenharmony_ci{ 6577db96d56Sopenharmony_ci audio_buf_info ai; 6587db96d56Sopenharmony_ci int nchannels=0, ssize=0; 6597db96d56Sopenharmony_ci 6607db96d56Sopenharmony_ci if (!_is_fd_valid(self->fd)) 6617db96d56Sopenharmony_ci return NULL; 6627db96d56Sopenharmony_ci 6637db96d56Sopenharmony_ci if (_ssize(self, &nchannels, &ssize) < 0 || !nchannels || !ssize) { 6647db96d56Sopenharmony_ci PyErr_SetFromErrno(PyExc_OSError); 6657db96d56Sopenharmony_ci return NULL; 6667db96d56Sopenharmony_ci } 6677db96d56Sopenharmony_ci if (ioctl(self->fd, SNDCTL_DSP_GETOSPACE, &ai) < 0) { 6687db96d56Sopenharmony_ci PyErr_SetFromErrno(PyExc_OSError); 6697db96d56Sopenharmony_ci return NULL; 6707db96d56Sopenharmony_ci } 6717db96d56Sopenharmony_ci return PyLong_FromLong((ai.fragstotal * ai.fragsize) / (nchannels * ssize)); 6727db96d56Sopenharmony_ci} 6737db96d56Sopenharmony_ci 6747db96d56Sopenharmony_ci/* obufcount returns the number of samples that are available in the 6757db96d56Sopenharmony_ci hardware for playing */ 6767db96d56Sopenharmony_cistatic PyObject * 6777db96d56Sopenharmony_cioss_obufcount(oss_audio_t *self, PyObject *unused) 6787db96d56Sopenharmony_ci{ 6797db96d56Sopenharmony_ci audio_buf_info ai; 6807db96d56Sopenharmony_ci int nchannels=0, ssize=0; 6817db96d56Sopenharmony_ci 6827db96d56Sopenharmony_ci if (!_is_fd_valid(self->fd)) 6837db96d56Sopenharmony_ci return NULL; 6847db96d56Sopenharmony_ci 6857db96d56Sopenharmony_ci if (_ssize(self, &nchannels, &ssize) < 0 || !nchannels || !ssize) { 6867db96d56Sopenharmony_ci PyErr_SetFromErrno(PyExc_OSError); 6877db96d56Sopenharmony_ci return NULL; 6887db96d56Sopenharmony_ci } 6897db96d56Sopenharmony_ci if (ioctl(self->fd, SNDCTL_DSP_GETOSPACE, &ai) < 0) { 6907db96d56Sopenharmony_ci PyErr_SetFromErrno(PyExc_OSError); 6917db96d56Sopenharmony_ci return NULL; 6927db96d56Sopenharmony_ci } 6937db96d56Sopenharmony_ci return PyLong_FromLong((ai.fragstotal * ai.fragsize - ai.bytes) / 6947db96d56Sopenharmony_ci (ssize * nchannels)); 6957db96d56Sopenharmony_ci} 6967db96d56Sopenharmony_ci 6977db96d56Sopenharmony_ci/* obufcount returns the number of samples that can be played without 6987db96d56Sopenharmony_ci blocking */ 6997db96d56Sopenharmony_cistatic PyObject * 7007db96d56Sopenharmony_cioss_obuffree(oss_audio_t *self, PyObject *unused) 7017db96d56Sopenharmony_ci{ 7027db96d56Sopenharmony_ci audio_buf_info ai; 7037db96d56Sopenharmony_ci int nchannels=0, ssize=0; 7047db96d56Sopenharmony_ci 7057db96d56Sopenharmony_ci if (!_is_fd_valid(self->fd)) 7067db96d56Sopenharmony_ci return NULL; 7077db96d56Sopenharmony_ci 7087db96d56Sopenharmony_ci if (_ssize(self, &nchannels, &ssize) < 0 || !nchannels || !ssize) { 7097db96d56Sopenharmony_ci PyErr_SetFromErrno(PyExc_OSError); 7107db96d56Sopenharmony_ci return NULL; 7117db96d56Sopenharmony_ci } 7127db96d56Sopenharmony_ci if (ioctl(self->fd, SNDCTL_DSP_GETOSPACE, &ai) < 0) { 7137db96d56Sopenharmony_ci PyErr_SetFromErrno(PyExc_OSError); 7147db96d56Sopenharmony_ci return NULL; 7157db96d56Sopenharmony_ci } 7167db96d56Sopenharmony_ci return PyLong_FromLong(ai.bytes / (ssize * nchannels)); 7177db96d56Sopenharmony_ci} 7187db96d56Sopenharmony_ci 7197db96d56Sopenharmony_cistatic PyObject * 7207db96d56Sopenharmony_cioss_getptr(oss_audio_t *self, PyObject *unused) 7217db96d56Sopenharmony_ci{ 7227db96d56Sopenharmony_ci count_info info; 7237db96d56Sopenharmony_ci int req; 7247db96d56Sopenharmony_ci 7257db96d56Sopenharmony_ci if (!_is_fd_valid(self->fd)) 7267db96d56Sopenharmony_ci return NULL; 7277db96d56Sopenharmony_ci 7287db96d56Sopenharmony_ci if (self->mode == O_RDONLY) 7297db96d56Sopenharmony_ci req = SNDCTL_DSP_GETIPTR; 7307db96d56Sopenharmony_ci else 7317db96d56Sopenharmony_ci req = SNDCTL_DSP_GETOPTR; 7327db96d56Sopenharmony_ci if (ioctl(self->fd, req, &info) == -1) { 7337db96d56Sopenharmony_ci PyErr_SetFromErrno(PyExc_OSError); 7347db96d56Sopenharmony_ci return NULL; 7357db96d56Sopenharmony_ci } 7367db96d56Sopenharmony_ci return Py_BuildValue("iii", info.bytes, info.blocks, info.ptr); 7377db96d56Sopenharmony_ci} 7387db96d56Sopenharmony_ci 7397db96d56Sopenharmony_ci 7407db96d56Sopenharmony_ci/* ---------------------------------------------------------------------- 7417db96d56Sopenharmony_ci * Methods of mixer objects (OSSMixerType) 7427db96d56Sopenharmony_ci */ 7437db96d56Sopenharmony_ci 7447db96d56Sopenharmony_cistatic PyObject * 7457db96d56Sopenharmony_cioss_mixer_close(oss_mixer_t *self, PyObject *unused) 7467db96d56Sopenharmony_ci{ 7477db96d56Sopenharmony_ci if (self->fd >= 0) { 7487db96d56Sopenharmony_ci close(self->fd); 7497db96d56Sopenharmony_ci self->fd = -1; 7507db96d56Sopenharmony_ci } 7517db96d56Sopenharmony_ci Py_RETURN_NONE; 7527db96d56Sopenharmony_ci} 7537db96d56Sopenharmony_ci 7547db96d56Sopenharmony_cistatic PyObject * 7557db96d56Sopenharmony_cioss_mixer_fileno(oss_mixer_t *self, PyObject *unused) 7567db96d56Sopenharmony_ci{ 7577db96d56Sopenharmony_ci if (!_is_fd_valid(self->fd)) 7587db96d56Sopenharmony_ci return NULL; 7597db96d56Sopenharmony_ci 7607db96d56Sopenharmony_ci return PyLong_FromLong(self->fd); 7617db96d56Sopenharmony_ci} 7627db96d56Sopenharmony_ci 7637db96d56Sopenharmony_ci/* Simple mixer interface methods */ 7647db96d56Sopenharmony_ci 7657db96d56Sopenharmony_cistatic PyObject * 7667db96d56Sopenharmony_cioss_mixer_controls(oss_mixer_t *self, PyObject *args) 7677db96d56Sopenharmony_ci{ 7687db96d56Sopenharmony_ci if (!_is_fd_valid(self->fd)) 7697db96d56Sopenharmony_ci return NULL; 7707db96d56Sopenharmony_ci 7717db96d56Sopenharmony_ci return _do_ioctl_1_internal(self->fd, args, "controls", 7727db96d56Sopenharmony_ci SOUND_MIXER_READ_DEVMASK); 7737db96d56Sopenharmony_ci} 7747db96d56Sopenharmony_ci 7757db96d56Sopenharmony_cistatic PyObject * 7767db96d56Sopenharmony_cioss_mixer_stereocontrols(oss_mixer_t *self, PyObject *args) 7777db96d56Sopenharmony_ci{ 7787db96d56Sopenharmony_ci if (!_is_fd_valid(self->fd)) 7797db96d56Sopenharmony_ci return NULL; 7807db96d56Sopenharmony_ci 7817db96d56Sopenharmony_ci return _do_ioctl_1_internal(self->fd, args, "stereocontrols", 7827db96d56Sopenharmony_ci SOUND_MIXER_READ_STEREODEVS); 7837db96d56Sopenharmony_ci} 7847db96d56Sopenharmony_ci 7857db96d56Sopenharmony_cistatic PyObject * 7867db96d56Sopenharmony_cioss_mixer_reccontrols(oss_mixer_t *self, PyObject *args) 7877db96d56Sopenharmony_ci{ 7887db96d56Sopenharmony_ci if (!_is_fd_valid(self->fd)) 7897db96d56Sopenharmony_ci return NULL; 7907db96d56Sopenharmony_ci 7917db96d56Sopenharmony_ci return _do_ioctl_1_internal(self->fd, args, "reccontrols", 7927db96d56Sopenharmony_ci SOUND_MIXER_READ_RECMASK); 7937db96d56Sopenharmony_ci} 7947db96d56Sopenharmony_ci 7957db96d56Sopenharmony_cistatic PyObject * 7967db96d56Sopenharmony_cioss_mixer_get(oss_mixer_t *self, PyObject *args) 7977db96d56Sopenharmony_ci{ 7987db96d56Sopenharmony_ci int channel, volume; 7997db96d56Sopenharmony_ci 8007db96d56Sopenharmony_ci if (!_is_fd_valid(self->fd)) 8017db96d56Sopenharmony_ci return NULL; 8027db96d56Sopenharmony_ci 8037db96d56Sopenharmony_ci /* Can't use _do_ioctl_1 because of encoded arg thingy. */ 8047db96d56Sopenharmony_ci if (!PyArg_ParseTuple(args, "i:get", &channel)) 8057db96d56Sopenharmony_ci return NULL; 8067db96d56Sopenharmony_ci 8077db96d56Sopenharmony_ci if (channel < 0 || channel > SOUND_MIXER_NRDEVICES) { 8087db96d56Sopenharmony_ci PyErr_SetString(OSSAudioError, "Invalid mixer channel specified."); 8097db96d56Sopenharmony_ci return NULL; 8107db96d56Sopenharmony_ci } 8117db96d56Sopenharmony_ci 8127db96d56Sopenharmony_ci if (ioctl(self->fd, MIXER_READ(channel), &volume) == -1) 8137db96d56Sopenharmony_ci return PyErr_SetFromErrno(PyExc_OSError); 8147db96d56Sopenharmony_ci 8157db96d56Sopenharmony_ci return Py_BuildValue("(ii)", volume & 0xff, (volume & 0xff00) >> 8); 8167db96d56Sopenharmony_ci} 8177db96d56Sopenharmony_ci 8187db96d56Sopenharmony_cistatic PyObject * 8197db96d56Sopenharmony_cioss_mixer_set(oss_mixer_t *self, PyObject *args) 8207db96d56Sopenharmony_ci{ 8217db96d56Sopenharmony_ci int channel, volume, leftVol, rightVol; 8227db96d56Sopenharmony_ci 8237db96d56Sopenharmony_ci if (!_is_fd_valid(self->fd)) 8247db96d56Sopenharmony_ci return NULL; 8257db96d56Sopenharmony_ci 8267db96d56Sopenharmony_ci /* Can't use _do_ioctl_1 because of encoded arg thingy. */ 8277db96d56Sopenharmony_ci if (!PyArg_ParseTuple(args, "i(ii):set", &channel, &leftVol, &rightVol)) 8287db96d56Sopenharmony_ci return NULL; 8297db96d56Sopenharmony_ci 8307db96d56Sopenharmony_ci if (channel < 0 || channel > SOUND_MIXER_NRDEVICES) { 8317db96d56Sopenharmony_ci PyErr_SetString(OSSAudioError, "Invalid mixer channel specified."); 8327db96d56Sopenharmony_ci return NULL; 8337db96d56Sopenharmony_ci } 8347db96d56Sopenharmony_ci 8357db96d56Sopenharmony_ci if (leftVol < 0 || rightVol < 0 || leftVol > 100 || rightVol > 100) { 8367db96d56Sopenharmony_ci PyErr_SetString(OSSAudioError, "Volumes must be between 0 and 100."); 8377db96d56Sopenharmony_ci return NULL; 8387db96d56Sopenharmony_ci } 8397db96d56Sopenharmony_ci 8407db96d56Sopenharmony_ci volume = (rightVol << 8) | leftVol; 8417db96d56Sopenharmony_ci 8427db96d56Sopenharmony_ci if (ioctl(self->fd, MIXER_WRITE(channel), &volume) == -1) 8437db96d56Sopenharmony_ci return PyErr_SetFromErrno(PyExc_OSError); 8447db96d56Sopenharmony_ci 8457db96d56Sopenharmony_ci return Py_BuildValue("(ii)", volume & 0xff, (volume & 0xff00) >> 8); 8467db96d56Sopenharmony_ci} 8477db96d56Sopenharmony_ci 8487db96d56Sopenharmony_cistatic PyObject * 8497db96d56Sopenharmony_cioss_mixer_get_recsrc(oss_mixer_t *self, PyObject *args) 8507db96d56Sopenharmony_ci{ 8517db96d56Sopenharmony_ci if (!_is_fd_valid(self->fd)) 8527db96d56Sopenharmony_ci return NULL; 8537db96d56Sopenharmony_ci 8547db96d56Sopenharmony_ci return _do_ioctl_1_internal(self->fd, args, "get_recsrc", 8557db96d56Sopenharmony_ci SOUND_MIXER_READ_RECSRC); 8567db96d56Sopenharmony_ci} 8577db96d56Sopenharmony_ci 8587db96d56Sopenharmony_cistatic PyObject * 8597db96d56Sopenharmony_cioss_mixer_set_recsrc(oss_mixer_t *self, PyObject *args) 8607db96d56Sopenharmony_ci{ 8617db96d56Sopenharmony_ci if (!_is_fd_valid(self->fd)) 8627db96d56Sopenharmony_ci return NULL; 8637db96d56Sopenharmony_ci 8647db96d56Sopenharmony_ci return _do_ioctl_1(self->fd, args, "set_recsrc", 8657db96d56Sopenharmony_ci SOUND_MIXER_WRITE_RECSRC); 8667db96d56Sopenharmony_ci} 8677db96d56Sopenharmony_ci 8687db96d56Sopenharmony_ci 8697db96d56Sopenharmony_ci/* ---------------------------------------------------------------------- 8707db96d56Sopenharmony_ci * Method tables and other bureaucracy 8717db96d56Sopenharmony_ci */ 8727db96d56Sopenharmony_ci 8737db96d56Sopenharmony_cistatic PyMethodDef oss_methods[] = { 8747db96d56Sopenharmony_ci /* Regular file methods */ 8757db96d56Sopenharmony_ci { "read", (PyCFunction)oss_read, METH_VARARGS }, 8767db96d56Sopenharmony_ci { "write", (PyCFunction)oss_write, METH_VARARGS }, 8777db96d56Sopenharmony_ci { "writeall", (PyCFunction)oss_writeall, METH_VARARGS }, 8787db96d56Sopenharmony_ci { "close", (PyCFunction)oss_close, METH_NOARGS }, 8797db96d56Sopenharmony_ci { "fileno", (PyCFunction)oss_fileno, METH_NOARGS }, 8807db96d56Sopenharmony_ci 8817db96d56Sopenharmony_ci /* Simple ioctl wrappers */ 8827db96d56Sopenharmony_ci { "nonblock", (PyCFunction)oss_nonblock, METH_NOARGS }, 8837db96d56Sopenharmony_ci { "setfmt", (PyCFunction)oss_setfmt, METH_VARARGS }, 8847db96d56Sopenharmony_ci { "getfmts", (PyCFunction)oss_getfmts, METH_NOARGS }, 8857db96d56Sopenharmony_ci { "channels", (PyCFunction)oss_channels, METH_VARARGS }, 8867db96d56Sopenharmony_ci { "speed", (PyCFunction)oss_speed, METH_VARARGS }, 8877db96d56Sopenharmony_ci { "sync", (PyCFunction)oss_sync, METH_VARARGS }, 8887db96d56Sopenharmony_ci { "reset", (PyCFunction)oss_reset, METH_VARARGS }, 8897db96d56Sopenharmony_ci { "post", (PyCFunction)oss_post, METH_VARARGS }, 8907db96d56Sopenharmony_ci 8917db96d56Sopenharmony_ci /* Convenience methods -- wrap a couple of ioctls together */ 8927db96d56Sopenharmony_ci { "setparameters", (PyCFunction)oss_setparameters, METH_VARARGS }, 8937db96d56Sopenharmony_ci { "bufsize", (PyCFunction)oss_bufsize, METH_NOARGS }, 8947db96d56Sopenharmony_ci { "obufcount", (PyCFunction)oss_obufcount, METH_NOARGS }, 8957db96d56Sopenharmony_ci { "obuffree", (PyCFunction)oss_obuffree, METH_NOARGS }, 8967db96d56Sopenharmony_ci { "getptr", (PyCFunction)oss_getptr, METH_NOARGS }, 8977db96d56Sopenharmony_ci 8987db96d56Sopenharmony_ci /* Aliases for backwards compatibility */ 8997db96d56Sopenharmony_ci { "flush", (PyCFunction)oss_sync, METH_VARARGS }, 9007db96d56Sopenharmony_ci 9017db96d56Sopenharmony_ci /* Support for the context management protocol */ 9027db96d56Sopenharmony_ci { "__enter__", oss_self, METH_NOARGS }, 9037db96d56Sopenharmony_ci { "__exit__", oss_exit, METH_VARARGS }, 9047db96d56Sopenharmony_ci 9057db96d56Sopenharmony_ci { NULL, NULL} /* sentinel */ 9067db96d56Sopenharmony_ci}; 9077db96d56Sopenharmony_ci 9087db96d56Sopenharmony_cistatic PyMethodDef oss_mixer_methods[] = { 9097db96d56Sopenharmony_ci /* Regular file method - OSS mixers are ioctl-only interface */ 9107db96d56Sopenharmony_ci { "close", (PyCFunction)oss_mixer_close, METH_NOARGS }, 9117db96d56Sopenharmony_ci { "fileno", (PyCFunction)oss_mixer_fileno, METH_NOARGS }, 9127db96d56Sopenharmony_ci 9137db96d56Sopenharmony_ci /* Support for the context management protocol */ 9147db96d56Sopenharmony_ci { "__enter__", oss_self, METH_NOARGS }, 9157db96d56Sopenharmony_ci { "__exit__", oss_exit, METH_VARARGS }, 9167db96d56Sopenharmony_ci 9177db96d56Sopenharmony_ci /* Simple ioctl wrappers */ 9187db96d56Sopenharmony_ci { "controls", (PyCFunction)oss_mixer_controls, METH_VARARGS }, 9197db96d56Sopenharmony_ci { "stereocontrols", (PyCFunction)oss_mixer_stereocontrols, METH_VARARGS}, 9207db96d56Sopenharmony_ci { "reccontrols", (PyCFunction)oss_mixer_reccontrols, METH_VARARGS}, 9217db96d56Sopenharmony_ci { "get", (PyCFunction)oss_mixer_get, METH_VARARGS }, 9227db96d56Sopenharmony_ci { "set", (PyCFunction)oss_mixer_set, METH_VARARGS }, 9237db96d56Sopenharmony_ci { "get_recsrc", (PyCFunction)oss_mixer_get_recsrc, METH_VARARGS }, 9247db96d56Sopenharmony_ci { "set_recsrc", (PyCFunction)oss_mixer_set_recsrc, METH_VARARGS }, 9257db96d56Sopenharmony_ci 9267db96d56Sopenharmony_ci { NULL, NULL} 9277db96d56Sopenharmony_ci}; 9287db96d56Sopenharmony_ci 9297db96d56Sopenharmony_cistatic PyMemberDef oss_members[] = { 9307db96d56Sopenharmony_ci {"name", T_STRING, offsetof(oss_audio_t, devicename), READONLY, NULL}, 9317db96d56Sopenharmony_ci {NULL} 9327db96d56Sopenharmony_ci}; 9337db96d56Sopenharmony_ci 9347db96d56Sopenharmony_cistatic PyObject * 9357db96d56Sopenharmony_cioss_closed_getter(oss_audio_t *self, void *closure) 9367db96d56Sopenharmony_ci{ 9377db96d56Sopenharmony_ci return PyBool_FromLong(self->fd == -1); 9387db96d56Sopenharmony_ci} 9397db96d56Sopenharmony_ci 9407db96d56Sopenharmony_cistatic PyObject * 9417db96d56Sopenharmony_cioss_mode_getter(oss_audio_t *self, void *closure) 9427db96d56Sopenharmony_ci{ 9437db96d56Sopenharmony_ci switch(self->mode) { 9447db96d56Sopenharmony_ci case O_RDONLY: 9457db96d56Sopenharmony_ci return PyUnicode_FromString("r"); 9467db96d56Sopenharmony_ci break; 9477db96d56Sopenharmony_ci case O_RDWR: 9487db96d56Sopenharmony_ci return PyUnicode_FromString("rw"); 9497db96d56Sopenharmony_ci break; 9507db96d56Sopenharmony_ci case O_WRONLY: 9517db96d56Sopenharmony_ci return PyUnicode_FromString("w"); 9527db96d56Sopenharmony_ci break; 9537db96d56Sopenharmony_ci default: 9547db96d56Sopenharmony_ci /* From newossobject(), self->mode can only be one 9557db96d56Sopenharmony_ci of these three values. */ 9567db96d56Sopenharmony_ci Py_UNREACHABLE(); 9577db96d56Sopenharmony_ci } 9587db96d56Sopenharmony_ci} 9597db96d56Sopenharmony_ci 9607db96d56Sopenharmony_cistatic PyGetSetDef oss_getsetlist[] = { 9617db96d56Sopenharmony_ci {"closed", (getter)oss_closed_getter, (setter)NULL, NULL}, 9627db96d56Sopenharmony_ci {"mode", (getter)oss_mode_getter, (setter)NULL, NULL}, 9637db96d56Sopenharmony_ci {NULL}, 9647db96d56Sopenharmony_ci}; 9657db96d56Sopenharmony_ci 9667db96d56Sopenharmony_cistatic PyTypeObject OSSAudioType = { 9677db96d56Sopenharmony_ci PyVarObject_HEAD_INIT(&PyType_Type, 0) 9687db96d56Sopenharmony_ci "ossaudiodev.oss_audio_device", /*tp_name*/ 9697db96d56Sopenharmony_ci sizeof(oss_audio_t), /*tp_basicsize*/ 9707db96d56Sopenharmony_ci 0, /*tp_itemsize*/ 9717db96d56Sopenharmony_ci /* methods */ 9727db96d56Sopenharmony_ci (destructor)oss_dealloc, /*tp_dealloc*/ 9737db96d56Sopenharmony_ci 0, /*tp_vectorcall_offset*/ 9747db96d56Sopenharmony_ci 0, /*tp_getattr*/ 9757db96d56Sopenharmony_ci 0, /*tp_setattr*/ 9767db96d56Sopenharmony_ci 0, /*tp_as_async*/ 9777db96d56Sopenharmony_ci 0, /*tp_repr*/ 9787db96d56Sopenharmony_ci 0, /*tp_as_number*/ 9797db96d56Sopenharmony_ci 0, /*tp_as_sequence*/ 9807db96d56Sopenharmony_ci 0, /*tp_as_mapping*/ 9817db96d56Sopenharmony_ci 0, /*tp_hash*/ 9827db96d56Sopenharmony_ci 0, /*tp_call*/ 9837db96d56Sopenharmony_ci 0, /*tp_str*/ 9847db96d56Sopenharmony_ci 0, /*tp_getattro*/ 9857db96d56Sopenharmony_ci 0, /*tp_setattro*/ 9867db96d56Sopenharmony_ci 0, /*tp_as_buffer*/ 9877db96d56Sopenharmony_ci Py_TPFLAGS_DEFAULT, /*tp_flags*/ 9887db96d56Sopenharmony_ci 0, /*tp_doc*/ 9897db96d56Sopenharmony_ci 0, /*tp_traverse*/ 9907db96d56Sopenharmony_ci 0, /*tp_clear*/ 9917db96d56Sopenharmony_ci 0, /*tp_richcompare*/ 9927db96d56Sopenharmony_ci 0, /*tp_weaklistoffset*/ 9937db96d56Sopenharmony_ci 0, /*tp_iter*/ 9947db96d56Sopenharmony_ci 0, /*tp_iternext*/ 9957db96d56Sopenharmony_ci oss_methods, /*tp_methods*/ 9967db96d56Sopenharmony_ci oss_members, /*tp_members*/ 9977db96d56Sopenharmony_ci oss_getsetlist, /*tp_getset*/ 9987db96d56Sopenharmony_ci}; 9997db96d56Sopenharmony_ci 10007db96d56Sopenharmony_cistatic PyTypeObject OSSMixerType = { 10017db96d56Sopenharmony_ci PyVarObject_HEAD_INIT(&PyType_Type, 0) 10027db96d56Sopenharmony_ci "ossaudiodev.oss_mixer_device", /*tp_name*/ 10037db96d56Sopenharmony_ci sizeof(oss_mixer_t), /*tp_basicsize*/ 10047db96d56Sopenharmony_ci 0, /*tp_itemsize*/ 10057db96d56Sopenharmony_ci /* methods */ 10067db96d56Sopenharmony_ci (destructor)oss_mixer_dealloc, /*tp_dealloc*/ 10077db96d56Sopenharmony_ci 0, /*tp_vectorcall_offset*/ 10087db96d56Sopenharmony_ci 0, /*tp_getattr*/ 10097db96d56Sopenharmony_ci 0, /*tp_setattr*/ 10107db96d56Sopenharmony_ci 0, /*tp_as_async*/ 10117db96d56Sopenharmony_ci 0, /*tp_repr*/ 10127db96d56Sopenharmony_ci 0, /*tp_as_number*/ 10137db96d56Sopenharmony_ci 0, /*tp_as_sequence*/ 10147db96d56Sopenharmony_ci 0, /*tp_as_mapping*/ 10157db96d56Sopenharmony_ci 0, /*tp_hash*/ 10167db96d56Sopenharmony_ci 0, /*tp_call*/ 10177db96d56Sopenharmony_ci 0, /*tp_str*/ 10187db96d56Sopenharmony_ci 0, /*tp_getattro*/ 10197db96d56Sopenharmony_ci 0, /*tp_setattro*/ 10207db96d56Sopenharmony_ci 0, /*tp_as_buffer*/ 10217db96d56Sopenharmony_ci Py_TPFLAGS_DEFAULT, /*tp_flags*/ 10227db96d56Sopenharmony_ci 0, /*tp_doc*/ 10237db96d56Sopenharmony_ci 0, /*tp_traverse*/ 10247db96d56Sopenharmony_ci 0, /*tp_clear*/ 10257db96d56Sopenharmony_ci 0, /*tp_richcompare*/ 10267db96d56Sopenharmony_ci 0, /*tp_weaklistoffset*/ 10277db96d56Sopenharmony_ci 0, /*tp_iter*/ 10287db96d56Sopenharmony_ci 0, /*tp_iternext*/ 10297db96d56Sopenharmony_ci oss_mixer_methods, /*tp_methods*/ 10307db96d56Sopenharmony_ci}; 10317db96d56Sopenharmony_ci 10327db96d56Sopenharmony_ci 10337db96d56Sopenharmony_cistatic PyObject * 10347db96d56Sopenharmony_ciossopen(PyObject *self, PyObject *args) 10357db96d56Sopenharmony_ci{ 10367db96d56Sopenharmony_ci return (PyObject *)newossobject(args); 10377db96d56Sopenharmony_ci} 10387db96d56Sopenharmony_ci 10397db96d56Sopenharmony_cistatic PyObject * 10407db96d56Sopenharmony_ciossopenmixer(PyObject *self, PyObject *args) 10417db96d56Sopenharmony_ci{ 10427db96d56Sopenharmony_ci return (PyObject *)newossmixerobject(args); 10437db96d56Sopenharmony_ci} 10447db96d56Sopenharmony_ci 10457db96d56Sopenharmony_cistatic PyMethodDef ossaudiodev_methods[] = { 10467db96d56Sopenharmony_ci { "open", ossopen, METH_VARARGS }, 10477db96d56Sopenharmony_ci { "openmixer", ossopenmixer, METH_VARARGS }, 10487db96d56Sopenharmony_ci { 0, 0 }, 10497db96d56Sopenharmony_ci}; 10507db96d56Sopenharmony_ci 10517db96d56Sopenharmony_ci 10527db96d56Sopenharmony_ci#define _EXPORT_INT(mod, name) \ 10537db96d56Sopenharmony_ci if (PyModule_AddIntConstant(mod, #name, (long) (name)) == -1) return NULL; 10547db96d56Sopenharmony_ci 10557db96d56Sopenharmony_ci 10567db96d56Sopenharmony_cistatic char *control_labels[] = SOUND_DEVICE_LABELS; 10577db96d56Sopenharmony_cistatic char *control_names[] = SOUND_DEVICE_NAMES; 10587db96d56Sopenharmony_ci 10597db96d56Sopenharmony_ci 10607db96d56Sopenharmony_cistatic int 10617db96d56Sopenharmony_cibuild_namelists (PyObject *module) 10627db96d56Sopenharmony_ci{ 10637db96d56Sopenharmony_ci PyObject *labels; 10647db96d56Sopenharmony_ci PyObject *names; 10657db96d56Sopenharmony_ci PyObject *s; 10667db96d56Sopenharmony_ci int num_controls; 10677db96d56Sopenharmony_ci int i; 10687db96d56Sopenharmony_ci 10697db96d56Sopenharmony_ci num_controls = Py_ARRAY_LENGTH(control_labels); 10707db96d56Sopenharmony_ci assert(num_controls == Py_ARRAY_LENGTH(control_names)); 10717db96d56Sopenharmony_ci 10727db96d56Sopenharmony_ci labels = PyList_New(num_controls); 10737db96d56Sopenharmony_ci names = PyList_New(num_controls); 10747db96d56Sopenharmony_ci if (labels == NULL || names == NULL) 10757db96d56Sopenharmony_ci goto error2; 10767db96d56Sopenharmony_ci for (i = 0; i < num_controls; i++) { 10777db96d56Sopenharmony_ci s = PyUnicode_FromString(control_labels[i]); 10787db96d56Sopenharmony_ci if (s == NULL) 10797db96d56Sopenharmony_ci goto error2; 10807db96d56Sopenharmony_ci PyList_SET_ITEM(labels, i, s); 10817db96d56Sopenharmony_ci 10827db96d56Sopenharmony_ci s = PyUnicode_FromString(control_names[i]); 10837db96d56Sopenharmony_ci if (s == NULL) 10847db96d56Sopenharmony_ci goto error2; 10857db96d56Sopenharmony_ci PyList_SET_ITEM(names, i, s); 10867db96d56Sopenharmony_ci } 10877db96d56Sopenharmony_ci 10887db96d56Sopenharmony_ci if (PyModule_AddObject(module, "control_labels", labels) == -1) 10897db96d56Sopenharmony_ci goto error2; 10907db96d56Sopenharmony_ci if (PyModule_AddObject(module, "control_names", names) == -1) 10917db96d56Sopenharmony_ci goto error1; 10927db96d56Sopenharmony_ci 10937db96d56Sopenharmony_ci return 0; 10947db96d56Sopenharmony_ci 10957db96d56Sopenharmony_cierror2: 10967db96d56Sopenharmony_ci Py_XDECREF(labels); 10977db96d56Sopenharmony_cierror1: 10987db96d56Sopenharmony_ci Py_XDECREF(names); 10997db96d56Sopenharmony_ci return -1; 11007db96d56Sopenharmony_ci} 11017db96d56Sopenharmony_ci 11027db96d56Sopenharmony_ci 11037db96d56Sopenharmony_cistatic struct PyModuleDef ossaudiodevmodule = { 11047db96d56Sopenharmony_ci PyModuleDef_HEAD_INIT, 11057db96d56Sopenharmony_ci "ossaudiodev", 11067db96d56Sopenharmony_ci NULL, 11077db96d56Sopenharmony_ci -1, 11087db96d56Sopenharmony_ci ossaudiodev_methods, 11097db96d56Sopenharmony_ci NULL, 11107db96d56Sopenharmony_ci NULL, 11117db96d56Sopenharmony_ci NULL, 11127db96d56Sopenharmony_ci NULL 11137db96d56Sopenharmony_ci}; 11147db96d56Sopenharmony_ci 11157db96d56Sopenharmony_ciPyMODINIT_FUNC 11167db96d56Sopenharmony_ciPyInit_ossaudiodev(void) 11177db96d56Sopenharmony_ci{ 11187db96d56Sopenharmony_ci PyObject *m; 11197db96d56Sopenharmony_ci 11207db96d56Sopenharmony_ci if (PyErr_WarnEx(PyExc_DeprecationWarning, 11217db96d56Sopenharmony_ci "'ossaudiodev' is deprecated and slated for removal in " 11227db96d56Sopenharmony_ci "Python 3.13", 11237db96d56Sopenharmony_ci 7)) { 11247db96d56Sopenharmony_ci return NULL; 11257db96d56Sopenharmony_ci } 11267db96d56Sopenharmony_ci 11277db96d56Sopenharmony_ci if (PyType_Ready(&OSSAudioType) < 0) 11287db96d56Sopenharmony_ci return NULL; 11297db96d56Sopenharmony_ci 11307db96d56Sopenharmony_ci if (PyType_Ready(&OSSMixerType) < 0) 11317db96d56Sopenharmony_ci return NULL; 11327db96d56Sopenharmony_ci 11337db96d56Sopenharmony_ci m = PyModule_Create(&ossaudiodevmodule); 11347db96d56Sopenharmony_ci if (m == NULL) 11357db96d56Sopenharmony_ci return NULL; 11367db96d56Sopenharmony_ci 11377db96d56Sopenharmony_ci OSSAudioError = PyErr_NewException("ossaudiodev.OSSAudioError", 11387db96d56Sopenharmony_ci NULL, NULL); 11397db96d56Sopenharmony_ci if (OSSAudioError) { 11407db96d56Sopenharmony_ci /* Each call to PyModule_AddObject decrefs it; compensate: */ 11417db96d56Sopenharmony_ci Py_INCREF(OSSAudioError); 11427db96d56Sopenharmony_ci Py_INCREF(OSSAudioError); 11437db96d56Sopenharmony_ci PyModule_AddObject(m, "error", OSSAudioError); 11447db96d56Sopenharmony_ci PyModule_AddObject(m, "OSSAudioError", OSSAudioError); 11457db96d56Sopenharmony_ci } 11467db96d56Sopenharmony_ci 11477db96d56Sopenharmony_ci /* Build 'control_labels' and 'control_names' lists and add them 11487db96d56Sopenharmony_ci to the module. */ 11497db96d56Sopenharmony_ci if (build_namelists(m) == -1) /* XXX what to do here? */ 11507db96d56Sopenharmony_ci return NULL; 11517db96d56Sopenharmony_ci 11527db96d56Sopenharmony_ci /* Expose the audio format numbers -- essential! */ 11537db96d56Sopenharmony_ci _EXPORT_INT(m, AFMT_QUERY); 11547db96d56Sopenharmony_ci _EXPORT_INT(m, AFMT_MU_LAW); 11557db96d56Sopenharmony_ci _EXPORT_INT(m, AFMT_A_LAW); 11567db96d56Sopenharmony_ci _EXPORT_INT(m, AFMT_IMA_ADPCM); 11577db96d56Sopenharmony_ci _EXPORT_INT(m, AFMT_U8); 11587db96d56Sopenharmony_ci _EXPORT_INT(m, AFMT_S16_LE); 11597db96d56Sopenharmony_ci _EXPORT_INT(m, AFMT_S16_BE); 11607db96d56Sopenharmony_ci _EXPORT_INT(m, AFMT_S8); 11617db96d56Sopenharmony_ci _EXPORT_INT(m, AFMT_U16_LE); 11627db96d56Sopenharmony_ci _EXPORT_INT(m, AFMT_U16_BE); 11637db96d56Sopenharmony_ci _EXPORT_INT(m, AFMT_MPEG); 11647db96d56Sopenharmony_ci#ifdef AFMT_AC3 11657db96d56Sopenharmony_ci _EXPORT_INT(m, AFMT_AC3); 11667db96d56Sopenharmony_ci#endif 11677db96d56Sopenharmony_ci#ifdef AFMT_S16_NE 11687db96d56Sopenharmony_ci _EXPORT_INT(m, AFMT_S16_NE); 11697db96d56Sopenharmony_ci#endif 11707db96d56Sopenharmony_ci#ifdef AFMT_U16_NE 11717db96d56Sopenharmony_ci _EXPORT_INT(m, AFMT_U16_NE); 11727db96d56Sopenharmony_ci#endif 11737db96d56Sopenharmony_ci#ifdef AFMT_S32_LE 11747db96d56Sopenharmony_ci _EXPORT_INT(m, AFMT_S32_LE); 11757db96d56Sopenharmony_ci#endif 11767db96d56Sopenharmony_ci#ifdef AFMT_S32_BE 11777db96d56Sopenharmony_ci _EXPORT_INT(m, AFMT_S32_BE); 11787db96d56Sopenharmony_ci#endif 11797db96d56Sopenharmony_ci#ifdef AFMT_MPEG 11807db96d56Sopenharmony_ci _EXPORT_INT(m, AFMT_MPEG); 11817db96d56Sopenharmony_ci#endif 11827db96d56Sopenharmony_ci 11837db96d56Sopenharmony_ci /* Expose the sound mixer device numbers. */ 11847db96d56Sopenharmony_ci _EXPORT_INT(m, SOUND_MIXER_NRDEVICES); 11857db96d56Sopenharmony_ci _EXPORT_INT(m, SOUND_MIXER_VOLUME); 11867db96d56Sopenharmony_ci _EXPORT_INT(m, SOUND_MIXER_BASS); 11877db96d56Sopenharmony_ci _EXPORT_INT(m, SOUND_MIXER_TREBLE); 11887db96d56Sopenharmony_ci _EXPORT_INT(m, SOUND_MIXER_SYNTH); 11897db96d56Sopenharmony_ci _EXPORT_INT(m, SOUND_MIXER_PCM); 11907db96d56Sopenharmony_ci _EXPORT_INT(m, SOUND_MIXER_SPEAKER); 11917db96d56Sopenharmony_ci _EXPORT_INT(m, SOUND_MIXER_LINE); 11927db96d56Sopenharmony_ci _EXPORT_INT(m, SOUND_MIXER_MIC); 11937db96d56Sopenharmony_ci _EXPORT_INT(m, SOUND_MIXER_CD); 11947db96d56Sopenharmony_ci _EXPORT_INT(m, SOUND_MIXER_IMIX); 11957db96d56Sopenharmony_ci _EXPORT_INT(m, SOUND_MIXER_ALTPCM); 11967db96d56Sopenharmony_ci _EXPORT_INT(m, SOUND_MIXER_RECLEV); 11977db96d56Sopenharmony_ci _EXPORT_INT(m, SOUND_MIXER_IGAIN); 11987db96d56Sopenharmony_ci _EXPORT_INT(m, SOUND_MIXER_OGAIN); 11997db96d56Sopenharmony_ci _EXPORT_INT(m, SOUND_MIXER_LINE1); 12007db96d56Sopenharmony_ci _EXPORT_INT(m, SOUND_MIXER_LINE2); 12017db96d56Sopenharmony_ci _EXPORT_INT(m, SOUND_MIXER_LINE3); 12027db96d56Sopenharmony_ci#ifdef SOUND_MIXER_DIGITAL1 12037db96d56Sopenharmony_ci _EXPORT_INT(m, SOUND_MIXER_DIGITAL1); 12047db96d56Sopenharmony_ci#endif 12057db96d56Sopenharmony_ci#ifdef SOUND_MIXER_DIGITAL2 12067db96d56Sopenharmony_ci _EXPORT_INT(m, SOUND_MIXER_DIGITAL2); 12077db96d56Sopenharmony_ci#endif 12087db96d56Sopenharmony_ci#ifdef SOUND_MIXER_DIGITAL3 12097db96d56Sopenharmony_ci _EXPORT_INT(m, SOUND_MIXER_DIGITAL3); 12107db96d56Sopenharmony_ci#endif 12117db96d56Sopenharmony_ci#ifdef SOUND_MIXER_PHONEIN 12127db96d56Sopenharmony_ci _EXPORT_INT(m, SOUND_MIXER_PHONEIN); 12137db96d56Sopenharmony_ci#endif 12147db96d56Sopenharmony_ci#ifdef SOUND_MIXER_PHONEOUT 12157db96d56Sopenharmony_ci _EXPORT_INT(m, SOUND_MIXER_PHONEOUT); 12167db96d56Sopenharmony_ci#endif 12177db96d56Sopenharmony_ci#ifdef SOUND_MIXER_VIDEO 12187db96d56Sopenharmony_ci _EXPORT_INT(m, SOUND_MIXER_VIDEO); 12197db96d56Sopenharmony_ci#endif 12207db96d56Sopenharmony_ci#ifdef SOUND_MIXER_RADIO 12217db96d56Sopenharmony_ci _EXPORT_INT(m, SOUND_MIXER_RADIO); 12227db96d56Sopenharmony_ci#endif 12237db96d56Sopenharmony_ci#ifdef SOUND_MIXER_MONITOR 12247db96d56Sopenharmony_ci _EXPORT_INT(m, SOUND_MIXER_MONITOR); 12257db96d56Sopenharmony_ci#endif 12267db96d56Sopenharmony_ci 12277db96d56Sopenharmony_ci /* Expose all the ioctl numbers for masochists who like to do this 12287db96d56Sopenharmony_ci stuff directly. */ 12297db96d56Sopenharmony_ci#ifdef SNDCTL_COPR_HALT 12307db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_COPR_HALT); 12317db96d56Sopenharmony_ci#endif 12327db96d56Sopenharmony_ci#ifdef SNDCTL_COPR_LOAD 12337db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_COPR_LOAD); 12347db96d56Sopenharmony_ci#endif 12357db96d56Sopenharmony_ci#ifdef SNDCTL_COPR_RCODE 12367db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_COPR_RCODE); 12377db96d56Sopenharmony_ci#endif 12387db96d56Sopenharmony_ci#ifdef SNDCTL_COPR_RCVMSG 12397db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_COPR_RCVMSG); 12407db96d56Sopenharmony_ci#endif 12417db96d56Sopenharmony_ci#ifdef SNDCTL_COPR_RDATA 12427db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_COPR_RDATA); 12437db96d56Sopenharmony_ci#endif 12447db96d56Sopenharmony_ci#ifdef SNDCTL_COPR_RESET 12457db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_COPR_RESET); 12467db96d56Sopenharmony_ci#endif 12477db96d56Sopenharmony_ci#ifdef SNDCTL_COPR_RUN 12487db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_COPR_RUN); 12497db96d56Sopenharmony_ci#endif 12507db96d56Sopenharmony_ci#ifdef SNDCTL_COPR_SENDMSG 12517db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_COPR_SENDMSG); 12527db96d56Sopenharmony_ci#endif 12537db96d56Sopenharmony_ci#ifdef SNDCTL_COPR_WCODE 12547db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_COPR_WCODE); 12557db96d56Sopenharmony_ci#endif 12567db96d56Sopenharmony_ci#ifdef SNDCTL_COPR_WDATA 12577db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_COPR_WDATA); 12587db96d56Sopenharmony_ci#endif 12597db96d56Sopenharmony_ci#ifdef SNDCTL_DSP_BIND_CHANNEL 12607db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_DSP_BIND_CHANNEL); 12617db96d56Sopenharmony_ci#endif 12627db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_DSP_CHANNELS); 12637db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_DSP_GETBLKSIZE); 12647db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_DSP_GETCAPS); 12657db96d56Sopenharmony_ci#ifdef SNDCTL_DSP_GETCHANNELMASK 12667db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_DSP_GETCHANNELMASK); 12677db96d56Sopenharmony_ci#endif 12687db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_DSP_GETFMTS); 12697db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_DSP_GETIPTR); 12707db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_DSP_GETISPACE); 12717db96d56Sopenharmony_ci#ifdef SNDCTL_DSP_GETODELAY 12727db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_DSP_GETODELAY); 12737db96d56Sopenharmony_ci#endif 12747db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_DSP_GETOPTR); 12757db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_DSP_GETOSPACE); 12767db96d56Sopenharmony_ci#ifdef SNDCTL_DSP_GETSPDIF 12777db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_DSP_GETSPDIF); 12787db96d56Sopenharmony_ci#endif 12797db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_DSP_GETTRIGGER); 12807db96d56Sopenharmony_ci#ifdef SNDCTL_DSP_MAPINBUF 12817db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_DSP_MAPINBUF); 12827db96d56Sopenharmony_ci#endif 12837db96d56Sopenharmony_ci#ifdef SNDCTL_DSP_MAPOUTBUF 12847db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_DSP_MAPOUTBUF); 12857db96d56Sopenharmony_ci#endif 12867db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_DSP_NONBLOCK); 12877db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_DSP_POST); 12887db96d56Sopenharmony_ci#ifdef SNDCTL_DSP_PROFILE 12897db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_DSP_PROFILE); 12907db96d56Sopenharmony_ci#endif 12917db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_DSP_RESET); 12927db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_DSP_SAMPLESIZE); 12937db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_DSP_SETDUPLEX); 12947db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_DSP_SETFMT); 12957db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_DSP_SETFRAGMENT); 12967db96d56Sopenharmony_ci#ifdef SNDCTL_DSP_SETSPDIF 12977db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_DSP_SETSPDIF); 12987db96d56Sopenharmony_ci#endif 12997db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_DSP_SETSYNCRO); 13007db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_DSP_SETTRIGGER); 13017db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_DSP_SPEED); 13027db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_DSP_STEREO); 13037db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_DSP_SUBDIVIDE); 13047db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_DSP_SYNC); 13057db96d56Sopenharmony_ci#ifdef SNDCTL_FM_4OP_ENABLE 13067db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_FM_4OP_ENABLE); 13077db96d56Sopenharmony_ci#endif 13087db96d56Sopenharmony_ci#ifdef SNDCTL_FM_LOAD_INSTR 13097db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_FM_LOAD_INSTR); 13107db96d56Sopenharmony_ci#endif 13117db96d56Sopenharmony_ci#ifdef SNDCTL_MIDI_INFO 13127db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_MIDI_INFO); 13137db96d56Sopenharmony_ci#endif 13147db96d56Sopenharmony_ci#ifdef SNDCTL_MIDI_MPUCMD 13157db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_MIDI_MPUCMD); 13167db96d56Sopenharmony_ci#endif 13177db96d56Sopenharmony_ci#ifdef SNDCTL_MIDI_MPUMODE 13187db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_MIDI_MPUMODE); 13197db96d56Sopenharmony_ci#endif 13207db96d56Sopenharmony_ci#ifdef SNDCTL_MIDI_PRETIME 13217db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_MIDI_PRETIME); 13227db96d56Sopenharmony_ci#endif 13237db96d56Sopenharmony_ci#ifdef SNDCTL_SEQ_CTRLRATE 13247db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_SEQ_CTRLRATE); 13257db96d56Sopenharmony_ci#endif 13267db96d56Sopenharmony_ci#ifdef SNDCTL_SEQ_GETINCOUNT 13277db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_SEQ_GETINCOUNT); 13287db96d56Sopenharmony_ci#endif 13297db96d56Sopenharmony_ci#ifdef SNDCTL_SEQ_GETOUTCOUNT 13307db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_SEQ_GETOUTCOUNT); 13317db96d56Sopenharmony_ci#endif 13327db96d56Sopenharmony_ci#ifdef SNDCTL_SEQ_GETTIME 13337db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_SEQ_GETTIME); 13347db96d56Sopenharmony_ci#endif 13357db96d56Sopenharmony_ci#ifdef SNDCTL_SEQ_NRMIDIS 13367db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_SEQ_NRMIDIS); 13377db96d56Sopenharmony_ci#endif 13387db96d56Sopenharmony_ci#ifdef SNDCTL_SEQ_NRSYNTHS 13397db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_SEQ_NRSYNTHS); 13407db96d56Sopenharmony_ci#endif 13417db96d56Sopenharmony_ci#ifdef SNDCTL_SEQ_OUTOFBAND 13427db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_SEQ_OUTOFBAND); 13437db96d56Sopenharmony_ci#endif 13447db96d56Sopenharmony_ci#ifdef SNDCTL_SEQ_PANIC 13457db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_SEQ_PANIC); 13467db96d56Sopenharmony_ci#endif 13477db96d56Sopenharmony_ci#ifdef SNDCTL_SEQ_PERCMODE 13487db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_SEQ_PERCMODE); 13497db96d56Sopenharmony_ci#endif 13507db96d56Sopenharmony_ci#ifdef SNDCTL_SEQ_RESET 13517db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_SEQ_RESET); 13527db96d56Sopenharmony_ci#endif 13537db96d56Sopenharmony_ci#ifdef SNDCTL_SEQ_RESETSAMPLES 13547db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_SEQ_RESETSAMPLES); 13557db96d56Sopenharmony_ci#endif 13567db96d56Sopenharmony_ci#ifdef SNDCTL_SEQ_SYNC 13577db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_SEQ_SYNC); 13587db96d56Sopenharmony_ci#endif 13597db96d56Sopenharmony_ci#ifdef SNDCTL_SEQ_TESTMIDI 13607db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_SEQ_TESTMIDI); 13617db96d56Sopenharmony_ci#endif 13627db96d56Sopenharmony_ci#ifdef SNDCTL_SEQ_THRESHOLD 13637db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_SEQ_THRESHOLD); 13647db96d56Sopenharmony_ci#endif 13657db96d56Sopenharmony_ci#ifdef SNDCTL_SYNTH_CONTROL 13667db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_SYNTH_CONTROL); 13677db96d56Sopenharmony_ci#endif 13687db96d56Sopenharmony_ci#ifdef SNDCTL_SYNTH_ID 13697db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_SYNTH_ID); 13707db96d56Sopenharmony_ci#endif 13717db96d56Sopenharmony_ci#ifdef SNDCTL_SYNTH_INFO 13727db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_SYNTH_INFO); 13737db96d56Sopenharmony_ci#endif 13747db96d56Sopenharmony_ci#ifdef SNDCTL_SYNTH_MEMAVL 13757db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_SYNTH_MEMAVL); 13767db96d56Sopenharmony_ci#endif 13777db96d56Sopenharmony_ci#ifdef SNDCTL_SYNTH_REMOVESAMPLE 13787db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_SYNTH_REMOVESAMPLE); 13797db96d56Sopenharmony_ci#endif 13807db96d56Sopenharmony_ci#ifdef SNDCTL_TMR_CONTINUE 13817db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_TMR_CONTINUE); 13827db96d56Sopenharmony_ci#endif 13837db96d56Sopenharmony_ci#ifdef SNDCTL_TMR_METRONOME 13847db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_TMR_METRONOME); 13857db96d56Sopenharmony_ci#endif 13867db96d56Sopenharmony_ci#ifdef SNDCTL_TMR_SELECT 13877db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_TMR_SELECT); 13887db96d56Sopenharmony_ci#endif 13897db96d56Sopenharmony_ci#ifdef SNDCTL_TMR_SOURCE 13907db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_TMR_SOURCE); 13917db96d56Sopenharmony_ci#endif 13927db96d56Sopenharmony_ci#ifdef SNDCTL_TMR_START 13937db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_TMR_START); 13947db96d56Sopenharmony_ci#endif 13957db96d56Sopenharmony_ci#ifdef SNDCTL_TMR_STOP 13967db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_TMR_STOP); 13977db96d56Sopenharmony_ci#endif 13987db96d56Sopenharmony_ci#ifdef SNDCTL_TMR_TEMPO 13997db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_TMR_TEMPO); 14007db96d56Sopenharmony_ci#endif 14017db96d56Sopenharmony_ci#ifdef SNDCTL_TMR_TIMEBASE 14027db96d56Sopenharmony_ci _EXPORT_INT(m, SNDCTL_TMR_TIMEBASE); 14037db96d56Sopenharmony_ci#endif 14047db96d56Sopenharmony_ci return m; 14057db96d56Sopenharmony_ci} 1406