Warning: That file was not part of the compilation database. It may have many parsing errors.
1 | /* CD module -- interface to Mark Callow's and Roger Chickering's */ |
---|---|
2 | /* CD Audio Library (CD). */ |
3 | |
4 | #include <sys/types.h> |
5 | #include <cdaudio.h> |
6 | #include "Python.h" |
7 | |
8 | #define NCALLBACKS 8 |
9 | |
10 | typedef struct { |
11 | PyObject_HEAD |
12 | CDPLAYER *ob_cdplayer; |
13 | } cdplayerobject; |
14 | |
15 | static PyObject *CdError; /* exception cd.error */ |
16 | |
17 | static PyObject * |
18 | CD_allowremoval(cdplayerobject *self, PyObject *args) |
19 | { |
20 | if (!PyArg_ParseTuple(args, ":allowremoval")) |
21 | return NULL; |
22 | |
23 | CDallowremoval(self->ob_cdplayer); |
24 | |
25 | Py_INCREF(Py_None); |
26 | return Py_None; |
27 | } |
28 | |
29 | static PyObject * |
30 | CD_preventremoval(cdplayerobject *self, PyObject *args) |
31 | { |
32 | if (!PyArg_ParseTuple(args, ":preventremoval")) |
33 | return NULL; |
34 | |
35 | CDpreventremoval(self->ob_cdplayer); |
36 | |
37 | Py_INCREF(Py_None); |
38 | return Py_None; |
39 | } |
40 | |
41 | static PyObject * |
42 | CD_bestreadsize(cdplayerobject *self, PyObject *args) |
43 | { |
44 | if (!PyArg_ParseTuple(args, ":bestreadsize")) |
45 | return NULL; |
46 | |
47 | return PyInt_FromLong((long) CDbestreadsize(self->ob_cdplayer)); |
48 | } |
49 | |
50 | static PyObject * |
51 | CD_close(cdplayerobject *self, PyObject *args) |
52 | { |
53 | if (!PyArg_ParseTuple(args, ":close")) |
54 | return NULL; |
55 | |
56 | if (!CDclose(self->ob_cdplayer)) { |
57 | PyErr_SetFromErrno(CdError); /* XXX - ??? */ |
58 | return NULL; |
59 | } |
60 | self->ob_cdplayer = NULL; |
61 | |
62 | Py_INCREF(Py_None); |
63 | return Py_None; |
64 | } |
65 | |
66 | static PyObject * |
67 | CD_eject(cdplayerobject *self, PyObject *args) |
68 | { |
69 | CDSTATUS status; |
70 | |
71 | if (!PyArg_ParseTuple(args, ":eject")) |
72 | return NULL; |
73 | |
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; |
81 | } |
82 | |
83 | Py_INCREF(Py_None); |
84 | return Py_None; |
85 | } |
86 | |
87 | static PyObject * |
88 | CD_getstatus(cdplayerobject *self, PyObject *args) |
89 | { |
90 | CDSTATUS status; |
91 | |
92 | if (!PyArg_ParseTuple(args, ":getstatus")) |
93 | return NULL; |
94 | |
95 | if (!CDgetstatus(self->ob_cdplayer, &status)) { |
96 | PyErr_SetFromErrno(CdError); /* XXX - ??? */ |
97 | return NULL; |
98 | } |
99 | |
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); |
106 | } |
107 | |
108 | static PyObject * |
109 | CD_gettrackinfo(cdplayerobject *self, PyObject *args) |
110 | { |
111 | int track; |
112 | CDTRACKINFO info; |
113 | CDSTATUS status; |
114 | |
115 | if (!PyArg_ParseTuple(args, "i:gettrackinfo", &track)) |
116 | return NULL; |
117 | |
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; |
125 | } |
126 | |
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); |
130 | } |
131 | |
132 | static PyObject * |
133 | CD_msftoblock(cdplayerobject *self, PyObject *args) |
134 | { |
135 | int min, sec, frame; |
136 | |
137 | if (!PyArg_ParseTuple(args, "iii:msftoblock", &min, &sec, &frame)) |
138 | return NULL; |
139 | |
140 | return PyInt_FromLong((long) CDmsftoblock(self->ob_cdplayer, |
141 | min, sec, frame)); |
142 | } |
143 | |
144 | static PyObject * |
145 | CD_play(cdplayerobject *self, PyObject *args) |
146 | { |
147 | int start, play; |
148 | CDSTATUS status; |
149 | |
150 | if (!PyArg_ParseTuple(args, "ii:play", &start, &play)) |
151 | return NULL; |
152 | |
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; |
160 | } |
161 | |
162 | Py_INCREF(Py_None); |
163 | return Py_None; |
164 | } |
165 | |
166 | static PyObject * |
167 | CD_playabs(cdplayerobject *self, PyObject *args) |
168 | { |
169 | int min, sec, frame, play; |
170 | CDSTATUS status; |
171 | |
172 | if (!PyArg_ParseTuple(args, "iiii:playabs", &min, &sec, &frame, &play)) |
173 | return NULL; |
174 | |
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; |
182 | } |
183 | |
184 | Py_INCREF(Py_None); |
185 | return Py_None; |
186 | } |
187 | |
188 | static PyObject * |
189 | CD_playtrack(cdplayerobject *self, PyObject *args) |
190 | { |
191 | int start, play; |
192 | CDSTATUS status; |
193 | |
194 | if (!PyArg_ParseTuple(args, "ii:playtrack", &start, &play)) |
195 | return NULL; |
196 | |
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; |
204 | } |
205 | |
206 | Py_INCREF(Py_None); |
207 | return Py_None; |
208 | } |
209 | |
210 | static PyObject * |
211 | CD_playtrackabs(cdplayerobject *self, PyObject *args) |
212 | { |
213 | int track, min, sec, frame, play; |
214 | CDSTATUS status; |
215 | |
216 | if (!PyArg_ParseTuple(args, "iiiii:playtrackabs", &track, &min, &sec, |
217 | &frame, &play)) |
218 | return NULL; |
219 | |
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; |
227 | } |
228 | |
229 | Py_INCREF(Py_None); |
230 | return Py_None; |
231 | } |
232 | |
233 | static PyObject * |
234 | CD_readda(cdplayerobject *self, PyObject *args) |
235 | { |
236 | int numframes, n; |
237 | PyObject *result; |
238 | |
239 | if (!PyArg_ParseTuple(args, "i:readda", &numframes)) |
240 | return NULL; |
241 | |
242 | result = PyString_FromStringAndSize(NULL, numframes * sizeof(CDFRAME)); |
243 | if (result == NULL) |
244 | return NULL; |
245 | |
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; |
252 | } |
253 | if (n < numframes) |
254 | _PyString_Resize(&result, n * sizeof(CDFRAME)); |
255 | |
256 | return result; |
257 | } |
258 | |
259 | static PyObject * |
260 | CD_seek(cdplayerobject *self, PyObject *args) |
261 | { |
262 | int min, sec, frame; |
263 | long PyTryBlock; |
264 | |
265 | if (!PyArg_ParseTuple(args, "iii:seek", &min, &sec, &frame)) |
266 | return NULL; |
267 | |
268 | PyTryBlock = CDseek(self->ob_cdplayer, min, sec, frame); |
269 | if (PyTryBlock == -1) { |
270 | PyErr_SetFromErrno(CdError); |
271 | return NULL; |
272 | } |
273 | |
274 | return PyInt_FromLong(PyTryBlock); |
275 | } |
276 | |
277 | static PyObject * |
278 | CD_seektrack(cdplayerobject *self, PyObject *args) |
279 | { |
280 | int track; |
281 | long PyTryBlock; |
282 | |
283 | if (!PyArg_ParseTuple(args, "i:seektrack", &track)) |
284 | return NULL; |
285 | |
286 | PyTryBlock = CDseektrack(self->ob_cdplayer, track); |
287 | if (PyTryBlock == -1) { |
288 | PyErr_SetFromErrno(CdError); |
289 | return NULL; |
290 | } |
291 | |
292 | return PyInt_FromLong(PyTryBlock); |
293 | } |
294 | |
295 | static PyObject * |
296 | CD_seekblock(cdplayerobject *self, PyObject *args) |
297 | { |
298 | unsigned long PyTryBlock; |
299 | |
300 | if (!PyArg_ParseTuple(args, "l:seekblock", &PyTryBlock)) |
301 | return NULL; |
302 | |
303 | PyTryBlock = CDseekblock(self->ob_cdplayer, PyTryBlock); |
304 | if (PyTryBlock == (unsigned long) -1) { |
305 | PyErr_SetFromErrno(CdError); |
306 | return NULL; |
307 | } |
308 | |
309 | return PyInt_FromLong(PyTryBlock); |
310 | } |
311 | |
312 | static PyObject * |
313 | CD_stop(cdplayerobject *self, PyObject *args) |
314 | { |
315 | CDSTATUS status; |
316 | |
317 | if (!PyArg_ParseTuple(args, ":stop")) |
318 | return NULL; |
319 | |
320 | if (!CDstop(self->ob_cdplayer)) { |
321 | if (CDgetstatus(self->ob_cdplayer, &status) && |
322 | status.state == CD_NODISC) |
323 | PyErr_SetString(CdError, "no disc in player"); |
324 | else |
325 | PyErr_SetString(CdError, "stop failed"); |
326 | return NULL; |
327 | } |
328 | |
329 | Py_INCREF(Py_None); |
330 | return Py_None; |
331 | } |
332 | |
333 | static PyObject * |
334 | CD_togglepause(cdplayerobject *self, PyObject *args) |
335 | { |
336 | CDSTATUS status; |
337 | |
338 | if (!PyArg_ParseTuple(args, ":togglepause")) |
339 | return NULL; |
340 | |
341 | if (!CDtogglepause(self->ob_cdplayer)) { |
342 | if (CDgetstatus(self->ob_cdplayer, &status) && |
343 | status.state == CD_NODISC) |
344 | PyErr_SetString(CdError, "no disc in player"); |
345 | else |
346 | PyErr_SetString(CdError, "togglepause failed"); |
347 | return NULL; |
348 | } |
349 | |
350 | Py_INCREF(Py_None); |
351 | return Py_None; |
352 | } |
353 | |
354 | static PyMethodDef cdplayer_methods[] = { |
355 | {"allowremoval", (PyCFunction)CD_allowremoval, METH_VARARGS}, |
356 | {"bestreadsize", (PyCFunction)CD_bestreadsize, METH_VARARGS}, |
357 | {"close", (PyCFunction)CD_close, METH_VARARGS}, |
358 | {"eject", (PyCFunction)CD_eject, METH_VARARGS}, |
359 | {"getstatus", (PyCFunction)CD_getstatus, METH_VARARGS}, |
360 | {"gettrackinfo", (PyCFunction)CD_gettrackinfo, METH_VARARGS}, |
361 | {"msftoblock", (PyCFunction)CD_msftoblock, METH_VARARGS}, |
362 | {"play", (PyCFunction)CD_play, METH_VARARGS}, |
363 | {"playabs", (PyCFunction)CD_playabs, METH_VARARGS}, |
364 | {"playtrack", (PyCFunction)CD_playtrack, METH_VARARGS}, |
365 | {"playtrackabs", (PyCFunction)CD_playtrackabs, METH_VARARGS}, |
366 | {"preventremoval", (PyCFunction)CD_preventremoval, METH_VARARGS}, |
367 | {"readda", (PyCFunction)CD_readda, METH_VARARGS}, |
368 | {"seek", (PyCFunction)CD_seek, METH_VARARGS}, |
369 | {"seekblock", (PyCFunction)CD_seekblock, METH_VARARGS}, |
370 | {"seektrack", (PyCFunction)CD_seektrack, METH_VARARGS}, |
371 | {"stop", (PyCFunction)CD_stop, METH_VARARGS}, |
372 | {"togglepause", (PyCFunction)CD_togglepause, METH_VARARGS}, |
373 | {NULL, NULL} /* sentinel */ |
374 | }; |
375 | |
376 | static void |
377 | cdplayer_dealloc(cdplayerobject *self) |
378 | { |
379 | if (self->ob_cdplayer != NULL) |
380 | CDclose(self->ob_cdplayer); |
381 | PyObject_Del(self); |
382 | } |
383 | |
384 | static PyObject * |
385 | cdplayer_getattr(cdplayerobject *self, char *name) |
386 | { |
387 | if (self->ob_cdplayer == NULL) { |
388 | PyErr_SetString(PyExc_RuntimeError, "no player active"); |
389 | return NULL; |
390 | } |
391 | return Py_FindMethod(cdplayer_methods, (PyObject *)self, name); |
392 | } |
393 | |
394 | PyTypeObject CdPlayertype = { |
395 | PyObject_HEAD_INIT(&PyType_Type) |
396 | 0, /*ob_size*/ |
397 | "cd.cdplayer", /*tp_name*/ |
398 | sizeof(cdplayerobject), /*tp_size*/ |
399 | 0, /*tp_itemsize*/ |
400 | /* methods */ |
401 | (destructor)cdplayer_dealloc, /*tp_dealloc*/ |
402 | 0, /*tp_print*/ |
403 | (getattrfunc)cdplayer_getattr, /*tp_getattr*/ |
404 | 0, /*tp_setattr*/ |
405 | 0, /*tp_compare*/ |
406 | 0, /*tp_repr*/ |
407 | }; |
408 | |
409 | static PyObject * |
410 | newcdplayerobject(CDPLAYER *cdp) |
411 | { |
412 | cdplayerobject *p; |
413 | |
414 | p = PyObject_New(cdplayerobject, &CdPlayertype); |
415 | if (p == NULL) |
416 | return NULL; |
417 | p->ob_cdplayer = cdp; |
418 | return (PyObject *) p; |
419 | } |
420 | |
421 | static PyObject * |
422 | CD_open(PyObject *self, PyObject *args) |
423 | { |
424 | char *dev, *direction; |
425 | CDPLAYER *cdp; |
426 | |
427 | /* |
428 | * Variable number of args. |
429 | * First defaults to "None", second defaults to "r". |
430 | */ |
431 | dev = NULL; |
432 | direction = "r"; |
433 | if (!PyArg_ParseTuple(args, "|zs:open", &dev, &direction)) |
434 | return NULL; |
435 | |
436 | cdp = CDopen(dev, direction); |
437 | if (cdp == NULL) { |
438 | PyErr_SetFromErrno(CdError); |
439 | return NULL; |
440 | } |
441 | |
442 | return newcdplayerobject(cdp); |
443 | } |
444 | |
445 | typedef struct { |
446 | PyObject_HEAD |
447 | CDPARSER *ob_cdparser; |
448 | struct { |
449 | PyObject *ob_cdcallback; |
450 | PyObject *ob_cdcallbackarg; |
451 | } ob_cdcallbacks[NCALLBACKS]; |
452 | } cdparserobject; |
453 | |
454 | static void |
455 | CD_callback(void *arg, CDDATATYPES type, void *data) |
456 | { |
457 | PyObject *result, *args, *v = NULL; |
458 | char *p; |
459 | int i; |
460 | cdparserobject *self; |
461 | |
462 | self = (cdparserobject *) arg; |
463 | args = PyTuple_New(3); |
464 | if (args == NULL) |
465 | return; |
466 | Py_INCREF(self->ob_cdcallbacks[type].ob_cdcallbackarg); |
467 | PyTuple_SetItem(args, 0, self->ob_cdcallbacks[type].ob_cdcallbackarg); |
468 | PyTuple_SetItem(args, 1, PyInt_FromLong((long) type)); |
469 | switch (type) { |
470 | case cd_audio: |
471 | v = PyString_FromStringAndSize(data, CDDA_DATASIZE); |
472 | break; |
473 | case cd_pnum: |
474 | case cd_index: |
475 | v = PyInt_FromLong(((CDPROGNUM *) data)->value); |
476 | break; |
477 | case cd_ptime: |
478 | case cd_atime: |
479 | #define ptr ((struct cdtimecode *) data) |
480 | v = Py_BuildValue("(iii)", |
481 | ptr->mhi * 10 + ptr->mlo, |
482 | ptr->shi * 10 + ptr->slo, |
483 | ptr->fhi * 10 + ptr->flo); |
484 | #undef ptr |
485 | break; |
486 | case cd_catalog: |
487 | v = PyString_FromStringAndSize(NULL, 13); |
488 | p = PyString_AsString(v); |
489 | for (i = 0; i < 13; i++) |
490 | *p++ = ((char *) data)[i] + |
491 | break; |
492 | case cd_ident: |
493 | #define ptr ((struct cdident *) data) |
494 | v = PyString_FromStringAndSize(NULL, 12); |
495 | p = PyString_AsString(v); |
496 | CDsbtoa(p, ptr->country, 2); |
497 | p += 2; |
498 | CDsbtoa(p, ptr->owner, 3); |
499 | p += 3; |
500 | *p++ = ptr->year[0] + |
501 | *p++ = ptr->year[1] + |
502 | *p++ = ptr->serial[0] + |
503 | *p++ = ptr->serial[1] + |
504 | *p++ = ptr->serial[2] + |
505 | *p++ = ptr->serial[3] + |
506 | *p++ = ptr->serial[4] + |
507 | #undef ptr |
508 | break; |
509 | case cd_control: |
510 | v = PyInt_FromLong((long) *((unchar *) data)); |
511 | break; |
512 | } |
513 | PyTuple_SetItem(args, 2, v); |
514 | if (PyErr_Occurred()) { |
515 | Py_DECREF(args); |
516 | return; |
517 | } |
518 | |
519 | result = PyEval_CallObject(self->ob_cdcallbacks[type].ob_cdcallback, |
520 | args); |
521 | Py_DECREF(args); |
522 | Py_XDECREF(result); |
523 | } |
524 | |
525 | static PyObject * |
526 | CD_deleteparser(cdparserobject *self, PyObject *args) |
527 | { |
528 | int i; |
529 | |
530 | if (!PyArg_ParseTuple(args, ":deleteparser")) |
531 | return NULL; |
532 | |
533 | CDdeleteparser(self->ob_cdparser); |
534 | self->ob_cdparser = NULL; |
535 | |
536 | /* no sense in keeping the callbacks, so remove them */ |
537 | for (i = 0; i < NCALLBACKS; i++) { |
538 | Py_XDECREF(self->ob_cdcallbacks[i].ob_cdcallback); |
539 | self->ob_cdcallbacks[i].ob_cdcallback = NULL; |
540 | Py_XDECREF(self->ob_cdcallbacks[i].ob_cdcallbackarg); |
541 | self->ob_cdcallbacks[i].ob_cdcallbackarg = NULL; |
542 | } |
543 | |
544 | Py_INCREF(Py_None); |
545 | return Py_None; |
546 | } |
547 | |
548 | static PyObject * |
549 | CD_parseframe(cdparserobject *self, PyObject *args) |
550 | { |
551 | char *cdfp; |
552 | int length; |
553 | CDFRAME *p; |
554 | |
555 | if (!PyArg_ParseTuple(args, "s#:parseframe", &cdfp, &length)) |
556 | return NULL; |
557 | |
558 | if (length % sizeof(CDFRAME) != 0) { |
559 | PyErr_SetString(PyExc_TypeError, "bad length"); |
560 | return NULL; |
561 | } |
562 | |
563 | p = (CDFRAME *) cdfp; |
564 | while (length > 0) { |
565 | CDparseframe(self->ob_cdparser, p); |
566 | length -= sizeof(CDFRAME); |
567 | p++; |
568 | if (PyErr_Occurred()) |
569 | return NULL; |
570 | } |
571 | |
572 | Py_INCREF(Py_None); |
573 | return Py_None; |
574 | } |
575 | |
576 | static PyObject * |
577 | CD_removecallback(cdparserobject *self, PyObject *args) |
578 | { |
579 | int type; |
580 | |
581 | if (!PyArg_ParseTuple(args, "i:removecallback", &type)) |
582 | return NULL; |
583 | |
584 | if (type < 0 || type >= NCALLBACKS) { |
585 | PyErr_SetString(PyExc_TypeError, "bad type"); |
586 | return NULL; |
587 | } |
588 | |
589 | CDremovecallback(self->ob_cdparser, (CDDATATYPES) type); |
590 | |
591 | Py_XDECREF(self->ob_cdcallbacks[type].ob_cdcallback); |
592 | self->ob_cdcallbacks[type].ob_cdcallback = NULL; |
593 | |
594 | Py_XDECREF(self->ob_cdcallbacks[type].ob_cdcallbackarg); |
595 | self->ob_cdcallbacks[type].ob_cdcallbackarg = NULL; |
596 | |
597 | Py_INCREF(Py_None); |
598 | return Py_None; |
599 | } |
600 | |
601 | static PyObject * |
602 | CD_resetparser(cdparserobject *self, PyObject *args) |
603 | { |
604 | if (!PyArg_ParseTuple(args, ":resetparser")) |
605 | return NULL; |
606 | |
607 | CDresetparser(self->ob_cdparser); |
608 | |
609 | Py_INCREF(Py_None); |
610 | return Py_None; |
611 | } |
612 | |
613 | static PyObject * |
614 | CD_addcallback(cdparserobject *self, PyObject *args) |
615 | { |
616 | int type; |
617 | PyObject *func, *funcarg; |
618 | |
619 | /* XXX - more work here */ |
620 | if (!PyArg_ParseTuple(args, "iOO:addcallback", &type, &func, &funcarg)) |
621 | return NULL; |
622 | |
623 | if (type < 0 || type >= NCALLBACKS) { |
624 | PyErr_SetString(PyExc_TypeError, "argument out of range"); |
625 | return NULL; |
626 | } |
627 | |
628 | #ifdef CDsetcallback |
629 | CDaddcallback(self->ob_cdparser, (CDDATATYPES) type, CD_callback, |
630 | (void *) self); |
631 | #else |
632 | CDsetcallback(self->ob_cdparser, (CDDATATYPES) type, CD_callback, |
633 | (void *) self); |
634 | #endif |
635 | Py_XDECREF(self->ob_cdcallbacks[type].ob_cdcallback); |
636 | Py_INCREF(func); |
637 | self->ob_cdcallbacks[type].ob_cdcallback = func; |
638 | Py_XDECREF(self->ob_cdcallbacks[type].ob_cdcallbackarg); |
639 | Py_INCREF(funcarg); |
640 | self->ob_cdcallbacks[type].ob_cdcallbackarg = funcarg; |
641 | |
642 | /* |
643 | if (type == cd_audio) { |
644 | sigfpe_[_UNDERFL].repls = _ZERO; |
645 | handle_sigfpes(_ON, _EN_UNDERFL, NULL, |
646 | _ABORT_ON_ERROR, NULL); |
647 | } |
648 | */ |
649 | |
650 | Py_INCREF(Py_None); |
651 | return Py_None; |
652 | } |
653 | |
654 | static PyMethodDef cdparser_methods[] = { |
655 | {"addcallback", (PyCFunction)CD_addcallback, METH_VARARGS}, |
656 | {"deleteparser", (PyCFunction)CD_deleteparser, METH_VARARGS}, |
657 | {"parseframe", (PyCFunction)CD_parseframe, METH_VARARGS}, |
658 | {"removecallback", (PyCFunction)CD_removecallback, METH_VARARGS}, |
659 | {"resetparser", (PyCFunction)CD_resetparser, METH_VARARGS}, |
660 | /* backward compatibility */ |
661 | {"setcallback", (PyCFunction)CD_addcallback, METH_VARARGS}, |
662 | {NULL, NULL} /* sentinel */ |
663 | }; |
664 | |
665 | static void |
666 | cdparser_dealloc(cdparserobject *self) |
667 | { |
668 | int i; |
669 | |
670 | for (i = 0; i < NCALLBACKS; i++) { |
671 | Py_XDECREF(self->ob_cdcallbacks[i].ob_cdcallback); |
672 | self->ob_cdcallbacks[i].ob_cdcallback = NULL; |
673 | Py_XDECREF(self->ob_cdcallbacks[i].ob_cdcallbackarg); |
674 | self->ob_cdcallbacks[i].ob_cdcallbackarg = NULL; |
675 | } |
676 | CDdeleteparser(self->ob_cdparser); |
677 | PyObject_Del(self); |
678 | } |
679 | |
680 | static PyObject * |
681 | cdparser_getattr(cdparserobject *self, char *name) |
682 | { |
683 | if (self->ob_cdparser == NULL) { |
684 | PyErr_SetString(PyExc_RuntimeError, "no parser active"); |
685 | return NULL; |
686 | } |
687 | |
688 | return Py_FindMethod(cdparser_methods, (PyObject *)self, name); |
689 | } |
690 | |
691 | PyTypeObject CdParsertype = { |
692 | PyObject_HEAD_INIT(&PyType_Type) |
693 | 0, /*ob_size*/ |
694 | "cd.cdparser", /*tp_name*/ |
695 | sizeof(cdparserobject), /*tp_size*/ |
696 | 0, /*tp_itemsize*/ |
697 | /* methods */ |
698 | (destructor)cdparser_dealloc, /*tp_dealloc*/ |
699 | 0, /*tp_print*/ |
700 | (getattrfunc)cdparser_getattr, /*tp_getattr*/ |
701 | 0, /*tp_setattr*/ |
702 | 0, /*tp_compare*/ |
703 | 0, /*tp_repr*/ |
704 | }; |
705 | |
706 | static PyObject * |
707 | newcdparserobject(CDPARSER *cdp) |
708 | { |
709 | cdparserobject *p; |
710 | int i; |
711 | |
712 | p = PyObject_New(cdparserobject, &CdParsertype); |
713 | if (p == NULL) |
714 | return NULL; |
715 | p->ob_cdparser = cdp; |
716 | for (i = 0; i < NCALLBACKS; i++) { |
717 | p->ob_cdcallbacks[i].ob_cdcallback = NULL; |
718 | p->ob_cdcallbacks[i].ob_cdcallbackarg = NULL; |
719 | } |
720 | return (PyObject *) p; |
721 | } |
722 | |
723 | static PyObject * |
724 | CD_createparser(PyObject *self, PyObject *args) |
725 | { |
726 | CDPARSER *cdp; |
727 | |
728 | if (!PyArg_ParseTuple(args, ":createparser")) |
729 | return NULL; |
730 | cdp = CDcreateparser(); |
731 | if (cdp == NULL) { |
732 | PyErr_SetString(CdError, "createparser failed"); |
733 | return NULL; |
734 | } |
735 | |
736 | return newcdparserobject(cdp); |
737 | } |
738 | |
739 | static PyObject * |
740 | CD_msftoframe(PyObject *self, PyObject *args) |
741 | { |
742 | int min, sec, frame; |
743 | |
744 | if (!PyArg_ParseTuple(args, "iii:msftoframe", &min, &sec, &frame)) |
745 | return NULL; |
746 | |
747 | return PyInt_FromLong((long) CDmsftoframe(min, sec, frame)); |
748 | } |
749 | |
750 | static PyMethodDef CD_methods[] = { |
751 | {"open", (PyCFunction)CD_open, METH_VARARGS}, |
752 | {"createparser", (PyCFunction)CD_createparser, METH_VARARGS}, |
753 | {"msftoframe", (PyCFunction)CD_msftoframe, METH_VARARGS}, |
754 | {NULL, NULL} /* Sentinel */ |
755 | }; |
756 | |
757 | void |
758 | initcd(void) |
759 | { |
760 | PyObject *m, *d; |
761 | |
762 | if (PyErr_WarnPy3k("the cd module has been removed in " |
763 | "Python 3.0", 2) < 0) |
764 | return; |
765 | |
766 | m = Py_InitModule("cd", CD_methods); |
767 | if (m == NULL) |
768 | return; |
769 | d = PyModule_GetDict(m); |
770 | |
771 | CdError = PyErr_NewException("cd.error", NULL, NULL); |
772 | PyDict_SetItemString(d, "error", CdError); |
773 | |
774 | /* Identifiers for the different types of callbacks from the parser */ |
775 | PyDict_SetItemString(d, "audio", PyInt_FromLong((long) cd_audio)); |
776 | PyDict_SetItemString(d, "pnum", PyInt_FromLong((long) cd_pnum)); |
777 | PyDict_SetItemString(d, "index", PyInt_FromLong((long) cd_index)); |
778 | PyDict_SetItemString(d, "ptime", PyInt_FromLong((long) cd_ptime)); |
779 | PyDict_SetItemString(d, "atime", PyInt_FromLong((long) cd_atime)); |
780 | PyDict_SetItemString(d, "catalog", PyInt_FromLong((long) cd_catalog)); |
781 | PyDict_SetItemString(d, "ident", PyInt_FromLong((long) cd_ident)); |
782 | PyDict_SetItemString(d, "control", PyInt_FromLong((long) cd_control)); |
783 | |
784 | /* Block size information for digital audio data */ |
785 | PyDict_SetItemString(d, "DATASIZE", |
786 | PyInt_FromLong((long) CDDA_DATASIZE)); |
787 | PyDict_SetItemString(d, "BLOCKSIZE", |
788 | PyInt_FromLong((long) CDDA_BLOCKSIZE)); |
789 | |
790 | /* Possible states for the cd player */ |
791 | PyDict_SetItemString(d, "ERROR", PyInt_FromLong((long) CD_ERROR)); |
792 | PyDict_SetItemString(d, "NODISC", PyInt_FromLong((long) CD_NODISC)); |
793 | PyDict_SetItemString(d, "READY", PyInt_FromLong((long) CD_READY)); |
794 | PyDict_SetItemString(d, "PLAYING", PyInt_FromLong((long) CD_PLAYING)); |
795 | PyDict_SetItemString(d, "PAUSED", PyInt_FromLong((long) CD_PAUSED)); |
796 | PyDict_SetItemString(d, "STILL", PyInt_FromLong((long) CD_STILL)); |
797 | #ifdef CD_CDROM /* only newer versions of the library */ |
798 | PyDict_SetItemString(d, "CDROM", PyInt_FromLong((long) CD_CDROM)); |
799 | #endif |
800 | } |
801 |
Warning: That file was not part of the compilation database. It may have many parsing errors.