blob: 4abef277345bc17019e43badc7d8a8b2af064461 [file] [log] [blame]
Guido van Rossum16b8f301992-04-13 18:22:53 +00001/**********************************************************
Guido van Rossum524b5881995-01-04 19:10:35 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossum16b8f301992-04-13 18:22:53 +00004
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/* CD module -- interface to Mark Callow's and Roger Chickering's */
26 /* CD Audio Library (CD). */
27
28#include <sys/types.h>
29#include <cdaudio.h>
Sjoerd Mullender542659b1995-03-28 12:06:23 +000030/* #include <sigfpe.h> */
Guido van Rossum16b8f301992-04-13 18:22:53 +000031#include "allobjects.h"
32#include "import.h"
33#include "modsupport.h"
Guido van Rossum16b8f301992-04-13 18:22:53 +000034#include "ceval.h"
35
36#define NCALLBACKS 8
37
38typedef struct {
39 OB_HEAD
40 CDPLAYER *ob_cdplayer;
41} cdplayerobject;
42
Sjoerd Mullender46927ba1992-09-24 10:48:40 +000043static object *CdError; /* exception cd.error */
44
Guido van Rossum16b8f301992-04-13 18:22:53 +000045static object *
46CD_allowremoval(self, args)
47 cdplayerobject *self;
48 object *args;
49{
Sjoerd Mullender542659b1995-03-28 12:06:23 +000050 if (!newgetargs(args, ""))
Guido van Rossum16b8f301992-04-13 18:22:53 +000051 return NULL;
52
53 CDallowremoval(self->ob_cdplayer);
54
55 INCREF(None);
56 return None;
57}
58
59static object *
60CD_preventremoval(self, args)
61 cdplayerobject *self;
62 object *args;
63{
Sjoerd Mullender542659b1995-03-28 12:06:23 +000064 if (!newgetargs(args, ""))
Guido van Rossum16b8f301992-04-13 18:22:53 +000065 return NULL;
66
67 CDpreventremoval(self->ob_cdplayer);
68
69 INCREF(None);
70 return None;
71}
72
73static object *
Guido van Rossum16b8f301992-04-13 18:22:53 +000074CD_bestreadsize(self, args)
75 cdplayerobject *self;
76 object *args;
77{
Sjoerd Mullender542659b1995-03-28 12:06:23 +000078 if (!newgetargs(args, ""))
Guido van Rossum16b8f301992-04-13 18:22:53 +000079 return NULL;
80
81 return newintobject((long) CDbestreadsize(self->ob_cdplayer));
82}
83
84static object *
85CD_close(self, args)
86 cdplayerobject *self;
87 object *args;
88{
Sjoerd Mullender542659b1995-03-28 12:06:23 +000089 if (!newgetargs(args, ""))
Guido van Rossum16b8f301992-04-13 18:22:53 +000090 return NULL;
91
92 if (!CDclose(self->ob_cdplayer)) {
Sjoerd Mullender46927ba1992-09-24 10:48:40 +000093 err_errno(CdError); /* XXX - ??? */
Guido van Rossum16b8f301992-04-13 18:22:53 +000094 return NULL;
95 }
96 self->ob_cdplayer = NULL;
97
98 INCREF(None);
99 return None;
100}
101
102static object *
103CD_eject(self, args)
104 cdplayerobject *self;
105 object *args;
106{
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000107 CDSTATUS status;
108
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000109 if (!newgetargs(args, ""))
Guido van Rossum16b8f301992-04-13 18:22:53 +0000110 return NULL;
111
112 if (!CDeject(self->ob_cdplayer)) {
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000113 if (CDgetstatus(self->ob_cdplayer, &status) &&
114 status.state == CD_NODISC)
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000115 err_setstr(CdError, "no disc in player");
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000116 else
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000117 err_setstr(CdError, "eject failed");
Guido van Rossum16b8f301992-04-13 18:22:53 +0000118 return NULL;
119 }
120
121 INCREF(None);
122 return None;
123}
124
125static object *
126CD_getstatus(self, args)
127 cdplayerobject *self;
128 object *args;
129{
130 CDSTATUS status;
131
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000132 if (!newgetargs(args, ""))
Guido van Rossum16b8f301992-04-13 18:22:53 +0000133 return NULL;
134
135 if (!CDgetstatus(self->ob_cdplayer, &status)) {
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000136 err_errno(CdError); /* XXX - ??? */
Guido van Rossum16b8f301992-04-13 18:22:53 +0000137 return NULL;
138 }
139
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000140 return mkvalue("(ii(iii)(iii)(iii)iiii)", status.state,
Guido van Rossumece6efe1992-04-15 15:56:11 +0000141 status.track, status.min, status.sec, status.frame,
142 status.abs_min, status.abs_sec, status.abs_frame,
143 status.total_min, status.total_sec, status.total_frame,
144 status.first, status.last, status.scsi_audio,
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000145 status.cur_block);
Guido van Rossum16b8f301992-04-13 18:22:53 +0000146}
147
148static object *
149CD_gettrackinfo(self, args)
150 cdplayerobject *self;
151 object *args;
152{
153 int track;
154 CDTRACKINFO info;
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000155 CDSTATUS status;
Guido van Rossum16b8f301992-04-13 18:22:53 +0000156
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000157 if (!newgetargs(args, "i", &track))
Guido van Rossum16b8f301992-04-13 18:22:53 +0000158 return NULL;
159
160 if (!CDgettrackinfo(self->ob_cdplayer, track, &info)) {
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000161 if (CDgetstatus(self->ob_cdplayer, &status) &&
162 status.state == CD_NODISC)
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000163 err_setstr(CdError, "no disc in player");
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000164 else
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000165 err_setstr(CdError, "gettrackinfo failed");
Guido van Rossum16b8f301992-04-13 18:22:53 +0000166 return NULL;
167 }
168
Guido van Rossumece6efe1992-04-15 15:56:11 +0000169 return mkvalue("((iii)(iii))",
Guido van Rossum16b8f301992-04-13 18:22:53 +0000170 info.start_min, info.start_sec, info.start_frame,
171 info.total_min, info.total_sec, info.total_frame);
172}
173
174static object *
175CD_msftoblock(self, args)
176 cdplayerobject *self;
177 object *args;
178{
179 int min, sec, frame;
Guido van Rossum16b8f301992-04-13 18:22:53 +0000180
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000181 if (!newgetargs(args, "iii", &min, &sec, &frame))
Guido van Rossum16b8f301992-04-13 18:22:53 +0000182 return NULL;
183
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000184 return newintobject((long) CDmsftoblock(self->ob_cdplayer,
185 min, sec, frame));
Guido van Rossum16b8f301992-04-13 18:22:53 +0000186}
187
188static object *
189CD_play(self, args)
190 cdplayerobject *self;
191 object *args;
192{
193 int start, play;
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000194 CDSTATUS status;
Guido van Rossum16b8f301992-04-13 18:22:53 +0000195
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000196 if (!newgetargs(args, "ii", &start, &play))
Guido van Rossum16b8f301992-04-13 18:22:53 +0000197 return NULL;
198
199 if (!CDplay(self->ob_cdplayer, start, play)) {
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000200 if (CDgetstatus(self->ob_cdplayer, &status) &&
201 status.state == CD_NODISC)
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000202 err_setstr(CdError, "no disc in player");
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000203 else
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000204 err_setstr(CdError, "play failed");
Guido van Rossum16b8f301992-04-13 18:22:53 +0000205 return NULL;
206 }
207
208 INCREF(None);
209 return None;
210}
211
212static object *
213CD_playabs(self, args)
214 cdplayerobject *self;
215 object *args;
216{
217 int min, sec, frame, play;
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000218 CDSTATUS status;
Guido van Rossum16b8f301992-04-13 18:22:53 +0000219
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000220 if (!newgetargs(args, "iiii", &min, &sec, &frame, &play))
Guido van Rossum16b8f301992-04-13 18:22:53 +0000221 return NULL;
222
223 if (!CDplayabs(self->ob_cdplayer, min, sec, frame, play)) {
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000224 if (CDgetstatus(self->ob_cdplayer, &status) &&
225 status.state == CD_NODISC)
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000226 err_setstr(CdError, "no disc in player");
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000227 else
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000228 err_setstr(CdError, "playabs failed");
Guido van Rossum16b8f301992-04-13 18:22:53 +0000229 return NULL;
230 }
231
232 INCREF(None);
233 return None;
234}
235
236static object *
237CD_playtrack(self, args)
238 cdplayerobject *self;
239 object *args;
240{
241 int start, play;
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000242 CDSTATUS status;
Guido van Rossum16b8f301992-04-13 18:22:53 +0000243
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000244 if (!newgetargs(args, "ii", &start, &play))
Guido van Rossum16b8f301992-04-13 18:22:53 +0000245 return NULL;
246
247 if (!CDplaytrack(self->ob_cdplayer, start, play)) {
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000248 if (CDgetstatus(self->ob_cdplayer, &status) &&
249 status.state == CD_NODISC)
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000250 err_setstr(CdError, "no disc in player");
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000251 else
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000252 err_setstr(CdError, "playtrack failed");
Guido van Rossum16b8f301992-04-13 18:22:53 +0000253 return NULL;
254 }
255
256 INCREF(None);
257 return None;
258}
259
260static object *
261CD_playtrackabs(self, args)
262 cdplayerobject *self;
263 object *args;
264{
265 int track, min, sec, frame, play;
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000266 CDSTATUS status;
Guido van Rossum16b8f301992-04-13 18:22:53 +0000267
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000268 if (!newgetargs(args, "iiiii", &track, &min, &sec, &frame, &play))
Guido van Rossum16b8f301992-04-13 18:22:53 +0000269 return NULL;
270
271 if (!CDplaytrackabs(self->ob_cdplayer, track, min, sec, frame, play)) {
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000272 if (CDgetstatus(self->ob_cdplayer, &status) &&
273 status.state == CD_NODISC)
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000274 err_setstr(CdError, "no disc in player");
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000275 else
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000276 err_setstr(CdError, "playtrackabs failed");
Guido van Rossum16b8f301992-04-13 18:22:53 +0000277 return NULL;
278 }
279
280 INCREF(None);
281 return None;
282}
283
284static object *
285CD_readda(self, args)
286 cdplayerobject *self;
287 object *args;
288{
289 int numframes, n;
290 object *result;
291
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000292 if (!newgetargs(args, "i", &numframes))
Guido van Rossum16b8f301992-04-13 18:22:53 +0000293 return NULL;
294
295 result = newsizedstringobject(NULL, numframes * sizeof(CDFRAME));
296 if (result == NULL)
297 return NULL;
298
299 n = CDreadda(self->ob_cdplayer, (CDFRAME *) getstringvalue(result), numframes);
300 if (n == -1) {
301 DECREF(result);
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000302 err_errno(CdError);
Guido van Rossum16b8f301992-04-13 18:22:53 +0000303 return NULL;
304 }
305 if (n < numframes)
306 if (resizestring(&result, n * sizeof(CDFRAME)))
307 return NULL;
308
309 return result;
310}
311
312static object *
313CD_seek(self, args)
314 cdplayerobject *self;
315 object *args;
316{
317 int min, sec, frame;
318 long block;
319
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000320 if (!newgetargs(args, "iii", &min, &sec, &frame))
Guido van Rossum16b8f301992-04-13 18:22:53 +0000321 return NULL;
322
323 block = CDseek(self->ob_cdplayer, min, sec, frame);
324 if (block == -1) {
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000325 err_errno(CdError);
Guido van Rossum16b8f301992-04-13 18:22:53 +0000326 return NULL;
327 }
328
329 return newintobject(block);
330}
331
332static object *
333CD_seektrack(self, args)
334 cdplayerobject *self;
335 object *args;
336{
337 int track;
338 long block;
339
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000340 if (!newgetargs(args, "i", &track))
Guido van Rossum16b8f301992-04-13 18:22:53 +0000341 return NULL;
342
343 block = CDseektrack(self->ob_cdplayer, track);
344 if (block == -1) {
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000345 err_errno(CdError);
Guido van Rossum16b8f301992-04-13 18:22:53 +0000346 return NULL;
347 }
348
349 return newintobject(block);
350}
351
352static object *
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000353CD_seekblock(self, args)
354 cdplayerobject *self;
355 object *args;
356{
357 unsigned long block;
358
359 if (!newgetargs(args, "l", &block))
360 return NULL;
361
362 block = CDseekblock(self->ob_cdplayer, block);
363 if (block == (unsigned long) -1) {
364 err_errno(CdError);
365 return NULL;
366 }
367
368 return newintobject(block);
369}
370
371static object *
Guido van Rossum16b8f301992-04-13 18:22:53 +0000372CD_stop(self, args)
373 cdplayerobject *self;
374 object *args;
375{
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000376 CDSTATUS status;
377
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000378 if (!newgetargs(args, ""))
Guido van Rossum16b8f301992-04-13 18:22:53 +0000379 return NULL;
380
381 if (!CDstop(self->ob_cdplayer)) {
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000382 if (CDgetstatus(self->ob_cdplayer, &status) &&
383 status.state == CD_NODISC)
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000384 err_setstr(CdError, "no disc in player");
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000385 else
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000386 err_setstr(CdError, "stop failed");
Guido van Rossum16b8f301992-04-13 18:22:53 +0000387 return NULL;
388 }
389
390 INCREF(None);
391 return None;
392}
393
394static object *
395CD_togglepause(self, args)
396 cdplayerobject *self;
397 object *args;
398{
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000399 CDSTATUS status;
400
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000401 if (!newgetargs(args, ""))
Guido van Rossum16b8f301992-04-13 18:22:53 +0000402 return NULL;
403
404 if (!CDtogglepause(self->ob_cdplayer)) {
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000405 if (CDgetstatus(self->ob_cdplayer, &status) &&
406 status.state == CD_NODISC)
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000407 err_setstr(CdError, "no disc in player");
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000408 else
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000409 err_setstr(CdError, "togglepause failed");
Guido van Rossum16b8f301992-04-13 18:22:53 +0000410 return NULL;
411 }
412
413 INCREF(None);
414 return None;
415}
416
417static struct methodlist cdplayer_methods[] = {
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000418 {"allowremoval", (method)CD_allowremoval, 1},
419 {"bestreadsize", (method)CD_bestreadsize, 1},
420 {"close", (method)CD_close, 1},
421 {"eject", (method)CD_eject, 1},
422 {"getstatus", (method)CD_getstatus, 1},
423 {"gettrackinfo", (method)CD_gettrackinfo, 1},
424 {"msftoblock", (method)CD_msftoblock, 1},
425 {"play", (method)CD_play, 1},
426 {"playabs", (method)CD_playabs, 1},
427 {"playtrack", (method)CD_playtrack, 1},
428 {"playtrackabs", (method)CD_playtrackabs, 1},
429 {"preventremoval", (method)CD_preventremoval, 1},
430 {"readda", (method)CD_readda, 1},
431 {"seek", (method)CD_seek, 1},
432 {"seekblock", (method)CD_seekblock, 1},
433 {"seektrack", (method)CD_seektrack, 1},
434 {"stop", (method)CD_stop, 1},
435 {"togglepause", (method)CD_togglepause, 1},
Guido van Rossum16b8f301992-04-13 18:22:53 +0000436 {NULL, NULL} /* sentinel */
437};
438
439static void
440cdplayer_dealloc(self)
441 cdplayerobject *self;
442{
443 if (self->ob_cdplayer != NULL)
444 CDclose(self->ob_cdplayer);
445 DEL(self);
446}
447
448static object *
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000449cdplayer_getattr(self, name)
450 cdplayerobject *self;
Guido van Rossum16b8f301992-04-13 18:22:53 +0000451 char *name;
452{
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000453 if (self->ob_cdplayer == NULL) {
454 err_setstr(RuntimeError, "no player active");
455 return NULL;
456 }
457 return findmethod(cdplayer_methods, (object *)self, name);
Guido van Rossum16b8f301992-04-13 18:22:53 +0000458}
459
460typeobject CdPlayertype = {
461 OB_HEAD_INIT(&Typetype)
462 0, /*ob_size*/
463 "cdplayer", /*tp_name*/
464 sizeof(cdplayerobject), /*tp_size*/
465 0, /*tp_itemsize*/
466 /* methods */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000467 (destructor)cdplayer_dealloc, /*tp_dealloc*/
Guido van Rossum16b8f301992-04-13 18:22:53 +0000468 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000469 (getattrfunc)cdplayer_getattr, /*tp_getattr*/
Guido van Rossum16b8f301992-04-13 18:22:53 +0000470 0, /*tp_setattr*/
471 0, /*tp_compare*/
472 0, /*tp_repr*/
473};
474
475static object *
476newcdplayerobject(cdp)
477 CDPLAYER *cdp;
478{
479 cdplayerobject *p;
480
481 p = NEWOBJ(cdplayerobject, &CdPlayertype);
482 if (p == NULL)
483 return NULL;
484 p->ob_cdplayer = cdp;
485 return (object *) p;
486}
487
488static object *
489CD_open(self, args)
490 object *self, *args;
491{
492 char *dev, *direction;
493 CDPLAYER *cdp;
494
495 /*
496 * Variable number of args.
497 * First defaults to "None", second defaults to "r".
498 */
499 dev = NULL;
500 direction = "r";
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000501 if (!newgetargs(args, "|zs", &dev, &direction))
502 return NULL;
Guido van Rossum16b8f301992-04-13 18:22:53 +0000503
504 cdp = CDopen(dev, direction);
505 if (cdp == NULL) {
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000506 err_errno(CdError);
Guido van Rossum16b8f301992-04-13 18:22:53 +0000507 return NULL;
508 }
509
510 return newcdplayerobject(cdp);
511}
512
513typedef struct {
514 OB_HEAD
515 CDPARSER *ob_cdparser;
516 struct {
517 object *ob_cdcallback;
518 object *ob_cdcallbackarg;
519 } ob_cdcallbacks[NCALLBACKS];
520} cdparserobject;
521
522static void
523CD_callback(arg, type, data)
524 void *arg;
525 CDDATATYPES type;
526 void *data;
527{
528 object *result, *args, *v;
529 char *p;
530 int i;
531 cdparserobject *self;
532
533 self = (cdparserobject *) arg;
534 args = newtupleobject(3);
535 if (args == NULL)
536 return;
537 INCREF(self->ob_cdcallbacks[type].ob_cdcallbackarg);
538 settupleitem(args, 0, self->ob_cdcallbacks[type].ob_cdcallbackarg);
539 settupleitem(args, 1, newintobject((long) type));
540 switch (type) {
541 case cd_audio:
542 v = newsizedstringobject(data, CDDA_DATASIZE);
543 break;
544 case cd_pnum:
545 case cd_index:
546 v = newintobject(((CDPROGNUM *) data)->value);
547 break;
548 case cd_ptime:
549 case cd_atime:
Guido van Rossumece6efe1992-04-15 15:56:11 +0000550#define ptr ((struct cdtimecode *) data)
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000551 v = mkvalue("(iii)",
552 ptr->mhi * 10 + ptr->mlo,
Guido van Rossumece6efe1992-04-15 15:56:11 +0000553 ptr->shi * 10 + ptr->slo,
554 ptr->fhi * 10 + ptr->flo);
555#undef ptr
Guido van Rossum16b8f301992-04-13 18:22:53 +0000556 break;
557 case cd_catalog:
558 v = newsizedstringobject(NULL, 13);
559 p = getstringvalue(v);
560 for (i = 0; i < 13; i++)
561 *p++ = ((char *) data)[i] + '0';
562 break;
563 case cd_ident:
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000564#define ptr ((struct cdident *) data)
Guido van Rossum16b8f301992-04-13 18:22:53 +0000565 v = newsizedstringobject(NULL, 12);
566 p = getstringvalue(v);
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000567 CDsbtoa(p, ptr->country, 2);
Guido van Rossum16b8f301992-04-13 18:22:53 +0000568 p += 2;
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000569 CDsbtoa(p, ptr->owner, 3);
Guido van Rossum16b8f301992-04-13 18:22:53 +0000570 p += 3;
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000571 *p++ = ptr->year[0] + '0';
572 *p++ = ptr->year[1] + '0';
573 *p++ = ptr->serial[0] + '0';
574 *p++ = ptr->serial[1] + '0';
575 *p++ = ptr->serial[2] + '0';
576 *p++ = ptr->serial[3] + '0';
577 *p++ = ptr->serial[4] + '0';
578#undef ptr
Guido van Rossum16b8f301992-04-13 18:22:53 +0000579 break;
580 case cd_control:
581 v = newintobject((long) *((unchar *) data));
582 break;
583 }
584 settupleitem(args, 2, v);
585 if (err_occurred()) {
586 DECREF(args);
587 return;
588 }
589
590 result = call_object(self->ob_cdcallbacks[type].ob_cdcallback, args);
591 DECREF(args);
592 XDECREF(result);
593}
594
595static object *
596CD_deleteparser(self, args)
597 cdparserobject *self;
598 object *args;
599{
600 int i;
601
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000602 if (!newgetargs(args, ""))
Guido van Rossum16b8f301992-04-13 18:22:53 +0000603 return NULL;
604
605 CDdeleteparser(self->ob_cdparser);
606 self->ob_cdparser = NULL;
607
608 /* no sense in keeping the callbacks, so remove them */
609 for (i = 0; i < NCALLBACKS; i++) {
610 XDECREF(self->ob_cdcallbacks[i].ob_cdcallback);
611 self->ob_cdcallbacks[i].ob_cdcallback = NULL;
612 XDECREF(self->ob_cdcallbacks[i].ob_cdcallbackarg);
613 self->ob_cdcallbacks[i].ob_cdcallbackarg = NULL;
614 }
615
616 INCREF(None);
617 return None;
618}
619
620static object *
621CD_parseframe(self, args)
622 cdparserobject *self;
623 object *args;
624{
625 char *cdfp;
626 int length;
627 CDFRAME *p;
628
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000629 if (!newgetargs(args, "s#", &cdfp, &length))
Guido van Rossum16b8f301992-04-13 18:22:53 +0000630 return NULL;
631
632 if (length % sizeof(CDFRAME) != 0) {
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000633 err_setstr(TypeError, "bad length");
Guido van Rossum16b8f301992-04-13 18:22:53 +0000634 return NULL;
635 }
636
637 p = (CDFRAME *) cdfp;
638 while (length > 0) {
639 CDparseframe(self->ob_cdparser, p);
640 length -= sizeof(CDFRAME);
641 p++;
642 if (err_occurred())
643 return NULL;
644 }
645
646 INCREF(None);
647 return None;
648}
649
650static object *
651CD_removecallback(self, args)
652 cdparserobject *self;
653 object *args;
654{
655 int type;
656
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000657 if (!newgetargs(args, "i", &type))
Guido van Rossum16b8f301992-04-13 18:22:53 +0000658 return NULL;
659
Guido van Rossumf16eda51992-08-03 19:06:59 +0000660 if (type < 0 || type >= NCALLBACKS) {
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000661 err_setstr(TypeError, "bad type");
Guido van Rossumf16eda51992-08-03 19:06:59 +0000662 return NULL;
663 }
664
Guido van Rossum16b8f301992-04-13 18:22:53 +0000665 CDremovecallback(self->ob_cdparser, (CDDATATYPES) type);
666
667 XDECREF(self->ob_cdcallbacks[type].ob_cdcallback);
668 self->ob_cdcallbacks[type].ob_cdcallback = NULL;
669
670 XDECREF(self->ob_cdcallbacks[type].ob_cdcallbackarg);
671 self->ob_cdcallbacks[type].ob_cdcallbackarg = NULL;
672
673 INCREF(None);
674 return None;
675}
676
677static object *
678CD_resetparser(self, args)
679 cdparserobject *self;
680 object *args;
681{
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000682 if (!newgetargs(args, ""))
Guido van Rossum16b8f301992-04-13 18:22:53 +0000683 return NULL;
684
685 CDresetparser(self->ob_cdparser);
686
687 INCREF(None);
688 return None;
689}
690
691static object *
Guido van Rossumf16eda51992-08-03 19:06:59 +0000692CD_addcallback(self, args)
Guido van Rossum16b8f301992-04-13 18:22:53 +0000693 cdparserobject *self;
694 object *args;
695{
696 int type;
Guido van Rossum234f9421993-06-17 12:35:49 +0000697 object *func, *funcarg;
Guido van Rossum16b8f301992-04-13 18:22:53 +0000698
Guido van Rossum16b8f301992-04-13 18:22:53 +0000699 /* XXX - more work here */
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000700 if (!newgetargs(args, "iOO", &type, &func, &funcarg))
Guido van Rossum16b8f301992-04-13 18:22:53 +0000701 return NULL;
702
703 if (type < 0 || type >= NCALLBACKS) {
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000704 err_setstr(TypeError, "argument out of range");
Guido van Rossum16b8f301992-04-13 18:22:53 +0000705 return NULL;
706 }
707
Sjoerd Mullender7c4eb401992-09-25 11:15:58 +0000708#ifdef CDsetcallback
Guido van Rossumf16eda51992-08-03 19:06:59 +0000709 CDaddcallback(self->ob_cdparser, (CDDATATYPES) type, CD_callback, (void *) self);
710#else
Guido van Rossum16b8f301992-04-13 18:22:53 +0000711 CDsetcallback(self->ob_cdparser, (CDDATATYPES) type, CD_callback, (void *) self);
Guido van Rossumf16eda51992-08-03 19:06:59 +0000712#endif
Guido van Rossum16b8f301992-04-13 18:22:53 +0000713 XDECREF(self->ob_cdcallbacks[type].ob_cdcallback);
Guido van Rossum234f9421993-06-17 12:35:49 +0000714 INCREF(func);
715 self->ob_cdcallbacks[type].ob_cdcallback = func;
Guido van Rossum16b8f301992-04-13 18:22:53 +0000716 XDECREF(self->ob_cdcallbacks[type].ob_cdcallbackarg);
Guido van Rossum234f9421993-06-17 12:35:49 +0000717 INCREF(funcarg);
718 self->ob_cdcallbacks[type].ob_cdcallbackarg = funcarg;
Guido van Rossum16b8f301992-04-13 18:22:53 +0000719
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000720/*
721 if (type == cd_audio) {
722 sigfpe_[_UNDERFL].repls = _ZERO;
723 handle_sigfpes(_ON, _EN_UNDERFL, NULL, _ABORT_ON_ERROR, NULL);
724 }
725*/
726
Guido van Rossum16b8f301992-04-13 18:22:53 +0000727 INCREF(None);
728 return None;
729}
730
731static struct methodlist cdparser_methods[] = {
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000732 {"addcallback", (method)CD_addcallback, 1},
733 {"deleteparser", (method)CD_deleteparser, 1},
734 {"parseframe", (method)CD_parseframe, 1},
735 {"removecallback", (method)CD_removecallback, 1},
736 {"resetparser", (method)CD_resetparser, 1},
737 {"setcallback", (method)CD_addcallback, 1}, /* backward compatibility */
Guido van Rossum16b8f301992-04-13 18:22:53 +0000738 {NULL, NULL} /* sentinel */
739};
740
741static void
742cdparser_dealloc(self)
743 cdparserobject *self;
744{
745 int i;
746
747 for (i = 0; i < NCALLBACKS; i++) {
748 XDECREF(self->ob_cdcallbacks[i].ob_cdcallback);
749 self->ob_cdcallbacks[i].ob_cdcallback = NULL;
750 XDECREF(self->ob_cdcallbacks[i].ob_cdcallbackarg);
751 self->ob_cdcallbacks[i].ob_cdcallbackarg = NULL;
752 }
753 CDdeleteparser(self->ob_cdparser);
754 DEL(self);
755}
756
757static object *
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000758cdparser_getattr(self, name)
759 cdparserobject *self;
Guido van Rossum16b8f301992-04-13 18:22:53 +0000760 char *name;
761{
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000762 if (self->ob_cdparser == NULL) {
763 err_setstr(RuntimeError, "no parser active");
764 return NULL;
765 }
766
767 return findmethod(cdparser_methods, (object *)self, name);
Guido van Rossum16b8f301992-04-13 18:22:53 +0000768}
769
770typeobject CdParsertype = {
771 OB_HEAD_INIT(&Typetype)
772 0, /*ob_size*/
773 "cdparser", /*tp_name*/
774 sizeof(cdparserobject), /*tp_size*/
775 0, /*tp_itemsize*/
776 /* methods */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000777 (destructor)cdparser_dealloc, /*tp_dealloc*/
Guido van Rossum16b8f301992-04-13 18:22:53 +0000778 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000779 (getattrfunc)cdparser_getattr, /*tp_getattr*/
Guido van Rossum16b8f301992-04-13 18:22:53 +0000780 0, /*tp_setattr*/
781 0, /*tp_compare*/
782 0, /*tp_repr*/
783};
784
785static object *
786newcdparserobject(cdp)
787 CDPARSER *cdp;
788{
789 cdparserobject *p;
790 int i;
791
792 p = NEWOBJ(cdparserobject, &CdParsertype);
793 if (p == NULL)
794 return NULL;
795 p->ob_cdparser = cdp;
796 for (i = 0; i < NCALLBACKS; i++) {
797 p->ob_cdcallbacks[i].ob_cdcallback = NULL;
798 p->ob_cdcallbacks[i].ob_cdcallbackarg = NULL;
799 }
800 return (object *) p;
801}
802
803static object *
804CD_createparser(self, args)
805 object *self, *args;
806{
807 CDPARSER *cdp;
808
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000809 if (!newgetargs(args, ""))
Guido van Rossum16b8f301992-04-13 18:22:53 +0000810 return NULL;
811 cdp = CDcreateparser();
812 if (cdp == NULL) {
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000813 err_setstr(CdError, "createparser failed");
Guido van Rossum16b8f301992-04-13 18:22:53 +0000814 return NULL;
815 }
816
817 return newcdparserobject(cdp);
818}
819
820static object *
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000821CD_msftoframe(self, args)
822 object *self, *args;
Guido van Rossum16b8f301992-04-13 18:22:53 +0000823{
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000824 int min, sec, frame;
Guido van Rossum16b8f301992-04-13 18:22:53 +0000825
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000826 if (!newgetargs(args, "iii", &min, &sec, &frame))
Guido van Rossum16b8f301992-04-13 18:22:53 +0000827 return NULL;
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000828
829 return newintobject((long) CDmsftoframe(min, sec, frame));
Guido van Rossum16b8f301992-04-13 18:22:53 +0000830}
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000831
Guido van Rossum16b8f301992-04-13 18:22:53 +0000832static struct methodlist CD_methods[] = {
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000833 {"open", (method)CD_open, 1},
834 {"createparser", (method)CD_createparser, 1},
835 {"msftoframe", (method)CD_msftoframe, 1},
Guido van Rossum16b8f301992-04-13 18:22:53 +0000836 {NULL, NULL} /* Sentinel */
837};
838
839void
840initcd()
841{
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000842 object *m, *d;
843
844 m = initmodule("cd", CD_methods);
845 d = getmoduledict(m);
846
847 CdError = newstringobject("cd.error");
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000848 dictinsert(d, "error", CdError);
849
850 /* Identifiers for the different types of callbacks from the parser */
851 dictinsert(d, "audio", newintobject((long) cd_audio));
852 dictinsert(d, "pnum", newintobject((long) cd_pnum));
853 dictinsert(d, "index", newintobject((long) cd_index));
854 dictinsert(d, "ptime", newintobject((long) cd_ptime));
855 dictinsert(d, "atime", newintobject((long) cd_atime));
856 dictinsert(d, "catalog", newintobject((long) cd_catalog));
857 dictinsert(d, "ident", newintobject((long) cd_ident));
858 dictinsert(d, "control", newintobject((long) cd_control));
859
860 /* Block size information for digital audio data */
861 dictinsert(d, "DATASIZE", newintobject((long) CDDA_DATASIZE));
862 dictinsert(d, "BLOCKSIZE", newintobject((long) CDDA_BLOCKSIZE));
863
864 /* Possible states for the cd player */
865 dictinsert(d, "ERROR", newintobject((long) CD_ERROR));
866 dictinsert(d, "NODISC", newintobject((long) CD_NODISC));
867 dictinsert(d, "READY", newintobject((long) CD_READY));
868 dictinsert(d, "PLAYING", newintobject((long) CD_PLAYING));
869 dictinsert(d, "PAUSED", newintobject((long) CD_PAUSED));
870 dictinsert(d, "STILL", newintobject((long) CD_STILL));
871#ifdef CD_CDROM /* only newer versions of the library */
872 dictinsert(d, "CDROM", newintobject((long) CD_CDROM));
873#endif
874
875 if (err_occurred())
876 fatal("can't initialize module cd");
Guido van Rossum16b8f301992-04-13 18:22:53 +0000877}