blob: d4e5ec91b3022daa82639ef5e3c1a85fc18ba1b3 [file] [log] [blame]
Guido van Rossum9c52e0f1992-06-03 17:06:14 +00001/***********************************************************
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00002Copyright (c) 2000, BeOpen.com.
3Copyright (c) 1995-2000, Corporation for National Research Initiatives.
4Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
5All rights reserved.
Guido van Rossum9c52e0f1992-06-03 17:06:14 +00006
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00007See the file "Misc/COPYRIGHT" for information on usage and
8redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
Guido van Rossum9c52e0f1992-06-03 17:06:14 +00009******************************************************************/
10
11/* Sad objects */
12
Barry Warsaw8496d391996-12-13 00:11:04 +000013#include "Python.h"
Guido van Rossum9c52e0f1992-06-03 17:06:14 +000014#include "structmember.h"
15
Guido van Rossumb6775db1994-08-01 11:34:53 +000016#ifdef HAVE_SYS_AUDIOIO_H
17#define SOLARIS
18#endif
19
Guido van Rossume29ed8f1996-12-10 15:21:30 +000020#ifdef HAVE_UNISTD_H
21#include <unistd.h>
22#endif
23
24#ifdef HAVE_FCNTL_H
25#include <fcntl.h>
26#endif
27
Guido van Rossum234f9421993-06-17 12:35:49 +000028#include <stropts.h>
Guido van Rossum9c52e0f1992-06-03 17:06:14 +000029#include <sys/ioctl.h>
Sjoerd Mullender66bca321993-12-03 16:54:45 +000030#ifdef SOLARIS
Guido van Rossumb6775db1994-08-01 11:34:53 +000031#include <sys/audioio.h>
Sjoerd Mullender66bca321993-12-03 16:54:45 +000032#else
Guido van Rossum9c52e0f1992-06-03 17:06:14 +000033#include <sun/audioio.h>
Sjoerd Mullender66bca321993-12-03 16:54:45 +000034#endif
Guido van Rossum9c52e0f1992-06-03 17:06:14 +000035
36/* #define offsetof(str,mem) ((int)(((str *)0)->mem)) */
37
38typedef struct {
Barry Warsaw8496d391996-12-13 00:11:04 +000039 PyObject_HEAD
Guido van Rossum9c52e0f1992-06-03 17:06:14 +000040 int x_fd; /* The open file */
41 int x_icount; /* # samples read */
42 int x_ocount; /* # samples written */
43 int x_isctl; /* True if control device */
44
45} sadobject;
46
47typedef struct {
Barry Warsaw8496d391996-12-13 00:11:04 +000048 PyObject_HEAD
Guido van Rossum9c52e0f1992-06-03 17:06:14 +000049 audio_info_t ai;
50} sadstatusobject;
51
Barry Warsaw8496d391996-12-13 00:11:04 +000052staticforward PyTypeObject Sadtype;
53staticforward PyTypeObject Sadstatustype;
Sjoerd Mullender66bca321993-12-03 16:54:45 +000054static sadstatusobject *sads_alloc(); /* Forward */
Guido van Rossum9c52e0f1992-06-03 17:06:14 +000055
Barry Warsaw8496d391996-12-13 00:11:04 +000056static PyObject *SunAudioError;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +000057
Guido van Rossum9c52e0f1992-06-03 17:06:14 +000058#define is_sadobject(v) ((v)->ob_type == &Sadtype)
59#define is_sadstatusobject(v) ((v)->ob_type == &Sadstatustype)
60
Barry Warsawb0d1b061998-10-31 22:52:54 +000061
Guido van Rossum9c52e0f1992-06-03 17:06:14 +000062static sadobject *
Peter Schneider-Kamp3e3175b2000-07-10 17:25:37 +000063newsadobject(PyObject *args)
Guido van Rossum9c52e0f1992-06-03 17:06:14 +000064{
65 sadobject *xp;
66 int fd;
67 char *mode;
68 int imode;
Barry Warsawb0d1b061998-10-31 22:52:54 +000069 char* basedev;
70 char* ctldev;
71 char* opendev;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +000072
73 /* Check arg for r/w/rw */
Peter Schneider-Kamp3e3175b2000-07-10 17:25:37 +000074 if (!PyArg_Parse(args, "s", &mode))
Barry Warsaw8496d391996-12-13 00:11:04 +000075 return NULL;
76 if (strcmp(mode, "r") == 0)
77 imode = 0;
78 else if (strcmp(mode, "w") == 0)
79 imode = 1;
80 else if (strcmp(mode, "rw") == 0)
81 imode = 2;
82 else if (strcmp(mode, "control") == 0)
83 imode = -1;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +000084 else {
Barry Warsaw8496d391996-12-13 00:11:04 +000085 PyErr_SetString(SunAudioError,
86 "Mode should be one of 'r', 'w', 'rw' or 'control'");
87 return NULL;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +000088 }
89
Barry Warsawb0d1b061998-10-31 22:52:54 +000090 /* Open the correct device. The base device name comes from the
91 * AUDIODEV environment variable first, then /dev/audio. The
92 * control device tacks "ctl" onto the base device name.
93 */
94 basedev = getenv("AUDIODEV");
95 if (!basedev)
96 basedev = "/dev/audio";
97 ctldev = PyMem_NEW(char, strlen(basedev) + 4);
98 if (!ctldev) {
99 PyErr_NoMemory();
Barry Warsaw8496d391996-12-13 00:11:04 +0000100 return NULL;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000101 }
Barry Warsawb0d1b061998-10-31 22:52:54 +0000102 strcpy(ctldev, basedev);
103 strcat(ctldev, "ctl");
104
105 if (imode < 0) {
106 opendev = ctldev;
107 fd = open(ctldev, 2);
108 }
109 else {
110 opendev = basedev;
111 fd = open(basedev, imode);
112 }
113 if (fd < 0) {
114 PyErr_SetFromErrnoWithFilename(SunAudioError, opendev);
115 return NULL;
116 }
117 PyMem_DEL(ctldev);
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000118
119 /* Create and initialize the object */
Guido van Rossumb18618d2000-05-03 23:44:39 +0000120 xp = PyObject_New(sadobject, &Sadtype);
Barry Warsaw42185a21997-01-09 22:29:57 +0000121 if (xp == NULL) {
122 close(fd);
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000123 return NULL;
Barry Warsaw42185a21997-01-09 22:29:57 +0000124 }
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000125 xp->x_fd = fd;
126 xp->x_icount = xp->x_ocount = 0;
127 xp->x_isctl = (imode < 0);
128
129 return xp;
130}
131
132/* Sad methods */
133
134static void
Peter Schneider-Kamp3e3175b2000-07-10 17:25:37 +0000135sad_dealloc(sadobject *xp)
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000136{
137 close(xp->x_fd);
Guido van Rossumb18618d2000-05-03 23:44:39 +0000138 PyObject_Del(xp);
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000139}
140
Barry Warsaw8496d391996-12-13 00:11:04 +0000141static PyObject *
Peter Schneider-Kamp3e3175b2000-07-10 17:25:37 +0000142sad_read(sadobject *self, PyObject *args)
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000143{
144 int size, count;
145 char *cp;
Barry Warsaw8496d391996-12-13 00:11:04 +0000146 PyObject *rv;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000147
Barry Warsaw8496d391996-12-13 00:11:04 +0000148 if (!PyArg_Parse(args, "i", &size))
149 return NULL;
150 rv = PyString_FromStringAndSize(NULL, size);
151 if (rv == NULL)
152 return NULL;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000153
Barry Warsaw8496d391996-12-13 00:11:04 +0000154 if (!(cp = PyString_AsString(rv)))
155 goto finally;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000156
157 count = read(self->x_fd, cp, size);
Barry Warsaw8496d391996-12-13 00:11:04 +0000158 if (count < 0) {
159 PyErr_SetFromErrno(SunAudioError);
160 goto finally;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000161 }
Barry Warsaw8496d391996-12-13 00:11:04 +0000162#if 0
163 /* TBD: why print this message if you can handle the condition?
Barry Warsaw42185a21997-01-09 22:29:57 +0000164 * assume it's debugging info which we can just as well get rid
165 * of. in any case this message should *not* be using printf!
166 */
Barry Warsaw8496d391996-12-13 00:11:04 +0000167 if (count != size)
168 printf("sunaudio: funny read rv %d wtd %d\n", count, size);
169#endif
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000170 self->x_icount += count;
171 return rv;
Barry Warsaw8496d391996-12-13 00:11:04 +0000172
173 finally:
174 Py_DECREF(rv);
175 return NULL;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000176}
177
Barry Warsaw8496d391996-12-13 00:11:04 +0000178static PyObject *
Peter Schneider-Kamp3e3175b2000-07-10 17:25:37 +0000179sad_write(sadobject *self, PyObject *args)
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000180{
181 char *cp;
182 int count, size;
183
Barry Warsaw8496d391996-12-13 00:11:04 +0000184 if (!PyArg_Parse(args, "s#", &cp, &size))
185 return NULL;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000186
187 count = write(self->x_fd, cp, size);
Barry Warsaw8496d391996-12-13 00:11:04 +0000188 if (count < 0) {
189 PyErr_SetFromErrno(SunAudioError);
190 return NULL;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000191 }
Barry Warsaw8496d391996-12-13 00:11:04 +0000192#if 0
193 if (count != size)
194 printf("sunaudio: funny write rv %d wanted %d\n", count, size);
195#endif
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000196 self->x_ocount += count;
197
Barry Warsaw8496d391996-12-13 00:11:04 +0000198 Py_INCREF(Py_None);
199 return Py_None;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000200}
201
Barry Warsaw8496d391996-12-13 00:11:04 +0000202static PyObject *
Peter Schneider-Kamp3e3175b2000-07-10 17:25:37 +0000203sad_getinfo(sadobject *self, PyObject *args)
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000204{
205 sadstatusobject *rv;
206
Barry Warsaw8496d391996-12-13 00:11:04 +0000207 if (!PyArg_Parse(args, ""))
208 return NULL;
Barry Warsaw42185a21997-01-09 22:29:57 +0000209 if (!(rv = sads_alloc()))
210 return NULL;
211
Barry Warsaw8496d391996-12-13 00:11:04 +0000212 if (ioctl(self->x_fd, AUDIO_GETINFO, &rv->ai) < 0) {
213 PyErr_SetFromErrno(SunAudioError);
214 Py_DECREF(rv);
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000215 return NULL;
216 }
Barry Warsaw8496d391996-12-13 00:11:04 +0000217 return (PyObject *)rv;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000218}
219
Barry Warsaw8496d391996-12-13 00:11:04 +0000220static PyObject *
Peter Schneider-Kamp3e3175b2000-07-10 17:25:37 +0000221sad_setinfo(sadobject *self, sadstatusobject *arg)
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000222{
Barry Warsaw8496d391996-12-13 00:11:04 +0000223 if (!is_sadstatusobject(arg)) {
224 PyErr_SetString(PyExc_TypeError,
225 "Must be sun audio status object");
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000226 return NULL;
227 }
Barry Warsaw8496d391996-12-13 00:11:04 +0000228 if (ioctl(self->x_fd, AUDIO_SETINFO, &arg->ai) < 0) {
229 PyErr_SetFromErrno(SunAudioError);
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000230 return NULL;
231 }
Barry Warsaw8496d391996-12-13 00:11:04 +0000232 Py_INCREF(Py_None);
233 return Py_None;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000234}
235
Barry Warsaw8496d391996-12-13 00:11:04 +0000236static PyObject *
Peter Schneider-Kamp3e3175b2000-07-10 17:25:37 +0000237sad_ibufcount(sadobject *self, PyObject *args)
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000238{
Barry Warsaw8496d391996-12-13 00:11:04 +0000239 audio_info_t ai;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000240
Barry Warsaw8496d391996-12-13 00:11:04 +0000241 if (!PyArg_Parse(args, ""))
242 return NULL;
243 if (ioctl(self->x_fd, AUDIO_GETINFO, &ai) < 0) {
244 PyErr_SetFromErrno(SunAudioError);
245 return NULL;
246 }
247 return PyInt_FromLong(ai.record.samples - self->x_icount);
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000248}
249
Barry Warsaw8496d391996-12-13 00:11:04 +0000250static PyObject *
Peter Schneider-Kamp3e3175b2000-07-10 17:25:37 +0000251sad_obufcount(sadobject *self, PyObject *args)
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000252{
Barry Warsaw8496d391996-12-13 00:11:04 +0000253 audio_info_t ai;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000254
Barry Warsaw8496d391996-12-13 00:11:04 +0000255 if (!PyArg_Parse(args, ""))
256 return NULL;
257 if (ioctl(self->x_fd, AUDIO_GETINFO, &ai) < 0) {
258 PyErr_SetFromErrno(SunAudioError);
259 return NULL;
260 }
Thomas Wouters7e474022000-07-16 12:04:32 +0000261 /* x_ocount is in bytes, whereas play.samples is in frames */
Guido van Rossum1e0b19e1997-04-11 15:23:52 +0000262 /* we want frames */
263 return PyInt_FromLong(self->x_ocount / (ai.play.channels *
264 ai.play.precision / 8) -
265 ai.play.samples);
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000266}
267
Barry Warsaw8496d391996-12-13 00:11:04 +0000268static PyObject *
Peter Schneider-Kamp3e3175b2000-07-10 17:25:37 +0000269sad_drain(sadobject *self, PyObject *args)
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000270{
271
Barry Warsaw8496d391996-12-13 00:11:04 +0000272 if (!PyArg_Parse(args, ""))
273 return NULL;
274 if (ioctl(self->x_fd, AUDIO_DRAIN, 0) < 0) {
275 PyErr_SetFromErrno(SunAudioError);
276 return NULL;
277 }
278 Py_INCREF(Py_None);
279 return Py_None;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000280}
281
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000282#ifdef SOLARIS
Barry Warsaw8496d391996-12-13 00:11:04 +0000283static PyObject *
Peter Schneider-Kamp3e3175b2000-07-10 17:25:37 +0000284sad_getdev(sadobject *self, PyObject *args)
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000285{
Barry Warsaw8496d391996-12-13 00:11:04 +0000286 struct audio_device ad;
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000287
Barry Warsaw8496d391996-12-13 00:11:04 +0000288 if (!PyArg_Parse(args, ""))
289 return NULL;
290 if (ioctl(self->x_fd, AUDIO_GETDEV, &ad) < 0) {
291 PyErr_SetFromErrno(SunAudioError);
292 return NULL;
293 }
294 return Py_BuildValue("(sss)", ad.name, ad.version, ad.config);
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000295}
296#endif
297
Barry Warsaw8496d391996-12-13 00:11:04 +0000298static PyObject *
Peter Schneider-Kamp3e3175b2000-07-10 17:25:37 +0000299sad_flush(sadobject *self, PyObject *args)
Guido van Rossum234f9421993-06-17 12:35:49 +0000300{
301
Barry Warsaw8496d391996-12-13 00:11:04 +0000302 if (!PyArg_Parse(args, ""))
303 return NULL;
304 if (ioctl(self->x_fd, I_FLUSH, FLUSHW) < 0) {
305 PyErr_SetFromErrno(SunAudioError);
306 return NULL;
307 }
308 Py_INCREF(Py_None);
309 return Py_None;
Guido van Rossum234f9421993-06-17 12:35:49 +0000310}
311
Barry Warsaw8496d391996-12-13 00:11:04 +0000312static PyObject *
Peter Schneider-Kamp3e3175b2000-07-10 17:25:37 +0000313sad_close(sadobject *self, PyObject *args)
Guido van Rossum234f9421993-06-17 12:35:49 +0000314{
315
Barry Warsaw8496d391996-12-13 00:11:04 +0000316 if (!PyArg_Parse(args, ""))
317 return NULL;
318 if (self->x_fd >= 0) {
319 close(self->x_fd);
320 self->x_fd = -1;
321 }
322 Py_INCREF(Py_None);
323 return Py_None;
Guido van Rossum234f9421993-06-17 12:35:49 +0000324}
325
Barry Warsawb0d1b061998-10-31 22:52:54 +0000326static PyObject *
Peter Schneider-Kamp3e3175b2000-07-10 17:25:37 +0000327sad_fileno(sadobject *self, PyObject *args)
Barry Warsawb0d1b061998-10-31 22:52:54 +0000328{
329 if (!PyArg_Parse(args, ""))
330 return NULL;
331
332 return PyInt_FromLong(self->x_fd);
333}
334
335
Barry Warsaw8496d391996-12-13 00:11:04 +0000336static PyMethodDef sad_methods[] = {
337 { "read", (PyCFunction)sad_read },
338 { "write", (PyCFunction)sad_write },
339 { "ibufcount", (PyCFunction)sad_ibufcount },
340 { "obufcount", (PyCFunction)sad_obufcount },
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000341#define CTL_METHODS 4
Barry Warsaw8496d391996-12-13 00:11:04 +0000342 { "getinfo", (PyCFunction)sad_getinfo },
343 { "setinfo", (PyCFunction)sad_setinfo },
344 { "drain", (PyCFunction)sad_drain },
345 { "flush", (PyCFunction)sad_flush },
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000346#ifdef SOLARIS
Barry Warsaw8496d391996-12-13 00:11:04 +0000347 { "getdev", (PyCFunction)sad_getdev },
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000348#endif
Barry Warsaw8496d391996-12-13 00:11:04 +0000349 { "close", (PyCFunction)sad_close },
Barry Warsawb0d1b061998-10-31 22:52:54 +0000350 { "fileno", (PyCFunction)sad_fileno },
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000351 {NULL, NULL} /* sentinel */
352};
353
Barry Warsaw8496d391996-12-13 00:11:04 +0000354static PyObject *
Peter Schneider-Kamp3e3175b2000-07-10 17:25:37 +0000355sad_getattr(sadobject *xp, char *name)
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000356{
Barry Warsaw8496d391996-12-13 00:11:04 +0000357 if (xp->x_isctl)
358 return Py_FindMethod(sad_methods+CTL_METHODS,
359 (PyObject *)xp, name);
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000360 else
Barry Warsaw8496d391996-12-13 00:11:04 +0000361 return Py_FindMethod(sad_methods, (PyObject *)xp, name);
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000362}
363
364/* ----------------------------------------------------------------- */
365
366static sadstatusobject *
367sads_alloc() {
Guido van Rossumb18618d2000-05-03 23:44:39 +0000368 return PyObject_New(sadstatusobject, &Sadstatustype);
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000369}
370
371static void
Peter Schneider-Kamp3e3175b2000-07-10 17:25:37 +0000372sads_dealloc(sadstatusobject *xp)
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000373{
Barry Warsaw8496d391996-12-13 00:11:04 +0000374 PyMem_DEL(xp);
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000375}
376
377#define OFF(x) offsetof(audio_info_t,x)
378static struct memberlist sads_ml[] = {
379 { "i_sample_rate", T_UINT, OFF(record.sample_rate) },
380 { "i_channels", T_UINT, OFF(record.channels) },
381 { "i_precision", T_UINT, OFF(record.precision) },
382 { "i_encoding", T_UINT, OFF(record.encoding) },
383 { "i_gain", T_UINT, OFF(record.gain) },
384 { "i_port", T_UINT, OFF(record.port) },
385 { "i_samples", T_UINT, OFF(record.samples) },
386 { "i_eof", T_UINT, OFF(record.eof) },
387 { "i_pause", T_UBYTE, OFF(record.pause) },
388 { "i_error", T_UBYTE, OFF(record.error) },
389 { "i_waiting", T_UBYTE, OFF(record.waiting) },
390 { "i_open", T_UBYTE, OFF(record.open) , RO},
391 { "i_active", T_UBYTE, OFF(record.active) , RO},
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000392#ifdef SOLARIS
393 { "i_buffer_size", T_UINT, OFF(record.buffer_size) },
394 { "i_balance", T_UBYTE, OFF(record.balance) },
395 { "i_avail_ports", T_UINT, OFF(record.avail_ports) },
396#endif
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000397
398 { "o_sample_rate", T_UINT, OFF(play.sample_rate) },
399 { "o_channels", T_UINT, OFF(play.channels) },
400 { "o_precision", T_UINT, OFF(play.precision) },
401 { "o_encoding", T_UINT, OFF(play.encoding) },
402 { "o_gain", T_UINT, OFF(play.gain) },
403 { "o_port", T_UINT, OFF(play.port) },
404 { "o_samples", T_UINT, OFF(play.samples) },
405 { "o_eof", T_UINT, OFF(play.eof) },
406 { "o_pause", T_UBYTE, OFF(play.pause) },
407 { "o_error", T_UBYTE, OFF(play.error) },
408 { "o_waiting", T_UBYTE, OFF(play.waiting) },
409 { "o_open", T_UBYTE, OFF(play.open) , RO},
410 { "o_active", T_UBYTE, OFF(play.active) , RO},
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000411#ifdef SOLARIS
412 { "o_buffer_size", T_UINT, OFF(play.buffer_size) },
413 { "o_balance", T_UBYTE, OFF(play.balance) },
414 { "o_avail_ports", T_UINT, OFF(play.avail_ports) },
415#endif
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000416
417 { "monitor_gain", T_UINT, OFF(monitor_gain) },
418 { NULL, 0, 0},
419};
420
Barry Warsaw8496d391996-12-13 00:11:04 +0000421static PyObject *
Peter Schneider-Kamp3e3175b2000-07-10 17:25:37 +0000422sads_getattr(sadstatusobject *xp, char *name)
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000423{
Barry Warsaw8496d391996-12-13 00:11:04 +0000424 return PyMember_Get((char *)&xp->ai, sads_ml, name);
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000425}
426
427static int
Peter Schneider-Kamp3e3175b2000-07-10 17:25:37 +0000428sads_setattr(sadstatusobject *xp, char *name, PyObject *v)
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000429{
Guido van Rossum94472a01992-09-04 09:45:18 +0000430
431 if (v == NULL) {
Barry Warsaw8496d391996-12-13 00:11:04 +0000432 PyErr_SetString(PyExc_TypeError,
433 "can't delete sun audio status attributes");
Guido van Rossumf156f501996-09-11 23:31:23 +0000434 return -1;
Guido van Rossum94472a01992-09-04 09:45:18 +0000435 }
Barry Warsaw8496d391996-12-13 00:11:04 +0000436 return PyMember_Set((char *)&xp->ai, sads_ml, name, v);
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000437}
438
439/* ------------------------------------------------------------------- */
440
441
Barry Warsaw8496d391996-12-13 00:11:04 +0000442static PyTypeObject Sadtype = {
443 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000444 0, /*ob_size*/
445 "sun_audio_device", /*tp_name*/
446 sizeof(sadobject), /*tp_size*/
447 0, /*tp_itemsize*/
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000448 /* methods */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000449 (destructor)sad_dealloc, /*tp_dealloc*/
450 0, /*tp_print*/
451 (getattrfunc)sad_getattr, /*tp_getattr*/
452 0, /*tp_setattr*/
453 0, /*tp_compare*/
454 0, /*tp_repr*/
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000455};
456
Barry Warsaw8496d391996-12-13 00:11:04 +0000457static PyTypeObject Sadstatustype = {
458 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000459 0, /*ob_size*/
460 "sun_audio_device_status", /*tp_name*/
461 sizeof(sadstatusobject), /*tp_size*/
462 0, /*tp_itemsize*/
463 /* methods */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000464 (destructor)sads_dealloc, /*tp_dealloc*/
465 0, /*tp_print*/
466 (getattrfunc)sads_getattr, /*tp_getattr*/
467 (setattrfunc)sads_setattr, /*tp_setattr*/
468 0, /*tp_compare*/
469 0, /*tp_repr*/
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000470};
471/* ------------------------------------------------------------------- */
472
Barry Warsaw8496d391996-12-13 00:11:04 +0000473static PyObject *
Peter Schneider-Kamp3e3175b2000-07-10 17:25:37 +0000474sadopen(PyObject *self, PyObject *args)
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000475{
Barry Warsaw8496d391996-12-13 00:11:04 +0000476 return (PyObject *)newsadobject(args);
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000477}
478
Barry Warsaw8496d391996-12-13 00:11:04 +0000479static PyMethodDef sunaudiodev_methods[] = {
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000480 { "open", sadopen },
481 { 0, 0 },
482};
483
484void
Barry Warsaw8496d391996-12-13 00:11:04 +0000485initsunaudiodev()
486{
487 PyObject *m, *d;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000488
Barry Warsaw8496d391996-12-13 00:11:04 +0000489 m = Py_InitModule("sunaudiodev", sunaudiodev_methods);
490 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000491 SunAudioError = PyErr_NewException("sunaudiodev.error", NULL, NULL);
Barry Warsaw42185a21997-01-09 22:29:57 +0000492 if (SunAudioError)
493 PyDict_SetItemString(d, "error", SunAudioError);
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000494}