1 /* Hey Emacs, this is -*-C-*-
2 ******************************************************************************
3 * linuxaudiodev.c -- Linux audio device for python.
6 * Created On : Thu Mar 2 21:10:33 2000
7 * Status : Unknown, Use with caution!
9 * Unless other notices are present in any part of this file
10 * explicitly claiming copyrights for other people and/or
11 * organizations, the contents of this file is fully copyright
12 * (C) 2000 Peter Bosch, all rights reserved.
13 ******************************************************************************
17 #include "structmember.h"
27 #include <sys/ioctl.h>
29 #include <linux/soundcard.h>
31 typedef unsigned long uint32_t;
33 #elif defined(__FreeBSD__)
34 #include <machine/soundcard.h>
36 #ifndef SNDCTL_DSP_CHANNELS
37 #define SNDCTL_DSP_CHANNELS SOUND_PCM_WRITE_CHANNELS
44 int x_fd
; /* The open file */
45 int x_mode
; /* file mode */
46 int x_icount
; /* Input count */
47 int x_ocount
; /* Output count */
48 uint32_t x_afmts
; /* Audio formats supported by hardware*/
51 /* XXX several format defined in soundcard.h are not supported,
52 including _NE (native endian) options and S32 options
60 { 8, AFMT_MU_LAW
, "logarithmic mu-law 8-bit audio" },
61 { 8, AFMT_A_LAW
, "logarithmic A-law 8-bit audio" },
62 { 8, AFMT_U8
, "linear unsigned 8-bit audio" },
63 { 8, AFMT_S8
, "linear signed 8-bit audio" },
64 { 16, AFMT_U16_BE
, "linear unsigned 16-bit big-endian audio" },
65 { 16, AFMT_U16_LE
, "linear unsigned 16-bit little-endian audio" },
66 { 16, AFMT_S16_BE
, "linear signed 16-bit big-endian audio" },
67 { 16, AFMT_S16_LE
, "linear signed 16-bit little-endian audio" },
68 { 16, AFMT_S16_NE
, "linear signed 16-bit native-endian audio" },
71 static int n_audio_types
= sizeof(audio_types
) / sizeof(audio_types
[0]);
73 static PyTypeObject Ladtype
;
75 static PyObject
*LinuxAudioError
;
78 newladobject(PyObject
*arg
)
85 /* Two ways to call linuxaudiodev.open():
86 open(device, mode) (for consistency with builtin open())
87 open(mode) (for backwards compatibility)
88 because the *first* argument is optional, parsing args is
90 if (!PyArg_ParseTuple(arg
, "s|s:open", &basedev
, &mode
))
92 if (mode
== NULL
) { /* only one arg supplied */
97 if (strcmp(mode
, "r") == 0)
99 else if (strcmp(mode
, "w") == 0)
102 PyErr_SetString(LinuxAudioError
, "mode should be 'r' or 'w'");
106 /* Open the correct device. The base device name comes from the
107 * AUDIODEV environment variable first, then /dev/dsp. The
108 * control device tacks "ctl" onto the base device name.
110 * Note that the only difference between /dev/audio and /dev/dsp
111 * is that the former uses logarithmic mu-law encoding and the
112 * latter uses 8-bit unsigned encoding.
115 if (basedev
== NULL
) { /* called with one arg */
116 basedev
= getenv("AUDIODEV");
117 if (basedev
== NULL
) /* $AUDIODEV not set */
118 basedev
= "/dev/dsp";
121 if ((fd
= open(basedev
, imode
)) == -1) {
122 PyErr_SetFromErrnoWithFilename(LinuxAudioError
, basedev
);
125 if (imode
== O_WRONLY
&& ioctl(fd
, SNDCTL_DSP_NONBLOCK
, NULL
) == -1) {
126 PyErr_SetFromErrnoWithFilename(LinuxAudioError
, basedev
);
129 if (ioctl(fd
, SNDCTL_DSP_GETFMTS
, &afmts
) == -1) {
130 PyErr_SetFromErrnoWithFilename(LinuxAudioError
, basedev
);
133 /* Create and initialize the object */
134 if ((xp
= PyObject_New(lad_t
, &Ladtype
)) == NULL
) {
140 xp
->x_icount
= xp
->x_ocount
= 0;
146 lad_dealloc(lad_t
*xp
)
148 /* if already closed, don't reclose it */
155 lad_read(lad_t
*self
, PyObject
*args
)
161 if (!PyArg_ParseTuple(args
, "i:read", &size
))
163 rv
= PyString_FromStringAndSize(NULL
, size
);
166 cp
= PyString_AS_STRING(rv
);
167 if ((count
= read(self
->x_fd
, cp
, size
)) < 0) {
168 PyErr_SetFromErrno(LinuxAudioError
);
172 self
->x_icount
+= count
;
173 _PyString_Resize(&rv
, count
);
178 lad_write(lad_t
*self
, PyObject
*args
)
182 fd_set write_set_fds
;
186 if (!PyArg_ParseTuple(args
, "s#:write", &cp
, &size
))
189 /* use select to wait for audio device to be available */
190 FD_ZERO(&write_set_fds
);
191 FD_SET(self
->x_fd
, &write_set_fds
);
192 tv
.tv_sec
= 4; /* timeout values */
196 select_retval
= select(self
->x_fd
+1, NULL
, &write_set_fds
, NULL
, &tv
);
197 tv
.tv_sec
= 1; tv
.tv_usec
= 0; /* willing to wait this long next time*/
199 if ((rv
= write(self
->x_fd
, cp
, size
)) == -1) {
200 if (errno
!= EAGAIN
) {
201 PyErr_SetFromErrno(LinuxAudioError
);
204 errno
= 0; /* EAGAIN: buffer is full, try again */
207 self
->x_ocount
+= rv
;
212 /* printf("Not able to write to linux audio device within %ld seconds\n", tv.tv_sec); */
213 PyErr_SetFromErrno(LinuxAudioError
);
222 lad_close(lad_t
*self
, PyObject
*args
)
224 if (!PyArg_ParseTuple(args
, ":close"))
227 if (self
->x_fd
>= 0) {
236 lad_fileno(lad_t
*self
, PyObject
*args
)
238 if (!PyArg_ParseTuple(args
, ":fileno"))
240 return PyInt_FromLong(self
->x_fd
);
244 lad_setparameters(lad_t
*self
, PyObject
*args
)
246 int rate
, ssize
, nchannels
, n
, fmt
, emulate
=0;
248 if (!PyArg_ParseTuple(args
, "iiii|i:setparameters",
249 &rate
, &ssize
, &nchannels
, &fmt
, &emulate
))
253 PyErr_Format(PyExc_ValueError
, "expected rate >= 0, not %d",
258 PyErr_Format(PyExc_ValueError
, "expected sample size >= 0, not %d",
262 if (nchannels
!= 1 && nchannels
!= 2) {
263 PyErr_Format(PyExc_ValueError
, "nchannels must be 1 or 2, not %d",
268 for (n
= 0; n
< n_audio_types
; n
++)
269 if (fmt
== audio_types
[n
].a_fmt
)
271 if (n
== n_audio_types
) {
272 PyErr_Format(PyExc_ValueError
, "unknown audio encoding: %d", fmt
);
275 if (audio_types
[n
].a_bps
!= ssize
) {
276 PyErr_Format(PyExc_ValueError
,
277 "for %s, expected sample size %d, not %d",
278 audio_types
[n
].a_name
, audio_types
[n
].a_bps
, ssize
);
283 if ((self
->x_afmts
& audio_types
[n
].a_fmt
) == 0) {
284 PyErr_Format(PyExc_ValueError
,
285 "%s format not supported by device",
286 audio_types
[n
].a_name
);
290 if (ioctl(self
->x_fd
, SNDCTL_DSP_SETFMT
,
291 &audio_types
[n
].a_fmt
) == -1) {
292 PyErr_SetFromErrno(LinuxAudioError
);
295 if (ioctl(self
->x_fd
, SNDCTL_DSP_CHANNELS
, &nchannels
) == -1) {
296 PyErr_SetFromErrno(LinuxAudioError
);
299 if (ioctl(self
->x_fd
, SNDCTL_DSP_SPEED
, &rate
) == -1) {
300 PyErr_SetFromErrno(LinuxAudioError
);
309 _ssize(lad_t
*self
, int *nchannels
, int *ssize
)
314 if (ioctl(self
->x_fd
, SNDCTL_DSP_SETFMT
, &fmt
) < 0)
322 *ssize
= sizeof(char);
328 *ssize
= sizeof(short);
335 if (ioctl(self
->x_fd
, SNDCTL_DSP_CHANNELS
, nchannels
) < 0)
341 /* bufsize returns the size of the hardware audio buffer in number
344 lad_bufsize(lad_t
*self
, PyObject
*args
)
347 int nchannels
=0, ssize
=0;
349 if (!PyArg_ParseTuple(args
, ":bufsize")) return NULL
;
351 if (_ssize(self
, &nchannels
, &ssize
) < 0 || !ssize
|| !nchannels
) {
352 PyErr_SetFromErrno(LinuxAudioError
);
355 if (ioctl(self
->x_fd
, SNDCTL_DSP_GETOSPACE
, &ai
) < 0) {
356 PyErr_SetFromErrno(LinuxAudioError
);
359 return PyInt_FromLong((ai
.fragstotal
* ai
.fragsize
) / (nchannels
* ssize
));
362 /* obufcount returns the number of samples that are available in the
363 hardware for playing */
365 lad_obufcount(lad_t
*self
, PyObject
*args
)
368 int nchannels
=0, ssize
=0;
370 if (!PyArg_ParseTuple(args
, ":obufcount"))
373 if (_ssize(self
, &nchannels
, &ssize
) < 0 || !ssize
|| !nchannels
) {
374 PyErr_SetFromErrno(LinuxAudioError
);
377 if (ioctl(self
->x_fd
, SNDCTL_DSP_GETOSPACE
, &ai
) < 0) {
378 PyErr_SetFromErrno(LinuxAudioError
);
381 return PyInt_FromLong((ai
.fragstotal
* ai
.fragsize
- ai
.bytes
) /
382 (ssize
* nchannels
));
385 /* obufcount returns the number of samples that can be played without
388 lad_obuffree(lad_t
*self
, PyObject
*args
)
391 int nchannels
=0, ssize
=0;
393 if (!PyArg_ParseTuple(args
, ":obuffree"))
396 if (_ssize(self
, &nchannels
, &ssize
) < 0 || !ssize
|| !nchannels
) {
397 PyErr_SetFromErrno(LinuxAudioError
);
400 if (ioctl(self
->x_fd
, SNDCTL_DSP_GETOSPACE
, &ai
) < 0) {
401 PyErr_SetFromErrno(LinuxAudioError
);
404 return PyInt_FromLong(ai
.bytes
/ (ssize
* nchannels
));
407 /* Flush the device */
409 lad_flush(lad_t
*self
, PyObject
*args
)
411 if (!PyArg_ParseTuple(args
, ":flush")) return NULL
;
413 if (ioctl(self
->x_fd
, SNDCTL_DSP_SYNC
, NULL
) == -1) {
414 PyErr_SetFromErrno(LinuxAudioError
);
422 lad_getptr(lad_t
*self
, PyObject
*args
)
427 if (!PyArg_ParseTuple(args
, ":getptr"))
430 if (self
->x_mode
== O_RDONLY
)
431 req
= SNDCTL_DSP_GETIPTR
;
433 req
= SNDCTL_DSP_GETOPTR
;
434 if (ioctl(self
->x_fd
, req
, &info
) == -1) {
435 PyErr_SetFromErrno(LinuxAudioError
);
438 return Py_BuildValue("iii", info
.bytes
, info
.blocks
, info
.ptr
);
441 static PyMethodDef lad_methods
[] = {
442 { "read", (PyCFunction
)lad_read
, METH_VARARGS
},
443 { "write", (PyCFunction
)lad_write
, METH_VARARGS
},
444 { "setparameters", (PyCFunction
)lad_setparameters
, METH_VARARGS
},
445 { "bufsize", (PyCFunction
)lad_bufsize
, METH_VARARGS
},
446 { "obufcount", (PyCFunction
)lad_obufcount
, METH_VARARGS
},
447 { "obuffree", (PyCFunction
)lad_obuffree
, METH_VARARGS
},
448 { "flush", (PyCFunction
)lad_flush
, METH_VARARGS
},
449 { "close", (PyCFunction
)lad_close
, METH_VARARGS
},
450 { "fileno", (PyCFunction
)lad_fileno
, METH_VARARGS
},
451 { "getptr", (PyCFunction
)lad_getptr
, METH_VARARGS
},
452 { NULL
, NULL
} /* sentinel */
456 lad_getattr(lad_t
*xp
, char *name
)
458 return Py_FindMethod(lad_methods
, (PyObject
*)xp
, name
);
461 static PyTypeObject Ladtype
= {
462 PyObject_HEAD_INIT(&PyType_Type
)
464 "linuxaudiodev.linux_audio_device", /*tp_name*/
465 sizeof(lad_t
), /*tp_size*/
468 (destructor
)lad_dealloc
, /*tp_dealloc*/
470 (getattrfunc
)lad_getattr
, /*tp_getattr*/
477 ladopen(PyObject
*self
, PyObject
*args
)
479 return (PyObject
*)newladobject(args
);
482 static PyMethodDef linuxaudiodev_methods
[] = {
483 { "open", ladopen
, METH_VARARGS
},
488 initlinuxaudiodev(void)
492 m
= Py_InitModule("linuxaudiodev", linuxaudiodev_methods
);
496 LinuxAudioError
= PyErr_NewException("linuxaudiodev.error", NULL
, NULL
);
498 PyModule_AddObject(m
, "error", LinuxAudioError
);
500 if (PyModule_AddIntConstant(m
, "AFMT_MU_LAW", (long)AFMT_MU_LAW
) == -1)
502 if (PyModule_AddIntConstant(m
, "AFMT_A_LAW", (long)AFMT_A_LAW
) == -1)
504 if (PyModule_AddIntConstant(m
, "AFMT_U8", (long)AFMT_U8
) == -1)
506 if (PyModule_AddIntConstant(m
, "AFMT_S8", (long)AFMT_S8
) == -1)
508 if (PyModule_AddIntConstant(m
, "AFMT_U16_BE", (long)AFMT_U16_BE
) == -1)
510 if (PyModule_AddIntConstant(m
, "AFMT_U16_LE", (long)AFMT_U16_LE
) == -1)
512 if (PyModule_AddIntConstant(m
, "AFMT_S16_BE", (long)AFMT_S16_BE
) == -1)
514 if (PyModule_AddIntConstant(m
, "AFMT_S16_LE", (long)AFMT_S16_LE
) == -1)
516 if (PyModule_AddIntConstant(m
, "AFMT_S16_NE", (long)AFMT_S16_NE
) == -1)