(py-indent-right, py-outdent-left): new commands, bound to C-c C-r and
[python/dscho.git] / Modules / almodule.c
blob052939ec5ff64d85fe2195695888d28296b353dc
1 /**********************************************************
2 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3 The Netherlands.
5 All Rights Reserved
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI not be used in advertising or publicity pertaining to
13 distribution of the software without specific, written prior permission.
15 STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16 THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17 FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18 FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21 OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 ******************************************************************/
25 /* AL module -- interface to Mark Callow's Audio Library (AL). */
27 #include <audio.h>
29 /* Check which version audio library we have: */
30 #ifdef AL_ERROR_NUMBER
31 #define AL_405
32 /* XXXX 4.0.5 libaudio also allows us to provide better error
33 ** handling (with ALseterrorhandler). We should implement that
34 ** sometime.
37 #endif
39 #include "allobjects.h"
40 #include "import.h"
41 #include "modsupport.h"
42 #include "structmember.h"
43 #include "ceval.h"
46 /* Config objects */
48 typedef struct {
49 OB_HEAD
50 ALconfig ob_config;
51 } configobject;
53 staticforward typeobject Configtype;
55 #define is_configobject(v) ((v)->ob_type == &Configtype)
57 /* Forward */
58 static int getconfigarg PROTO((object *, ALconfig *));
59 static int getstrstrconfigarg PROTO((object *, char **, char **, ALconfig *));
61 static object *
62 setConfig (self, args, func)
63 configobject *self;
64 object *args;
65 void (*func)(ALconfig, long);
67 long par;
69 if (!getlongarg (args, &par)) return NULL;
71 (*func) (self-> ob_config, par);
73 INCREF (None);
74 return None;
77 static object *
78 getConfig (self, args, func)
79 configobject *self;
80 object *args;
81 long (*func)(ALconfig);
83 long par;
85 if (!getnoarg (args)) return NULL;
87 par = (*func) (self-> ob_config);
89 return newintobject (par);
92 static object *
93 al_setqueuesize (self, args)
94 configobject *self;
95 object *args;
97 return (setConfig (self, args, ALsetqueuesize));
100 static object *
101 al_getqueuesize (self, args)
102 configobject *self;
103 object *args;
105 return (getConfig (self, args, ALgetqueuesize));
108 static object *
109 al_setwidth (self, args)
110 configobject *self;
111 object *args;
113 return (setConfig (self, args, ALsetwidth));
116 static object *
117 al_getwidth (self, args)
118 configobject *self;
119 object *args;
121 return (getConfig (self, args, ALgetwidth));
124 static object *
125 al_getchannels (self, args)
126 configobject *self;
127 object *args;
129 return (getConfig (self, args, ALgetchannels));
132 static object *
133 al_setchannels (self, args)
134 configobject *self;
135 object *args;
137 return (setConfig (self, args, ALsetchannels));
140 #ifdef AL_405
142 static object *
143 al_getsampfmt (self, args)
144 configobject *self;
145 object *args;
147 return (getConfig (self, args, ALgetsampfmt));
150 static object *
151 al_setsampfmt (self, args)
152 configobject *self;
153 object *args;
155 return (setConfig (self, args, ALsetsampfmt));
158 static object *
159 al_getfloatmax(self, args)
160 configobject *self;
161 object *args;
163 double arg;
165 if ( !getnoarg(args) )
166 return 0;
167 arg = ALgetfloatmax(self->ob_config);
168 return newfloatobject(arg);
171 static object *
172 al_setfloatmax(self, args)
173 configobject *self;
174 object *args;
176 double arg;
178 if ( !getargs(args, "d", &arg) )
179 return 0;
180 ALsetfloatmax(self->ob_config, arg);
181 INCREF(None);
182 return None;
184 #endif /* AL_405 */
186 static struct methodlist config_methods[] = {
187 {"getqueuesize", (method)al_getqueuesize},
188 {"setqueuesize", (method)al_setqueuesize},
189 {"getwidth", (method)al_getwidth},
190 {"setwidth", (method)al_setwidth},
191 {"getchannels", (method)al_getchannels},
192 {"setchannels", (method)al_setchannels},
193 #ifdef AL_405
194 {"getsampfmt", (method)al_getsampfmt},
195 {"setsampfmt", (method)al_setsampfmt},
196 {"getfloatmax", (method)al_getfloatmax},
197 {"setfloatmax", (method)al_setfloatmax},
198 #endif /* AL_405 */
199 {NULL, NULL} /* sentinel */
202 static void
203 config_dealloc(self)
204 configobject *self;
206 ALfreeconfig(self->ob_config);
207 DEL(self);
210 static object *
211 config_getattr(self, name)
212 configobject *self;
213 char *name;
215 return findmethod(config_methods, (object *)self, name);
218 static typeobject Configtype = {
219 OB_HEAD_INIT(&Typetype)
220 0, /*ob_size*/
221 "config", /*tp_name*/
222 sizeof(configobject), /*tp_size*/
223 0, /*tp_itemsize*/
224 /* methods */
225 (destructor)config_dealloc, /*tp_dealloc*/
226 0, /*tp_print*/
227 (getattrfunc)config_getattr, /*tp_getattr*/
228 0, /*tp_setattr*/
229 0, /*tp_compare*/
230 0, /*tp_repr*/
233 static object *
234 newconfigobject(config)
235 ALconfig config;
237 configobject *p;
239 p = NEWOBJ(configobject, &Configtype);
240 if (p == NULL)
241 return NULL;
242 p->ob_config = config;
243 return (object *)p;
246 /* Port objects */
248 typedef struct {
249 OB_HEAD
250 ALport ob_port;
251 } portobject;
253 staticforward typeobject Porttype;
255 #define is_portobject(v) ((v)->ob_type == &Porttype)
257 static object *
258 al_closeport (self, args)
259 portobject *self;
260 object *args;
262 if (!getnoarg (args)) return NULL;
264 if (self->ob_port != NULL) {
265 ALcloseport (self-> ob_port);
266 self->ob_port = NULL;
267 /* XXX Using a closed port may dump core! */
270 INCREF (None);
271 return None;
274 static object *
275 al_getfd (self, args)
276 portobject *self;
277 object *args;
279 int fd;
281 if (!getnoarg (args)) return NULL;
283 fd = ALgetfd (self-> ob_port);
285 return newintobject (fd);
288 static object *
289 al_getfilled (self, args)
290 portobject *self;
291 object *args;
293 long count;
295 if (!getnoarg (args)) return NULL;
297 count = ALgetfilled (self-> ob_port);
299 return newintobject (count);
302 static object *
303 al_getfillable (self, args)
304 portobject *self;
305 object *args;
307 long count;
309 if (!getnoarg (args)) return NULL;
311 count = ALgetfillable (self-> ob_port);
313 return newintobject (count);
316 static object *
317 al_readsamps (self, args)
318 portobject *self;
319 object *args;
321 long count;
322 object *v;
323 ALconfig c;
324 int width;
326 if (!getlongarg (args, &count)) return NULL;
328 if (count <= 0)
330 err_setstr (RuntimeError, "al.readsamps : arg <= 0");
331 return NULL;
334 c = ALgetconfig(self->ob_port);
335 #ifdef AL_405
336 width = ALgetsampfmt(c);
337 if ( width == AL_SAMPFMT_FLOAT )
338 width = sizeof(float);
339 else if ( width == AL_SAMPFMT_DOUBLE )
340 width = sizeof(double);
341 else
342 width = ALgetwidth(c);
343 #else
344 width = ALgetwidth(c);
345 #endif /* AL_405 */
346 ALfreeconfig(c);
347 v = newsizedstringobject ((char *)NULL, width * count);
348 if (v == NULL) return NULL;
350 BGN_SAVE
351 ALreadsamps (self-> ob_port, (void *) getstringvalue(v), count);
352 END_SAVE
354 return (v);
357 static object *
358 al_writesamps (self, args)
359 portobject *self;
360 object *args;
362 long count;
363 char *buf;
364 int size, width;
365 ALconfig c;
367 if (!getargs (args, "s#", &buf, &size)) return NULL;
369 c = ALgetconfig(self->ob_port);
370 #ifdef AL_405
371 width = ALgetsampfmt(c);
372 if ( width == AL_SAMPFMT_FLOAT )
373 width = sizeof(float);
374 else if ( width == AL_SAMPFMT_DOUBLE )
375 width = sizeof(double);
376 else
377 width = ALgetwidth(c);
378 #else
379 width = ALgetwidth(c);
380 #endif /* AL_405 */
381 ALfreeconfig(c);
382 BGN_SAVE
383 ALwritesamps (self-> ob_port, (void *) buf, (long) size / width);
384 END_SAVE
386 INCREF (None);
387 return None;
390 static object *
391 al_getfillpoint (self, args)
392 portobject *self;
393 object *args;
395 long count;
397 if (!getnoarg (args)) return NULL;
399 count = ALgetfillpoint (self-> ob_port);
401 return newintobject (count);
404 static object *
405 al_setfillpoint (self, args)
406 portobject *self;
407 object *args;
409 long count;
411 if (!getlongarg (args, &count)) return NULL;
413 ALsetfillpoint (self-> ob_port, count);
415 INCREF (None);
416 return (None);
419 static object *
420 al_setconfig (self, args)
421 portobject *self;
422 object *args;
424 ALconfig config;
426 if (!getconfigarg (args, &config)) return NULL;
428 ALsetconfig (self-> ob_port, config);
430 INCREF (None);
431 return (None);
434 static object *
435 al_getconfig (self, args)
436 portobject *self;
437 object *args;
439 ALconfig config;
441 if (!getnoarg (args)) return NULL;
443 config = ALgetconfig (self-> ob_port);
445 return newconfigobject (config);
448 #ifdef AL_405
449 static object *
450 al_getstatus (self, args)
451 portobject *self;
452 object *args;
454 object *list, *v;
455 long *PVbuffer;
456 long length;
457 int i;
459 if (!getargs(args, "O", &list))
460 return NULL;
461 if (!is_listobject(list)) {
462 err_badarg();
463 return NULL;
465 length = getlistsize(list);
466 PVbuffer = NEW(long, length);
467 if (PVbuffer == NULL)
468 return err_nomem();
469 for (i = 0; i < length; i++) {
470 v = getlistitem(list, i);
471 if (!is_intobject(v)) {
472 DEL(PVbuffer);
473 err_badarg();
474 return NULL;
476 PVbuffer[i] = getintvalue(v);
479 ALgetstatus(self->ob_port, PVbuffer, length);
481 for (i = 0; i < length; i++)
482 setlistitem(list, i, newintobject(PVbuffer[i]));
484 DEL(PVbuffer);
486 INCREF(None);
487 return None;
489 #endif /* AL_405 */
491 static struct methodlist port_methods[] = {
492 {"closeport", (method)al_closeport},
493 {"getfd", (method)al_getfd},
494 {"fileno", (method)al_getfd},
495 {"getfilled", (method)al_getfilled},
496 {"getfillable", (method)al_getfillable},
497 {"readsamps", (method)al_readsamps},
498 {"writesamps", (method)al_writesamps},
499 {"setfillpoint", (method)al_setfillpoint},
500 {"getfillpoint", (method)al_getfillpoint},
501 {"setconfig", (method)al_setconfig},
502 {"getconfig", (method)al_getconfig},
503 #ifdef AL_405
504 {"getstatus", (method)al_getstatus},
505 #endif /* AL_405 */
506 {NULL, NULL} /* sentinel */
509 static void
510 port_dealloc(p)
511 portobject *p;
513 if (p->ob_port != NULL)
514 ALcloseport(p->ob_port);
515 DEL(p);
518 static object *
519 port_getattr(p, name)
520 portobject *p;
521 char *name;
523 return findmethod(port_methods, (object *)p, name);
526 static typeobject Porttype = {
527 OB_HEAD_INIT(&Typetype)
528 0, /*ob_size*/
529 "port", /*tp_name*/
530 sizeof(portobject), /*tp_size*/
531 0, /*tp_itemsize*/
532 /* methods */
533 (destructor)port_dealloc, /*tp_dealloc*/
534 0, /*tp_print*/
535 (getattrfunc)port_getattr, /*tp_getattr*/
536 0, /*tp_setattr*/
537 0, /*tp_compare*/
538 0, /*tp_repr*/
541 static object *
542 newportobject(port)
543 ALport port;
545 portobject *p;
547 p = NEWOBJ(portobject, &Porttype);
548 if (p == NULL)
549 return NULL;
550 p->ob_port = port;
551 return (object *)p;
554 /* the module al */
556 static object *
557 al_openport (self, args)
558 object *self, *args;
560 char *name, *dir;
561 ALport port;
562 ALconfig config = NULL;
563 int size;
565 if (args == NULL || !is_tupleobject(args)) {
566 err_badarg ();
567 return NULL;
569 size = gettuplesize(args);
570 if (size == 2) {
571 if (!getargs (args, "(ss)", &name, &dir))
572 return NULL;
574 else if (size == 3) {
575 if (!getstrstrconfigarg (args, &name, &dir, &config))
576 return NULL;
578 else {
579 err_badarg ();
580 return NULL;
583 port = ALopenport(name, dir, config);
585 if (port == NULL) {
586 err_errno(RuntimeError);
587 return NULL;
590 return newportobject (port);
593 static object *
594 al_newconfig (self, args)
595 object *self, *args;
597 ALconfig config;
599 if (!getnoarg (args)) return NULL;
601 config = ALnewconfig ();
602 if (config == NULL) {
603 err_errno(RuntimeError);
604 return NULL;
607 return newconfigobject (config);
610 static object *
611 al_queryparams(self, args)
612 object *self, *args;
614 long device;
615 long length;
616 long *PVbuffer;
617 long PVdummy[2];
618 object *v;
619 object *w;
621 if (!getlongarg (args, &device))
622 return NULL;
623 length = ALqueryparams(device, PVdummy, 2L);
624 PVbuffer = NEW(long, length);
625 if (PVbuffer == NULL)
626 return err_nomem();
627 (void) ALqueryparams(device, PVbuffer, length);
628 v = newlistobject((int)length);
629 if (v != NULL) {
630 int i;
631 for (i = 0; i < length; i++)
632 setlistitem(v, i, newintobject(PVbuffer[i]));
634 DEL(PVbuffer);
635 return v;
638 static object *
639 doParams(args, func, modified)
640 object *args;
641 void (*func)(long, long *, long);
642 int modified;
644 long device;
645 object *list, *v;
646 long *PVbuffer;
647 long length;
648 int i;
650 if (!getargs(args, "(lO)", &device, &list))
651 return NULL;
652 if (!is_listobject(list)) {
653 err_badarg();
654 return NULL;
656 length = getlistsize(list);
657 PVbuffer = NEW(long, length);
658 if (PVbuffer == NULL)
659 return err_nomem();
660 for (i = 0; i < length; i++) {
661 v = getlistitem(list, i);
662 if (!is_intobject(v)) {
663 DEL(PVbuffer);
664 err_badarg();
665 return NULL;
667 PVbuffer[i] = getintvalue(v);
670 (*func)(device, PVbuffer, length);
672 if (modified) {
673 for (i = 0; i < length; i++)
674 setlistitem(list, i, newintobject(PVbuffer[i]));
677 DEL(PVbuffer);
679 INCREF(None);
680 return None;
683 static object *
684 al_getparams(self, args)
685 object *self, *args;
687 return doParams(args, ALgetparams, 1);
690 static object *
691 al_setparams(self, args)
692 object *self, *args;
694 return doParams(args, ALsetparams, 0);
697 static object *
698 al_getname(self, args)
699 object *self, *args;
701 long device, descriptor;
702 char *name;
703 if (!getargs(args, "(ll)", &device, &descriptor))
704 return NULL;
705 name = ALgetname(device, descriptor);
706 if (name == NULL) {
707 err_setstr(ValueError, "al.getname: bad descriptor");
708 return NULL;
710 return newstringobject(name);
713 static object *
714 al_getdefault(self, args)
715 object *self, *args;
717 long device, descriptor, value;
718 if (!getargs(args, "(ll)", &device, &descriptor))
719 return NULL;
720 value = ALgetdefault(device, descriptor);
721 return newlongobject(value);
724 static object *
725 al_getminmax(self, args)
726 object *self, *args;
728 long device, descriptor, min, max;
729 if (!getargs(args, "(ll)", &device, &descriptor))
730 return NULL;
731 min = -1;
732 max = -1;
733 ALgetminmax(device, descriptor, &min, &max);
734 return mkvalue("ll", min, max);
737 static struct methodlist al_methods[] = {
738 {"openport", (method)al_openport},
739 {"newconfig", (method)al_newconfig},
740 {"queryparams", (method)al_queryparams},
741 {"getparams", (method)al_getparams},
742 {"setparams", (method)al_setparams},
743 {"getname", (method)al_getname},
744 {"getdefault", (method)al_getdefault},
745 {"getminmax", (method)al_getminmax},
746 {NULL, NULL} /* sentinel */
749 void
750 inital()
752 initmodule("al", al_methods);
755 static int
756 getconfigarg(o, conf)
757 object *o;
758 ALconfig *conf;
760 if (o == NULL || !is_configobject(o))
761 return err_badarg ();
763 *conf = ((configobject *) o) -> ob_config;
765 return 1;
768 static int
769 getstrstrconfigarg(v, a, b, c)
770 object *v;
771 char **a;
772 char **b;
773 ALconfig *c;
775 object *o;
776 return getargs(v, "(ssO)", a, b, &o) && getconfigarg(o, c);