diff options
author | Jack Jansen <jack.jansen@cwi.nl> | 1998-02-25 15:47:51 (GMT) |
---|---|---|
committer | Jack Jansen <jack.jansen@cwi.nl> | 1998-02-25 15:47:51 (GMT) |
commit | 52b38b795b0a60d5667a7396322f3d5128340c6d (patch) | |
tree | 3c059cead440796d53f56aa4df2fbf55db2c079f /Mac/Modules/snd/sndsupport.py | |
parent | e742a82067c29786287ce8c6500b68220e9921de (diff) | |
download | cpython-52b38b795b0a60d5667a7396322f3d5128340c6d.zip cpython-52b38b795b0a60d5667a7396322f3d5128340c6d.tar.gz cpython-52b38b795b0a60d5667a7396322f3d5128340c6d.tar.bz2 |
Support for sound input added. The interface is even worse than the
sound-output interface, so this needs a Python wrapper shortly.
Diffstat (limited to 'Mac/Modules/snd/sndsupport.py')
-rw-r--r-- | Mac/Modules/snd/sndsupport.py | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/Mac/Modules/snd/sndsupport.py b/Mac/Modules/snd/sndsupport.py index b3b32f1..cabfa27 100644 --- a/Mac/Modules/snd/sndsupport.py +++ b/Mac/Modules/snd/sndsupport.py @@ -48,6 +48,13 @@ SndChannelPtr = SndChannelPtrType('SndChannelPtr', 'SndCh') SndCommand = OpaqueType('SndCommand', 'SndCmd') SndCommand_ptr = OpaqueType('SndCommand', 'SndCmd') SndListHandle = OpaqueByValueType("SndListHandle", "ResObj") +SPBPtr = OpaqueByValueType("SPBPtr", "SPBObj") + +# +# NOTE: the following is pretty dangerous. For void pointers we pass buffer addresses +# but we have no way to check that the buffer is big enough. This is the same problem +# as in C, though (but Pythoneers may not be suspecting this...) +void_ptr = Type("void *", "w") class SndCallBackType(InputOnlyType): def __init__(self): @@ -118,6 +125,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 */ """ @@ -152,6 +161,52 @@ SndCh_UserRoutine(SndChannelPtr chan, SndCommand *cmd) SetA5(A5); } } + +/* 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); + } +} """ @@ -177,11 +232,118 @@ class SndObjectDefinition(ObjectDefinition): def outputFreeIt(self, itselfname): Output("SndDisposeChannel(%s, 1);", itselfname) + +# + +class SpbObjectDefinition(ObjectDefinition): + + def outputStructMembers(self): + Output("/* Members used to implement callbacks: */") + Output("PyObject *ob_completion;") + Output("PyObject *ob_interrupt;") + Output("PyObject *ob_thiscallback;"); + Output("long ob_A5;") + Output("SPB ob_spb;") + + def outputNew(self): + Output() + Output("%sPyObject *%s_New()", self.static, self.prefix) + OutLbrace() + Output("%s *it;", self.objecttype) + self.outputCheckNewArg() + Output("it = PyObject_NEW(%s, &%s);", self.objecttype, self.typename) + Output("if (it == NULL) return NULL;") + self.outputInitStructMembers() + Output("return (PyObject *)it;") + OutRbrace() + + def outputInitStructMembers(self): + Output("it->ob_completion = NULL;") + Output("it->ob_interrupt = NULL;") + Output("it->ob_thiscallback = NULL;") + Output("it->ob_A5 = SetCurrentA5();") + Output("memset((char *)&it->ob_spb, 0, sizeof(it->ob_spb));") + Output("it->ob_spb.userLong = (long)it;") + + def outputCleanupStructMembers(self): + ObjectDefinition.outputCleanupStructMembers(self) + Output("self->ob_spb.userLong = 0;") + Output("self->ob_thiscallback = 0;") + Output("Py_XDECREF(self->ob_completion);") + Output("Py_XDECREF(self->ob_interrupt);") + + def outputConvert(self): + Output("%s%s_Convert(v, p_itself)", self.static, self.prefix) + IndentLevel() + Output("PyObject *v;") + Output("%s *p_itself;", self.itselftype) + DedentLevel() + OutLbrace() + self.outputCheckConvertArg() + Output("if (!%s_Check(v))", self.prefix) + OutLbrace() + Output('PyErr_SetString(PyExc_TypeError, "%s required");', self.name) + Output("return 0;") + OutRbrace() + Output("*p_itself = &((%s *)v)->ob_spb;", self.objecttype) + Output("return 1;") + OutRbrace() + + def outputSetattr(self): + Output() + Output("static int %s_setattr(self, name, value)", self.prefix) + IndentLevel() + Output("%s *self;", self.objecttype) + Output("char *name;") + Output("PyObject *value;") + DedentLevel() + OutLbrace() + self.outputSetattrBody() + OutRbrace() + def outputSetattrBody(self): + Output(""" + 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;""") + + def outputGetattrHook(self): + Output(""" + 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);""") + + sndobject = SndObjectDefinition('SndChannel', 'SndCh', 'SndChannelPtr') +spbobject = SpbObjectDefinition('SPB', 'SPBObj', 'SPBPtr') +spbgenerator = ManualGenerator("SPB", "return SPBObj_New();") module = MacModule('Snd', 'Snd', includestuff, finalstuff, initstuff) module.addobject(sndobject) +module.addobject(spbobject) +module.add(spbgenerator) # create lists of functions and object methods |