/Mac/Modules/snd/_Sndmodule.c

http://unladen-swallow.googlecode.com/ · C · 1161 lines · 1035 code · 108 blank · 18 comment · 139 complexity · 1fe03c09cc8cc0f22850918b95a0b244 MD5 · raw file

  1. /* ========================== Module _Snd =========================== */
  2. #include "Python.h"
  3. #ifndef __LP64__
  4. #include "pymactoolbox.h"
  5. /* Macro to test whether a weak-loaded CFM function exists */
  6. #define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL ) {\
  7. PyErr_SetString(PyExc_NotImplementedError, \
  8. "Not available in this shared library/OS version"); \
  9. return NULL; \
  10. }} while(0)
  11. #include <Carbon/Carbon.h>
  12. /* Convert a SndCommand argument */
  13. static int
  14. SndCmd_Convert(PyObject *v, SndCommand *pc)
  15. {
  16. int len;
  17. pc->param1 = 0;
  18. pc->param2 = 0;
  19. if (PyTuple_Check(v)) {
  20. if (PyArg_ParseTuple(v, "h|hl", &pc->cmd, &pc->param1, &pc->param2))
  21. return 1;
  22. PyErr_Clear();
  23. return PyArg_ParseTuple(v, "Hhs#", &pc->cmd, &pc->param1, &pc->param2, &len);
  24. }
  25. return PyArg_Parse(v, "H", &pc->cmd);
  26. }
  27. static pascal void SndCh_UserRoutine(SndChannelPtr chan, SndCommand *cmd); /* Forward */
  28. static pascal void SPB_completion(SPBPtr my_spb); /* Forward */
  29. static PyObject *Snd_Error;
  30. /* --------------------- Object type SndChannel --------------------- */
  31. static PyTypeObject SndChannel_Type;
  32. #define SndCh_Check(x) ((x)->ob_type == &SndChannel_Type || PyObject_TypeCheck((x), &SndChannel_Type))
  33. typedef struct SndChannelObject {
  34. PyObject_HEAD
  35. SndChannelPtr ob_itself;
  36. /* Members used to implement callbacks: */
  37. PyObject *ob_callback;
  38. long ob_A5;
  39. SndCommand ob_cmd;
  40. } SndChannelObject;
  41. static PyObject *SndCh_New(SndChannelPtr itself)
  42. {
  43. SndChannelObject *it;
  44. it = PyObject_NEW(SndChannelObject, &SndChannel_Type);
  45. if (it == NULL) return NULL;
  46. it->ob_itself = itself;
  47. it->ob_callback = NULL;
  48. it->ob_A5 = SetCurrentA5();
  49. return (PyObject *)it;
  50. }
  51. static void SndCh_dealloc(SndChannelObject *self)
  52. {
  53. SndDisposeChannel(self->ob_itself, 1);
  54. Py_XDECREF(self->ob_callback);
  55. PyObject_Free((PyObject *)self);
  56. }
  57. static PyObject *SndCh_SndDoCommand(SndChannelObject *_self, PyObject *_args)
  58. {
  59. PyObject *_res = NULL;
  60. OSErr _err;
  61. SndCommand cmd;
  62. Boolean noWait;
  63. if (!PyArg_ParseTuple(_args, "O&b",
  64. SndCmd_Convert, &cmd,
  65. &noWait))
  66. return NULL;
  67. _err = SndDoCommand(_self->ob_itself,
  68. &cmd,
  69. noWait);
  70. if (_err != noErr) return PyMac_Error(_err);
  71. Py_INCREF(Py_None);
  72. _res = Py_None;
  73. return _res;
  74. }
  75. static PyObject *SndCh_SndDoImmediate(SndChannelObject *_self, PyObject *_args)
  76. {
  77. PyObject *_res = NULL;
  78. OSErr _err;
  79. SndCommand cmd;
  80. if (!PyArg_ParseTuple(_args, "O&",
  81. SndCmd_Convert, &cmd))
  82. return NULL;
  83. _err = SndDoImmediate(_self->ob_itself,
  84. &cmd);
  85. if (_err != noErr) return PyMac_Error(_err);
  86. Py_INCREF(Py_None);
  87. _res = Py_None;
  88. return _res;
  89. }
  90. static PyObject *SndCh_SndPlay(SndChannelObject *_self, PyObject *_args)
  91. {
  92. PyObject *_res = NULL;
  93. OSErr _err;
  94. SndListHandle sndHandle;
  95. Boolean async;
  96. if (!PyArg_ParseTuple(_args, "O&b",
  97. ResObj_Convert, &sndHandle,
  98. &async))
  99. return NULL;
  100. _err = SndPlay(_self->ob_itself,
  101. sndHandle,
  102. async);
  103. if (_err != noErr) return PyMac_Error(_err);
  104. Py_INCREF(Py_None);
  105. _res = Py_None;
  106. return _res;
  107. }
  108. static PyObject *SndCh_SndChannelStatus(SndChannelObject *_self, PyObject *_args)
  109. {
  110. PyObject *_res = NULL;
  111. OSErr _err;
  112. short theLength;
  113. SCStatus theStatus__out__;
  114. if (!PyArg_ParseTuple(_args, "h",
  115. &theLength))
  116. return NULL;
  117. _err = SndChannelStatus(_self->ob_itself,
  118. theLength,
  119. &theStatus__out__);
  120. if (_err != noErr) return PyMac_Error(_err);
  121. _res = Py_BuildValue("s#",
  122. (char *)&theStatus__out__, (int)sizeof(SCStatus));
  123. return _res;
  124. }
  125. static PyObject *SndCh_SndGetInfo(SndChannelObject *_self, PyObject *_args)
  126. {
  127. PyObject *_res = NULL;
  128. OSErr _err;
  129. OSType selector;
  130. void * infoPtr;
  131. if (!PyArg_ParseTuple(_args, "O&w",
  132. PyMac_GetOSType, &selector,
  133. &infoPtr))
  134. return NULL;
  135. _err = SndGetInfo(_self->ob_itself,
  136. selector,
  137. infoPtr);
  138. if (_err != noErr) return PyMac_Error(_err);
  139. Py_INCREF(Py_None);
  140. _res = Py_None;
  141. return _res;
  142. }
  143. static PyObject *SndCh_SndSetInfo(SndChannelObject *_self, PyObject *_args)
  144. {
  145. PyObject *_res = NULL;
  146. OSErr _err;
  147. OSType selector;
  148. void * infoPtr;
  149. if (!PyArg_ParseTuple(_args, "O&w",
  150. PyMac_GetOSType, &selector,
  151. &infoPtr))
  152. return NULL;
  153. _err = SndSetInfo(_self->ob_itself,
  154. selector,
  155. infoPtr);
  156. if (_err != noErr) return PyMac_Error(_err);
  157. Py_INCREF(Py_None);
  158. _res = Py_None;
  159. return _res;
  160. }
  161. static PyMethodDef SndCh_methods[] = {
  162. {"SndDoCommand", (PyCFunction)SndCh_SndDoCommand, 1,
  163. PyDoc_STR("(SndCommand cmd, Boolean noWait) -> None")},
  164. {"SndDoImmediate", (PyCFunction)SndCh_SndDoImmediate, 1,
  165. PyDoc_STR("(SndCommand cmd) -> None")},
  166. {"SndPlay", (PyCFunction)SndCh_SndPlay, 1,
  167. PyDoc_STR("(SndListHandle sndHandle, Boolean async) -> None")},
  168. {"SndChannelStatus", (PyCFunction)SndCh_SndChannelStatus, 1,
  169. PyDoc_STR("(short theLength) -> (SCStatus theStatus)")},
  170. {"SndGetInfo", (PyCFunction)SndCh_SndGetInfo, 1,
  171. PyDoc_STR("(OSType selector, void * infoPtr) -> None")},
  172. {"SndSetInfo", (PyCFunction)SndCh_SndSetInfo, 1,
  173. PyDoc_STR("(OSType selector, void * infoPtr) -> None")},
  174. {NULL, NULL, 0}
  175. };
  176. #define SndCh_getsetlist NULL
  177. #define SndCh_compare NULL
  178. #define SndCh_repr NULL
  179. #define SndCh_hash NULL
  180. static PyTypeObject SndChannel_Type = {
  181. PyObject_HEAD_INIT(NULL)
  182. 0, /*ob_size*/
  183. "_Snd.SndChannel", /*tp_name*/
  184. sizeof(SndChannelObject), /*tp_basicsize*/
  185. 0, /*tp_itemsize*/
  186. /* methods */
  187. (destructor) SndCh_dealloc, /*tp_dealloc*/
  188. 0, /*tp_print*/
  189. (getattrfunc)0, /*tp_getattr*/
  190. (setattrfunc)0, /*tp_setattr*/
  191. (cmpfunc) SndCh_compare, /*tp_compare*/
  192. (reprfunc) SndCh_repr, /*tp_repr*/
  193. (PyNumberMethods *)0, /* tp_as_number */
  194. (PySequenceMethods *)0, /* tp_as_sequence */
  195. (PyMappingMethods *)0, /* tp_as_mapping */
  196. (hashfunc) SndCh_hash, /*tp_hash*/
  197. 0, /*tp_call*/
  198. 0, /*tp_str*/
  199. PyObject_GenericGetAttr, /*tp_getattro*/
  200. PyObject_GenericSetAttr, /*tp_setattro */
  201. 0, /*tp_as_buffer*/
  202. Py_TPFLAGS_DEFAULT, /* tp_flags */
  203. 0, /*tp_doc*/
  204. 0, /*tp_traverse*/
  205. 0, /*tp_clear*/
  206. 0, /*tp_richcompare*/
  207. 0, /*tp_weaklistoffset*/
  208. 0, /*tp_iter*/
  209. 0, /*tp_iternext*/
  210. SndCh_methods, /* tp_methods */
  211. 0, /*tp_members*/
  212. SndCh_getsetlist, /*tp_getset*/
  213. 0, /*tp_base*/
  214. 0, /*tp_dict*/
  215. 0, /*tp_descr_get*/
  216. 0, /*tp_descr_set*/
  217. 0, /*tp_dictoffset*/
  218. 0, /*tp_init*/
  219. 0, /*tp_alloc*/
  220. 0, /*tp_new*/
  221. 0, /*tp_free*/
  222. };
  223. /* ------------------- End object type SndChannel ------------------- */
  224. /* ------------------------ Object type SPB ------------------------- */
  225. static PyTypeObject SPB_Type;
  226. #define SPBObj_Check(x) ((x)->ob_type == &SPB_Type || PyObject_TypeCheck((x), &SPB_Type))
  227. typedef struct SPBObject {
  228. PyObject_HEAD
  229. /* Members used to implement callbacks: */
  230. PyObject *ob_completion;
  231. PyObject *ob_interrupt;
  232. PyObject *ob_thiscallback;
  233. long ob_A5;
  234. SPB ob_spb;
  235. } SPBObject;
  236. static PyObject *SPBObj_New(void)
  237. {
  238. SPBObject *it;
  239. it = PyObject_NEW(SPBObject, &SPB_Type);
  240. if (it == NULL) return NULL;
  241. it->ob_completion = NULL;
  242. it->ob_interrupt = NULL;
  243. it->ob_thiscallback = NULL;
  244. it->ob_A5 = SetCurrentA5();
  245. memset((char *)&it->ob_spb, 0, sizeof(it->ob_spb));
  246. it->ob_spb.userLong = (long)it;
  247. return (PyObject *)it;
  248. }
  249. static int SPBObj_Convert(PyObject *v, SPBPtr *p_itself)
  250. {
  251. if (!SPBObj_Check(v))
  252. {
  253. PyErr_SetString(PyExc_TypeError, "SPB required");
  254. return 0;
  255. }
  256. *p_itself = &((SPBObject *)v)->ob_spb;
  257. return 1;
  258. }
  259. static void SPBObj_dealloc(SPBObject *self)
  260. {
  261. /* Cleanup of self->ob_itself goes here */
  262. self->ob_spb.userLong = 0;
  263. self->ob_thiscallback = 0;
  264. Py_XDECREF(self->ob_completion);
  265. Py_XDECREF(self->ob_interrupt);
  266. PyObject_Free((PyObject *)self);
  267. }
  268. static PyMethodDef SPBObj_methods[] = {
  269. {NULL, NULL, 0}
  270. };
  271. static PyObject *SPBObj_get_inRefNum(SPBObject *self, void *closure)
  272. {
  273. return Py_BuildValue("l", self->ob_spb.inRefNum);
  274. }
  275. static int SPBObj_set_inRefNum(SPBObject *self, PyObject *v, void *closure)
  276. {
  277. return -1 + PyArg_Parse(v, "l", &self->ob_spb.inRefNum);
  278. return 0;
  279. }
  280. static PyObject *SPBObj_get_count(SPBObject *self, void *closure)
  281. {
  282. return Py_BuildValue("l", self->ob_spb.count);
  283. }
  284. static int SPBObj_set_count(SPBObject *self, PyObject *v, void *closure)
  285. {
  286. return -1 + PyArg_Parse(v, "l", &self->ob_spb.count);
  287. return 0;
  288. }
  289. static PyObject *SPBObj_get_milliseconds(SPBObject *self, void *closure)
  290. {
  291. return Py_BuildValue("l", self->ob_spb.milliseconds);
  292. }
  293. static int SPBObj_set_milliseconds(SPBObject *self, PyObject *v, void *closure)
  294. {
  295. return -1 + PyArg_Parse(v, "l", &self->ob_spb.milliseconds);
  296. return 0;
  297. }
  298. static PyObject *SPBObj_get_error(SPBObject *self, void *closure)
  299. {
  300. return Py_BuildValue("h", self->ob_spb.error);
  301. }
  302. #define SPBObj_set_error NULL
  303. #define SPBObj_get_completionRoutine NULL
  304. static int SPBObj_set_completionRoutine(SPBObject *self, PyObject *v, void *closure)
  305. {
  306. self->ob_spb.completionRoutine = NewSICompletionUPP(SPB_completion);
  307. self->ob_completion = v;
  308. Py_INCREF(v);
  309. return 0;
  310. return 0;
  311. }
  312. static PyGetSetDef SPBObj_getsetlist[] = {
  313. {"inRefNum", (getter)SPBObj_get_inRefNum, (setter)SPBObj_set_inRefNum, NULL},
  314. {"count", (getter)SPBObj_get_count, (setter)SPBObj_set_count, NULL},
  315. {"milliseconds", (getter)SPBObj_get_milliseconds, (setter)SPBObj_set_milliseconds, NULL},
  316. {"error", (getter)SPBObj_get_error, (setter)SPBObj_set_error, NULL},
  317. {"completionRoutine", (getter)SPBObj_get_completionRoutine, (setter)SPBObj_set_completionRoutine, NULL},
  318. {NULL, NULL, NULL, NULL},
  319. };
  320. #define SPBObj_compare NULL
  321. #define SPBObj_repr NULL
  322. #define SPBObj_hash NULL
  323. static PyTypeObject SPB_Type = {
  324. PyObject_HEAD_INIT(NULL)
  325. 0, /*ob_size*/
  326. "_Snd.SPB", /*tp_name*/
  327. sizeof(SPBObject), /*tp_basicsize*/
  328. 0, /*tp_itemsize*/
  329. /* methods */
  330. (destructor) SPBObj_dealloc, /*tp_dealloc*/
  331. 0, /*tp_print*/
  332. (getattrfunc)0, /*tp_getattr*/
  333. (setattrfunc)0, /*tp_setattr*/
  334. (cmpfunc) SPBObj_compare, /*tp_compare*/
  335. (reprfunc) SPBObj_repr, /*tp_repr*/
  336. (PyNumberMethods *)0, /* tp_as_number */
  337. (PySequenceMethods *)0, /* tp_as_sequence */
  338. (PyMappingMethods *)0, /* tp_as_mapping */
  339. (hashfunc) SPBObj_hash, /*tp_hash*/
  340. 0, /*tp_call*/
  341. 0, /*tp_str*/
  342. PyObject_GenericGetAttr, /*tp_getattro*/
  343. PyObject_GenericSetAttr, /*tp_setattro */
  344. 0, /*tp_as_buffer*/
  345. Py_TPFLAGS_DEFAULT, /* tp_flags */
  346. 0, /*tp_doc*/
  347. 0, /*tp_traverse*/
  348. 0, /*tp_clear*/
  349. 0, /*tp_richcompare*/
  350. 0, /*tp_weaklistoffset*/
  351. 0, /*tp_iter*/
  352. 0, /*tp_iternext*/
  353. SPBObj_methods, /* tp_methods */
  354. 0, /*tp_members*/
  355. SPBObj_getsetlist, /*tp_getset*/
  356. 0, /*tp_base*/
  357. 0, /*tp_dict*/
  358. 0, /*tp_descr_get*/
  359. 0, /*tp_descr_set*/
  360. 0, /*tp_dictoffset*/
  361. 0, /*tp_init*/
  362. 0, /*tp_alloc*/
  363. 0, /*tp_new*/
  364. 0, /*tp_free*/
  365. };
  366. /* ---------------------- End object type SPB ----------------------- */
  367. static PyObject *Snd_SPB(PyObject *_self, PyObject *_args)
  368. {
  369. PyObject *_res = NULL;
  370. _res = SPBObj_New(); return _res;
  371. }
  372. static PyObject *Snd_SysBeep(PyObject *_self, PyObject *_args)
  373. {
  374. PyObject *_res = NULL;
  375. short duration;
  376. if (!PyArg_ParseTuple(_args, "h",
  377. &duration))
  378. return NULL;
  379. SysBeep(duration);
  380. Py_INCREF(Py_None);
  381. _res = Py_None;
  382. return _res;
  383. }
  384. static PyObject *Snd_SndNewChannel(PyObject *_self, PyObject *_args)
  385. {
  386. PyObject *_res = NULL;
  387. OSErr _err;
  388. SndChannelPtr chan = 0;
  389. short synth;
  390. long init;
  391. PyObject* userRoutine;
  392. if (!PyArg_ParseTuple(_args, "hlO",
  393. &synth,
  394. &init,
  395. &userRoutine))
  396. return NULL;
  397. if (userRoutine != Py_None && !PyCallable_Check(userRoutine))
  398. {
  399. PyErr_SetString(PyExc_TypeError, "callback must be callable");
  400. goto userRoutine__error__;
  401. }
  402. _err = SndNewChannel(&chan,
  403. synth,
  404. init,
  405. NewSndCallBackUPP(SndCh_UserRoutine));
  406. if (_err != noErr) return PyMac_Error(_err);
  407. _res = Py_BuildValue("O&",
  408. SndCh_New, chan);
  409. if (_res != NULL && userRoutine != Py_None)
  410. {
  411. SndChannelObject *p = (SndChannelObject *)_res;
  412. p->ob_itself->userInfo = (long)p;
  413. Py_INCREF(userRoutine);
  414. p->ob_callback = userRoutine;
  415. }
  416. userRoutine__error__: ;
  417. return _res;
  418. }
  419. static PyObject *Snd_SndSoundManagerVersion(PyObject *_self, PyObject *_args)
  420. {
  421. PyObject *_res = NULL;
  422. NumVersion _rv;
  423. if (!PyArg_ParseTuple(_args, ""))
  424. return NULL;
  425. _rv = SndSoundManagerVersion();
  426. _res = Py_BuildValue("O&",
  427. PyMac_BuildNumVersion, _rv);
  428. return _res;
  429. }
  430. static PyObject *Snd_SndManagerStatus(PyObject *_self, PyObject *_args)
  431. {
  432. PyObject *_res = NULL;
  433. OSErr _err;
  434. short theLength;
  435. SMStatus theStatus__out__;
  436. if (!PyArg_ParseTuple(_args, "h",
  437. &theLength))
  438. return NULL;
  439. _err = SndManagerStatus(theLength,
  440. &theStatus__out__);
  441. if (_err != noErr) return PyMac_Error(_err);
  442. _res = Py_BuildValue("s#",
  443. (char *)&theStatus__out__, (int)sizeof(SMStatus));
  444. return _res;
  445. }
  446. static PyObject *Snd_SndGetSysBeepState(PyObject *_self, PyObject *_args)
  447. {
  448. PyObject *_res = NULL;
  449. short sysBeepState;
  450. if (!PyArg_ParseTuple(_args, ""))
  451. return NULL;
  452. SndGetSysBeepState(&sysBeepState);
  453. _res = Py_BuildValue("h",
  454. sysBeepState);
  455. return _res;
  456. }
  457. static PyObject *Snd_SndSetSysBeepState(PyObject *_self, PyObject *_args)
  458. {
  459. PyObject *_res = NULL;
  460. OSErr _err;
  461. short sysBeepState;
  462. if (!PyArg_ParseTuple(_args, "h",
  463. &sysBeepState))
  464. return NULL;
  465. _err = SndSetSysBeepState(sysBeepState);
  466. if (_err != noErr) return PyMac_Error(_err);
  467. Py_INCREF(Py_None);
  468. _res = Py_None;
  469. return _res;
  470. }
  471. static PyObject *Snd_GetSysBeepVolume(PyObject *_self, PyObject *_args)
  472. {
  473. PyObject *_res = NULL;
  474. OSErr _err;
  475. long level;
  476. if (!PyArg_ParseTuple(_args, ""))
  477. return NULL;
  478. _err = GetSysBeepVolume(&level);
  479. if (_err != noErr) return PyMac_Error(_err);
  480. _res = Py_BuildValue("l",
  481. level);
  482. return _res;
  483. }
  484. static PyObject *Snd_SetSysBeepVolume(PyObject *_self, PyObject *_args)
  485. {
  486. PyObject *_res = NULL;
  487. OSErr _err;
  488. long level;
  489. if (!PyArg_ParseTuple(_args, "l",
  490. &level))
  491. return NULL;
  492. _err = SetSysBeepVolume(level);
  493. if (_err != noErr) return PyMac_Error(_err);
  494. Py_INCREF(Py_None);
  495. _res = Py_None;
  496. return _res;
  497. }
  498. static PyObject *Snd_GetDefaultOutputVolume(PyObject *_self, PyObject *_args)
  499. {
  500. PyObject *_res = NULL;
  501. OSErr _err;
  502. long level;
  503. if (!PyArg_ParseTuple(_args, ""))
  504. return NULL;
  505. _err = GetDefaultOutputVolume(&level);
  506. if (_err != noErr) return PyMac_Error(_err);
  507. _res = Py_BuildValue("l",
  508. level);
  509. return _res;
  510. }
  511. static PyObject *Snd_SetDefaultOutputVolume(PyObject *_self, PyObject *_args)
  512. {
  513. PyObject *_res = NULL;
  514. OSErr _err;
  515. long level;
  516. if (!PyArg_ParseTuple(_args, "l",
  517. &level))
  518. return NULL;
  519. _err = SetDefaultOutputVolume(level);
  520. if (_err != noErr) return PyMac_Error(_err);
  521. Py_INCREF(Py_None);
  522. _res = Py_None;
  523. return _res;
  524. }
  525. static PyObject *Snd_GetSoundHeaderOffset(PyObject *_self, PyObject *_args)
  526. {
  527. PyObject *_res = NULL;
  528. OSErr _err;
  529. SndListHandle sndHandle;
  530. long offset;
  531. if (!PyArg_ParseTuple(_args, "O&",
  532. ResObj_Convert, &sndHandle))
  533. return NULL;
  534. _err = GetSoundHeaderOffset(sndHandle,
  535. &offset);
  536. if (_err != noErr) return PyMac_Error(_err);
  537. _res = Py_BuildValue("l",
  538. offset);
  539. return _res;
  540. }
  541. static PyObject *Snd_GetCompressionInfo(PyObject *_self, PyObject *_args)
  542. {
  543. PyObject *_res = NULL;
  544. OSErr _err;
  545. short compressionID;
  546. OSType format;
  547. short numChannels;
  548. short sampleSize;
  549. CompressionInfo cp__out__;
  550. if (!PyArg_ParseTuple(_args, "hO&hh",
  551. &compressionID,
  552. PyMac_GetOSType, &format,
  553. &numChannels,
  554. &sampleSize))
  555. return NULL;
  556. _err = GetCompressionInfo(compressionID,
  557. format,
  558. numChannels,
  559. sampleSize,
  560. &cp__out__);
  561. if (_err != noErr) return PyMac_Error(_err);
  562. _res = Py_BuildValue("s#",
  563. (char *)&cp__out__, (int)sizeof(CompressionInfo));
  564. return _res;
  565. }
  566. static PyObject *Snd_SetSoundPreference(PyObject *_self, PyObject *_args)
  567. {
  568. PyObject *_res = NULL;
  569. OSErr _err;
  570. OSType theType;
  571. Str255 name;
  572. Handle settings;
  573. if (!PyArg_ParseTuple(_args, "O&O&",
  574. PyMac_GetOSType, &theType,
  575. ResObj_Convert, &settings))
  576. return NULL;
  577. _err = SetSoundPreference(theType,
  578. name,
  579. settings);
  580. if (_err != noErr) return PyMac_Error(_err);
  581. _res = Py_BuildValue("O&",
  582. PyMac_BuildStr255, name);
  583. return _res;
  584. }
  585. static PyObject *Snd_GetSoundPreference(PyObject *_self, PyObject *_args)
  586. {
  587. PyObject *_res = NULL;
  588. OSErr _err;
  589. OSType theType;
  590. Str255 name;
  591. Handle settings;
  592. if (!PyArg_ParseTuple(_args, "O&O&",
  593. PyMac_GetOSType, &theType,
  594. ResObj_Convert, &settings))
  595. return NULL;
  596. _err = GetSoundPreference(theType,
  597. name,
  598. settings);
  599. if (_err != noErr) return PyMac_Error(_err);
  600. _res = Py_BuildValue("O&",
  601. PyMac_BuildStr255, name);
  602. return _res;
  603. }
  604. static PyObject *Snd_GetCompressionName(PyObject *_self, PyObject *_args)
  605. {
  606. PyObject *_res = NULL;
  607. OSErr _err;
  608. OSType compressionType;
  609. Str255 compressionName;
  610. if (!PyArg_ParseTuple(_args, "O&",
  611. PyMac_GetOSType, &compressionType))
  612. return NULL;
  613. _err = GetCompressionName(compressionType,
  614. compressionName);
  615. if (_err != noErr) return PyMac_Error(_err);
  616. _res = Py_BuildValue("O&",
  617. PyMac_BuildStr255, compressionName);
  618. return _res;
  619. }
  620. static PyObject *Snd_SPBVersion(PyObject *_self, PyObject *_args)
  621. {
  622. PyObject *_res = NULL;
  623. NumVersion _rv;
  624. if (!PyArg_ParseTuple(_args, ""))
  625. return NULL;
  626. _rv = SPBVersion();
  627. _res = Py_BuildValue("O&",
  628. PyMac_BuildNumVersion, _rv);
  629. return _res;
  630. }
  631. static PyObject *Snd_SndRecord(PyObject *_self, PyObject *_args)
  632. {
  633. PyObject *_res = NULL;
  634. OSErr _err;
  635. Point corner;
  636. OSType quality;
  637. SndListHandle sndHandle;
  638. if (!PyArg_ParseTuple(_args, "O&O&",
  639. PyMac_GetPoint, &corner,
  640. PyMac_GetOSType, &quality))
  641. return NULL;
  642. _err = SndRecord((ModalFilterUPP)0,
  643. corner,
  644. quality,
  645. &sndHandle);
  646. if (_err != noErr) return PyMac_Error(_err);
  647. _res = Py_BuildValue("O&",
  648. ResObj_New, sndHandle);
  649. return _res;
  650. }
  651. static PyObject *Snd_SPBSignInDevice(PyObject *_self, PyObject *_args)
  652. {
  653. PyObject *_res = NULL;
  654. OSErr _err;
  655. short deviceRefNum;
  656. Str255 deviceName;
  657. if (!PyArg_ParseTuple(_args, "hO&",
  658. &deviceRefNum,
  659. PyMac_GetStr255, deviceName))
  660. return NULL;
  661. _err = SPBSignInDevice(deviceRefNum,
  662. deviceName);
  663. if (_err != noErr) return PyMac_Error(_err);
  664. Py_INCREF(Py_None);
  665. _res = Py_None;
  666. return _res;
  667. }
  668. static PyObject *Snd_SPBSignOutDevice(PyObject *_self, PyObject *_args)
  669. {
  670. PyObject *_res = NULL;
  671. OSErr _err;
  672. short deviceRefNum;
  673. if (!PyArg_ParseTuple(_args, "h",
  674. &deviceRefNum))
  675. return NULL;
  676. _err = SPBSignOutDevice(deviceRefNum);
  677. if (_err != noErr) return PyMac_Error(_err);
  678. Py_INCREF(Py_None);
  679. _res = Py_None;
  680. return _res;
  681. }
  682. static PyObject *Snd_SPBGetIndexedDevice(PyObject *_self, PyObject *_args)
  683. {
  684. PyObject *_res = NULL;
  685. OSErr _err;
  686. short count;
  687. Str255 deviceName;
  688. Handle deviceIconHandle;
  689. if (!PyArg_ParseTuple(_args, "h",
  690. &count))
  691. return NULL;
  692. _err = SPBGetIndexedDevice(count,
  693. deviceName,
  694. &deviceIconHandle);
  695. if (_err != noErr) return PyMac_Error(_err);
  696. _res = Py_BuildValue("O&O&",
  697. PyMac_BuildStr255, deviceName,
  698. ResObj_New, deviceIconHandle);
  699. return _res;
  700. }
  701. static PyObject *Snd_SPBOpenDevice(PyObject *_self, PyObject *_args)
  702. {
  703. PyObject *_res = NULL;
  704. OSErr _err;
  705. Str255 deviceName;
  706. short permission;
  707. long inRefNum;
  708. if (!PyArg_ParseTuple(_args, "O&h",
  709. PyMac_GetStr255, deviceName,
  710. &permission))
  711. return NULL;
  712. _err = SPBOpenDevice(deviceName,
  713. permission,
  714. &inRefNum);
  715. if (_err != noErr) return PyMac_Error(_err);
  716. _res = Py_BuildValue("l",
  717. inRefNum);
  718. return _res;
  719. }
  720. static PyObject *Snd_SPBCloseDevice(PyObject *_self, PyObject *_args)
  721. {
  722. PyObject *_res = NULL;
  723. OSErr _err;
  724. long inRefNum;
  725. if (!PyArg_ParseTuple(_args, "l",
  726. &inRefNum))
  727. return NULL;
  728. _err = SPBCloseDevice(inRefNum);
  729. if (_err != noErr) return PyMac_Error(_err);
  730. Py_INCREF(Py_None);
  731. _res = Py_None;
  732. return _res;
  733. }
  734. static PyObject *Snd_SPBRecord(PyObject *_self, PyObject *_args)
  735. {
  736. PyObject *_res = NULL;
  737. OSErr _err;
  738. SPBPtr inParamPtr;
  739. Boolean asynchFlag;
  740. if (!PyArg_ParseTuple(_args, "O&b",
  741. SPBObj_Convert, &inParamPtr,
  742. &asynchFlag))
  743. return NULL;
  744. _err = SPBRecord(inParamPtr,
  745. asynchFlag);
  746. if (_err != noErr) return PyMac_Error(_err);
  747. Py_INCREF(Py_None);
  748. _res = Py_None;
  749. return _res;
  750. }
  751. static PyObject *Snd_SPBPauseRecording(PyObject *_self, PyObject *_args)
  752. {
  753. PyObject *_res = NULL;
  754. OSErr _err;
  755. long inRefNum;
  756. if (!PyArg_ParseTuple(_args, "l",
  757. &inRefNum))
  758. return NULL;
  759. _err = SPBPauseRecording(inRefNum);
  760. if (_err != noErr) return PyMac_Error(_err);
  761. Py_INCREF(Py_None);
  762. _res = Py_None;
  763. return _res;
  764. }
  765. static PyObject *Snd_SPBResumeRecording(PyObject *_self, PyObject *_args)
  766. {
  767. PyObject *_res = NULL;
  768. OSErr _err;
  769. long inRefNum;
  770. if (!PyArg_ParseTuple(_args, "l",
  771. &inRefNum))
  772. return NULL;
  773. _err = SPBResumeRecording(inRefNum);
  774. if (_err != noErr) return PyMac_Error(_err);
  775. Py_INCREF(Py_None);
  776. _res = Py_None;
  777. return _res;
  778. }
  779. static PyObject *Snd_SPBStopRecording(PyObject *_self, PyObject *_args)
  780. {
  781. PyObject *_res = NULL;
  782. OSErr _err;
  783. long inRefNum;
  784. if (!PyArg_ParseTuple(_args, "l",
  785. &inRefNum))
  786. return NULL;
  787. _err = SPBStopRecording(inRefNum);
  788. if (_err != noErr) return PyMac_Error(_err);
  789. Py_INCREF(Py_None);
  790. _res = Py_None;
  791. return _res;
  792. }
  793. static PyObject *Snd_SPBGetRecordingStatus(PyObject *_self, PyObject *_args)
  794. {
  795. PyObject *_res = NULL;
  796. OSErr _err;
  797. long inRefNum;
  798. short recordingStatus;
  799. short meterLevel;
  800. unsigned long totalSamplesToRecord;
  801. unsigned long numberOfSamplesRecorded;
  802. unsigned long totalMsecsToRecord;
  803. unsigned long numberOfMsecsRecorded;
  804. if (!PyArg_ParseTuple(_args, "l",
  805. &inRefNum))
  806. return NULL;
  807. _err = SPBGetRecordingStatus(inRefNum,
  808. &recordingStatus,
  809. &meterLevel,
  810. &totalSamplesToRecord,
  811. &numberOfSamplesRecorded,
  812. &totalMsecsToRecord,
  813. &numberOfMsecsRecorded);
  814. if (_err != noErr) return PyMac_Error(_err);
  815. _res = Py_BuildValue("hhllll",
  816. recordingStatus,
  817. meterLevel,
  818. totalSamplesToRecord,
  819. numberOfSamplesRecorded,
  820. totalMsecsToRecord,
  821. numberOfMsecsRecorded);
  822. return _res;
  823. }
  824. static PyObject *Snd_SPBGetDeviceInfo(PyObject *_self, PyObject *_args)
  825. {
  826. PyObject *_res = NULL;
  827. OSErr _err;
  828. long inRefNum;
  829. OSType infoType;
  830. void * infoData;
  831. if (!PyArg_ParseTuple(_args, "lO&w",
  832. &inRefNum,
  833. PyMac_GetOSType, &infoType,
  834. &infoData))
  835. return NULL;
  836. _err = SPBGetDeviceInfo(inRefNum,
  837. infoType,
  838. infoData);
  839. if (_err != noErr) return PyMac_Error(_err);
  840. Py_INCREF(Py_None);
  841. _res = Py_None;
  842. return _res;
  843. }
  844. static PyObject *Snd_SPBSetDeviceInfo(PyObject *_self, PyObject *_args)
  845. {
  846. PyObject *_res = NULL;
  847. OSErr _err;
  848. long inRefNum;
  849. OSType infoType;
  850. void * infoData;
  851. if (!PyArg_ParseTuple(_args, "lO&w",
  852. &inRefNum,
  853. PyMac_GetOSType, &infoType,
  854. &infoData))
  855. return NULL;
  856. _err = SPBSetDeviceInfo(inRefNum,
  857. infoType,
  858. infoData);
  859. if (_err != noErr) return PyMac_Error(_err);
  860. Py_INCREF(Py_None);
  861. _res = Py_None;
  862. return _res;
  863. }
  864. static PyObject *Snd_SPBMillisecondsToBytes(PyObject *_self, PyObject *_args)
  865. {
  866. PyObject *_res = NULL;
  867. OSErr _err;
  868. long inRefNum;
  869. long milliseconds;
  870. if (!PyArg_ParseTuple(_args, "l",
  871. &inRefNum))
  872. return NULL;
  873. _err = SPBMillisecondsToBytes(inRefNum,
  874. &milliseconds);
  875. if (_err != noErr) return PyMac_Error(_err);
  876. _res = Py_BuildValue("l",
  877. milliseconds);
  878. return _res;
  879. }
  880. static PyObject *Snd_SPBBytesToMilliseconds(PyObject *_self, PyObject *_args)
  881. {
  882. PyObject *_res = NULL;
  883. OSErr _err;
  884. long inRefNum;
  885. long byteCount;
  886. if (!PyArg_ParseTuple(_args, "l",
  887. &inRefNum))
  888. return NULL;
  889. _err = SPBBytesToMilliseconds(inRefNum,
  890. &byteCount);
  891. if (_err != noErr) return PyMac_Error(_err);
  892. _res = Py_BuildValue("l",
  893. byteCount);
  894. return _res;
  895. }
  896. #endif /* __LP64__ */
  897. static PyMethodDef Snd_methods[] = {
  898. #ifndef __LP64__
  899. {"SPB", (PyCFunction)Snd_SPB, 1,
  900. PyDoc_STR(NULL)},
  901. {"SysBeep", (PyCFunction)Snd_SysBeep, 1,
  902. PyDoc_STR("(short duration) -> None")},
  903. {"SndNewChannel", (PyCFunction)Snd_SndNewChannel, 1,
  904. PyDoc_STR("(short synth, long init, PyObject* userRoutine) -> (SndChannelPtr chan)")},
  905. {"SndSoundManagerVersion", (PyCFunction)Snd_SndSoundManagerVersion, 1,
  906. PyDoc_STR("() -> (NumVersion _rv)")},
  907. {"SndManagerStatus", (PyCFunction)Snd_SndManagerStatus, 1,
  908. PyDoc_STR("(short theLength) -> (SMStatus theStatus)")},
  909. {"SndGetSysBeepState", (PyCFunction)Snd_SndGetSysBeepState, 1,
  910. PyDoc_STR("() -> (short sysBeepState)")},
  911. {"SndSetSysBeepState", (PyCFunction)Snd_SndSetSysBeepState, 1,
  912. PyDoc_STR("(short sysBeepState) -> None")},
  913. {"GetSysBeepVolume", (PyCFunction)Snd_GetSysBeepVolume, 1,
  914. PyDoc_STR("() -> (long level)")},
  915. {"SetSysBeepVolume", (PyCFunction)Snd_SetSysBeepVolume, 1,
  916. PyDoc_STR("(long level) -> None")},
  917. {"GetDefaultOutputVolume", (PyCFunction)Snd_GetDefaultOutputVolume, 1,
  918. PyDoc_STR("() -> (long level)")},
  919. {"SetDefaultOutputVolume", (PyCFunction)Snd_SetDefaultOutputVolume, 1,
  920. PyDoc_STR("(long level) -> None")},
  921. {"GetSoundHeaderOffset", (PyCFunction)Snd_GetSoundHeaderOffset, 1,
  922. PyDoc_STR("(SndListHandle sndHandle) -> (long offset)")},
  923. {"GetCompressionInfo", (PyCFunction)Snd_GetCompressionInfo, 1,
  924. PyDoc_STR("(short compressionID, OSType format, short numChannels, short sampleSize) -> (CompressionInfo cp)")},
  925. {"SetSoundPreference", (PyCFunction)Snd_SetSoundPreference, 1,
  926. PyDoc_STR("(OSType theType, Handle settings) -> (Str255 name)")},
  927. {"GetSoundPreference", (PyCFunction)Snd_GetSoundPreference, 1,
  928. PyDoc_STR("(OSType theType, Handle settings) -> (Str255 name)")},
  929. {"GetCompressionName", (PyCFunction)Snd_GetCompressionName, 1,
  930. PyDoc_STR("(OSType compressionType) -> (Str255 compressionName)")},
  931. {"SPBVersion", (PyCFunction)Snd_SPBVersion, 1,
  932. PyDoc_STR("() -> (NumVersion _rv)")},
  933. {"SndRecord", (PyCFunction)Snd_SndRecord, 1,
  934. PyDoc_STR("(Point corner, OSType quality) -> (SndListHandle sndHandle)")},
  935. {"SPBSignInDevice", (PyCFunction)Snd_SPBSignInDevice, 1,
  936. PyDoc_STR("(short deviceRefNum, Str255 deviceName) -> None")},
  937. {"SPBSignOutDevice", (PyCFunction)Snd_SPBSignOutDevice, 1,
  938. PyDoc_STR("(short deviceRefNum) -> None")},
  939. {"SPBGetIndexedDevice", (PyCFunction)Snd_SPBGetIndexedDevice, 1,
  940. PyDoc_STR("(short count) -> (Str255 deviceName, Handle deviceIconHandle)")},
  941. {"SPBOpenDevice", (PyCFunction)Snd_SPBOpenDevice, 1,
  942. PyDoc_STR("(Str255 deviceName, short permission) -> (long inRefNum)")},
  943. {"SPBCloseDevice", (PyCFunction)Snd_SPBCloseDevice, 1,
  944. PyDoc_STR("(long inRefNum) -> None")},
  945. {"SPBRecord", (PyCFunction)Snd_SPBRecord, 1,
  946. PyDoc_STR("(SPBPtr inParamPtr, Boolean asynchFlag) -> None")},
  947. {"SPBPauseRecording", (PyCFunction)Snd_SPBPauseRecording, 1,
  948. PyDoc_STR("(long inRefNum) -> None")},
  949. {"SPBResumeRecording", (PyCFunction)Snd_SPBResumeRecording, 1,
  950. PyDoc_STR("(long inRefNum) -> None")},
  951. {"SPBStopRecording", (PyCFunction)Snd_SPBStopRecording, 1,
  952. PyDoc_STR("(long inRefNum) -> None")},
  953. {"SPBGetRecordingStatus", (PyCFunction)Snd_SPBGetRecordingStatus, 1,
  954. PyDoc_STR("(long inRefNum) -> (short recordingStatus, short meterLevel, unsigned long totalSamplesToRecord, unsigned long numberOfSamplesRecorded, unsigned long totalMsecsToRecord, unsigned long numberOfMsecsRecorded)")},
  955. {"SPBGetDeviceInfo", (PyCFunction)Snd_SPBGetDeviceInfo, 1,
  956. PyDoc_STR("(long inRefNum, OSType infoType, void * infoData) -> None")},
  957. {"SPBSetDeviceInfo", (PyCFunction)Snd_SPBSetDeviceInfo, 1,
  958. PyDoc_STR("(long inRefNum, OSType infoType, void * infoData) -> None")},
  959. {"SPBMillisecondsToBytes", (PyCFunction)Snd_SPBMillisecondsToBytes, 1,
  960. PyDoc_STR("(long inRefNum) -> (long milliseconds)")},
  961. {"SPBBytesToMilliseconds", (PyCFunction)Snd_SPBBytesToMilliseconds, 1,
  962. PyDoc_STR("(long inRefNum) -> (long byteCount)")},
  963. #endif /* __LP64__ */
  964. {NULL, NULL, 0}
  965. };
  966. #ifndef __LP64__
  967. /* Routine passed to Py_AddPendingCall -- call the Python callback */
  968. static int
  969. SndCh_CallCallBack(void *arg)
  970. {
  971. SndChannelObject *p = (SndChannelObject *)arg;
  972. PyObject *args;
  973. PyObject *res;
  974. args = Py_BuildValue("(O(hhl))",
  975. p, p->ob_cmd.cmd, p->ob_cmd.param1, p->ob_cmd.param2);
  976. res = PyEval_CallObject(p->ob_callback, args);
  977. Py_DECREF(args);
  978. if (res == NULL)
  979. return -1;
  980. Py_DECREF(res);
  981. return 0;
  982. }
  983. /* Routine passed to NewSndChannel -- schedule a call to SndCh_CallCallBack */
  984. static pascal void
  985. SndCh_UserRoutine(SndChannelPtr chan, SndCommand *cmd)
  986. {
  987. SndChannelObject *p = (SndChannelObject *)(chan->userInfo);
  988. if (p->ob_callback != NULL) {
  989. long A5 = SetA5(p->ob_A5);
  990. p->ob_cmd = *cmd;
  991. Py_AddPendingCall(SndCh_CallCallBack, (void *)p);
  992. SetA5(A5);
  993. }
  994. }
  995. /* SPB callbacks - Schedule callbacks to Python */
  996. static int
  997. SPB_CallCallBack(void *arg)
  998. {
  999. SPBObject *p = (SPBObject *)arg;
  1000. PyObject *args;
  1001. PyObject *res;
  1002. if ( p->ob_thiscallback == 0 ) return 0;
  1003. args = Py_BuildValue("(O)", p);
  1004. res = PyEval_CallObject(p->ob_thiscallback, args);
  1005. p->ob_thiscallback = 0;
  1006. Py_DECREF(args);
  1007. if (res == NULL)
  1008. return -1;
  1009. Py_DECREF(res);
  1010. return 0;
  1011. }
  1012. static pascal void
  1013. SPB_completion(SPBPtr my_spb)
  1014. {
  1015. SPBObject *p = (SPBObject *)(my_spb->userLong);
  1016. if (p && p->ob_completion) {
  1017. long A5 = SetA5(p->ob_A5);
  1018. p->ob_thiscallback = p->ob_completion; /* Hope we cannot get two at the same time */
  1019. Py_AddPendingCall(SPB_CallCallBack, (void *)p);
  1020. SetA5(A5);
  1021. }
  1022. }
  1023. #endif /* __LP64__ */
  1024. void init_Snd(void)
  1025. {
  1026. PyObject *m;
  1027. #ifndef __LP64__
  1028. PyObject *d;
  1029. #endif /* __LP64__ */
  1030. m = Py_InitModule("_Snd", Snd_methods);
  1031. #ifndef __LP64__
  1032. d = PyModule_GetDict(m);
  1033. Snd_Error = PyMac_GetOSErrException();
  1034. if (Snd_Error == NULL ||
  1035. PyDict_SetItemString(d, "Error", Snd_Error) != 0)
  1036. return;
  1037. SndChannel_Type.ob_type = &PyType_Type;
  1038. if (PyType_Ready(&SndChannel_Type) < 0) return;
  1039. Py_INCREF(&SndChannel_Type);
  1040. PyModule_AddObject(m, "SndChannel", (PyObject *)&SndChannel_Type);
  1041. /* Backward-compatible name */
  1042. Py_INCREF(&SndChannel_Type);
  1043. PyModule_AddObject(m, "SndChannelType", (PyObject *)&SndChannel_Type);
  1044. SPB_Type.ob_type = &PyType_Type;
  1045. if (PyType_Ready(&SPB_Type) < 0) return;
  1046. Py_INCREF(&SPB_Type);
  1047. PyModule_AddObject(m, "SPB", (PyObject *)&SPB_Type);
  1048. /* Backward-compatible name */
  1049. Py_INCREF(&SPB_Type);
  1050. PyModule_AddObject(m, "SPBType", (PyObject *)&SPB_Type);
  1051. #endif /* __LP64__ */
  1052. }
  1053. /* ======================== End module _Snd ========================= */