summaryrefslogtreecommitdiffstats
path: root/Mac/Modules/snd/Sndmodule.c
diff options
context:
space:
mode:
Diffstat (limited to 'Mac/Modules/snd/Sndmodule.c')
-rw-r--r--Mac/Modules/snd/Sndmodule.c278
1 files changed, 278 insertions, 0 deletions
diff --git a/Mac/Modules/snd/Sndmodule.c b/Mac/Modules/snd/Sndmodule.c
index 06031ab..accb563 100644
--- a/Mac/Modules/snd/Sndmodule.c
+++ b/Mac/Modules/snd/Sndmodule.c
@@ -76,6 +76,8 @@ SndCmd_Convert(PyObject *v, SndCommand *pc)
}
static pascal void SndCh_UserRoutine(SndChannelPtr chan, SndCommand *cmd); /* Forward */
+static pascal void SPB_completion(SPBPtr my_spb); /* Forward */
+static pascal void SPB_interrupt(SPBPtr my_spb); /* Forward */
static PyObject *Snd_Error;
@@ -315,6 +317,133 @@ staticforward PyTypeObject SndChannel_Type = {
/* ------------------- End object type SndChannel ------------------- */
+/* ------------------------ Object type SPB ------------------------- */
+
+staticforward PyTypeObject SPB_Type;
+
+#define SPBObj_Check(x) ((x)->ob_type == &SPB_Type)
+
+typedef struct SPBObject {
+ PyObject_HEAD
+ /* Members used to implement callbacks: */
+ PyObject *ob_completion;
+ PyObject *ob_interrupt;
+ PyObject *ob_thiscallback;
+ long ob_A5;
+ SPB ob_spb;
+} SPBObject;
+
+static PyObject *SPBObj_New()
+{
+ SPBObject *it;
+ it = PyObject_NEW(SPBObject, &SPB_Type);
+ if (it == NULL) return NULL;
+ it->ob_completion = NULL;
+ it->ob_interrupt = NULL;
+ it->ob_thiscallback = NULL;
+ it->ob_A5 = SetCurrentA5();
+ memset((char *)&it->ob_spb, 0, sizeof(it->ob_spb));
+ it->ob_spb.userLong = (long)it;
+ return (PyObject *)it;
+}
+static SPBObj_Convert(v, p_itself)
+ PyObject *v;
+ SPBPtr *p_itself;
+{
+ if (!SPBObj_Check(v))
+ {
+ PyErr_SetString(PyExc_TypeError, "SPB required");
+ return 0;
+ }
+ *p_itself = &((SPBObject *)v)->ob_spb;
+ return 1;
+}
+
+static void SPBObj_dealloc(self)
+ SPBObject *self;
+{
+ /* Cleanup of self->ob_itself goes here */
+ self->ob_spb.userLong = 0;
+ self->ob_thiscallback = 0;
+ Py_XDECREF(self->ob_completion);
+ Py_XDECREF(self->ob_interrupt);
+ PyMem_DEL(self);
+}
+
+static PyMethodDef SPBObj_methods[] = {
+ {NULL, NULL, 0}
+};
+
+static PyMethodChain SPBObj_chain = { SPBObj_methods, NULL };
+
+static PyObject *SPBObj_getattr(self, name)
+ SPBObject *self;
+ char *name;
+{
+
+ if (strcmp(name, "inRefNum") == 0)
+ return Py_BuildValue("l", self->ob_spb.inRefNum);
+ else if (strcmp(name, "count") == 0)
+ return Py_BuildValue("l", self->ob_spb.count);
+ else if (strcmp(name, "milliseconds") == 0)
+ return Py_BuildValue("l", self->ob_spb.milliseconds);
+ else if (strcmp(name, "error") == 0)
+ return Py_BuildValue("h", self->ob_spb.error);
+ return Py_FindMethodInChain(&SPBObj_chain, (PyObject *)self, name);
+}
+
+static int SPBObj_setattr(self, name, value)
+ SPBObject *self;
+ char *name;
+ PyObject *value;
+{
+
+ if (strcmp(name, "inRefNum") == 0)
+ return PyArg_Parse(value, "l", &self->ob_spb.inRefNum);
+ else if (strcmp(name, "count") == 0)
+ return PyArg_Parse(value, "l", &self->ob_spb.count);
+ else if (strcmp(name, "milliseconds") == 0)
+ return PyArg_Parse(value, "l", &self->ob_spb.milliseconds);
+ else if (strcmp(name, "buffer") == 0)
+ return PyArg_Parse(value, "w#", &self->ob_spb.bufferPtr, &self->ob_spb.bufferLength);
+ else if (strcmp(name, "completionRoutine") == 0) {
+ self->ob_spb.completionRoutine = NewSICompletionProc(SPB_completion);
+ self->ob_completion = value;
+ Py_INCREF(value);
+ return 0;
+ } else if (strcmp(name, "interruptRoutine") == 0) {
+ self->ob_spb.completionRoutine = NewSIInterruptProc(SPB_interrupt);
+ self->ob_interrupt = value;
+ Py_INCREF(value);
+ return 0;
+ }
+ return -1;
+}
+
+staticforward PyTypeObject SPB_Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0, /*ob_size*/
+ "SPB", /*tp_name*/
+ sizeof(SPBObject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor) SPBObj_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ (getattrfunc) SPBObj_getattr, /*tp_getattr*/
+ (setattrfunc) SPBObj_setattr, /*tp_setattr*/
+};
+
+/* ---------------------- End object type SPB ----------------------- */
+
+
+static PyObject *Snd_SPB(_self, _args)
+ PyObject *_self;
+ PyObject *_args;
+{
+ PyObject *_res = NULL;
+ return SPBObj_New();
+}
+
static PyObject *Snd_SysBeep(_self, _args)
PyObject *_self;
PyObject *_args;
@@ -839,6 +968,49 @@ static PyObject *Snd_SPBCloseDevice(_self, _args)
return _res;
}
+static PyObject *Snd_SPBRecord(_self, _args)
+ PyObject *_self;
+ PyObject *_args;
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ SPBPtr inParamPtr;
+ Boolean asynchFlag;
+ if (!PyArg_ParseTuple(_args, "O&b",
+ SPBObj_Convert, &inParamPtr,
+ &asynchFlag))
+ return NULL;
+ _err = SPBRecord(inParamPtr,
+ asynchFlag);
+ if (_err != noErr) return PyMac_Error(_err);
+ Py_INCREF(Py_None);
+ _res = Py_None;
+ return _res;
+}
+
+static PyObject *Snd_SPBRecordToFile(_self, _args)
+ PyObject *_self;
+ PyObject *_args;
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ short fRefNum;
+ SPBPtr inParamPtr;
+ Boolean asynchFlag;
+ if (!PyArg_ParseTuple(_args, "hO&b",
+ &fRefNum,
+ SPBObj_Convert, &inParamPtr,
+ &asynchFlag))
+ return NULL;
+ _err = SPBRecordToFile(fRefNum,
+ inParamPtr,
+ asynchFlag);
+ if (_err != noErr) return PyMac_Error(_err);
+ Py_INCREF(Py_None);
+ _res = Py_None;
+ return _res;
+}
+
static PyObject *Snd_SPBPauseRecording(_self, _args)
PyObject *_self;
PyObject *_args;
@@ -924,6 +1096,52 @@ static PyObject *Snd_SPBGetRecordingStatus(_self, _args)
return _res;
}
+static PyObject *Snd_SPBGetDeviceInfo(_self, _args)
+ PyObject *_self;
+ PyObject *_args;
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ long inRefNum;
+ OSType infoType;
+ void * infoData;
+ if (!PyArg_ParseTuple(_args, "lO&w",
+ &inRefNum,
+ PyMac_GetOSType, &infoType,
+ &infoData))
+ return NULL;
+ _err = SPBGetDeviceInfo(inRefNum,
+ infoType,
+ infoData);
+ if (_err != noErr) return PyMac_Error(_err);
+ Py_INCREF(Py_None);
+ _res = Py_None;
+ return _res;
+}
+
+static PyObject *Snd_SPBSetDeviceInfo(_self, _args)
+ PyObject *_self;
+ PyObject *_args;
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ long inRefNum;
+ OSType infoType;
+ void * infoData;
+ if (!PyArg_ParseTuple(_args, "lO&w",
+ &inRefNum,
+ PyMac_GetOSType, &infoType,
+ &infoData))
+ return NULL;
+ _err = SPBSetDeviceInfo(inRefNum,
+ infoType,
+ infoData);
+ if (_err != noErr) return PyMac_Error(_err);
+ Py_INCREF(Py_None);
+ _res = Py_None;
+ return _res;
+}
+
static PyObject *Snd_SPBMillisecondsToBytes(_self, _args)
PyObject *_self;
PyObject *_args;
@@ -963,6 +1181,8 @@ static PyObject *Snd_SPBBytesToMilliseconds(_self, _args)
}
static PyMethodDef Snd_methods[] = {
+ {"SPB", (PyCFunction)Snd_SPB, 1,
+ NULL},
{"SysBeep", (PyCFunction)Snd_SysBeep, 1,
"(short duration) -> None"},
{"SndNewChannel", (PyCFunction)Snd_SndNewChannel, 1,
@@ -1009,6 +1229,10 @@ static PyMethodDef Snd_methods[] = {
"(Str255 deviceName, short permission) -> (long inRefNum)"},
{"SPBCloseDevice", (PyCFunction)Snd_SPBCloseDevice, 1,
"(long inRefNum) -> None"},
+ {"SPBRecord", (PyCFunction)Snd_SPBRecord, 1,
+ "(SPBPtr inParamPtr, Boolean asynchFlag) -> None"},
+ {"SPBRecordToFile", (PyCFunction)Snd_SPBRecordToFile, 1,
+ "(short fRefNum, SPBPtr inParamPtr, Boolean asynchFlag) -> None"},
{"SPBPauseRecording", (PyCFunction)Snd_SPBPauseRecording, 1,
"(long inRefNum) -> None"},
{"SPBResumeRecording", (PyCFunction)Snd_SPBResumeRecording, 1,
@@ -1017,6 +1241,10 @@ static PyMethodDef Snd_methods[] = {
"(long inRefNum) -> None"},
{"SPBGetRecordingStatus", (PyCFunction)Snd_SPBGetRecordingStatus, 1,
"(long inRefNum) -> (short recordingStatus, short meterLevel, unsigned long totalSamplesToRecord, unsigned long numberOfSamplesRecorded, unsigned long totalMsecsToRecord, unsigned long numberOfMsecsRecorded)"},
+ {"SPBGetDeviceInfo", (PyCFunction)Snd_SPBGetDeviceInfo, 1,
+ "(long inRefNum, OSType infoType, void * infoData) -> None"},
+ {"SPBSetDeviceInfo", (PyCFunction)Snd_SPBSetDeviceInfo, 1,
+ "(long inRefNum, OSType infoType, void * infoData) -> None"},
{"SPBMillisecondsToBytes", (PyCFunction)Snd_SPBMillisecondsToBytes, 1,
"(long inRefNum) -> (long milliseconds)"},
{"SPBBytesToMilliseconds", (PyCFunction)Snd_SPBBytesToMilliseconds, 1,
@@ -1057,6 +1285,52 @@ SndCh_UserRoutine(SndChannelPtr chan, SndCommand *cmd)
}
}
+/* SPB callbacks - Schedule callbacks to Python */
+static int
+SPB_CallCallBack(arg)
+ void *arg;
+{
+ SPBObject *p = (SPBObject *)arg;
+ PyObject *args;
+ PyObject *res;
+
+ if ( p->ob_thiscallback == 0 ) return 0;
+ args = Py_BuildValue("(O)", p);
+ res = PyEval_CallObject(p->ob_thiscallback, args);
+ p->ob_thiscallback = 0;
+ Py_DECREF(args);
+ if (res == NULL)
+ return -1;
+ Py_DECREF(res);
+ return 0;
+}
+
+static pascal void
+SPB_completion(SPBPtr my_spb)
+{
+ SPBObject *p = (SPBObject *)(my_spb->userLong);
+
+ if (p && p->ob_completion) {
+ long A5 = SetA5(p->ob_A5);
+ p->ob_thiscallback = p->ob_completion; /* Hope we cannot get two at the same time */
+ Py_AddPendingCall(SPB_CallCallBack, (void *)p);
+ SetA5(A5);
+ }
+}
+
+static pascal void
+SPB_interrupt(SPBPtr my_spb)
+{
+ SPBObject *p = (SPBObject *)(my_spb->userLong);
+
+ if (p && p->ob_interrupt) {
+ long A5 = SetA5(p->ob_A5);
+ p->ob_thiscallback = p->ob_interrupt; /* Hope we cannot get two at the same time */
+ Py_AddPendingCall(SPB_CallCallBack, (void *)p);
+ SetA5(A5);
+ }
+}
+
void initSnd()
{
@@ -1077,6 +1351,10 @@ void initSnd()
Py_INCREF(&SndChannel_Type);
if (PyDict_SetItemString(d, "SndChannelType", (PyObject *)&SndChannel_Type) != 0)
Py_FatalError("can't initialize SndChannelType");
+ SPB_Type.ob_type = &PyType_Type;
+ Py_INCREF(&SPB_Type);
+ if (PyDict_SetItemString(d, "SPBType", (PyObject *)&SPB_Type) != 0)
+ Py_FatalError("can't initialize SPBType");
}
/* ========================= End module Snd ========================= */