blob: f7b942690cbb4f9e0b13261d3cb06b03cf6a59a9 [file] [log] [blame]
Guido van Rossum9c52e0f1992-06-03 17:06:14 +00001/***********************************************************
Guido van Rossum524b5881995-01-04 19:10:35 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossum9c52e0f1992-06-03 17:06:14 +00004
5 All Rights Reserved
6
Guido van Rossumd266eb41996-10-25 14:44:06 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Guido van Rossum9c52e0f1992-06-03 17:06:14 +00009provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000010both that copyright notice and this permission notice appear in
Guido van Rossum9c52e0f1992-06-03 17:06:14 +000011supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Guido van Rossum9c52e0f1992-06-03 17:06:14 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Guido van Rossum9c52e0f1992-06-03 17:06:14 +000029
30******************************************************************/
31
32/* Sad objects */
33
Barry Warsaw8496d391996-12-13 00:11:04 +000034#include "Python.h"
Guido van Rossum9c52e0f1992-06-03 17:06:14 +000035#include "structmember.h"
36
Guido van Rossumb6775db1994-08-01 11:34:53 +000037#ifdef HAVE_SYS_AUDIOIO_H
38#define SOLARIS
39#endif
40
Guido van Rossume29ed8f1996-12-10 15:21:30 +000041#ifdef HAVE_UNISTD_H
42#include <unistd.h>
43#endif
44
45#ifdef HAVE_FCNTL_H
46#include <fcntl.h>
47#endif
48
Guido van Rossum234f9421993-06-17 12:35:49 +000049#include <stropts.h>
Guido van Rossum9c52e0f1992-06-03 17:06:14 +000050#include <sys/ioctl.h>
Sjoerd Mullender66bca321993-12-03 16:54:45 +000051#ifdef SOLARIS
Guido van Rossumb6775db1994-08-01 11:34:53 +000052#include <sys/audioio.h>
Sjoerd Mullender66bca321993-12-03 16:54:45 +000053#else
Guido van Rossum9c52e0f1992-06-03 17:06:14 +000054#include <sun/audioio.h>
Sjoerd Mullender66bca321993-12-03 16:54:45 +000055#endif
Guido van Rossum9c52e0f1992-06-03 17:06:14 +000056
57/* #define offsetof(str,mem) ((int)(((str *)0)->mem)) */
58
59typedef struct {
Barry Warsaw8496d391996-12-13 00:11:04 +000060 PyObject_HEAD
Guido van Rossum9c52e0f1992-06-03 17:06:14 +000061 int x_fd; /* The open file */
62 int x_icount; /* # samples read */
63 int x_ocount; /* # samples written */
64 int x_isctl; /* True if control device */
65
66} sadobject;
67
68typedef struct {
Barry Warsaw8496d391996-12-13 00:11:04 +000069 PyObject_HEAD
Guido van Rossum9c52e0f1992-06-03 17:06:14 +000070 audio_info_t ai;
71} sadstatusobject;
72
Barry Warsaw8496d391996-12-13 00:11:04 +000073staticforward PyTypeObject Sadtype;
74staticforward PyTypeObject Sadstatustype;
Sjoerd Mullender66bca321993-12-03 16:54:45 +000075static sadstatusobject *sads_alloc(); /* Forward */
Guido van Rossum9c52e0f1992-06-03 17:06:14 +000076
Barry Warsaw8496d391996-12-13 00:11:04 +000077static PyObject *SunAudioError;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +000078
Guido van Rossum9c52e0f1992-06-03 17:06:14 +000079#define is_sadobject(v) ((v)->ob_type == &Sadtype)
80#define is_sadstatusobject(v) ((v)->ob_type == &Sadstatustype)
81
Barry Warsawb0d1b061998-10-31 22:52:54 +000082
Guido van Rossum9c52e0f1992-06-03 17:06:14 +000083static sadobject *
84newsadobject(arg)
Barry Warsaw8496d391996-12-13 00:11:04 +000085 PyObject *arg;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +000086{
87 sadobject *xp;
88 int fd;
89 char *mode;
90 int imode;
Barry Warsawb0d1b061998-10-31 22:52:54 +000091 char* basedev;
92 char* ctldev;
93 char* opendev;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +000094
95 /* Check arg for r/w/rw */
Barry Warsaw8496d391996-12-13 00:11:04 +000096 if (!PyArg_Parse(arg, "s", &mode))
97 return NULL;
98 if (strcmp(mode, "r") == 0)
99 imode = 0;
100 else if (strcmp(mode, "w") == 0)
101 imode = 1;
102 else if (strcmp(mode, "rw") == 0)
103 imode = 2;
104 else if (strcmp(mode, "control") == 0)
105 imode = -1;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000106 else {
Barry Warsaw8496d391996-12-13 00:11:04 +0000107 PyErr_SetString(SunAudioError,
108 "Mode should be one of 'r', 'w', 'rw' or 'control'");
109 return NULL;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000110 }
111
Barry Warsawb0d1b061998-10-31 22:52:54 +0000112 /* Open the correct device. The base device name comes from the
113 * AUDIODEV environment variable first, then /dev/audio. The
114 * control device tacks "ctl" onto the base device name.
115 */
116 basedev = getenv("AUDIODEV");
117 if (!basedev)
118 basedev = "/dev/audio";
119 ctldev = PyMem_NEW(char, strlen(basedev) + 4);
120 if (!ctldev) {
121 PyErr_NoMemory();
Barry Warsaw8496d391996-12-13 00:11:04 +0000122 return NULL;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000123 }
Barry Warsawb0d1b061998-10-31 22:52:54 +0000124 strcpy(ctldev, basedev);
125 strcat(ctldev, "ctl");
126
127 if (imode < 0) {
128 opendev = ctldev;
129 fd = open(ctldev, 2);
130 }
131 else {
132 opendev = basedev;
133 fd = open(basedev, imode);
134 }
135 if (fd < 0) {
136 PyErr_SetFromErrnoWithFilename(SunAudioError, opendev);
137 return NULL;
138 }
139 PyMem_DEL(ctldev);
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000140
141 /* Create and initialize the object */
Guido van Rossumb18618d2000-05-03 23:44:39 +0000142 xp = PyObject_New(sadobject, &Sadtype);
Barry Warsaw42185a21997-01-09 22:29:57 +0000143 if (xp == NULL) {
144 close(fd);
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000145 return NULL;
Barry Warsaw42185a21997-01-09 22:29:57 +0000146 }
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000147 xp->x_fd = fd;
148 xp->x_icount = xp->x_ocount = 0;
149 xp->x_isctl = (imode < 0);
150
151 return xp;
152}
153
154/* Sad methods */
155
156static void
157sad_dealloc(xp)
158 sadobject *xp;
159{
160 close(xp->x_fd);
Guido van Rossumb18618d2000-05-03 23:44:39 +0000161 PyObject_Del(xp);
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000162}
163
Barry Warsaw8496d391996-12-13 00:11:04 +0000164static PyObject *
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000165sad_read(self, args)
166 sadobject *self;
Barry Warsaw8496d391996-12-13 00:11:04 +0000167 PyObject *args;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000168{
169 int size, count;
170 char *cp;
Barry Warsaw8496d391996-12-13 00:11:04 +0000171 PyObject *rv;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000172
Barry Warsaw8496d391996-12-13 00:11:04 +0000173 if (!PyArg_Parse(args, "i", &size))
174 return NULL;
175 rv = PyString_FromStringAndSize(NULL, size);
176 if (rv == NULL)
177 return NULL;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000178
Barry Warsaw8496d391996-12-13 00:11:04 +0000179 if (!(cp = PyString_AsString(rv)))
180 goto finally;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000181
182 count = read(self->x_fd, cp, size);
Barry Warsaw8496d391996-12-13 00:11:04 +0000183 if (count < 0) {
184 PyErr_SetFromErrno(SunAudioError);
185 goto finally;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000186 }
Barry Warsaw8496d391996-12-13 00:11:04 +0000187#if 0
188 /* TBD: why print this message if you can handle the condition?
Barry Warsaw42185a21997-01-09 22:29:57 +0000189 * assume it's debugging info which we can just as well get rid
190 * of. in any case this message should *not* be using printf!
191 */
Barry Warsaw8496d391996-12-13 00:11:04 +0000192 if (count != size)
193 printf("sunaudio: funny read rv %d wtd %d\n", count, size);
194#endif
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000195 self->x_icount += count;
196 return rv;
Barry Warsaw8496d391996-12-13 00:11:04 +0000197
198 finally:
199 Py_DECREF(rv);
200 return NULL;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000201}
202
Barry Warsaw8496d391996-12-13 00:11:04 +0000203static PyObject *
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000204sad_write(self, args)
205 sadobject *self;
Barry Warsaw8496d391996-12-13 00:11:04 +0000206 PyObject *args;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000207{
208 char *cp;
209 int count, size;
210
Barry Warsaw8496d391996-12-13 00:11:04 +0000211 if (!PyArg_Parse(args, "s#", &cp, &size))
212 return NULL;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000213
214 count = write(self->x_fd, cp, size);
Barry Warsaw8496d391996-12-13 00:11:04 +0000215 if (count < 0) {
216 PyErr_SetFromErrno(SunAudioError);
217 return NULL;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000218 }
Barry Warsaw8496d391996-12-13 00:11:04 +0000219#if 0
220 if (count != size)
221 printf("sunaudio: funny write rv %d wanted %d\n", count, size);
222#endif
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000223 self->x_ocount += count;
224
Barry Warsaw8496d391996-12-13 00:11:04 +0000225 Py_INCREF(Py_None);
226 return Py_None;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000227}
228
Barry Warsaw8496d391996-12-13 00:11:04 +0000229static PyObject *
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000230sad_getinfo(self, args)
Barry Warsaw8496d391996-12-13 00:11:04 +0000231 sadobject *self;
232 PyObject *args;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000233{
234 sadstatusobject *rv;
235
Barry Warsaw8496d391996-12-13 00:11:04 +0000236 if (!PyArg_Parse(args, ""))
237 return NULL;
Barry Warsaw42185a21997-01-09 22:29:57 +0000238 if (!(rv = sads_alloc()))
239 return NULL;
240
Barry Warsaw8496d391996-12-13 00:11:04 +0000241 if (ioctl(self->x_fd, AUDIO_GETINFO, &rv->ai) < 0) {
242 PyErr_SetFromErrno(SunAudioError);
243 Py_DECREF(rv);
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000244 return NULL;
245 }
Barry Warsaw8496d391996-12-13 00:11:04 +0000246 return (PyObject *)rv;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000247}
248
Barry Warsaw8496d391996-12-13 00:11:04 +0000249static PyObject *
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000250sad_setinfo(self, arg)
Barry Warsaw8496d391996-12-13 00:11:04 +0000251 sadobject *self;
252 sadstatusobject *arg;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000253{
Barry Warsaw8496d391996-12-13 00:11:04 +0000254 if (!is_sadstatusobject(arg)) {
255 PyErr_SetString(PyExc_TypeError,
256 "Must be sun audio status object");
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000257 return NULL;
258 }
Barry Warsaw8496d391996-12-13 00:11:04 +0000259 if (ioctl(self->x_fd, AUDIO_SETINFO, &arg->ai) < 0) {
260 PyErr_SetFromErrno(SunAudioError);
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000261 return NULL;
262 }
Barry Warsaw8496d391996-12-13 00:11:04 +0000263 Py_INCREF(Py_None);
264 return Py_None;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000265}
266
Barry Warsaw8496d391996-12-13 00:11:04 +0000267static PyObject *
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000268sad_ibufcount(self, args)
Barry Warsaw8496d391996-12-13 00:11:04 +0000269 sadobject *self;
270 PyObject *args;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000271{
Barry Warsaw8496d391996-12-13 00:11:04 +0000272 audio_info_t ai;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000273
Barry Warsaw8496d391996-12-13 00:11:04 +0000274 if (!PyArg_Parse(args, ""))
275 return NULL;
276 if (ioctl(self->x_fd, AUDIO_GETINFO, &ai) < 0) {
277 PyErr_SetFromErrno(SunAudioError);
278 return NULL;
279 }
280 return PyInt_FromLong(ai.record.samples - self->x_icount);
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000281}
282
Barry Warsaw8496d391996-12-13 00:11:04 +0000283static PyObject *
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000284sad_obufcount(self, args)
Barry Warsaw8496d391996-12-13 00:11:04 +0000285 sadobject *self;
286 PyObject *args;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000287{
Barry Warsaw8496d391996-12-13 00:11:04 +0000288 audio_info_t ai;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000289
Barry Warsaw8496d391996-12-13 00:11:04 +0000290 if (!PyArg_Parse(args, ""))
291 return NULL;
292 if (ioctl(self->x_fd, AUDIO_GETINFO, &ai) < 0) {
293 PyErr_SetFromErrno(SunAudioError);
294 return NULL;
295 }
Guido van Rossum1e0b19e1997-04-11 15:23:52 +0000296 /* x_ocount is in bytes, wheras play.samples is in frames */
297 /* we want frames */
298 return PyInt_FromLong(self->x_ocount / (ai.play.channels *
299 ai.play.precision / 8) -
300 ai.play.samples);
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000301}
302
Barry Warsaw8496d391996-12-13 00:11:04 +0000303static PyObject *
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000304sad_drain(self, args)
Barry Warsaw8496d391996-12-13 00:11:04 +0000305 sadobject *self;
306 PyObject *args;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000307{
308
Barry Warsaw8496d391996-12-13 00:11:04 +0000309 if (!PyArg_Parse(args, ""))
310 return NULL;
311 if (ioctl(self->x_fd, AUDIO_DRAIN, 0) < 0) {
312 PyErr_SetFromErrno(SunAudioError);
313 return NULL;
314 }
315 Py_INCREF(Py_None);
316 return Py_None;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000317}
318
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000319#ifdef SOLARIS
Barry Warsaw8496d391996-12-13 00:11:04 +0000320static PyObject *
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000321sad_getdev(self, args)
Barry Warsaw8496d391996-12-13 00:11:04 +0000322 sadobject *self;
323 PyObject *args;
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000324{
Barry Warsaw8496d391996-12-13 00:11:04 +0000325 struct audio_device ad;
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000326
Barry Warsaw8496d391996-12-13 00:11:04 +0000327 if (!PyArg_Parse(args, ""))
328 return NULL;
329 if (ioctl(self->x_fd, AUDIO_GETDEV, &ad) < 0) {
330 PyErr_SetFromErrno(SunAudioError);
331 return NULL;
332 }
333 return Py_BuildValue("(sss)", ad.name, ad.version, ad.config);
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000334}
335#endif
336
Barry Warsaw8496d391996-12-13 00:11:04 +0000337static PyObject *
Guido van Rossum234f9421993-06-17 12:35:49 +0000338sad_flush(self, args)
Barry Warsaw8496d391996-12-13 00:11:04 +0000339 sadobject *self;
340 PyObject *args;
Guido van Rossum234f9421993-06-17 12:35:49 +0000341{
342
Barry Warsaw8496d391996-12-13 00:11:04 +0000343 if (!PyArg_Parse(args, ""))
344 return NULL;
345 if (ioctl(self->x_fd, I_FLUSH, FLUSHW) < 0) {
346 PyErr_SetFromErrno(SunAudioError);
347 return NULL;
348 }
349 Py_INCREF(Py_None);
350 return Py_None;
Guido van Rossum234f9421993-06-17 12:35:49 +0000351}
352
Barry Warsaw8496d391996-12-13 00:11:04 +0000353static PyObject *
Guido van Rossum234f9421993-06-17 12:35:49 +0000354sad_close(self, args)
Barry Warsaw8496d391996-12-13 00:11:04 +0000355 sadobject *self;
356 PyObject *args;
Guido van Rossum234f9421993-06-17 12:35:49 +0000357{
358
Barry Warsaw8496d391996-12-13 00:11:04 +0000359 if (!PyArg_Parse(args, ""))
360 return NULL;
361 if (self->x_fd >= 0) {
362 close(self->x_fd);
363 self->x_fd = -1;
364 }
365 Py_INCREF(Py_None);
366 return Py_None;
Guido van Rossum234f9421993-06-17 12:35:49 +0000367}
368
Barry Warsawb0d1b061998-10-31 22:52:54 +0000369static PyObject *
370sad_fileno(self, args)
371 sadobject *self;
372 PyObject *args;
373{
374 if (!PyArg_Parse(args, ""))
375 return NULL;
376
377 return PyInt_FromLong(self->x_fd);
378}
379
380
Barry Warsaw8496d391996-12-13 00:11:04 +0000381static PyMethodDef sad_methods[] = {
382 { "read", (PyCFunction)sad_read },
383 { "write", (PyCFunction)sad_write },
384 { "ibufcount", (PyCFunction)sad_ibufcount },
385 { "obufcount", (PyCFunction)sad_obufcount },
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000386#define CTL_METHODS 4
Barry Warsaw8496d391996-12-13 00:11:04 +0000387 { "getinfo", (PyCFunction)sad_getinfo },
388 { "setinfo", (PyCFunction)sad_setinfo },
389 { "drain", (PyCFunction)sad_drain },
390 { "flush", (PyCFunction)sad_flush },
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000391#ifdef SOLARIS
Barry Warsaw8496d391996-12-13 00:11:04 +0000392 { "getdev", (PyCFunction)sad_getdev },
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000393#endif
Barry Warsaw8496d391996-12-13 00:11:04 +0000394 { "close", (PyCFunction)sad_close },
Barry Warsawb0d1b061998-10-31 22:52:54 +0000395 { "fileno", (PyCFunction)sad_fileno },
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000396 {NULL, NULL} /* sentinel */
397};
398
Barry Warsaw8496d391996-12-13 00:11:04 +0000399static PyObject *
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000400sad_getattr(xp, name)
401 sadobject *xp;
402 char *name;
403{
Barry Warsaw8496d391996-12-13 00:11:04 +0000404 if (xp->x_isctl)
405 return Py_FindMethod(sad_methods+CTL_METHODS,
406 (PyObject *)xp, name);
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000407 else
Barry Warsaw8496d391996-12-13 00:11:04 +0000408 return Py_FindMethod(sad_methods, (PyObject *)xp, name);
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000409}
410
411/* ----------------------------------------------------------------- */
412
413static sadstatusobject *
414sads_alloc() {
Guido van Rossumb18618d2000-05-03 23:44:39 +0000415 return PyObject_New(sadstatusobject, &Sadstatustype);
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000416}
417
418static void
419sads_dealloc(xp)
Barry Warsaw8496d391996-12-13 00:11:04 +0000420 sadstatusobject *xp;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000421{
Barry Warsaw8496d391996-12-13 00:11:04 +0000422 PyMem_DEL(xp);
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000423}
424
425#define OFF(x) offsetof(audio_info_t,x)
426static struct memberlist sads_ml[] = {
427 { "i_sample_rate", T_UINT, OFF(record.sample_rate) },
428 { "i_channels", T_UINT, OFF(record.channels) },
429 { "i_precision", T_UINT, OFF(record.precision) },
430 { "i_encoding", T_UINT, OFF(record.encoding) },
431 { "i_gain", T_UINT, OFF(record.gain) },
432 { "i_port", T_UINT, OFF(record.port) },
433 { "i_samples", T_UINT, OFF(record.samples) },
434 { "i_eof", T_UINT, OFF(record.eof) },
435 { "i_pause", T_UBYTE, OFF(record.pause) },
436 { "i_error", T_UBYTE, OFF(record.error) },
437 { "i_waiting", T_UBYTE, OFF(record.waiting) },
438 { "i_open", T_UBYTE, OFF(record.open) , RO},
439 { "i_active", T_UBYTE, OFF(record.active) , RO},
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000440#ifdef SOLARIS
441 { "i_buffer_size", T_UINT, OFF(record.buffer_size) },
442 { "i_balance", T_UBYTE, OFF(record.balance) },
443 { "i_avail_ports", T_UINT, OFF(record.avail_ports) },
444#endif
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000445
446 { "o_sample_rate", T_UINT, OFF(play.sample_rate) },
447 { "o_channels", T_UINT, OFF(play.channels) },
448 { "o_precision", T_UINT, OFF(play.precision) },
449 { "o_encoding", T_UINT, OFF(play.encoding) },
450 { "o_gain", T_UINT, OFF(play.gain) },
451 { "o_port", T_UINT, OFF(play.port) },
452 { "o_samples", T_UINT, OFF(play.samples) },
453 { "o_eof", T_UINT, OFF(play.eof) },
454 { "o_pause", T_UBYTE, OFF(play.pause) },
455 { "o_error", T_UBYTE, OFF(play.error) },
456 { "o_waiting", T_UBYTE, OFF(play.waiting) },
457 { "o_open", T_UBYTE, OFF(play.open) , RO},
458 { "o_active", T_UBYTE, OFF(play.active) , RO},
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000459#ifdef SOLARIS
460 { "o_buffer_size", T_UINT, OFF(play.buffer_size) },
461 { "o_balance", T_UBYTE, OFF(play.balance) },
462 { "o_avail_ports", T_UINT, OFF(play.avail_ports) },
463#endif
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000464
465 { "monitor_gain", T_UINT, OFF(monitor_gain) },
466 { NULL, 0, 0},
467};
468
Barry Warsaw8496d391996-12-13 00:11:04 +0000469static PyObject *
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000470sads_getattr(xp, name)
Barry Warsaw8496d391996-12-13 00:11:04 +0000471 sadstatusobject *xp;
472 char *name;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000473{
Barry Warsaw8496d391996-12-13 00:11:04 +0000474 return PyMember_Get((char *)&xp->ai, sads_ml, name);
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000475}
476
477static int
478sads_setattr(xp, name, v)
Barry Warsaw8496d391996-12-13 00:11:04 +0000479 sadstatusobject *xp;
480 char *name;
481 PyObject *v;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000482{
Guido van Rossum94472a01992-09-04 09:45:18 +0000483
484 if (v == NULL) {
Barry Warsaw8496d391996-12-13 00:11:04 +0000485 PyErr_SetString(PyExc_TypeError,
486 "can't delete sun audio status attributes");
Guido van Rossumf156f501996-09-11 23:31:23 +0000487 return -1;
Guido van Rossum94472a01992-09-04 09:45:18 +0000488 }
Barry Warsaw8496d391996-12-13 00:11:04 +0000489 return PyMember_Set((char *)&xp->ai, sads_ml, name, v);
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000490}
491
492/* ------------------------------------------------------------------- */
493
494
Barry Warsaw8496d391996-12-13 00:11:04 +0000495static PyTypeObject Sadtype = {
496 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000497 0, /*ob_size*/
498 "sun_audio_device", /*tp_name*/
499 sizeof(sadobject), /*tp_size*/
500 0, /*tp_itemsize*/
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000501 /* methods */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000502 (destructor)sad_dealloc, /*tp_dealloc*/
503 0, /*tp_print*/
504 (getattrfunc)sad_getattr, /*tp_getattr*/
505 0, /*tp_setattr*/
506 0, /*tp_compare*/
507 0, /*tp_repr*/
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000508};
509
Barry Warsaw8496d391996-12-13 00:11:04 +0000510static PyTypeObject Sadstatustype = {
511 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000512 0, /*ob_size*/
513 "sun_audio_device_status", /*tp_name*/
514 sizeof(sadstatusobject), /*tp_size*/
515 0, /*tp_itemsize*/
516 /* methods */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000517 (destructor)sads_dealloc, /*tp_dealloc*/
518 0, /*tp_print*/
519 (getattrfunc)sads_getattr, /*tp_getattr*/
520 (setattrfunc)sads_setattr, /*tp_setattr*/
521 0, /*tp_compare*/
522 0, /*tp_repr*/
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000523};
524/* ------------------------------------------------------------------- */
525
Barry Warsaw8496d391996-12-13 00:11:04 +0000526static PyObject *
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000527sadopen(self, args)
Barry Warsaw8496d391996-12-13 00:11:04 +0000528 PyObject *self;
529 PyObject *args;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000530{
Barry Warsaw8496d391996-12-13 00:11:04 +0000531 return (PyObject *)newsadobject(args);
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000532}
533
Barry Warsaw8496d391996-12-13 00:11:04 +0000534static PyMethodDef sunaudiodev_methods[] = {
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000535 { "open", sadopen },
536 { 0, 0 },
537};
538
539void
Barry Warsaw8496d391996-12-13 00:11:04 +0000540initsunaudiodev()
541{
542 PyObject *m, *d;
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000543
Barry Warsaw8496d391996-12-13 00:11:04 +0000544 m = Py_InitModule("sunaudiodev", sunaudiodev_methods);
545 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000546 SunAudioError = PyErr_NewException("sunaudiodev.error", NULL, NULL);
Barry Warsaw42185a21997-01-09 22:29:57 +0000547 if (SunAudioError)
548 PyDict_SetItemString(d, "error", SunAudioError);
Guido van Rossum9c52e0f1992-06-03 17:06:14 +0000549}