blob: 6972e8222aa88239a32957d3ff23be4b004a3bcc [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{
Guido van Rossumfc58e581992-01-27 16:45:55 +0000369 char *buf;
370 int size, width;
Guido van Rossumb3a5b9b1991-09-10 14:54:05 +0000371 ALconfig c;
Guido van Rossume3db8621991-09-09 23:33:34 +0000372
Guido van Rossumfc58e581992-01-27 16:45:55 +0000373 if (!getargs (args, "s#", &buf, &size)) return NULL;
Guido van Rossume3db8621991-09-09 23:33:34 +0000374
Guido van Rossumb3a5b9b1991-09-10 14:54:05 +0000375 c = ALgetconfig(self->ob_port);
Jack Jansene8a3c281993-02-10 14:10:56 +0000376#ifdef AL_405
377 width = ALgetsampfmt(c);
378 if ( width == AL_SAMPFMT_FLOAT )
379 width = sizeof(float);
380 else if ( width == AL_SAMPFMT_DOUBLE )
381 width = sizeof(double);
382 else
383 width = ALgetwidth(c);
384#else
Guido van Rossumb3a5b9b1991-09-10 14:54:05 +0000385 width = ALgetwidth(c);
Jack Jansene8a3c281993-02-10 14:10:56 +0000386#endif /* AL_405 */
Guido van Rossumb3a5b9b1991-09-10 14:54:05 +0000387 ALfreeconfig(c);
Jack Jansen743db361992-08-13 14:13:11 +0000388 BGN_SAVE
Guido van Rossumfc58e581992-01-27 16:45:55 +0000389 ALwritesamps (self-> ob_port, (void *) buf, (long) size / width);
Jack Jansen743db361992-08-13 14:13:11 +0000390 END_SAVE
Guido van Rossume3db8621991-09-09 23:33:34 +0000391
392 INCREF (None);
393 return None;
394}
395
396static object *
397al_getfillpoint (self, args)
398 portobject *self;
399 object *args;
400{
401 long count;
402
Guido van Rossumfc58e581992-01-27 16:45:55 +0000403 if (!getnoarg (args)) return NULL;
Guido van Rossume3db8621991-09-09 23:33:34 +0000404
405 count = ALgetfillpoint (self-> ob_port);
406
407 return newintobject (count);
408}
409
410static object *
411al_setfillpoint (self, args)
412 portobject *self;
413 object *args;
414{
415 long count;
416
Guido van Rossumfc58e581992-01-27 16:45:55 +0000417 if (!getlongarg (args, &count)) return NULL;
Guido van Rossume3db8621991-09-09 23:33:34 +0000418
419 ALsetfillpoint (self-> ob_port, count);
420
421 INCREF (None);
422 return (None);
423}
424
425static object *
426al_setconfig (self, args)
427 portobject *self;
428 object *args;
429{
430 ALconfig config;
431
Guido van Rossumfc58e581992-01-27 16:45:55 +0000432 if (!getconfigarg (args, &config)) return NULL;
Guido van Rossume3db8621991-09-09 23:33:34 +0000433
434 ALsetconfig (self-> ob_port, config);
435
436 INCREF (None);
437 return (None);
438}
439
440static object *
441al_getconfig (self, args)
442 portobject *self;
443 object *args;
444{
445 ALconfig config;
446
Guido van Rossumfc58e581992-01-27 16:45:55 +0000447 if (!getnoarg (args)) return NULL;
Guido van Rossume3db8621991-09-09 23:33:34 +0000448
449 config = ALgetconfig (self-> ob_port);
450
451 return newconfigobject (config);
452}
453
Jack Jansene8a3c281993-02-10 14:10:56 +0000454#ifdef AL_405
455static object *
456al_getstatus (self, args)
457 portobject *self;
458 object *args;
459{
460 object *list, *v;
461 long *PVbuffer;
462 long length;
463 int i;
464
465 if (!getargs(args, "O", &list))
466 return NULL;
467 if (!is_listobject(list)) {
468 err_badarg();
469 return NULL;
470 }
471 length = getlistsize(list);
472 PVbuffer = NEW(long, length);
473 if (PVbuffer == NULL)
474 return err_nomem();
475 for (i = 0; i < length; i++) {
476 v = getlistitem(list, i);
477 if (!is_intobject(v)) {
478 DEL(PVbuffer);
479 err_badarg();
480 return NULL;
481 }
482 PVbuffer[i] = getintvalue(v);
483 }
484
485 ALgetstatus(self->ob_port, PVbuffer, length);
486
487 for (i = 0; i < length; i++)
488 setlistitem(list, i, newintobject(PVbuffer[i]));
489
490 DEL(PVbuffer);
491
492 INCREF(None);
493 return None;
494}
495#endif /* AL_405 */
496
Guido van Rossume3db8621991-09-09 23:33:34 +0000497static struct methodlist port_methods[] = {
Guido van Rossumb6775db1994-08-01 11:34:53 +0000498 {"closeport", (method)al_closeport},
499 {"getfd", (method)al_getfd},
500 {"fileno", (method)al_getfd},
501 {"getfilled", (method)al_getfilled},
502 {"getfillable", (method)al_getfillable},
503 {"readsamps", (method)al_readsamps},
504 {"writesamps", (method)al_writesamps},
505 {"setfillpoint", (method)al_setfillpoint},
506 {"getfillpoint", (method)al_getfillpoint},
507 {"setconfig", (method)al_setconfig},
508 {"getconfig", (method)al_getconfig},
Jack Jansene8a3c281993-02-10 14:10:56 +0000509#ifdef AL_405
Guido van Rossumb6775db1994-08-01 11:34:53 +0000510 {"getstatus", (method)al_getstatus},
Jack Jansene8a3c281993-02-10 14:10:56 +0000511#endif /* AL_405 */
Guido van Rossume3db8621991-09-09 23:33:34 +0000512 {NULL, NULL} /* sentinel */
513};
514
515static void
516port_dealloc(p)
517 portobject *p;
518{
519 if (p->ob_port != NULL)
520 ALcloseport(p->ob_port);
521 DEL(p);
522}
523
524static object *
525port_getattr(p, name)
526 portobject *p;
527 char *name;
528{
529 return findmethod(port_methods, (object *)p, name);
530}
531
Guido van Rossumb6775db1994-08-01 11:34:53 +0000532static typeobject Porttype = {
Guido van Rossume3db8621991-09-09 23:33:34 +0000533 OB_HEAD_INIT(&Typetype)
534 0, /*ob_size*/
535 "port", /*tp_name*/
536 sizeof(portobject), /*tp_size*/
537 0, /*tp_itemsize*/
538 /* methods */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000539 (destructor)port_dealloc, /*tp_dealloc*/
Guido van Rossume3db8621991-09-09 23:33:34 +0000540 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000541 (getattrfunc)port_getattr, /*tp_getattr*/
Guido van Rossume3db8621991-09-09 23:33:34 +0000542 0, /*tp_setattr*/
543 0, /*tp_compare*/
544 0, /*tp_repr*/
545};
546
547static object *
548newportobject(port)
549 ALport port;
550{
551 portobject *p;
552
553 p = NEWOBJ(portobject, &Porttype);
554 if (p == NULL)
555 return NULL;
556 p->ob_port = port;
557 return (object *)p;
558}
559
560/* the module al */
561
562static object *
563al_openport (self, args)
564 object *self, *args;
565{
Guido van Rossumfc58e581992-01-27 16:45:55 +0000566 char *name, *dir;
Guido van Rossume3db8621991-09-09 23:33:34 +0000567 ALport port;
568 ALconfig config = NULL;
Guido van Rossumc0aab891991-10-20 20:10:46 +0000569 int size;
Guido van Rossume3db8621991-09-09 23:33:34 +0000570
Guido van Rossumc0aab891991-10-20 20:10:46 +0000571 if (args == NULL || !is_tupleobject(args)) {
Guido van Rossumfc58e581992-01-27 16:45:55 +0000572 err_badarg ();
Guido van Rossumc0aab891991-10-20 20:10:46 +0000573 return NULL;
574 }
575 size = gettuplesize(args);
Guido van Rossume3db8621991-09-09 23:33:34 +0000576 if (size == 2) {
Guido van Rossum234f9421993-06-17 12:35:49 +0000577 if (!getargs (args, "(ss)", &name, &dir))
Guido van Rossume3db8621991-09-09 23:33:34 +0000578 return NULL;
579 }
580 else if (size == 3) {
581 if (!getstrstrconfigarg (args, &name, &dir, &config))
582 return NULL;
583 }
584 else {
Guido van Rossumfc58e581992-01-27 16:45:55 +0000585 err_badarg ();
Guido van Rossume3db8621991-09-09 23:33:34 +0000586 return NULL;
587 }
588
Guido van Rossumfc58e581992-01-27 16:45:55 +0000589 port = ALopenport(name, dir, config);
Guido van Rossume3db8621991-09-09 23:33:34 +0000590
Guido van Rossumc0aab891991-10-20 20:10:46 +0000591 if (port == NULL) {
592 err_errno(RuntimeError);
593 return NULL;
594 }
595
Guido van Rossume3db8621991-09-09 23:33:34 +0000596 return newportobject (port);
597}
598
599static object *
600al_newconfig (self, args)
601 object *self, *args;
602{
603 ALconfig config;
604
605 if (!getnoarg (args)) return NULL;
606
607 config = ALnewconfig ();
Guido van Rossumc0aab891991-10-20 20:10:46 +0000608 if (config == NULL) {
609 err_errno(RuntimeError);
610 return NULL;
611 }
Guido van Rossume3db8621991-09-09 23:33:34 +0000612
613 return newconfigobject (config);
614}
Guido van Rossumb3a5b9b1991-09-10 14:54:05 +0000615
616static object *
617al_queryparams(self, args)
618 object *self, *args;
619{
620 long device;
621 long length;
622 long *PVbuffer;
623 long PVdummy[2];
624 object *v;
Guido van Rossumb3a5b9b1991-09-10 14:54:05 +0000625
Guido van Rossumfc58e581992-01-27 16:45:55 +0000626 if (!getlongarg (args, &device))
Guido van Rossumb3a5b9b1991-09-10 14:54:05 +0000627 return NULL;
628 length = ALqueryparams(device, PVdummy, 2L);
629 PVbuffer = NEW(long, length);
630 if (PVbuffer == NULL)
631 return err_nomem();
632 (void) ALqueryparams(device, PVbuffer, length);
633 v = newlistobject((int)length);
634 if (v != NULL) {
635 int i;
636 for (i = 0; i < length; i++)
637 setlistitem(v, i, newintobject(PVbuffer[i]));
638 }
639 DEL(PVbuffer);
640 return v;
641}
642
643static object *
644doParams(args, func, modified)
645 object *args;
646 void (*func)(long, long *, long);
647 int modified;
648{
649 long device;
650 object *list, *v;
651 long *PVbuffer;
652 long length;
653 int i;
Guido van Rossume3db8621991-09-09 23:33:34 +0000654
Guido van Rossumfc58e581992-01-27 16:45:55 +0000655 if (!getargs(args, "(lO)", &device, &list))
Guido van Rossumb3a5b9b1991-09-10 14:54:05 +0000656 return NULL;
657 if (!is_listobject(list)) {
658 err_badarg();
659 return NULL;
660 }
661 length = getlistsize(list);
662 PVbuffer = NEW(long, length);
663 if (PVbuffer == NULL)
664 return err_nomem();
665 for (i = 0; i < length; i++) {
666 v = getlistitem(list, i);
667 if (!is_intobject(v)) {
668 DEL(PVbuffer);
669 err_badarg();
670 return NULL;
671 }
672 PVbuffer[i] = getintvalue(v);
673 }
674
Guido van Rossum8db03071991-09-13 15:31:47 +0000675 (*func)(device, PVbuffer, length);
Guido van Rossumb3a5b9b1991-09-10 14:54:05 +0000676
677 if (modified) {
678 for (i = 0; i < length; i++)
679 setlistitem(list, i, newintobject(PVbuffer[i]));
680 }
681
Guido van Rossumc0aab891991-10-20 20:10:46 +0000682 DEL(PVbuffer);
683
Guido van Rossumb3a5b9b1991-09-10 14:54:05 +0000684 INCREF(None);
685 return None;
686}
687
688static object *
689al_getparams(self, args)
690 object *self, *args;
691{
692 return doParams(args, ALgetparams, 1);
693}
694
695static object *
696al_setparams(self, args)
697 object *self, *args;
698{
699 return doParams(args, ALsetparams, 0);
700}
701
Guido van Rossum448f4bf1992-08-19 16:41:15 +0000702static object *
703al_getname(self, args)
704 object *self, *args;
705{
706 long device, descriptor;
707 char *name;
708 if (!getargs(args, "(ll)", &device, &descriptor))
709 return NULL;
710 name = ALgetname(device, descriptor);
711 if (name == NULL) {
712 err_setstr(ValueError, "al.getname: bad descriptor");
713 return NULL;
714 }
715 return newstringobject(name);
716}
717
718static object *
719al_getdefault(self, args)
720 object *self, *args;
721{
722 long device, descriptor, value;
723 if (!getargs(args, "(ll)", &device, &descriptor))
724 return NULL;
725 value = ALgetdefault(device, descriptor);
726 return newlongobject(value);
727}
728
729static object *
730al_getminmax(self, args)
731 object *self, *args;
732{
733 long device, descriptor, min, max;
734 if (!getargs(args, "(ll)", &device, &descriptor))
735 return NULL;
736 min = -1;
737 max = -1;
738 ALgetminmax(device, descriptor, &min, &max);
739 return mkvalue("ll", min, max);
740}
741
Guido van Rossume3db8621991-09-09 23:33:34 +0000742static struct methodlist al_methods[] = {
Guido van Rossumb6775db1994-08-01 11:34:53 +0000743 {"openport", (method)al_openport},
744 {"newconfig", (method)al_newconfig},
745 {"queryparams", (method)al_queryparams},
746 {"getparams", (method)al_getparams},
747 {"setparams", (method)al_setparams},
748 {"getname", (method)al_getname},
749 {"getdefault", (method)al_getdefault},
750 {"getminmax", (method)al_getminmax},
Guido van Rossume3db8621991-09-09 23:33:34 +0000751 {NULL, NULL} /* sentinel */
752};
753
754void
755inital()
756{
757 initmodule("al", al_methods);
758}
759
Guido van Rossumfc58e581992-01-27 16:45:55 +0000760static int
761getconfigarg(o, conf)
762 object *o;
Guido van Rossume3db8621991-09-09 23:33:34 +0000763 ALconfig *conf;
764{
765 if (o == NULL || !is_configobject(o))
766 return err_badarg ();
767
Guido van Rossumfc58e581992-01-27 16:45:55 +0000768 *conf = ((configobject *) o) -> ob_config;
Guido van Rossume3db8621991-09-09 23:33:34 +0000769
770 return 1;
771}
772
Guido van Rossumfc58e581992-01-27 16:45:55 +0000773static int
Guido van Rossume3db8621991-09-09 23:33:34 +0000774getstrstrconfigarg(v, a, b, c)
775 object *v;
Guido van Rossumfc58e581992-01-27 16:45:55 +0000776 char **a;
777 char **b;
Guido van Rossume3db8621991-09-09 23:33:34 +0000778 ALconfig *c;
779{
Guido van Rossumfc58e581992-01-27 16:45:55 +0000780 object *o;
781 return getargs(v, "(ssO)", a, b, &o) && getconfigarg(o, c);
Guido van Rossume3db8621991-09-09 23:33:34 +0000782}