1 
2 /* ========================== Module _Snd =========================== */
3 
4 #include "Python.h"
5 
6 #ifndef __LP64__
7 
8 
9 #include "pymactoolbox.h"
10 
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)
17 
18 
19 #include <Carbon/Carbon.h>
20 
21 /* Convert a SndCommand argument */
22 static int
SndCmd_Convert(PyObject * v,SndCommand * pc)23 SndCmd_Convert(PyObject *v, SndCommand *pc)
24 {
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);
33     }
34     return PyArg_Parse(v, "H", &pc->cmd);
35 }
36 
37 static pascal void SndCh_UserRoutine(SndChannelPtr chan, SndCommand *cmd); /* Forward */
38 static pascal void SPB_completion(SPBPtr my_spb); /* Forward */
39 
40 static PyObject *Snd_Error;
41 
42 /* --------------------- Object type SndChannel --------------------- */
43 
44 static PyTypeObject SndChannel_Type;
45 
46 #define SndCh_Check(x) ((x)->ob_type == &SndChannel_Type || PyObject_TypeCheck((x), &SndChannel_Type))
47 
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;
56 
SndCh_New(SndChannelPtr itself)57 static PyObject *SndCh_New(SndChannelPtr itself)
58 {
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;
66 }
67 
SndCh_dealloc(SndChannelObject * self)68 static void SndCh_dealloc(SndChannelObject *self)
69 {
70     SndDisposeChannel(self->ob_itself, 1);
71     Py_XDECREF(self->ob_callback);
72     PyObject_Free((PyObject *)self);
73 }
74 
SndCh_SndDoCommand(SndChannelObject * _self,PyObject * _args)75 static PyObject *SndCh_SndDoCommand(SndChannelObject *_self, PyObject *_args)
76 {
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;
92 }
93 
SndCh_SndDoImmediate(SndChannelObject * _self,PyObject * _args)94 static PyObject *SndCh_SndDoImmediate(SndChannelObject *_self, PyObject *_args)
95 {
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;
108 }
109 
SndCh_SndPlay(SndChannelObject * _self,PyObject * _args)110 static PyObject *SndCh_SndPlay(SndChannelObject *_self, PyObject *_args)
111 {
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;
127 }
128 
SndCh_SndChannelStatus(SndChannelObject * _self,PyObject * _args)129 static PyObject *SndCh_SndChannelStatus(SndChannelObject *_self, PyObject *_args)
130 {
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;
145 }
146 
SndCh_SndGetInfo(SndChannelObject * _self,PyObject * _args)147 static PyObject *SndCh_SndGetInfo(SndChannelObject *_self, PyObject *_args)
148 {
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;
164 }
165 
SndCh_SndSetInfo(SndChannelObject * _self,PyObject * _args)166 static PyObject *SndCh_SndSetInfo(SndChannelObject *_self, PyObject *_args)
167 {
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;
183 }
184 
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}
199 };
200 
201 #define SndCh_getsetlist NULL
202 
203 
204 #define SndCh_compare NULL
205 
206 #define SndCh_repr NULL
207 
208 #define SndCh_hash NULL
209 
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*/
252 };
253 
254 /* ------------------- End object type SndChannel ------------------- */
255 
256 
257 /* ------------------------ Object type SPB ------------------------- */
258 
259 static PyTypeObject SPB_Type;
260 
261 #define SPBObj_Check(x) ((x)->ob_type == &SPB_Type || PyObject_TypeCheck((x), &SPB_Type))
262 
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;
272 
SPBObj_New(void)273 static PyObject *SPBObj_New(void)
274 {
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;
285 }
SPBObj_Convert(PyObject * v,SPBPtr * p_itself)286 static int SPBObj_Convert(PyObject *v, SPBPtr *p_itself)
287 {
288     if (!SPBObj_Check(v))
289     {
290         PyErr_SetString(PyExc_TypeError, "SPB required");
291         return 0;
292     }
293     *p_itself = &((SPBObject *)v)->ob_spb;
294     return 1;
295 }
296 
SPBObj_dealloc(SPBObject * self)297 static void SPBObj_dealloc(SPBObject *self)
298 {
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);
305 }
306 
307 static PyMethodDef SPBObj_methods[] = {
308     {NULL, NULL, 0}
309 };
310 
SPBObj_get_inRefNum(SPBObject * self,void * closure)311 static PyObject *SPBObj_get_inRefNum(SPBObject *self, void *closure)
312 {
313     return Py_BuildValue("l", self->ob_spb.inRefNum);
314 }
315 
SPBObj_set_inRefNum(SPBObject * self,PyObject * v,void * closure)316 static int SPBObj_set_inRefNum(SPBObject *self, PyObject *v, void *closure)
317 {
318     return -1 + PyArg_Parse(v, "l", &self->ob_spb.inRefNum);
319     return 0;
320 }
321 
SPBObj_get_count(SPBObject * self,void * closure)322 static PyObject *SPBObj_get_count(SPBObject *self, void *closure)
323 {
324     return Py_BuildValue("l", self->ob_spb.count);
325 }
326 
SPBObj_set_count(SPBObject * self,PyObject * v,void * closure)327 static int SPBObj_set_count(SPBObject *self, PyObject *v, void *closure)
328 {
329     return -1 + PyArg_Parse(v, "l", &self->ob_spb.count);
330     return 0;
331 }
332 
SPBObj_get_milliseconds(SPBObject * self,void * closure)333 static PyObject *SPBObj_get_milliseconds(SPBObject *self, void *closure)
334 {
335     return Py_BuildValue("l", self->ob_spb.milliseconds);
336 }
337 
SPBObj_set_milliseconds(SPBObject * self,PyObject * v,void * closure)338 static int SPBObj_set_milliseconds(SPBObject *self, PyObject *v, void *closure)
339 {
340     return -1 + PyArg_Parse(v, "l", &self->ob_spb.milliseconds);
341     return 0;
342 }
343 
SPBObj_get_error(SPBObject * self,void * closure)344 static PyObject *SPBObj_get_error(SPBObject *self, void *closure)
345 {
346     return Py_BuildValue("h", self->ob_spb.error);
347 }
348 
349 #define SPBObj_set_error NULL
350 
351 #define SPBObj_get_completionRoutine NULL
352 
SPBObj_set_completionRoutine(SPBObject * self,PyObject * v,void * closure)353 static int SPBObj_set_completionRoutine(SPBObject *self, PyObject *v, void *closure)
354 {
355     self->ob_spb.completionRoutine = NewSICompletionUPP(SPB_completion);
356                 self->ob_completion = v;
357                 Py_INCREF(v);
358                 return 0;
359     return 0;
360 }
361 
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},
369 };
370 
371 
372 #define SPBObj_compare NULL
373 
374 #define SPBObj_repr NULL
375 
376 #define SPBObj_hash NULL
377 
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*/
420 };
421 
422 /* ---------------------- End object type SPB ----------------------- */
423 
424 
Snd_SPB(PyObject * _self,PyObject * _args)425 static PyObject *Snd_SPB(PyObject *_self, PyObject *_args)
426 {
427     PyObject *_res = NULL;
428     _res = SPBObj_New(); return _res;
429 }
430 
Snd_SysBeep(PyObject * _self,PyObject * _args)431 static PyObject *Snd_SysBeep(PyObject *_self, PyObject *_args)
432 {
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;
442 }
443 
Snd_SndNewChannel(PyObject * _self,PyObject * _args)444 static PyObject *Snd_SndNewChannel(PyObject *_self, PyObject *_args)
445 {
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))
458     {
459         PyErr_SetString(PyExc_TypeError, "callback must be callable");
460         goto userRoutine__error__;
461     }
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)
470     {
471         SndChannelObject *p = (SndChannelObject *)_res;
472         p->ob_itself->userInfo = (long)p;
473         Py_INCREF(userRoutine);
474         p->ob_callback = userRoutine;
475     }
476  userRoutine__error__: ;
477     return _res;
478 }
479 
Snd_SndSoundManagerVersion(PyObject * _self,PyObject * _args)480 static PyObject *Snd_SndSoundManagerVersion(PyObject *_self, PyObject *_args)
481 {
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;
490 }
491 
Snd_SndManagerStatus(PyObject * _self,PyObject * _args)492 static PyObject *Snd_SndManagerStatus(PyObject *_self, PyObject *_args)
493 {
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;
507 }
508 
Snd_SndGetSysBeepState(PyObject * _self,PyObject * _args)509 static PyObject *Snd_SndGetSysBeepState(PyObject *_self, PyObject *_args)
510 {
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;
519 }
520 
Snd_SndSetSysBeepState(PyObject * _self,PyObject * _args)521 static PyObject *Snd_SndSetSysBeepState(PyObject *_self, PyObject *_args)
522 {
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;
534 }
535 
Snd_GetSysBeepVolume(PyObject * _self,PyObject * _args)536 static PyObject *Snd_GetSysBeepVolume(PyObject *_self, PyObject *_args)
537 {
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;
548 }
549 
Snd_SetSysBeepVolume(PyObject * _self,PyObject * _args)550 static PyObject *Snd_SetSysBeepVolume(PyObject *_self, PyObject *_args)
551 {
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;
563 }
564 
Snd_GetDefaultOutputVolume(PyObject * _self,PyObject * _args)565 static PyObject *Snd_GetDefaultOutputVolume(PyObject *_self, PyObject *_args)
566 {
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;
577 }
578 
Snd_SetDefaultOutputVolume(PyObject * _self,PyObject * _args)579 static PyObject *Snd_SetDefaultOutputVolume(PyObject *_self, PyObject *_args)
580 {
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;
592 }
593 
Snd_GetSoundHeaderOffset(PyObject * _self,PyObject * _args)594 static PyObject *Snd_GetSoundHeaderOffset(PyObject *_self, PyObject *_args)
595 {
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;
609 }
610 
Snd_GetCompressionInfo(PyObject * _self,PyObject * _args)611 static PyObject *Snd_GetCompressionInfo(PyObject *_self, PyObject *_args)
612 {
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;
635 }
636 
Snd_SetSoundPreference(PyObject * _self,PyObject * _args)637 static PyObject *Snd_SetSoundPreference(PyObject *_self, PyObject *_args)
638 {
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;
655 }
656 
Snd_GetSoundPreference(PyObject * _self,PyObject * _args)657 static PyObject *Snd_GetSoundPreference(PyObject *_self, PyObject *_args)
658 {
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;
675 }
676 
Snd_GetCompressionName(PyObject * _self,PyObject * _args)677 static PyObject *Snd_GetCompressionName(PyObject *_self, PyObject *_args)
678 {
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;
692 }
693 
Snd_SPBVersion(PyObject * _self,PyObject * _args)694 static PyObject *Snd_SPBVersion(PyObject *_self, PyObject *_args)
695 {
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;
704 }
705 
Snd_SndRecord(PyObject * _self,PyObject * _args)706 static PyObject *Snd_SndRecord(PyObject *_self, PyObject *_args)
707 {
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;
725 }
726 
Snd_SPBSignInDevice(PyObject * _self,PyObject * _args)727 static PyObject *Snd_SPBSignInDevice(PyObject *_self, PyObject *_args)
728 {
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;
743 }
744 
Snd_SPBSignOutDevice(PyObject * _self,PyObject * _args)745 static PyObject *Snd_SPBSignOutDevice(PyObject *_self, PyObject *_args)
746 {
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;
758 }
759 
Snd_SPBGetIndexedDevice(PyObject * _self,PyObject * _args)760 static PyObject *Snd_SPBGetIndexedDevice(PyObject *_self, PyObject *_args)
761 {
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;
778 }
779 
Snd_SPBOpenDevice(PyObject * _self,PyObject * _args)780 static PyObject *Snd_SPBOpenDevice(PyObject *_self, PyObject *_args)
781 {
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;
798 }
799 
Snd_SPBCloseDevice(PyObject * _self,PyObject * _args)800 static PyObject *Snd_SPBCloseDevice(PyObject *_self, PyObject *_args)
801 {
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;
813 }
814 
Snd_SPBRecord(PyObject * _self,PyObject * _args)815 static PyObject *Snd_SPBRecord(PyObject *_self, PyObject *_args)
816 {
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;
831 }
832 
Snd_SPBPauseRecording(PyObject * _self,PyObject * _args)833 static PyObject *Snd_SPBPauseRecording(PyObject *_self, PyObject *_args)
834 {
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;
846 }
847 
Snd_SPBResumeRecording(PyObject * _self,PyObject * _args)848 static PyObject *Snd_SPBResumeRecording(PyObject *_self, PyObject *_args)
849 {
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;
861 }
862 
Snd_SPBStopRecording(PyObject * _self,PyObject * _args)863 static PyObject *Snd_SPBStopRecording(PyObject *_self, PyObject *_args)
864 {
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;
876 }
877 
Snd_SPBGetRecordingStatus(PyObject * _self,PyObject * _args)878 static PyObject *Snd_SPBGetRecordingStatus(PyObject *_self, PyObject *_args)
879 {
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;
908 }
909 
Snd_SPBGetDeviceInfo(PyObject * _self,PyObject * _args)910 static PyObject *Snd_SPBGetDeviceInfo(PyObject *_self, PyObject *_args)
911 {
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;
929 }
930 
Snd_SPBSetDeviceInfo(PyObject * _self,PyObject * _args)931 static PyObject *Snd_SPBSetDeviceInfo(PyObject *_self, PyObject *_args)
932 {
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;
950 }
951 
Snd_SPBMillisecondsToBytes(PyObject * _self,PyObject * _args)952 static PyObject *Snd_SPBMillisecondsToBytes(PyObject *_self, PyObject *_args)
953 {
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;
967 }
968 
Snd_SPBBytesToMilliseconds(PyObject * _self,PyObject * _args)969 static PyObject *Snd_SPBBytesToMilliseconds(PyObject *_self, PyObject *_args)
970 {
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;
984 }
985 #endif /* __LP64__ */
986 
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}
1055 };
1056 
1057 
1058 #ifndef __LP64__
1059 
1060 /* Routine passed to Py_AddPendingCall -- call the Python callback */
1061 static int
SndCh_CallCallBack(void * arg)1062 SndCh_CallCallBack(void *arg)
1063 {
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;
1075 }
1076 
1077 /* Routine passed to NewSndChannel -- schedule a call to SndCh_CallCallBack */
1078 static pascal void
SndCh_UserRoutine(SndChannelPtr chan,SndCommand * cmd)1079 SndCh_UserRoutine(SndChannelPtr chan, SndCommand *cmd)
1080 {
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);
1087     }
1088 }
1089 
1090 /* SPB callbacks - Schedule callbacks to Python */
1091 static int
SPB_CallCallBack(void * arg)1092 SPB_CallCallBack(void *arg)
1093 {
1094     SPBObject *p = (SPBObject *)arg;
1095     PyObject *args;
1096     PyObject *res;
1097 
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;
1107 }
1108 
1109 static pascal void
SPB_completion(SPBPtr my_spb)1110 SPB_completion(SPBPtr my_spb)
1111 {
1112     SPBObject *p = (SPBObject *)(my_spb->userLong);
1113 
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);
1119     }
1120 }
1121 #endif /* __LP64__ */
1122 
1123 
1124 
init_Snd(void)1125 void init_Snd(void)
1126 {
1127     PyObject *m;
1128 #ifndef __LP64__
1129     PyObject *d;
1130 #endif /* __LP64__ */
1131 
1132 
1133 
1134 
1135 
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__ */
1160 }
1161 
1162 /* ======================== End module _Snd ========================= */
1163 
1164