Home | History | Annotate | Download | only in snd
      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
     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 
     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 
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 }
    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 
    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 
    311 static PyObject *SPBObj_get_inRefNum(SPBObject *self, void *closure)
    312 {
    313     return Py_BuildValue("l", self->ob_spb.inRefNum);
    314 }
    315 
    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 
    322 static PyObject *SPBObj_get_count(SPBObject *self, void *closure)
    323 {
    324     return Py_BuildValue("l", self->ob_spb.count);
    325 }
    326 
    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 
    333 static PyObject *SPBObj_get_milliseconds(SPBObject *self, void *closure)
    334 {
    335     return Py_BuildValue("l", self->ob_spb.milliseconds);
    336 }
    337 
    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 
    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 
    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 
    425 static PyObject *Snd_SPB(PyObject *_self, PyObject *_args)
    426 {
    427     PyObject *_res = NULL;
    428     _res = SPBObj_New(); return _res;
    429 }
    430 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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
   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
   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
   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
   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 
   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