blob: 806ad75e630d33769732a4c282ebb366bc4e6f81 [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;
Guido van Rossumc0aab891991-10-20 20:10:46 +0000426 int size;
Guido van Rossume3db8621991-09-09 23:33:34 +0000427
Guido van Rossumc0aab891991-10-20 20:10:46 +0000428 if (args == NULL || !is_tupleobject(args)) {
429 err_badarg();
430 return NULL;
431 }
432 size = gettuplesize(args);
Guido van Rossume3db8621991-09-09 23:33:34 +0000433 if (size == 2) {
434 if (!getstrstrarg (args, &name, &dir))
435 return NULL;
436 }
437 else if (size == 3) {
438 if (!getstrstrconfigarg (args, &name, &dir, &config))
439 return NULL;
440 }
441 else {
442 err_badarg();
443 return NULL;
444 }
445
446 port = ALopenport(getstringvalue(name), getstringvalue(dir), config);
447
Guido van Rossumc0aab891991-10-20 20:10:46 +0000448 if (port == NULL) {
449 err_errno(RuntimeError);
450 return NULL;
451 }
452
Guido van Rossume3db8621991-09-09 23:33:34 +0000453 return newportobject (port);
454}
455
456static object *
457al_newconfig (self, args)
458 object *self, *args;
459{
460 ALconfig config;
461
462 if (!getnoarg (args)) return NULL;
463
464 config = ALnewconfig ();
Guido van Rossumc0aab891991-10-20 20:10:46 +0000465 if (config == NULL) {
466 err_errno(RuntimeError);
467 return NULL;
468 }
Guido van Rossume3db8621991-09-09 23:33:34 +0000469
470 return newconfigobject (config);
471}
Guido van Rossumb3a5b9b1991-09-10 14:54:05 +0000472
473static object *
474al_queryparams(self, args)
475 object *self, *args;
476{
477 long device;
478 long length;
479 long *PVbuffer;
480 long PVdummy[2];
481 object *v;
482 object *w;
483
484 if (!getlongarg(args, &device))
485 return NULL;
486 length = ALqueryparams(device, PVdummy, 2L);
487 PVbuffer = NEW(long, length);
488 if (PVbuffer == NULL)
489 return err_nomem();
490 (void) ALqueryparams(device, PVbuffer, length);
491 v = newlistobject((int)length);
492 if (v != NULL) {
493 int i;
494 for (i = 0; i < length; i++)
495 setlistitem(v, i, newintobject(PVbuffer[i]));
496 }
497 DEL(PVbuffer);
498 return v;
499}
500
501static object *
502doParams(args, func, modified)
503 object *args;
504 void (*func)(long, long *, long);
505 int modified;
506{
507 long device;
508 object *list, *v;
509 long *PVbuffer;
510 long length;
511 int i;
Guido van Rossume3db8621991-09-09 23:33:34 +0000512
Guido van Rossumb3a5b9b1991-09-10 14:54:05 +0000513 if (!getlongobjectarg(args, &device, &list))
514 return NULL;
515 if (!is_listobject(list)) {
516 err_badarg();
517 return NULL;
518 }
519 length = getlistsize(list);
520 PVbuffer = NEW(long, length);
521 if (PVbuffer == NULL)
522 return err_nomem();
523 for (i = 0; i < length; i++) {
524 v = getlistitem(list, i);
525 if (!is_intobject(v)) {
526 DEL(PVbuffer);
527 err_badarg();
528 return NULL;
529 }
530 PVbuffer[i] = getintvalue(v);
531 }
532
Guido van Rossum8db03071991-09-13 15:31:47 +0000533 (*func)(device, PVbuffer, length);
Guido van Rossumb3a5b9b1991-09-10 14:54:05 +0000534
535 if (modified) {
536 for (i = 0; i < length; i++)
537 setlistitem(list, i, newintobject(PVbuffer[i]));
538 }
539
Guido van Rossumc0aab891991-10-20 20:10:46 +0000540 DEL(PVbuffer);
541
Guido van Rossumb3a5b9b1991-09-10 14:54:05 +0000542 INCREF(None);
543 return None;
544}
545
546static object *
547al_getparams(self, args)
548 object *self, *args;
549{
550 return doParams(args, ALgetparams, 1);
551}
552
553static object *
554al_setparams(self, args)
555 object *self, *args;
556{
557 return doParams(args, ALsetparams, 0);
558}
559
Guido van Rossume3db8621991-09-09 23:33:34 +0000560static struct methodlist al_methods[] = {
561 {"openport", al_openport},
562 {"newconfig", al_newconfig},
Guido van Rossumb3a5b9b1991-09-10 14:54:05 +0000563 {"queryparams", al_queryparams},
564 {"getparams", al_getparams},
565 {"setparams", al_setparams},
Guido van Rossume3db8621991-09-09 23:33:34 +0000566 {NULL, NULL} /* sentinel */
567};
568
569void
570inital()
571{
572 initmodule("al", al_methods);
573}
574
575int
576getconfigarg (o, conf)
577 configobject *o;
578 ALconfig *conf;
579{
580 if (o == NULL || !is_configobject(o))
581 return err_badarg ();
582
583 *conf = o-> ob_config;
584
585 return 1;
586}
587
588int
589getstrstrconfigarg(v, a, b, c)
590 object *v;
591 object **a;
592 object **b;
593 ALconfig *c;
594{
595 if (v == NULL || !is_tupleobject(v) || gettuplesize(v) != 3) {
596 return err_badarg();
597 }
598
599 return getstrarg(gettupleitem(v, 0), a) &&
600 getstrarg(gettupleitem(v, 1), b) &&
601 getconfigarg (gettupleitem (v, 2), c);
602}