ยปCore Development>Code coverage>Modules/ossaudiodev.c

Python code coverage for Modules/ossaudiodev.c

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