This commit was manufactured by cvs2svn to create tag 'r22a4-fork'.
[python/dscho.git] / Modules / cdmodule.c
blobee58c5efbd38fb60dec317e7e04a424784493cb7
1 /* CD module -- interface to Mark Callow's and Roger Chickering's */
2 /* CD Audio Library (CD). */
4 #include <sys/types.h>
5 #include <cdaudio.h>
6 #include "Python.h"
8 #define NCALLBACKS 8
10 typedef struct {
11 PyObject_HEAD
12 CDPLAYER *ob_cdplayer;
13 } cdplayerobject;
15 static PyObject *CdError; /* exception cd.error */
17 static PyObject *
18 CD_allowremoval(cdplayerobject *self, PyObject *args)
20 if (!PyArg_ParseTuple(args, ":allowremoval"))
21 return NULL;
23 CDallowremoval(self->ob_cdplayer);
25 Py_INCREF(Py_None);
26 return Py_None;
29 static PyObject *
30 CD_preventremoval(cdplayerobject *self, PyObject *args)
32 if (!PyArg_ParseTuple(args, ":preventremoval"))
33 return NULL;
35 CDpreventremoval(self->ob_cdplayer);
37 Py_INCREF(Py_None);
38 return Py_None;
41 static PyObject *
42 CD_bestreadsize(cdplayerobject *self, PyObject *args)
44 if (!PyArg_ParseTuple(args, ":bestreadsize"))
45 return NULL;
47 return PyInt_FromLong((long) CDbestreadsize(self->ob_cdplayer));
50 static PyObject *
51 CD_close(cdplayerobject *self, PyObject *args)
53 if (!PyArg_ParseTuple(args, ":close"))
54 return NULL;
56 if (!CDclose(self->ob_cdplayer)) {
57 PyErr_SetFromErrno(CdError); /* XXX - ??? */
58 return NULL;
60 self->ob_cdplayer = NULL;
62 Py_INCREF(Py_None);
63 return Py_None;
66 static PyObject *
67 CD_eject(cdplayerobject *self, PyObject *args)
69 CDSTATUS status;
71 if (!PyArg_ParseTuple(args, ":eject"))
72 return NULL;
74 if (!CDeject(self->ob_cdplayer)) {
75 if (CDgetstatus(self->ob_cdplayer, &status) &&
76 status.state == CD_NODISC)
77 PyErr_SetString(CdError, "no disc in player");
78 else
79 PyErr_SetString(CdError, "eject failed");
80 return NULL;
83 Py_INCREF(Py_None);
84 return Py_None;
87 static PyObject *
88 CD_getstatus(cdplayerobject *self, PyObject *args)
90 CDSTATUS status;
92 if (!PyArg_ParseTuple(args, ":getstatus"))
93 return NULL;
95 if (!CDgetstatus(self->ob_cdplayer, &status)) {
96 PyErr_SetFromErrno(CdError); /* XXX - ??? */
97 return NULL;
100 return Py_BuildValue("(ii(iii)(iii)(iii)iiii)", status.state,
101 status.track, status.min, status.sec, status.frame,
102 status.abs_min, status.abs_sec, status.abs_frame,
103 status.total_min, status.total_sec, status.total_frame,
104 status.first, status.last, status.scsi_audio,
105 status.cur_block);
108 static PyObject *
109 CD_gettrackinfo(cdplayerobject *self, PyObject *args)
111 int track;
112 CDTRACKINFO info;
113 CDSTATUS status;
115 if (!PyArg_ParseTuple(args, "i:gettrackinfo", &track))
116 return NULL;
118 if (!CDgettrackinfo(self->ob_cdplayer, track, &info)) {
119 if (CDgetstatus(self->ob_cdplayer, &status) &&
120 status.state == CD_NODISC)
121 PyErr_SetString(CdError, "no disc in player");
122 else
123 PyErr_SetString(CdError, "gettrackinfo failed");
124 return NULL;
127 return Py_BuildValue("((iii)(iii))",
128 info.start_min, info.start_sec, info.start_frame,
129 info.total_min, info.total_sec, info.total_frame);
132 static PyObject *
133 CD_msftoblock(cdplayerobject *self, PyObject *args)
135 int min, sec, frame;
137 if (!PyArg_ParseTuple(args, "iii:msftoblock", &min, &sec, &frame))
138 return NULL;
140 return PyInt_FromLong((long) CDmsftoblock(self->ob_cdplayer,
141 min, sec, frame));
144 static PyObject *
145 CD_play(cdplayerobject *self, PyObject *args)
147 int start, play;
148 CDSTATUS status;
150 if (!PyArg_ParseTuple(args, "ii:play", &start, &play))
151 return NULL;
153 if (!CDplay(self->ob_cdplayer, start, play)) {
154 if (CDgetstatus(self->ob_cdplayer, &status) &&
155 status.state == CD_NODISC)
156 PyErr_SetString(CdError, "no disc in player");
157 else
158 PyErr_SetString(CdError, "play failed");
159 return NULL;
162 Py_INCREF(Py_None);
163 return Py_None;
166 static PyObject *
167 CD_playabs(cdplayerobject *self, PyObject *args)
169 int min, sec, frame, play;
170 CDSTATUS status;
172 if (!PyArg_ParseTuple(args, "iiii:playabs", &min, &sec, &frame, &play))
173 return NULL;
175 if (!CDplayabs(self->ob_cdplayer, min, sec, frame, play)) {
176 if (CDgetstatus(self->ob_cdplayer, &status) &&
177 status.state == CD_NODISC)
178 PyErr_SetString(CdError, "no disc in player");
179 else
180 PyErr_SetString(CdError, "playabs failed");
181 return NULL;
184 Py_INCREF(Py_None);
185 return Py_None;
188 static PyObject *
189 CD_playtrack(cdplayerobject *self, PyObject *args)
191 int start, play;
192 CDSTATUS status;
194 if (!PyArg_ParseTuple(args, "ii:playtrack", &start, &play))
195 return NULL;
197 if (!CDplaytrack(self->ob_cdplayer, start, play)) {
198 if (CDgetstatus(self->ob_cdplayer, &status) &&
199 status.state == CD_NODISC)
200 PyErr_SetString(CdError, "no disc in player");
201 else
202 PyErr_SetString(CdError, "playtrack failed");
203 return NULL;
206 Py_INCREF(Py_None);
207 return Py_None;
210 static PyObject *
211 CD_playtrackabs(cdplayerobject *self, PyObject *args)
213 int track, min, sec, frame, play;
214 CDSTATUS status;
216 if (!PyArg_ParseTuple(args, "iiiii:playtrackabs", &track, &min, &sec,
217 &frame, &play))
218 return NULL;
220 if (!CDplaytrackabs(self->ob_cdplayer, track, min, sec, frame, play)) {
221 if (CDgetstatus(self->ob_cdplayer, &status) &&
222 status.state == CD_NODISC)
223 PyErr_SetString(CdError, "no disc in player");
224 else
225 PyErr_SetString(CdError, "playtrackabs failed");
226 return NULL;
229 Py_INCREF(Py_None);
230 return Py_None;
233 static PyObject *
234 CD_readda(cdplayerobject *self, PyObject *args)
236 int numframes, n;
237 PyObject *result;
239 if (!PyArg_ParseTuple(args, "i:readda", &numframes))
240 return NULL;
242 result = PyString_FromStringAndSize(NULL, numframes * sizeof(CDFRAME));
243 if (result == NULL)
244 return NULL;
246 n = CDreadda(self->ob_cdplayer,
247 (CDFRAME *) PyString_AsString(result), numframes);
248 if (n == -1) {
249 Py_DECREF(result);
250 PyErr_SetFromErrno(CdError);
251 return NULL;
253 if (n < numframes)
254 if (_PyString_Resize(&result, n * sizeof(CDFRAME)))
255 return NULL;
257 return result;
260 static PyObject *
261 CD_seek(cdplayerobject *self, PyObject *args)
263 int min, sec, frame;
264 long PyTryBlock;
266 if (!PyArg_ParseTuple(args, "iii:seek", &min, &sec, &frame))
267 return NULL;
269 PyTryBlock = CDseek(self->ob_cdplayer, min, sec, frame);
270 if (PyTryBlock == -1) {
271 PyErr_SetFromErrno(CdError);
272 return NULL;
275 return PyInt_FromLong(PyTryBlock);
278 static PyObject *
279 CD_seektrack(cdplayerobject *self, PyObject *args)
281 int track;
282 long PyTryBlock;
284 if (!PyArg_ParseTuple(args, "i:seektrack", &track))
285 return NULL;
287 PyTryBlock = CDseektrack(self->ob_cdplayer, track);
288 if (PyTryBlock == -1) {
289 PyErr_SetFromErrno(CdError);
290 return NULL;
293 return PyInt_FromLong(PyTryBlock);
296 static PyObject *
297 CD_seekblock(cdplayerobject *self, PyObject *args)
299 unsigned long PyTryBlock;
301 if (!PyArg_ParseTuple(args, "l:seekblock", &PyTryBlock))
302 return NULL;
304 PyTryBlock = CDseekblock(self->ob_cdplayer, PyTryBlock);
305 if (PyTryBlock == (unsigned long) -1) {
306 PyErr_SetFromErrno(CdError);
307 return NULL;
310 return PyInt_FromLong(PyTryBlock);
313 static PyObject *
314 CD_stop(cdplayerobject *self, PyObject *args)
316 CDSTATUS status;
318 if (!PyArg_ParseTuple(args, ":stop"))
319 return NULL;
321 if (!CDstop(self->ob_cdplayer)) {
322 if (CDgetstatus(self->ob_cdplayer, &status) &&
323 status.state == CD_NODISC)
324 PyErr_SetString(CdError, "no disc in player");
325 else
326 PyErr_SetString(CdError, "stop failed");
327 return NULL;
330 Py_INCREF(Py_None);
331 return Py_None;
334 static PyObject *
335 CD_togglepause(cdplayerobject *self, PyObject *args)
337 CDSTATUS status;
339 if (!PyArg_ParseTuple(args, ":togglepause"))
340 return NULL;
342 if (!CDtogglepause(self->ob_cdplayer)) {
343 if (CDgetstatus(self->ob_cdplayer, &status) &&
344 status.state == CD_NODISC)
345 PyErr_SetString(CdError, "no disc in player");
346 else
347 PyErr_SetString(CdError, "togglepause failed");
348 return NULL;
351 Py_INCREF(Py_None);
352 return Py_None;
355 static PyMethodDef cdplayer_methods[] = {
356 {"allowremoval", (PyCFunction)CD_allowremoval, 1},
357 {"bestreadsize", (PyCFunction)CD_bestreadsize, 1},
358 {"close", (PyCFunction)CD_close, 1},
359 {"eject", (PyCFunction)CD_eject, 1},
360 {"getstatus", (PyCFunction)CD_getstatus, 1},
361 {"gettrackinfo", (PyCFunction)CD_gettrackinfo, 1},
362 {"msftoblock", (PyCFunction)CD_msftoblock, 1},
363 {"play", (PyCFunction)CD_play, 1},
364 {"playabs", (PyCFunction)CD_playabs, 1},
365 {"playtrack", (PyCFunction)CD_playtrack, 1},
366 {"playtrackabs", (PyCFunction)CD_playtrackabs, 1},
367 {"preventremoval", (PyCFunction)CD_preventremoval, 1},
368 {"readda", (PyCFunction)CD_readda, 1},
369 {"seek", (PyCFunction)CD_seek, 1},
370 {"seekblock", (PyCFunction)CD_seekblock, 1},
371 {"seektrack", (PyCFunction)CD_seektrack, 1},
372 {"stop", (PyCFunction)CD_stop, 1},
373 {"togglepause", (PyCFunction)CD_togglepause, 1},
374 {NULL, NULL} /* sentinel */
377 static void
378 cdplayer_dealloc(cdplayerobject *self)
380 if (self->ob_cdplayer != NULL)
381 CDclose(self->ob_cdplayer);
382 PyObject_Del(self);
385 static PyObject *
386 cdplayer_getattr(cdplayerobject *self, char *name)
388 if (self->ob_cdplayer == NULL) {
389 PyErr_SetString(PyExc_RuntimeError, "no player active");
390 return NULL;
392 return Py_FindMethod(cdplayer_methods, (PyObject *)self, name);
395 PyTypeObject CdPlayertype = {
396 PyObject_HEAD_INIT(&PyType_Type)
397 0, /*ob_size*/
398 "cdplayer", /*tp_name*/
399 sizeof(cdplayerobject), /*tp_size*/
400 0, /*tp_itemsize*/
401 /* methods */
402 (destructor)cdplayer_dealloc, /*tp_dealloc*/
403 0, /*tp_print*/
404 (getattrfunc)cdplayer_getattr, /*tp_getattr*/
405 0, /*tp_setattr*/
406 0, /*tp_compare*/
407 0, /*tp_repr*/
410 static PyObject *
411 newcdplayerobject(CDPLAYER *cdp)
413 cdplayerobject *p;
415 p = PyObject_New(cdplayerobject, &CdPlayertype);
416 if (p == NULL)
417 return NULL;
418 p->ob_cdplayer = cdp;
419 return (PyObject *) p;
422 static PyObject *
423 CD_open(PyObject *self, PyObject *args)
425 char *dev, *direction;
426 CDPLAYER *cdp;
429 * Variable number of args.
430 * First defaults to "None", second defaults to "r".
432 dev = NULL;
433 direction = "r";
434 if (!PyArg_ParseTuple(args, "|zs:open", &dev, &direction))
435 return NULL;
437 cdp = CDopen(dev, direction);
438 if (cdp == NULL) {
439 PyErr_SetFromErrno(CdError);
440 return NULL;
443 return newcdplayerobject(cdp);
446 typedef struct {
447 PyObject_HEAD
448 CDPARSER *ob_cdparser;
449 struct {
450 PyObject *ob_cdcallback;
451 PyObject *ob_cdcallbackarg;
452 } ob_cdcallbacks[NCALLBACKS];
453 } cdparserobject;
455 static void
456 CD_callback(void *arg, CDDATATYPES type, void *data)
458 PyObject *result, *args, *v = NULL;
459 char *p;
460 int i;
461 cdparserobject *self;
463 self = (cdparserobject *) arg;
464 args = PyTuple_New(3);
465 if (args == NULL)
466 return;
467 Py_INCREF(self->ob_cdcallbacks[type].ob_cdcallbackarg);
468 PyTuple_SetItem(args, 0, self->ob_cdcallbacks[type].ob_cdcallbackarg);
469 PyTuple_SetItem(args, 1, PyInt_FromLong((long) type));
470 switch (type) {
471 case cd_audio:
472 v = PyString_FromStringAndSize(data, CDDA_DATASIZE);
473 break;
474 case cd_pnum:
475 case cd_index:
476 v = PyInt_FromLong(((CDPROGNUM *) data)->value);
477 break;
478 case cd_ptime:
479 case cd_atime:
480 #define ptr ((struct cdtimecode *) data)
481 v = Py_BuildValue("(iii)",
482 ptr->mhi * 10 + ptr->mlo,
483 ptr->shi * 10 + ptr->slo,
484 ptr->fhi * 10 + ptr->flo);
485 #undef ptr
486 break;
487 case cd_catalog:
488 v = PyString_FromStringAndSize(NULL, 13);
489 p = PyString_AsString(v);
490 for (i = 0; i < 13; i++)
491 *p++ = ((char *) data)[i] + '0';
492 break;
493 case cd_ident:
494 #define ptr ((struct cdident *) data)
495 v = PyString_FromStringAndSize(NULL, 12);
496 p = PyString_AsString(v);
497 CDsbtoa(p, ptr->country, 2);
498 p += 2;
499 CDsbtoa(p, ptr->owner, 3);
500 p += 3;
501 *p++ = ptr->year[0] + '0';
502 *p++ = ptr->year[1] + '0';
503 *p++ = ptr->serial[0] + '0';
504 *p++ = ptr->serial[1] + '0';
505 *p++ = ptr->serial[2] + '0';
506 *p++ = ptr->serial[3] + '0';
507 *p++ = ptr->serial[4] + '0';
508 #undef ptr
509 break;
510 case cd_control:
511 v = PyInt_FromLong((long) *((unchar *) data));
512 break;
514 PyTuple_SetItem(args, 2, v);
515 if (PyErr_Occurred()) {
516 Py_DECREF(args);
517 return;
520 result = PyEval_CallObject(self->ob_cdcallbacks[type].ob_cdcallback,
521 args);
522 Py_DECREF(args);
523 Py_XDECREF(result);
526 static PyObject *
527 CD_deleteparser(cdparserobject *self, PyObject *args)
529 int i;
531 if (!PyArg_ParseTuple(args, ":deleteparser"))
532 return NULL;
534 CDdeleteparser(self->ob_cdparser);
535 self->ob_cdparser = NULL;
537 /* no sense in keeping the callbacks, so remove them */
538 for (i = 0; i < NCALLBACKS; i++) {
539 Py_XDECREF(self->ob_cdcallbacks[i].ob_cdcallback);
540 self->ob_cdcallbacks[i].ob_cdcallback = NULL;
541 Py_XDECREF(self->ob_cdcallbacks[i].ob_cdcallbackarg);
542 self->ob_cdcallbacks[i].ob_cdcallbackarg = NULL;
545 Py_INCREF(Py_None);
546 return Py_None;
549 static PyObject *
550 CD_parseframe(cdparserobject *self, PyObject *args)
552 char *cdfp;
553 int length;
554 CDFRAME *p;
556 if (!PyArg_ParseTuple(args, "s#:parseframe", &cdfp, &length))
557 return NULL;
559 if (length % sizeof(CDFRAME) != 0) {
560 PyErr_SetString(PyExc_TypeError, "bad length");
561 return NULL;
564 p = (CDFRAME *) cdfp;
565 while (length > 0) {
566 CDparseframe(self->ob_cdparser, p);
567 length -= sizeof(CDFRAME);
568 p++;
569 if (PyErr_Occurred())
570 return NULL;
573 Py_INCREF(Py_None);
574 return Py_None;
577 static PyObject *
578 CD_removecallback(cdparserobject *self, PyObject *args)
580 int type;
582 if (!PyArg_ParseTuple(args, "i:removecallback", &type))
583 return NULL;
585 if (type < 0 || type >= NCALLBACKS) {
586 PyErr_SetString(PyExc_TypeError, "bad type");
587 return NULL;
590 CDremovecallback(self->ob_cdparser, (CDDATATYPES) type);
592 Py_XDECREF(self->ob_cdcallbacks[type].ob_cdcallback);
593 self->ob_cdcallbacks[type].ob_cdcallback = NULL;
595 Py_XDECREF(self->ob_cdcallbacks[type].ob_cdcallbackarg);
596 self->ob_cdcallbacks[type].ob_cdcallbackarg = NULL;
598 Py_INCREF(Py_None);
599 return Py_None;
602 static PyObject *
603 CD_resetparser(cdparserobject *self, PyObject *args)
605 if (!PyArg_ParseTuple(args, ":resetparser"))
606 return NULL;
608 CDresetparser(self->ob_cdparser);
610 Py_INCREF(Py_None);
611 return Py_None;
614 static PyObject *
615 CD_addcallback(cdparserobject *self, PyObject *args)
617 int type;
618 PyObject *func, *funcarg;
620 /* XXX - more work here */
621 if (!PyArg_ParseTuple(args, "iOO:addcallback", &type, &func, &funcarg))
622 return NULL;
624 if (type < 0 || type >= NCALLBACKS) {
625 PyErr_SetString(PyExc_TypeError, "argument out of range");
626 return NULL;
629 #ifdef CDsetcallback
630 CDaddcallback(self->ob_cdparser, (CDDATATYPES) type, CD_callback,
631 (void *) self);
632 #else
633 CDsetcallback(self->ob_cdparser, (CDDATATYPES) type, CD_callback,
634 (void *) self);
635 #endif
636 Py_XDECREF(self->ob_cdcallbacks[type].ob_cdcallback);
637 Py_INCREF(func);
638 self->ob_cdcallbacks[type].ob_cdcallback = func;
639 Py_XDECREF(self->ob_cdcallbacks[type].ob_cdcallbackarg);
640 Py_INCREF(funcarg);
641 self->ob_cdcallbacks[type].ob_cdcallbackarg = funcarg;
644 if (type == cd_audio) {
645 sigfpe_[_UNDERFL].repls = _ZERO;
646 handle_sigfpes(_ON, _EN_UNDERFL, NULL,
647 _ABORT_ON_ERROR, NULL);
651 Py_INCREF(Py_None);
652 return Py_None;
655 static PyMethodDef cdparser_methods[] = {
656 {"addcallback", (PyCFunction)CD_addcallback, 1},
657 {"deleteparser", (PyCFunction)CD_deleteparser, 1},
658 {"parseframe", (PyCFunction)CD_parseframe, 1},
659 {"removecallback", (PyCFunction)CD_removecallback, 1},
660 {"resetparser", (PyCFunction)CD_resetparser, 1},
661 /* backward compatibility */
662 {"setcallback", (PyCFunction)CD_addcallback, 1},
663 {NULL, NULL} /* sentinel */
666 static void
667 cdparser_dealloc(cdparserobject *self)
669 int i;
671 for (i = 0; i < NCALLBACKS; i++) {
672 Py_XDECREF(self->ob_cdcallbacks[i].ob_cdcallback);
673 self->ob_cdcallbacks[i].ob_cdcallback = NULL;
674 Py_XDECREF(self->ob_cdcallbacks[i].ob_cdcallbackarg);
675 self->ob_cdcallbacks[i].ob_cdcallbackarg = NULL;
677 CDdeleteparser(self->ob_cdparser);
678 PyObject_Del(self);
681 static PyObject *
682 cdparser_getattr(cdparserobject *self, char *name)
684 if (self->ob_cdparser == NULL) {
685 PyErr_SetString(PyExc_RuntimeError, "no parser active");
686 return NULL;
689 return Py_FindMethod(cdparser_methods, (PyObject *)self, name);
692 PyTypeObject CdParsertype = {
693 PyObject_HEAD_INIT(&PyType_Type)
694 0, /*ob_size*/
695 "cdparser", /*tp_name*/
696 sizeof(cdparserobject), /*tp_size*/
697 0, /*tp_itemsize*/
698 /* methods */
699 (destructor)cdparser_dealloc, /*tp_dealloc*/
700 0, /*tp_print*/
701 (getattrfunc)cdparser_getattr, /*tp_getattr*/
702 0, /*tp_setattr*/
703 0, /*tp_compare*/
704 0, /*tp_repr*/
707 static PyObject *
708 newcdparserobject(CDPARSER *cdp)
710 cdparserobject *p;
711 int i;
713 p = PyObject_New(cdparserobject, &CdParsertype);
714 if (p == NULL)
715 return NULL;
716 p->ob_cdparser = cdp;
717 for (i = 0; i < NCALLBACKS; i++) {
718 p->ob_cdcallbacks[i].ob_cdcallback = NULL;
719 p->ob_cdcallbacks[i].ob_cdcallbackarg = NULL;
721 return (PyObject *) p;
724 static PyObject *
725 CD_createparser(PyObject *self, PyObject *args)
727 CDPARSER *cdp;
729 if (!PyArg_ParseTuple(args, ":createparser"))
730 return NULL;
731 cdp = CDcreateparser();
732 if (cdp == NULL) {
733 PyErr_SetString(CdError, "createparser failed");
734 return NULL;
737 return newcdparserobject(cdp);
740 static PyObject *
741 CD_msftoframe(PyObject *self, PyObject *args)
743 int min, sec, frame;
745 if (!PyArg_ParseTuple(args, "iii:msftoframe", &min, &sec, &frame))
746 return NULL;
748 return PyInt_FromLong((long) CDmsftoframe(min, sec, frame));
751 static PyMethodDef CD_methods[] = {
752 {"open", (PyCFunction)CD_open, 1},
753 {"createparser", (PyCFunction)CD_createparser, 1},
754 {"msftoframe", (PyCFunction)CD_msftoframe, 1},
755 {NULL, NULL} /* Sentinel */
758 void
759 initcd(void)
761 PyObject *m, *d;
763 m = Py_InitModule("cd", CD_methods);
764 d = PyModule_GetDict(m);
766 CdError = PyErr_NewException("cd.error", NULL, NULL);
767 PyDict_SetItemString(d, "error", CdError);
769 /* Identifiers for the different types of callbacks from the parser */
770 PyDict_SetItemString(d, "audio", PyInt_FromLong((long) cd_audio));
771 PyDict_SetItemString(d, "pnum", PyInt_FromLong((long) cd_pnum));
772 PyDict_SetItemString(d, "index", PyInt_FromLong((long) cd_index));
773 PyDict_SetItemString(d, "ptime", PyInt_FromLong((long) cd_ptime));
774 PyDict_SetItemString(d, "atime", PyInt_FromLong((long) cd_atime));
775 PyDict_SetItemString(d, "catalog", PyInt_FromLong((long) cd_catalog));
776 PyDict_SetItemString(d, "ident", PyInt_FromLong((long) cd_ident));
777 PyDict_SetItemString(d, "control", PyInt_FromLong((long) cd_control));
779 /* Block size information for digital audio data */
780 PyDict_SetItemString(d, "DATASIZE",
781 PyInt_FromLong((long) CDDA_DATASIZE));
782 PyDict_SetItemString(d, "BLOCKSIZE",
783 PyInt_FromLong((long) CDDA_BLOCKSIZE));
785 /* Possible states for the cd player */
786 PyDict_SetItemString(d, "ERROR", PyInt_FromLong((long) CD_ERROR));
787 PyDict_SetItemString(d, "NODISC", PyInt_FromLong((long) CD_NODISC));
788 PyDict_SetItemString(d, "READY", PyInt_FromLong((long) CD_READY));
789 PyDict_SetItemString(d, "PLAYING", PyInt_FromLong((long) CD_PLAYING));
790 PyDict_SetItemString(d, "PAUSED", PyInt_FromLong((long) CD_PAUSED));
791 PyDict_SetItemString(d, "STILL", PyInt_FromLong((long) CD_STILL));
792 #ifdef CD_CDROM /* only newer versions of the library */
793 PyDict_SetItemString(d, "CDROM", PyInt_FromLong((long) CD_CDROM));
794 #endif