At the release of 1.0.1.
[python/dscho.git] / Modules / almodule.c
blobd731eff16e48aa734126c56c04fd1d30a1e779bc
1 /**********************************************************
2 Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum,
3 Amsterdam, 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 extern typeobject Configtype; /* Forward */
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", al_getqueuesize},
188 {"setqueuesize", al_setqueuesize},
189 {"getwidth", al_getwidth},
190 {"setwidth", al_setwidth},
191 {"getchannels", al_getchannels},
192 {"setchannels", al_setchannels},
193 #ifdef AL_405
194 {"getsampfmt", al_getsampfmt},
195 {"setsampfmt", al_setsampfmt},
196 {"getfloatmax", al_getfloatmax},
197 {"setfloatmax", 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 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 config_dealloc, /*tp_dealloc*/
226 0, /*tp_print*/
227 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 extern typeobject Porttype; /* Forward */
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", al_closeport},
493 {"close", al_closeport},
494 {"getfd", al_getfd},
495 {"fileno", al_getfd},
496 {"getfilled", al_getfilled},
497 {"getfillable", al_getfillable},
498 {"readsamps", al_readsamps},
499 {"writesamps", al_writesamps},
500 {"setfillpoint", al_setfillpoint},
501 {"getfillpoint", al_getfillpoint},
502 {"setconfig", al_setconfig},
503 {"getconfig", al_getconfig},
504 #ifdef AL_405
505 {"getstatus", al_getstatus},
506 #endif /* AL_405 */
507 {NULL, NULL} /* sentinel */
510 static void
511 port_dealloc(p)
512 portobject *p;
514 if (p->ob_port != NULL)
515 ALcloseport(p->ob_port);
516 DEL(p);
519 static object *
520 port_getattr(p, name)
521 portobject *p;
522 char *name;
524 return findmethod(port_methods, (object *)p, name);
527 typeobject Porttype = {
528 OB_HEAD_INIT(&Typetype)
529 0, /*ob_size*/
530 "port", /*tp_name*/
531 sizeof(portobject), /*tp_size*/
532 0, /*tp_itemsize*/
533 /* methods */
534 port_dealloc, /*tp_dealloc*/
535 0, /*tp_print*/
536 port_getattr, /*tp_getattr*/
537 0, /*tp_setattr*/
538 0, /*tp_compare*/
539 0, /*tp_repr*/
542 static object *
543 newportobject(port)
544 ALport port;
546 portobject *p;
548 p = NEWOBJ(portobject, &Porttype);
549 if (p == NULL)
550 return NULL;
551 p->ob_port = port;
552 return (object *)p;
555 /* the module al */
557 static object *
558 al_openport (self, args)
559 object *self, *args;
561 char *name, *dir;
562 ALport port;
563 ALconfig config = NULL;
564 int size;
566 if (args == NULL || !is_tupleobject(args)) {
567 err_badarg ();
568 return NULL;
570 size = gettuplesize(args);
571 if (size == 2) {
572 if (!getargs (args, "(ss)", &name, &dir))
573 return NULL;
575 else if (size == 3) {
576 if (!getstrstrconfigarg (args, &name, &dir, &config))
577 return NULL;
579 else {
580 err_badarg ();
581 return NULL;
584 port = ALopenport(name, dir, config);
586 if (port == NULL) {
587 err_errno(RuntimeError);
588 return NULL;
591 return newportobject (port);
594 static object *
595 al_newconfig (self, args)
596 object *self, *args;
598 ALconfig config;
600 if (!getnoarg (args)) return NULL;
602 config = ALnewconfig ();
603 if (config == NULL) {
604 err_errno(RuntimeError);
605 return NULL;
608 return newconfigobject (config);
611 static object *
612 al_queryparams(self, args)
613 object *self, *args;
615 long device;
616 long length;
617 long *PVbuffer;
618 long PVdummy[2];
619 object *v;
620 object *w;
622 if (!getlongarg (args, &device))
623 return NULL;
624 length = ALqueryparams(device, PVdummy, 2L);
625 PVbuffer = NEW(long, length);
626 if (PVbuffer == NULL)
627 return err_nomem();
628 (void) ALqueryparams(device, PVbuffer, length);
629 v = newlistobject((int)length);
630 if (v != NULL) {
631 int i;
632 for (i = 0; i < length; i++)
633 setlistitem(v, i, newintobject(PVbuffer[i]));
635 DEL(PVbuffer);
636 return v;
639 static object *
640 doParams(args, func, modified)
641 object *args;
642 void (*func)(long, long *, long);
643 int modified;
645 long device;
646 object *list, *v;
647 long *PVbuffer;
648 long length;
649 int i;
651 if (!getargs(args, "(lO)", &device, &list))
652 return NULL;
653 if (!is_listobject(list)) {
654 err_badarg();
655 return NULL;
657 length = getlistsize(list);
658 PVbuffer = NEW(long, length);
659 if (PVbuffer == NULL)
660 return err_nomem();
661 for (i = 0; i < length; i++) {
662 v = getlistitem(list, i);
663 if (!is_intobject(v)) {
664 DEL(PVbuffer);
665 err_badarg();
666 return NULL;
668 PVbuffer[i] = getintvalue(v);
671 (*func)(device, PVbuffer, length);
673 if (modified) {
674 for (i = 0; i < length; i++)
675 setlistitem(list, i, newintobject(PVbuffer[i]));
678 DEL(PVbuffer);
680 INCREF(None);
681 return None;
684 static object *
685 al_getparams(self, args)
686 object *self, *args;
688 return doParams(args, ALgetparams, 1);
691 static object *
692 al_setparams(self, args)
693 object *self, *args;
695 return doParams(args, ALsetparams, 0);
698 static object *
699 al_getname(self, args)
700 object *self, *args;
702 long device, descriptor;
703 char *name;
704 if (!getargs(args, "(ll)", &device, &descriptor))
705 return NULL;
706 name = ALgetname(device, descriptor);
707 if (name == NULL) {
708 err_setstr(ValueError, "al.getname: bad descriptor");
709 return NULL;
711 return newstringobject(name);
714 static object *
715 al_getdefault(self, args)
716 object *self, *args;
718 long device, descriptor, value;
719 if (!getargs(args, "(ll)", &device, &descriptor))
720 return NULL;
721 value = ALgetdefault(device, descriptor);
722 return newlongobject(value);
725 static object *
726 al_getminmax(self, args)
727 object *self, *args;
729 long device, descriptor, min, max;
730 if (!getargs(args, "(ll)", &device, &descriptor))
731 return NULL;
732 min = -1;
733 max = -1;
734 ALgetminmax(device, descriptor, &min, &max);
735 return mkvalue("ll", min, max);
738 static struct methodlist al_methods[] = {
739 {"openport", al_openport},
740 {"newconfig", al_newconfig},
741 {"queryparams", al_queryparams},
742 {"getparams", al_getparams},
743 {"setparams", al_setparams},
744 {"getname", al_getname},
745 {"getdefault", al_getdefault},
746 {"getminmax", al_getminmax},
747 {NULL, NULL} /* sentinel */
750 void
751 inital()
753 initmodule("al", al_methods);
756 static int
757 getconfigarg(o, conf)
758 object *o;
759 ALconfig *conf;
761 if (o == NULL || !is_configobject(o))
762 return err_badarg ();
764 *conf = ((configobject *) o) -> ob_config;
766 return 1;
769 static int
770 getstrstrconfigarg(v, a, b, c)
771 object *v;
772 char **a;
773 char **b;
774 ALconfig *c;
776 object *o;
777 return getargs(v, "(ssO)", a, b, &o) && getconfigarg(o, c);