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