blob: 52d3bada4c271a161b27b30214f414e6509cc0ce [file] [log] [blame]
Guido van Rossume3db8621991-09-09 23:33:34 +00001/**********************************************************
Guido van Rossum524b5881995-01-04 19:10:35 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossume3db8621991-09-09 23:33:34 +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 Rossume3db8621991-09-09 23:33:34 +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 Rossume3db8621991-09-09 23:33:34 +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 Rossume3db8621991-09-09 23:33:34 +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 Rossume3db8621991-09-09 23:33:34 +000029
30******************************************************************/
31
Guido van Rossum57737981992-05-15 11:06:29 +000032/* AL module -- interface to Mark Callow's Audio Library (AL). */
Guido van Rossume3db8621991-09-09 23:33:34 +000033
Guido van Rossumb6775db1994-08-01 11:34:53 +000034#include <audio.h>
Guido van Rossume3db8621991-09-09 23:33:34 +000035
Jack Jansene8a3c281993-02-10 14:10:56 +000036/* Check which version audio library we have: */
37#ifdef AL_ERROR_NUMBER
38#define AL_405
39/* XXXX 4.0.5 libaudio also allows us to provide better error
40** handling (with ALseterrorhandler). We should implement that
41** sometime.
42*/
43
44#endif
45
Guido van Rossume3db8621991-09-09 23:33:34 +000046#include "allobjects.h"
47#include "import.h"
48#include "modsupport.h"
49#include "structmember.h"
Jack Jansen743db361992-08-13 14:13:11 +000050#include "ceval.h"
Guido van Rossume3db8621991-09-09 23:33:34 +000051
52
53/* Config objects */
54
55typedef struct {
56 OB_HEAD
57 ALconfig ob_config;
58} configobject;
59
Guido van Rossumb6775db1994-08-01 11:34:53 +000060staticforward typeobject Configtype;
Guido van Rossume3db8621991-09-09 23:33:34 +000061
62#define is_configobject(v) ((v)->ob_type == &Configtype)
63
Guido van Rossumfc58e581992-01-27 16:45:55 +000064/* Forward */
65static int getconfigarg PROTO((object *, ALconfig *));
66static int getstrstrconfigarg PROTO((object *, char **, char **, ALconfig *));
67
Guido van Rossume3db8621991-09-09 23:33:34 +000068static object *
69setConfig (self, args, func)
70 configobject *self;
71 object *args;
72 void (*func)(ALconfig, long);
73{
74 long par;
75
Guido van Rossumfc58e581992-01-27 16:45:55 +000076 if (!getlongarg (args, &par)) return NULL;
Guido van Rossume3db8621991-09-09 23:33:34 +000077
78 (*func) (self-> ob_config, par);
79
80 INCREF (None);
81 return None;
82}
83
84static object *
85getConfig (self, args, func)
86 configobject *self;
87 object *args;
88 long (*func)(ALconfig);
89{
90 long par;
91
Guido van Rossumfc58e581992-01-27 16:45:55 +000092 if (!getnoarg (args)) return NULL;
Guido van Rossume3db8621991-09-09 23:33:34 +000093
94 par = (*func) (self-> ob_config);
95
96 return newintobject (par);
97}
98
99static object *
100al_setqueuesize (self, args)
101 configobject *self;
102 object *args;
103{
104 return (setConfig (self, args, ALsetqueuesize));
105}
106
107static object *
108al_getqueuesize (self, args)
109 configobject *self;
110 object *args;
111{
112 return (getConfig (self, args, ALgetqueuesize));
113}
114
115static object *
116al_setwidth (self, args)
117 configobject *self;
118 object *args;
119{
120 return (setConfig (self, args, ALsetwidth));
121}
122
123static object *
124al_getwidth (self, args)
125 configobject *self;
126 object *args;
127{
128 return (getConfig (self, args, ALgetwidth));
129}
130
131static object *
132al_getchannels (self, args)
133 configobject *self;
134 object *args;
135{
136 return (getConfig (self, args, ALgetchannels));
137}
138
139static object *
140al_setchannels (self, args)
141 configobject *self;
142 object *args;
143{
144 return (setConfig (self, args, ALsetchannels));
145}
146
Jack Jansene8a3c281993-02-10 14:10:56 +0000147#ifdef AL_405
148
149static object *
150al_getsampfmt (self, args)
151 configobject *self;
152 object *args;
153{
154 return (getConfig (self, args, ALgetsampfmt));
155}
156
157static object *
158al_setsampfmt (self, args)
159 configobject *self;
160 object *args;
161{
162 return (setConfig (self, args, ALsetsampfmt));
163}
164
165static object *
166al_getfloatmax(self, args)
167 configobject *self;
168 object *args;
169{
170 double arg;
171
172 if ( !getnoarg(args) )
173 return 0;
174 arg = ALgetfloatmax(self->ob_config);
175 return newfloatobject(arg);
176}
177
178static object *
179al_setfloatmax(self, args)
180 configobject *self;
181 object *args;
182{
183 double arg;
184
185 if ( !getargs(args, "d", &arg) )
186 return 0;
187 ALsetfloatmax(self->ob_config, arg);
188 INCREF(None);
189 return None;
190}
191#endif /* AL_405 */
192
Guido van Rossume3db8621991-09-09 23:33:34 +0000193static struct methodlist config_methods[] = {
Guido van Rossumb6775db1994-08-01 11:34:53 +0000194 {"getqueuesize", (method)al_getqueuesize},
195 {"setqueuesize", (method)al_setqueuesize},
196 {"getwidth", (method)al_getwidth},
197 {"setwidth", (method)al_setwidth},
198 {"getchannels", (method)al_getchannels},
199 {"setchannels", (method)al_setchannels},
Jack Jansene8a3c281993-02-10 14:10:56 +0000200#ifdef AL_405
Guido van Rossumb6775db1994-08-01 11:34:53 +0000201 {"getsampfmt", (method)al_getsampfmt},
202 {"setsampfmt", (method)al_setsampfmt},
203 {"getfloatmax", (method)al_getfloatmax},
204 {"setfloatmax", (method)al_setfloatmax},
Jack Jansene8a3c281993-02-10 14:10:56 +0000205#endif /* AL_405 */
Guido van Rossume3db8621991-09-09 23:33:34 +0000206 {NULL, NULL} /* sentinel */
207};
208
209static void
210config_dealloc(self)
211 configobject *self;
212{
213 ALfreeconfig(self->ob_config);
214 DEL(self);
215}
216
217static object *
218config_getattr(self, name)
219 configobject *self;
220 char *name;
221{
222 return findmethod(config_methods, (object *)self, name);
223}
224
Guido van Rossumb6775db1994-08-01 11:34:53 +0000225static typeobject Configtype = {
Guido van Rossume3db8621991-09-09 23:33:34 +0000226 OB_HEAD_INIT(&Typetype)
227 0, /*ob_size*/
228 "config", /*tp_name*/
229 sizeof(configobject), /*tp_size*/
230 0, /*tp_itemsize*/
231 /* methods */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000232 (destructor)config_dealloc, /*tp_dealloc*/
Guido van Rossume3db8621991-09-09 23:33:34 +0000233 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000234 (getattrfunc)config_getattr, /*tp_getattr*/
Guido van Rossume3db8621991-09-09 23:33:34 +0000235 0, /*tp_setattr*/
236 0, /*tp_compare*/
237 0, /*tp_repr*/
238};
239
240static object *
241newconfigobject(config)
242 ALconfig config;
243{
244 configobject *p;
245
246 p = NEWOBJ(configobject, &Configtype);
247 if (p == NULL)
248 return NULL;
249 p->ob_config = config;
250 return (object *)p;
251}
252
253/* Port objects */
254
255typedef struct {
256 OB_HEAD
257 ALport ob_port;
258} portobject;
259
Guido van Rossumb6775db1994-08-01 11:34:53 +0000260staticforward typeobject Porttype;
Guido van Rossume3db8621991-09-09 23:33:34 +0000261
262#define is_portobject(v) ((v)->ob_type == &Porttype)
263
264static object *
265al_closeport (self, args)
266 portobject *self;
267 object *args;
268{
Guido van Rossumfc58e581992-01-27 16:45:55 +0000269 if (!getnoarg (args)) return NULL;
Guido van Rossume3db8621991-09-09 23:33:34 +0000270
271 if (self->ob_port != NULL) {
272 ALcloseport (self-> ob_port);
273 self->ob_port = NULL;
274 /* XXX Using a closed port may dump core! */
275 }
276
277 INCREF (None);
278 return None;
279}
280
281static object *
282al_getfd (self, args)
283 portobject *self;
284 object *args;
285{
286 int fd;
287
Guido van Rossumfc58e581992-01-27 16:45:55 +0000288 if (!getnoarg (args)) return NULL;
Guido van Rossume3db8621991-09-09 23:33:34 +0000289
290 fd = ALgetfd (self-> ob_port);
291
292 return newintobject (fd);
293}
294
295static object *
296al_getfilled (self, args)
297 portobject *self;
298 object *args;
299{
300 long count;
301
Guido van Rossumfc58e581992-01-27 16:45:55 +0000302 if (!getnoarg (args)) return NULL;
Guido van Rossume3db8621991-09-09 23:33:34 +0000303
304 count = ALgetfilled (self-> ob_port);
305
306 return newintobject (count);
307}
308
309static object *
310al_getfillable (self, args)
311 portobject *self;
312 object *args;
313{
314 long count;
315
Guido van Rossumfc58e581992-01-27 16:45:55 +0000316 if (!getnoarg (args)) return NULL;
Guido van Rossume3db8621991-09-09 23:33:34 +0000317
318 count = ALgetfillable (self-> ob_port);
319
320 return newintobject (count);
321}
322
323static object *
324al_readsamps (self, args)
325 portobject *self;
326 object *args;
327{
328 long count;
329 object *v;
Guido van Rossumb3a5b9b1991-09-10 14:54:05 +0000330 ALconfig c;
Guido van Rossume3db8621991-09-09 23:33:34 +0000331 int width;
332
333 if (!getlongarg (args, &count)) return NULL;
334
335 if (count <= 0)
336 {
337 err_setstr (RuntimeError, "al.readsamps : arg <= 0");
338 return NULL;
339 }
340
Guido van Rossumb3a5b9b1991-09-10 14:54:05 +0000341 c = ALgetconfig(self->ob_port);
Jack Jansene8a3c281993-02-10 14:10:56 +0000342#ifdef AL_405
343 width = ALgetsampfmt(c);
344 if ( width == AL_SAMPFMT_FLOAT )
345 width = sizeof(float);
346 else if ( width == AL_SAMPFMT_DOUBLE )
347 width = sizeof(double);
348 else
349 width = ALgetwidth(c);
350#else
Guido van Rossumb3a5b9b1991-09-10 14:54:05 +0000351 width = ALgetwidth(c);
Jack Jansene8a3c281993-02-10 14:10:56 +0000352#endif /* AL_405 */
Guido van Rossumb3a5b9b1991-09-10 14:54:05 +0000353 ALfreeconfig(c);
Guido van Rossume3db8621991-09-09 23:33:34 +0000354 v = newsizedstringobject ((char *)NULL, width * count);
355 if (v == NULL) return NULL;
356
Jack Jansen743db361992-08-13 14:13:11 +0000357 BGN_SAVE
Guido van Rossume3db8621991-09-09 23:33:34 +0000358 ALreadsamps (self-> ob_port, (void *) getstringvalue(v), count);
Jack Jansen743db361992-08-13 14:13:11 +0000359 END_SAVE
Guido van Rossume3db8621991-09-09 23:33:34 +0000360
361 return (v);
362}
363
364static object *
365al_writesamps (self, args)
366 portobject *self;
367 object *args;
368{
369 long count;
Guido van Rossumfc58e581992-01-27 16:45:55 +0000370 char *buf;
371 int size, width;
Guido van Rossumb3a5b9b1991-09-10 14:54:05 +0000372 ALconfig c;
Guido van Rossume3db8621991-09-09 23:33:34 +0000373
Guido van Rossumfc58e581992-01-27 16:45:55 +0000374 if (!getargs (args, "s#", &buf, &size)) return NULL;
Guido van Rossume3db8621991-09-09 23:33:34 +0000375
Guido van Rossumb3a5b9b1991-09-10 14:54:05 +0000376 c = ALgetconfig(self->ob_port);
Jack Jansene8a3c281993-02-10 14:10:56 +0000377#ifdef AL_405
378 width = ALgetsampfmt(c);
379 if ( width == AL_SAMPFMT_FLOAT )
380 width = sizeof(float);
381 else if ( width == AL_SAMPFMT_DOUBLE )
382 width = sizeof(double);
383 else
384 width = ALgetwidth(c);
385#else
Guido van Rossumb3a5b9b1991-09-10 14:54:05 +0000386 width = ALgetwidth(c);
Jack Jansene8a3c281993-02-10 14:10:56 +0000387#endif /* AL_405 */
Guido van Rossumb3a5b9b1991-09-10 14:54:05 +0000388 ALfreeconfig(c);
Jack Jansen743db361992-08-13 14:13:11 +0000389 BGN_SAVE
Guido van Rossumfc58e581992-01-27 16:45:55 +0000390 ALwritesamps (self-> ob_port, (void *) buf, (long) size / width);
Jack Jansen743db361992-08-13 14:13:11 +0000391 END_SAVE
Guido van Rossume3db8621991-09-09 23:33:34 +0000392
393 INCREF (None);
394 return None;
395}
396
397static object *
398al_getfillpoint (self, args)
399 portobject *self;
400 object *args;
401{
402 long count;
403
Guido van Rossumfc58e581992-01-27 16:45:55 +0000404 if (!getnoarg (args)) return NULL;
Guido van Rossume3db8621991-09-09 23:33:34 +0000405
406 count = ALgetfillpoint (self-> ob_port);
407
408 return newintobject (count);
409}
410
411static object *
412al_setfillpoint (self, args)
413 portobject *self;
414 object *args;
415{
416 long count;
417
Guido van Rossumfc58e581992-01-27 16:45:55 +0000418 if (!getlongarg (args, &count)) return NULL;
Guido van Rossume3db8621991-09-09 23:33:34 +0000419
420 ALsetfillpoint (self-> ob_port, count);
421
422 INCREF (None);
423 return (None);
424}
425
426static object *
427al_setconfig (self, args)
428 portobject *self;
429 object *args;
430{
431 ALconfig config;
432
Guido van Rossumfc58e581992-01-27 16:45:55 +0000433 if (!getconfigarg (args, &config)) return NULL;
Guido van Rossume3db8621991-09-09 23:33:34 +0000434
435 ALsetconfig (self-> ob_port, config);
436
437 INCREF (None);
438 return (None);
439}
440
441static object *
442al_getconfig (self, args)
443 portobject *self;
444 object *args;
445{
446 ALconfig config;
447
Guido van Rossumfc58e581992-01-27 16:45:55 +0000448 if (!getnoarg (args)) return NULL;
Guido van Rossume3db8621991-09-09 23:33:34 +0000449
450 config = ALgetconfig (self-> ob_port);
451
452 return newconfigobject (config);
453}
454
Jack Jansene8a3c281993-02-10 14:10:56 +0000455#ifdef AL_405
456static object *
457al_getstatus (self, args)
458 portobject *self;
459 object *args;
460{
461 object *list, *v;
462 long *PVbuffer;
463 long length;
464 int i;
465
466 if (!getargs(args, "O", &list))
467 return NULL;
468 if (!is_listobject(list)) {
469 err_badarg();
470 return NULL;
471 }
472 length = getlistsize(list);
473 PVbuffer = NEW(long, length);
474 if (PVbuffer == NULL)
475 return err_nomem();
476 for (i = 0; i < length; i++) {
477 v = getlistitem(list, i);
478 if (!is_intobject(v)) {
479 DEL(PVbuffer);
480 err_badarg();
481 return NULL;
482 }
483 PVbuffer[i] = getintvalue(v);
484 }
485
486 ALgetstatus(self->ob_port, PVbuffer, length);
487
488 for (i = 0; i < length; i++)
489 setlistitem(list, i, newintobject(PVbuffer[i]));
490
491 DEL(PVbuffer);
492
493 INCREF(None);
494 return None;
495}
496#endif /* AL_405 */
497
Guido van Rossume3db8621991-09-09 23:33:34 +0000498static struct methodlist port_methods[] = {
Guido van Rossumb6775db1994-08-01 11:34:53 +0000499 {"closeport", (method)al_closeport},
500 {"getfd", (method)al_getfd},
501 {"fileno", (method)al_getfd},
502 {"getfilled", (method)al_getfilled},
503 {"getfillable", (method)al_getfillable},
504 {"readsamps", (method)al_readsamps},
505 {"writesamps", (method)al_writesamps},
506 {"setfillpoint", (method)al_setfillpoint},
507 {"getfillpoint", (method)al_getfillpoint},
508 {"setconfig", (method)al_setconfig},
509 {"getconfig", (method)al_getconfig},
Jack Jansene8a3c281993-02-10 14:10:56 +0000510#ifdef AL_405
Guido van Rossumb6775db1994-08-01 11:34:53 +0000511 {"getstatus", (method)al_getstatus},
Jack Jansene8a3c281993-02-10 14:10:56 +0000512#endif /* AL_405 */
Guido van Rossume3db8621991-09-09 23:33:34 +0000513 {NULL, NULL} /* sentinel */
514};
515
516static void
517port_dealloc(p)
518 portobject *p;
519{
520 if (p->ob_port != NULL)
521 ALcloseport(p->ob_port);
522 DEL(p);
523}
524
525static object *
526port_getattr(p, name)
527 portobject *p;
528 char *name;
529{
530 return findmethod(port_methods, (object *)p, name);
531}
532
Guido van Rossumb6775db1994-08-01 11:34:53 +0000533static typeobject Porttype = {
Guido van Rossume3db8621991-09-09 23:33:34 +0000534 OB_HEAD_INIT(&Typetype)
535 0, /*ob_size*/
536 "port", /*tp_name*/
537 sizeof(portobject), /*tp_size*/
538 0, /*tp_itemsize*/
539 /* methods */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000540 (destructor)port_dealloc, /*tp_dealloc*/
Guido van Rossume3db8621991-09-09 23:33:34 +0000541 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000542 (getattrfunc)port_getattr, /*tp_getattr*/
Guido van Rossume3db8621991-09-09 23:33:34 +0000543 0, /*tp_setattr*/
544 0, /*tp_compare*/
545 0, /*tp_repr*/
546};
547
548static object *
549newportobject(port)
550 ALport port;
551{
552 portobject *p;
553
554 p = NEWOBJ(portobject, &Porttype);
555 if (p == NULL)
556 return NULL;
557 p->ob_port = port;
558 return (object *)p;
559}
560
561/* the module al */
562
563static object *
564al_openport (self, args)
565 object *self, *args;
566{
Guido van Rossumfc58e581992-01-27 16:45:55 +0000567 char *name, *dir;
Guido van Rossume3db8621991-09-09 23:33:34 +0000568 ALport port;
569 ALconfig config = NULL;
Guido van Rossumc0aab891991-10-20 20:10:46 +0000570 int size;
Guido van Rossume3db8621991-09-09 23:33:34 +0000571
Guido van Rossumc0aab891991-10-20 20:10:46 +0000572 if (args == NULL || !is_tupleobject(args)) {
Guido van Rossumfc58e581992-01-27 16:45:55 +0000573 err_badarg ();
Guido van Rossumc0aab891991-10-20 20:10:46 +0000574 return NULL;
575 }
576 size = gettuplesize(args);
Guido van Rossume3db8621991-09-09 23:33:34 +0000577 if (size == 2) {
Guido van Rossum234f9421993-06-17 12:35:49 +0000578 if (!getargs (args, "(ss)", &name, &dir))
Guido van Rossume3db8621991-09-09 23:33:34 +0000579 return NULL;
580 }
581 else if (size == 3) {
582 if (!getstrstrconfigarg (args, &name, &dir, &config))
583 return NULL;
584 }
585 else {
Guido van Rossumfc58e581992-01-27 16:45:55 +0000586 err_badarg ();
Guido van Rossume3db8621991-09-09 23:33:34 +0000587 return NULL;
588 }
589
Guido van Rossumfc58e581992-01-27 16:45:55 +0000590 port = ALopenport(name, dir, config);
Guido van Rossume3db8621991-09-09 23:33:34 +0000591
Guido van Rossumc0aab891991-10-20 20:10:46 +0000592 if (port == NULL) {
593 err_errno(RuntimeError);
594 return NULL;
595 }
596
Guido van Rossume3db8621991-09-09 23:33:34 +0000597 return newportobject (port);
598}
599
600static object *
601al_newconfig (self, args)
602 object *self, *args;
603{
604 ALconfig config;
605
606 if (!getnoarg (args)) return NULL;
607
608 config = ALnewconfig ();
Guido van Rossumc0aab891991-10-20 20:10:46 +0000609 if (config == NULL) {
610 err_errno(RuntimeError);
611 return NULL;
612 }
Guido van Rossume3db8621991-09-09 23:33:34 +0000613
614 return newconfigobject (config);
615}
Guido van Rossumb3a5b9b1991-09-10 14:54:05 +0000616
617static object *
618al_queryparams(self, args)
619 object *self, *args;
620{
621 long device;
622 long length;
623 long *PVbuffer;
624 long PVdummy[2];
625 object *v;
626 object *w;
627
Guido van Rossumfc58e581992-01-27 16:45:55 +0000628 if (!getlongarg (args, &device))
Guido van Rossumb3a5b9b1991-09-10 14:54:05 +0000629 return NULL;
630 length = ALqueryparams(device, PVdummy, 2L);
631 PVbuffer = NEW(long, length);
632 if (PVbuffer == NULL)
633 return err_nomem();
634 (void) ALqueryparams(device, PVbuffer, length);
635 v = newlistobject((int)length);
636 if (v != NULL) {
637 int i;
638 for (i = 0; i < length; i++)
639 setlistitem(v, i, newintobject(PVbuffer[i]));
640 }
641 DEL(PVbuffer);
642 return v;
643}
644
645static object *
646doParams(args, func, modified)
647 object *args;
648 void (*func)(long, long *, long);
649 int modified;
650{
651 long device;
652 object *list, *v;
653 long *PVbuffer;
654 long length;
655 int i;
Guido van Rossume3db8621991-09-09 23:33:34 +0000656
Guido van Rossumfc58e581992-01-27 16:45:55 +0000657 if (!getargs(args, "(lO)", &device, &list))
Guido van Rossumb3a5b9b1991-09-10 14:54:05 +0000658 return NULL;
659 if (!is_listobject(list)) {
660 err_badarg();
661 return NULL;
662 }
663 length = getlistsize(list);
664 PVbuffer = NEW(long, length);
665 if (PVbuffer == NULL)
666 return err_nomem();
667 for (i = 0; i < length; i++) {
668 v = getlistitem(list, i);
669 if (!is_intobject(v)) {
670 DEL(PVbuffer);
671 err_badarg();
672 return NULL;
673 }
674 PVbuffer[i] = getintvalue(v);
675 }
676
Guido van Rossum8db03071991-09-13 15:31:47 +0000677 (*func)(device, PVbuffer, length);
Guido van Rossumb3a5b9b1991-09-10 14:54:05 +0000678
679 if (modified) {
680 for (i = 0; i < length; i++)
681 setlistitem(list, i, newintobject(PVbuffer[i]));
682 }
683
Guido van Rossumc0aab891991-10-20 20:10:46 +0000684 DEL(PVbuffer);
685
Guido van Rossumb3a5b9b1991-09-10 14:54:05 +0000686 INCREF(None);
687 return None;
688}
689
690static object *
691al_getparams(self, args)
692 object *self, *args;
693{
694 return doParams(args, ALgetparams, 1);
695}
696
697static object *
698al_setparams(self, args)
699 object *self, *args;
700{
701 return doParams(args, ALsetparams, 0);
702}
703
Guido van Rossum448f4bf1992-08-19 16:41:15 +0000704static object *
705al_getname(self, args)
706 object *self, *args;
707{
708 long device, descriptor;
709 char *name;
710 if (!getargs(args, "(ll)", &device, &descriptor))
711 return NULL;
712 name = ALgetname(device, descriptor);
713 if (name == NULL) {
714 err_setstr(ValueError, "al.getname: bad descriptor");
715 return NULL;
716 }
717 return newstringobject(name);
718}
719
720static object *
721al_getdefault(self, args)
722 object *self, *args;
723{
724 long device, descriptor, value;
725 if (!getargs(args, "(ll)", &device, &descriptor))
726 return NULL;
727 value = ALgetdefault(device, descriptor);
728 return newlongobject(value);
729}
730
731static object *
732al_getminmax(self, args)
733 object *self, *args;
734{
735 long device, descriptor, min, max;
736 if (!getargs(args, "(ll)", &device, &descriptor))
737 return NULL;
738 min = -1;
739 max = -1;
740 ALgetminmax(device, descriptor, &min, &max);
741 return mkvalue("ll", min, max);
742}
743
Guido van Rossume3db8621991-09-09 23:33:34 +0000744static struct methodlist al_methods[] = {
Guido van Rossumb6775db1994-08-01 11:34:53 +0000745 {"openport", (method)al_openport},
746 {"newconfig", (method)al_newconfig},
747 {"queryparams", (method)al_queryparams},
748 {"getparams", (method)al_getparams},
749 {"setparams", (method)al_setparams},
750 {"getname", (method)al_getname},
751 {"getdefault", (method)al_getdefault},
752 {"getminmax", (method)al_getminmax},
Guido van Rossume3db8621991-09-09 23:33:34 +0000753 {NULL, NULL} /* sentinel */
754};
755
756void
757inital()
758{
759 initmodule("al", al_methods);
760}
761
Guido van Rossumfc58e581992-01-27 16:45:55 +0000762static int
763getconfigarg(o, conf)
764 object *o;
Guido van Rossume3db8621991-09-09 23:33:34 +0000765 ALconfig *conf;
766{
767 if (o == NULL || !is_configobject(o))
768 return err_badarg ();
769
Guido van Rossumfc58e581992-01-27 16:45:55 +0000770 *conf = ((configobject *) o) -> ob_config;
Guido van Rossume3db8621991-09-09 23:33:34 +0000771
772 return 1;
773}
774
Guido van Rossumfc58e581992-01-27 16:45:55 +0000775static int
Guido van Rossume3db8621991-09-09 23:33:34 +0000776getstrstrconfigarg(v, a, b, c)
777 object *v;
Guido van Rossumfc58e581992-01-27 16:45:55 +0000778 char **a;
779 char **b;
Guido van Rossume3db8621991-09-09 23:33:34 +0000780 ALconfig *c;
781{
Guido van Rossumfc58e581992-01-27 16:45:55 +0000782 object *o;
783 return getargs(v, "(ssO)", a, b, &o) && getconfigarg(o, c);
Guido van Rossume3db8621991-09-09 23:33:34 +0000784}