blob: 47aa52aacf57c6aa780d050d22a12a8edc5484b5 [file] [log] [blame]
Guido van Rossume3db8621991-09-09 23:33:34 +00001/**********************************************************
2Copyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
3Netherlands.
4
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
25/* AL module -- interface to Mark Calows' Auido Library (AL). */
26
27#include "audio.h"
28
29#include "allobjects.h"
30#include "import.h"
31#include "modsupport.h"
32#include "structmember.h"
33
34
35/* Config objects */
36
37typedef struct {
38 OB_HEAD
39 ALconfig ob_config;
40} configobject;
41
42extern typeobject Configtype; /* Forward */
43
44#define is_configobject(v) ((v)->ob_type == &Configtype)
45
46static object *
47setConfig (self, args, func)
48 configobject *self;
49 object *args;
50 void (*func)(ALconfig, long);
51{
52 long par;
53
54 if (!getlongarg(args, &par)) return NULL;
55
56 (*func) (self-> ob_config, par);
57
58 INCREF (None);
59 return None;
60}
61
62static object *
63getConfig (self, args, func)
64 configobject *self;
65 object *args;
66 long (*func)(ALconfig);
67{
68 long par;
69
70 if (!getnoarg(args)) return NULL;
71
72 par = (*func) (self-> ob_config);
73
74 return newintobject (par);
75}
76
77static object *
78al_setqueuesize (self, args)
79 configobject *self;
80 object *args;
81{
82 return (setConfig (self, args, ALsetqueuesize));
83}
84
85static object *
86al_getqueuesize (self, args)
87 configobject *self;
88 object *args;
89{
90 return (getConfig (self, args, ALgetqueuesize));
91}
92
93static object *
94al_setwidth (self, args)
95 configobject *self;
96 object *args;
97{
98 return (setConfig (self, args, ALsetwidth));
99}
100
101static object *
102al_getwidth (self, args)
103 configobject *self;
104 object *args;
105{
106 return (getConfig (self, args, ALgetwidth));
107}
108
109static object *
110al_getchannels (self, args)
111 configobject *self;
112 object *args;
113{
114 return (getConfig (self, args, ALgetchannels));
115}
116
117static object *
118al_setchannels (self, args)
119 configobject *self;
120 object *args;
121{
122 return (setConfig (self, args, ALsetchannels));
123}
124
125static struct methodlist config_methods[] = {
126 {"getqueuesize", al_getqueuesize},
127 {"setqueuesize", al_setqueuesize},
128 {"getwidth", al_getwidth},
129 {"setwidth", al_setwidth},
130 {"getchannels", al_getchannels},
131 {"setchannels", al_setchannels},
132 {NULL, NULL} /* sentinel */
133};
134
135static void
136config_dealloc(self)
137 configobject *self;
138{
139 ALfreeconfig(self->ob_config);
140 DEL(self);
141}
142
143static object *
144config_getattr(self, name)
145 configobject *self;
146 char *name;
147{
148 return findmethod(config_methods, (object *)self, name);
149}
150
151typeobject Configtype = {
152 OB_HEAD_INIT(&Typetype)
153 0, /*ob_size*/
154 "config", /*tp_name*/
155 sizeof(configobject), /*tp_size*/
156 0, /*tp_itemsize*/
157 /* methods */
158 config_dealloc, /*tp_dealloc*/
159 0, /*tp_print*/
160 config_getattr, /*tp_getattr*/
161 0, /*tp_setattr*/
162 0, /*tp_compare*/
163 0, /*tp_repr*/
164};
165
166static object *
167newconfigobject(config)
168 ALconfig config;
169{
170 configobject *p;
171
172 p = NEWOBJ(configobject, &Configtype);
173 if (p == NULL)
174 return NULL;
175 p->ob_config = config;
176 return (object *)p;
177}
178
179/* Port objects */
180
181typedef struct {
182 OB_HEAD
183 ALport ob_port;
184} portobject;
185
186extern typeobject Porttype; /* Forward */
187
188#define is_portobject(v) ((v)->ob_type == &Porttype)
189
190static object *
191al_closeport (self, args)
192 portobject *self;
193 object *args;
194{
195 if (!getnoarg(args)) return NULL;
196
197 if (self->ob_port != NULL) {
198 ALcloseport (self-> ob_port);
199 self->ob_port = NULL;
200 /* XXX Using a closed port may dump core! */
201 }
202
203 INCREF (None);
204 return None;
205}
206
207static object *
208al_getfd (self, args)
209 portobject *self;
210 object *args;
211{
212 int fd;
213
214 if (!getnoarg(args)) return NULL;
215
216 fd = ALgetfd (self-> ob_port);
217
218 return newintobject (fd);
219}
220
221static object *
222al_getfilled (self, args)
223 portobject *self;
224 object *args;
225{
226 long count;
227
228 if (!getnoarg(args)) return NULL;
229
230 count = ALgetfilled (self-> ob_port);
231
232 return newintobject (count);
233}
234
235static object *
236al_getfillable (self, args)
237 portobject *self;
238 object *args;
239{
240 long count;
241
242 if (!getnoarg(args)) return NULL;
243
244 count = ALgetfillable (self-> ob_port);
245
246 return newintobject (count);
247}
248
249static object *
250al_readsamps (self, args)
251 portobject *self;
252 object *args;
253{
254 long count;
255 object *v;
Guido van Rossumb3a5b9b1991-09-10 14:54:05 +0000256 ALconfig c;
Guido van Rossume3db8621991-09-09 23:33:34 +0000257 int width;
258
259 if (!getlongarg (args, &count)) return NULL;
260
261 if (count <= 0)
262 {
263 err_setstr (RuntimeError, "al.readsamps : arg <= 0");
264 return NULL;
265 }
266
Guido van Rossumb3a5b9b1991-09-10 14:54:05 +0000267 c = ALgetconfig(self->ob_port);
268 width = ALgetwidth(c);
269 ALfreeconfig(c);
Guido van Rossume3db8621991-09-09 23:33:34 +0000270 v = newsizedstringobject ((char *)NULL, width * count);
271 if (v == NULL) return NULL;
272
273 ALreadsamps (self-> ob_port, (void *) getstringvalue(v), count);
274
275 return (v);
276}
277
278static object *
279al_writesamps (self, args)
280 portobject *self;
281 object *args;
282{
283 long count;
284 object *v;
Guido van Rossumb3a5b9b1991-09-10 14:54:05 +0000285 ALconfig c;
Guido van Rossume3db8621991-09-09 23:33:34 +0000286 int width;
287
288 if (!getstrarg (args, &v)) return NULL;
289
Guido van Rossumb3a5b9b1991-09-10 14:54:05 +0000290 c = ALgetconfig(self->ob_port);
291 width = ALgetwidth(c);
292 ALfreeconfig(c);
Guido van Rossume3db8621991-09-09 23:33:34 +0000293 ALwritesamps (self-> ob_port, (void *) getstringvalue(v),
294 getstringsize(v) / width);
295
296 INCREF (None);
297 return None;
298}
299
300static object *
301al_getfillpoint (self, args)
302 portobject *self;
303 object *args;
304{
305 long count;
306
307 if (!getnoarg(args)) return NULL;
308
309 count = ALgetfillpoint (self-> ob_port);
310
311 return newintobject (count);
312}
313
314static object *
315al_setfillpoint (self, args)
316 portobject *self;
317 object *args;
318{
319 long count;
320
321 if (!getlongarg(args, &count)) return NULL;
322
323 ALsetfillpoint (self-> ob_port, count);
324
325 INCREF (None);
326 return (None);
327}
328
329static object *
330al_setconfig (self, args)
331 portobject *self;
332 object *args;
333{
334 ALconfig config;
335
336 if (!getconfigarg(args, &config)) return NULL;
337
338 ALsetconfig (self-> ob_port, config);
339
340 INCREF (None);
341 return (None);
342}
343
344static object *
345al_getconfig (self, args)
346 portobject *self;
347 object *args;
348{
349 ALconfig config;
350
351 if (!getnoarg(args)) return NULL;
352
353 config = ALgetconfig (self-> ob_port);
354
355 return newconfigobject (config);
356}
357
358static struct methodlist port_methods[] = {
359 {"closeport", al_closeport},
360 {"getfd", al_getfd},
361 {"getfilled", al_getfilled},
362 {"getfillable", al_getfillable},
363 {"readsamps", al_readsamps},
364 {"writesamps", al_writesamps},
365 {"setfillpoint", al_setfillpoint},
366 {"getfillpoint", al_getfillpoint},
367 {"setconfig", al_setconfig},
368 {"getconfig", al_getconfig},
369 {NULL, NULL} /* sentinel */
370};
371
372static void
373port_dealloc(p)
374 portobject *p;
375{
376 if (p->ob_port != NULL)
377 ALcloseport(p->ob_port);
378 DEL(p);
379}
380
381static object *
382port_getattr(p, name)
383 portobject *p;
384 char *name;
385{
386 return findmethod(port_methods, (object *)p, name);
387}
388
389typeobject Porttype = {
390 OB_HEAD_INIT(&Typetype)
391 0, /*ob_size*/
392 "port", /*tp_name*/
393 sizeof(portobject), /*tp_size*/
394 0, /*tp_itemsize*/
395 /* methods */
396 port_dealloc, /*tp_dealloc*/
397 0, /*tp_print*/
398 port_getattr, /*tp_getattr*/
399 0, /*tp_setattr*/
400 0, /*tp_compare*/
401 0, /*tp_repr*/
402};
403
404static object *
405newportobject(port)
406 ALport port;
407{
408 portobject *p;
409
410 p = NEWOBJ(portobject, &Porttype);
411 if (p == NULL)
412 return NULL;
413 p->ob_port = port;
414 return (object *)p;
415}
416
417/* the module al */
418
419static object *
420al_openport (self, args)
421 object *self, *args;
422{
423 object *name, *dir;
424 ALport port;
425 ALconfig config = NULL;
426 int size = gettuplesize(args);
427
428 if (size == 2) {
429 if (!getstrstrarg (args, &name, &dir))
430 return NULL;
431 }
432 else if (size == 3) {
433 if (!getstrstrconfigarg (args, &name, &dir, &config))
434 return NULL;
435 }
436 else {
437 err_badarg();
438 return NULL;
439 }
440
441 port = ALopenport(getstringvalue(name), getstringvalue(dir), config);
442
443 return newportobject (port);
444}
445
446static object *
447al_newconfig (self, args)
448 object *self, *args;
449{
450 ALconfig config;
451
452 if (!getnoarg (args)) return NULL;
453
454 config = ALnewconfig ();
455
456 return newconfigobject (config);
457}
Guido van Rossumb3a5b9b1991-09-10 14:54:05 +0000458
459static object *
460al_queryparams(self, args)
461 object *self, *args;
462{
463 long device;
464 long length;
465 long *PVbuffer;
466 long PVdummy[2];
467 object *v;
468 object *w;
469
470 if (!getlongarg(args, &device))
471 return NULL;
472 length = ALqueryparams(device, PVdummy, 2L);
473 PVbuffer = NEW(long, length);
474 if (PVbuffer == NULL)
475 return err_nomem();
476 (void) ALqueryparams(device, PVbuffer, length);
477 v = newlistobject((int)length);
478 if (v != NULL) {
479 int i;
480 for (i = 0; i < length; i++)
481 setlistitem(v, i, newintobject(PVbuffer[i]));
482 }
483 DEL(PVbuffer);
484 return v;
485}
486
487static object *
488doParams(args, func, modified)
489 object *args;
490 void (*func)(long, long *, long);
491 int modified;
492{
493 long device;
494 object *list, *v;
495 long *PVbuffer;
496 long length;
497 int i;
Guido van Rossume3db8621991-09-09 23:33:34 +0000498
Guido van Rossumb3a5b9b1991-09-10 14:54:05 +0000499 if (!getlongobjectarg(args, &device, &list))
500 return NULL;
501 if (!is_listobject(list)) {
502 err_badarg();
503 return NULL;
504 }
505 length = getlistsize(list);
506 PVbuffer = NEW(long, length);
507 if (PVbuffer == NULL)
508 return err_nomem();
509 for (i = 0; i < length; i++) {
510 v = getlistitem(list, i);
511 if (!is_intobject(v)) {
512 DEL(PVbuffer);
513 err_badarg();
514 return NULL;
515 }
516 PVbuffer[i] = getintvalue(v);
517 }
518
519 ALgetparams(device, PVbuffer, length);
520
521 if (modified) {
522 for (i = 0; i < length; i++)
523 setlistitem(list, i, newintobject(PVbuffer[i]));
524 }
525
526 INCREF(None);
527 return None;
528}
529
530static object *
531al_getparams(self, args)
532 object *self, *args;
533{
534 return doParams(args, ALgetparams, 1);
535}
536
537static object *
538al_setparams(self, args)
539 object *self, *args;
540{
541 return doParams(args, ALsetparams, 0);
542}
543
Guido van Rossume3db8621991-09-09 23:33:34 +0000544static struct methodlist al_methods[] = {
545 {"openport", al_openport},
546 {"newconfig", al_newconfig},
Guido van Rossumb3a5b9b1991-09-10 14:54:05 +0000547 {"queryparams", al_queryparams},
548 {"getparams", al_getparams},
549 {"setparams", al_setparams},
Guido van Rossume3db8621991-09-09 23:33:34 +0000550 {NULL, NULL} /* sentinel */
551};
552
553void
554inital()
555{
556 initmodule("al", al_methods);
557}
558
559int
560getconfigarg (o, conf)
561 configobject *o;
562 ALconfig *conf;
563{
564 if (o == NULL || !is_configobject(o))
565 return err_badarg ();
566
567 *conf = o-> ob_config;
568
569 return 1;
570}
571
572int
573getstrstrconfigarg(v, a, b, c)
574 object *v;
575 object **a;
576 object **b;
577 ALconfig *c;
578{
579 if (v == NULL || !is_tupleobject(v) || gettuplesize(v) != 3) {
580 return err_badarg();
581 }
582
583 return getstrarg(gettupleitem(v, 0), a) &&
584 getstrarg(gettupleitem(v, 1), b) &&
585 getconfigarg (gettupleitem (v, 2), c);
586}