/Modules/cdmodule.c

http://unladen-swallow.googlecode.com/ · C · 800 lines · 646 code · 133 blank · 21 comment · 96 complexity · 011cbefc1db862a58526c6edcf2d2cac MD5 · raw file

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