@@ -76,6 +76,8 @@ SndCmd_Convert(PyObject *v, SndCommand *pc)
7676}
7777
7878static pascal void SndCh_UserRoutine (SndChannelPtr chan , SndCommand * cmd ); /* Forward */
79+ static pascal void SPB_completion (SPBPtr my_spb ); /* Forward */
80+ static pascal void SPB_interrupt (SPBPtr my_spb ); /* Forward */
7981
8082static PyObject * Snd_Error ;
8183
@@ -315,6 +317,133 @@ staticforward PyTypeObject SndChannel_Type = {
315317/* ------------------- End object type SndChannel ------------------- */
316318
317319
320+ /* ------------------------ Object type SPB ------------------------- */
321+
322+ staticforward PyTypeObject SPB_Type ;
323+
324+ #define SPBObj_Check (x ) ((x)->ob_type == &SPB_Type)
325+
326+ typedef struct SPBObject {
327+ PyObject_HEAD
328+ /* Members used to implement callbacks: */
329+ PyObject * ob_completion ;
330+ PyObject * ob_interrupt ;
331+ PyObject * ob_thiscallback ;
332+ long ob_A5 ;
333+ SPB ob_spb ;
334+ } SPBObject ;
335+
336+ static PyObject * SPBObj_New ()
337+ {
338+ SPBObject * it ;
339+ it = PyObject_NEW (SPBObject , & SPB_Type );
340+ if (it == NULL ) return NULL ;
341+ it -> ob_completion = NULL ;
342+ it -> ob_interrupt = NULL ;
343+ it -> ob_thiscallback = NULL ;
344+ it -> ob_A5 = SetCurrentA5 ();
345+ memset ((char * )& it -> ob_spb , 0 , sizeof (it -> ob_spb ));
346+ it -> ob_spb .userLong = (long )it ;
347+ return (PyObject * )it ;
348+ }
349+ static SPBObj_Convert (v , p_itself )
350+ PyObject * v ;
351+ SPBPtr * p_itself ;
352+ {
353+ if (!SPBObj_Check (v ))
354+ {
355+ PyErr_SetString (PyExc_TypeError , "SPB required" );
356+ return 0 ;
357+ }
358+ * p_itself = & ((SPBObject * )v )-> ob_spb ;
359+ return 1 ;
360+ }
361+
362+ static void SPBObj_dealloc (self )
363+ SPBObject * self ;
364+ {
365+ /* Cleanup of self->ob_itself goes here */
366+ self -> ob_spb .userLong = 0 ;
367+ self -> ob_thiscallback = 0 ;
368+ Py_XDECREF (self -> ob_completion );
369+ Py_XDECREF (self -> ob_interrupt );
370+ PyMem_DEL (self );
371+ }
372+
373+ static PyMethodDef SPBObj_methods [] = {
374+ {NULL , NULL , 0 }
375+ };
376+
377+ static PyMethodChain SPBObj_chain = { SPBObj_methods , NULL };
378+
379+ static PyObject * SPBObj_getattr (self , name )
380+ SPBObject * self ;
381+ char * name ;
382+ {
383+
384+ if (strcmp (name , "inRefNum" ) == 0 )
385+ return Py_BuildValue ("l" , self -> ob_spb .inRefNum );
386+ else if (strcmp (name , "count" ) == 0 )
387+ return Py_BuildValue ("l" , self -> ob_spb .count );
388+ else if (strcmp (name , "milliseconds" ) == 0 )
389+ return Py_BuildValue ("l" , self -> ob_spb .milliseconds );
390+ else if (strcmp (name , "error" ) == 0 )
391+ return Py_BuildValue ("h" , self -> ob_spb .error );
392+ return Py_FindMethodInChain (& SPBObj_chain , (PyObject * )self , name );
393+ }
394+
395+ static int SPBObj_setattr (self , name , value )
396+ SPBObject * self ;
397+ char * name ;
398+ PyObject * value ;
399+ {
400+
401+ if (strcmp (name , "inRefNum" ) == 0 )
402+ return PyArg_Parse (value , "l" , & self -> ob_spb .inRefNum );
403+ else if (strcmp (name , "count" ) == 0 )
404+ return PyArg_Parse (value , "l" , & self -> ob_spb .count );
405+ else if (strcmp (name , "milliseconds" ) == 0 )
406+ return PyArg_Parse (value , "l" , & self -> ob_spb .milliseconds );
407+ else if (strcmp (name , "buffer" ) == 0 )
408+ return PyArg_Parse (value , "w#" , & self -> ob_spb .bufferPtr , & self -> ob_spb .bufferLength );
409+ else if (strcmp (name , "completionRoutine" ) == 0 ) {
410+ self -> ob_spb .completionRoutine = NewSICompletionProc (SPB_completion );
411+ self -> ob_completion = value ;
412+ Py_INCREF (value );
413+ return 0 ;
414+ } else if (strcmp (name , "interruptRoutine" ) == 0 ) {
415+ self -> ob_spb .completionRoutine = NewSIInterruptProc (SPB_interrupt );
416+ self -> ob_interrupt = value ;
417+ Py_INCREF (value );
418+ return 0 ;
419+ }
420+ return -1 ;
421+ }
422+
423+ staticforward PyTypeObject SPB_Type = {
424+ PyObject_HEAD_INIT (& PyType_Type )
425+ 0 , /*ob_size*/
426+ "SPB" , /*tp_name*/
427+ sizeof (SPBObject ), /*tp_basicsize*/
428+ 0 , /*tp_itemsize*/
429+ /* methods */
430+ (destructor ) SPBObj_dealloc , /*tp_dealloc*/
431+ 0 , /*tp_print*/
432+ (getattrfunc ) SPBObj_getattr , /*tp_getattr*/
433+ (setattrfunc ) SPBObj_setattr , /*tp_setattr*/
434+ };
435+
436+ /* ---------------------- End object type SPB ----------------------- */
437+
438+
439+ static PyObject * Snd_SPB (_self , _args )
440+ PyObject * _self ;
441+ PyObject * _args ;
442+ {
443+ PyObject * _res = NULL ;
444+ return SPBObj_New ();
445+ }
446+
318447static PyObject * Snd_SysBeep (_self , _args )
319448 PyObject * _self ;
320449 PyObject * _args ;
@@ -839,6 +968,49 @@ static PyObject *Snd_SPBCloseDevice(_self, _args)
839968 return _res ;
840969}
841970
971+ static PyObject * Snd_SPBRecord (_self , _args )
972+ PyObject * _self ;
973+ PyObject * _args ;
974+ {
975+ PyObject * _res = NULL ;
976+ OSErr _err ;
977+ SPBPtr inParamPtr ;
978+ Boolean asynchFlag ;
979+ if (!PyArg_ParseTuple (_args , "O&b" ,
980+ SPBObj_Convert , & inParamPtr ,
981+ & asynchFlag ))
982+ return NULL ;
983+ _err = SPBRecord (inParamPtr ,
984+ asynchFlag );
985+ if (_err != noErr ) return PyMac_Error (_err );
986+ Py_INCREF (Py_None );
987+ _res = Py_None ;
988+ return _res ;
989+ }
990+
991+ static PyObject * Snd_SPBRecordToFile (_self , _args )
992+ PyObject * _self ;
993+ PyObject * _args ;
994+ {
995+ PyObject * _res = NULL ;
996+ OSErr _err ;
997+ short fRefNum ;
998+ SPBPtr inParamPtr ;
999+ Boolean asynchFlag ;
1000+ if (!PyArg_ParseTuple (_args , "hO&b" ,
1001+ & fRefNum ,
1002+ SPBObj_Convert , & inParamPtr ,
1003+ & asynchFlag ))
1004+ return NULL ;
1005+ _err = SPBRecordToFile (fRefNum ,
1006+ inParamPtr ,
1007+ asynchFlag );
1008+ if (_err != noErr ) return PyMac_Error (_err );
1009+ Py_INCREF (Py_None );
1010+ _res = Py_None ;
1011+ return _res ;
1012+ }
1013+
8421014static PyObject * Snd_SPBPauseRecording (_self , _args )
8431015 PyObject * _self ;
8441016 PyObject * _args ;
@@ -924,6 +1096,52 @@ static PyObject *Snd_SPBGetRecordingStatus(_self, _args)
9241096 return _res ;
9251097}
9261098
1099+ static PyObject * Snd_SPBGetDeviceInfo (_self , _args )
1100+ PyObject * _self ;
1101+ PyObject * _args ;
1102+ {
1103+ PyObject * _res = NULL ;
1104+ OSErr _err ;
1105+ long inRefNum ;
1106+ OSType infoType ;
1107+ void * infoData ;
1108+ if (!PyArg_ParseTuple (_args , "lO&w" ,
1109+ & inRefNum ,
1110+ PyMac_GetOSType , & infoType ,
1111+ & infoData ))
1112+ return NULL ;
1113+ _err = SPBGetDeviceInfo (inRefNum ,
1114+ infoType ,
1115+ infoData );
1116+ if (_err != noErr ) return PyMac_Error (_err );
1117+ Py_INCREF (Py_None );
1118+ _res = Py_None ;
1119+ return _res ;
1120+ }
1121+
1122+ static PyObject * Snd_SPBSetDeviceInfo (_self , _args )
1123+ PyObject * _self ;
1124+ PyObject * _args ;
1125+ {
1126+ PyObject * _res = NULL ;
1127+ OSErr _err ;
1128+ long inRefNum ;
1129+ OSType infoType ;
1130+ void * infoData ;
1131+ if (!PyArg_ParseTuple (_args , "lO&w" ,
1132+ & inRefNum ,
1133+ PyMac_GetOSType , & infoType ,
1134+ & infoData ))
1135+ return NULL ;
1136+ _err = SPBSetDeviceInfo (inRefNum ,
1137+ infoType ,
1138+ infoData );
1139+ if (_err != noErr ) return PyMac_Error (_err );
1140+ Py_INCREF (Py_None );
1141+ _res = Py_None ;
1142+ return _res ;
1143+ }
1144+
9271145static PyObject * Snd_SPBMillisecondsToBytes (_self , _args )
9281146 PyObject * _self ;
9291147 PyObject * _args ;
@@ -963,6 +1181,8 @@ static PyObject *Snd_SPBBytesToMilliseconds(_self, _args)
9631181}
9641182
9651183static PyMethodDef Snd_methods [] = {
1184+ {"SPB" , (PyCFunction )Snd_SPB , 1 ,
1185+ NULL },
9661186 {"SysBeep" , (PyCFunction )Snd_SysBeep , 1 ,
9671187 "(short duration) -> None" },
9681188 {"SndNewChannel" , (PyCFunction )Snd_SndNewChannel , 1 ,
@@ -1009,6 +1229,10 @@ static PyMethodDef Snd_methods[] = {
10091229 "(Str255 deviceName, short permission) -> (long inRefNum)" },
10101230 {"SPBCloseDevice" , (PyCFunction )Snd_SPBCloseDevice , 1 ,
10111231 "(long inRefNum) -> None" },
1232+ {"SPBRecord" , (PyCFunction )Snd_SPBRecord , 1 ,
1233+ "(SPBPtr inParamPtr, Boolean asynchFlag) -> None" },
1234+ {"SPBRecordToFile" , (PyCFunction )Snd_SPBRecordToFile , 1 ,
1235+ "(short fRefNum, SPBPtr inParamPtr, Boolean asynchFlag) -> None" },
10121236 {"SPBPauseRecording" , (PyCFunction )Snd_SPBPauseRecording , 1 ,
10131237 "(long inRefNum) -> None" },
10141238 {"SPBResumeRecording" , (PyCFunction )Snd_SPBResumeRecording , 1 ,
@@ -1017,6 +1241,10 @@ static PyMethodDef Snd_methods[] = {
10171241 "(long inRefNum) -> None" },
10181242 {"SPBGetRecordingStatus" , (PyCFunction )Snd_SPBGetRecordingStatus , 1 ,
10191243 "(long inRefNum) -> (short recordingStatus, short meterLevel, unsigned long totalSamplesToRecord, unsigned long numberOfSamplesRecorded, unsigned long totalMsecsToRecord, unsigned long numberOfMsecsRecorded)" },
1244+ {"SPBGetDeviceInfo" , (PyCFunction )Snd_SPBGetDeviceInfo , 1 ,
1245+ "(long inRefNum, OSType infoType, void * infoData) -> None" },
1246+ {"SPBSetDeviceInfo" , (PyCFunction )Snd_SPBSetDeviceInfo , 1 ,
1247+ "(long inRefNum, OSType infoType, void * infoData) -> None" },
10201248 {"SPBMillisecondsToBytes" , (PyCFunction )Snd_SPBMillisecondsToBytes , 1 ,
10211249 "(long inRefNum) -> (long milliseconds)" },
10221250 {"SPBBytesToMilliseconds" , (PyCFunction )Snd_SPBBytesToMilliseconds , 1 ,
@@ -1057,6 +1285,52 @@ SndCh_UserRoutine(SndChannelPtr chan, SndCommand *cmd)
10571285 }
10581286}
10591287
1288+ /* SPB callbacks - Schedule callbacks to Python */
1289+ static int
1290+ SPB_CallCallBack (arg )
1291+ void * arg ;
1292+ {
1293+ SPBObject * p = (SPBObject * )arg ;
1294+ PyObject * args ;
1295+ PyObject * res ;
1296+
1297+ if ( p -> ob_thiscallback == 0 ) return 0 ;
1298+ args = Py_BuildValue ("(O)" , p );
1299+ res = PyEval_CallObject (p -> ob_thiscallback , args );
1300+ p -> ob_thiscallback = 0 ;
1301+ Py_DECREF (args );
1302+ if (res == NULL )
1303+ return -1 ;
1304+ Py_DECREF (res );
1305+ return 0 ;
1306+ }
1307+
1308+ static pascal void
1309+ SPB_completion (SPBPtr my_spb )
1310+ {
1311+ SPBObject * p = (SPBObject * )(my_spb -> userLong );
1312+
1313+ if (p && p -> ob_completion ) {
1314+ long A5 = SetA5 (p -> ob_A5 );
1315+ p -> ob_thiscallback = p -> ob_completion ; /* Hope we cannot get two at the same time */
1316+ Py_AddPendingCall (SPB_CallCallBack , (void * )p );
1317+ SetA5 (A5 );
1318+ }
1319+ }
1320+
1321+ static pascal void
1322+ SPB_interrupt (SPBPtr my_spb )
1323+ {
1324+ SPBObject * p = (SPBObject * )(my_spb -> userLong );
1325+
1326+ if (p && p -> ob_interrupt ) {
1327+ long A5 = SetA5 (p -> ob_A5 );
1328+ p -> ob_thiscallback = p -> ob_interrupt ; /* Hope we cannot get two at the same time */
1329+ Py_AddPendingCall (SPB_CallCallBack , (void * )p );
1330+ SetA5 (A5 );
1331+ }
1332+ }
1333+
10601334
10611335void initSnd ()
10621336{
@@ -1077,6 +1351,10 @@ void initSnd()
10771351 Py_INCREF (& SndChannel_Type );
10781352 if (PyDict_SetItemString (d , "SndChannelType" , (PyObject * )& SndChannel_Type ) != 0 )
10791353 Py_FatalError ("can't initialize SndChannelType" );
1354+ SPB_Type .ob_type = & PyType_Type ;
1355+ Py_INCREF (& SPB_Type );
1356+ if (PyDict_SetItemString (d , "SPBType" , (PyObject * )& SPB_Type ) != 0 )
1357+ Py_FatalError ("can't initialize SPBType" );
10801358}
10811359
10821360/* ========================= End module Snd ========================= */
0 commit comments