From 3e0446e7fda10c3d85a628b8c1effaa5bf7f5529 Mon Sep 17 00:00:00 2001 From: Thomas Grill Date: Mon, 14 Mar 2005 04:58:13 +0000 Subject: fixes for OSX docs optimizations and fixes use optimized version optimized function calls adjust pd and py files for correct argument passing more optimizations svn path=/trunk/; revision=2627 --- externals/grill/py/build/config-lnx.def | 1 + externals/grill/py/build/config-mac.def | 1 + externals/grill/py/build/config-win.def | 1 + externals/grill/py/pd/sendrecv-1.pd | 66 ++++++++--------- externals/grill/py/pd/sig-1.pd | 56 +++++++-------- externals/grill/py/pd/thread-1.pd | 122 ++++++++++++++++---------------- externals/grill/py/scripts/sig.py | 24 +++++++ externals/grill/py/source/main.cpp | 26 +++---- externals/grill/py/source/main.h | 25 ++++--- externals/grill/py/source/py.cpp | 12 ++-- externals/grill/py/source/pybuffer.cpp | 12 +++- externals/grill/py/source/pydsp.cpp | 72 +++++++++---------- externals/grill/py/source/pyext.cpp | 18 +++-- 13 files changed, 236 insertions(+), 200 deletions(-) diff --git a/externals/grill/py/build/config-lnx.def b/externals/grill/py/build/config-lnx.def index 3eba0d96..e24f8b17 100644 --- a/externals/grill/py/build/config-lnx.def +++ b/externals/grill/py/build/config-lnx.def @@ -5,4 +5,5 @@ PYTHONPREFIX=/usr PYTHONVERSION=2.3 # uncomment if numarray support should be compiled in +# for info about numarray see http://numeric.scipy.org # PY_NUMARRAY=1 diff --git a/externals/grill/py/build/config-mac.def b/externals/grill/py/build/config-mac.def index a966f137..684c70b3 100644 --- a/externals/grill/py/build/config-mac.def +++ b/externals/grill/py/build/config-mac.def @@ -1,2 +1,3 @@ # uncomment if numarray support should be compiled in +# for info about numarray see http://numeric.scipy.org # PY_NUMARRAY=1 diff --git a/externals/grill/py/build/config-win.def b/externals/grill/py/build/config-win.def index f587116d..31cfe0a9 100644 --- a/externals/grill/py/build/config-win.def +++ b/externals/grill/py/build/config-win.def @@ -2,4 +2,5 @@ PYTHONPATH=c:\programme\prog\python24 # uncomment if numarray support should be compiled in +# for info about numarray see http://numeric.scipy.org # PY_NUMARRAY=1 diff --git a/externals/grill/py/pd/sendrecv-1.pd b/externals/grill/py/pd/sendrecv-1.pd index 02ac052a..c2b8a500 100644 --- a/externals/grill/py/pd/sendrecv-1.pd +++ b/externals/grill/py/pd/sendrecv-1.pd @@ -1,33 +1,33 @@ -#N canvas 145 126 654 329 12; -#X msg 125 81 reload mi ma; -#X floatatom 48 238 5 0 0 0 - - -; -#X floatatom 297 239 5 0 0 0 - - -; -#X obj 297 263 s mi; -#X floatatom 143 265 5 0 0 0 - - -; -#X floatatom 382 267 5 0 0 0 - - -; -#X obj 382 240 r ma; -#X obj 48 262 s he; -#X obj 143 238 r hu; -#X text 233 80 reload with different args; -#X msg 20 82 help; -#X msg 19 114 doc; -#X msg 58 114 doc+; -#X obj 49 165 pyext sendrecv ex1 he hu; -#X text 30 218 scroll here; -#X text 292 219 or here; -#X obj 16 13 cnv 15 600 40 empty empty py/pyext 10 22 0 24 -260818 --1 0; -#X msg 202 128 bind; -#X msg 249 129 unbind; -#X text 213 16 Python script objects \, (C)2003-2005 Thomas Grill; -#X text 213 32 http://grrrr.org/ext; -#X connect 0 0 13 0; -#X connect 1 0 7 0; -#X connect 2 0 3 0; -#X connect 6 0 5 0; -#X connect 8 0 4 0; -#X connect 10 0 13 0; -#X connect 11 0 13 0; -#X connect 12 0 13 0; -#X connect 17 0 13 1; -#X connect 18 0 13 1; +#N canvas 145 126 658 333 12; +#X msg 125 81 reload mi ma; +#X floatatom 48 238 5 0 0 0 - - -; +#X floatatom 297 239 5 0 0 0 - - -; +#X obj 297 263 s mi; +#X floatatom 143 265 5 0 0 0 - - -; +#X floatatom 382 267 5 0 0 0 - - -; +#X obj 382 240 r ma; +#X obj 48 262 s he; +#X obj 143 238 r hu; +#X text 247 81 reload with different args; +#X msg 20 82 help; +#X msg 19 114 doc; +#X msg 58 114 doc+; +#X obj 49 165 pyext sendrecv ex1 he hu; +#X text 30 218 scroll here; +#X text 292 219 or here; +#X obj 16 13 cnv 15 600 40 empty empty py/pyext 10 22 0 24 -260818 +-1 0; +#X msg 202 128 bind; +#X msg 249 129 unbind; +#X text 213 16 Python script objects \, (C)2003-2005 Thomas Grill; +#X text 213 32 http://grrrr.org/ext; +#X connect 0 0 13 0; +#X connect 1 0 7 0; +#X connect 2 0 3 0; +#X connect 6 0 5 0; +#X connect 8 0 4 0; +#X connect 10 0 13 0; +#X connect 11 0 13 0; +#X connect 12 0 13 0; +#X connect 17 0 13 1; +#X connect 18 0 13 1; diff --git a/externals/grill/py/pd/sig-1.pd b/externals/grill/py/pd/sig-1.pd index aaba2fc7..88d38e89 100644 --- a/externals/grill/py/pd/sig-1.pd +++ b/externals/grill/py/pd/sig-1.pd @@ -1,28 +1,28 @@ -#N canvas 56 67 651 303 12; -#X obj 56 234 dac~; -#X msg 523 211 \; pd dsp 1; -#X obj 524 184 loadbang; -#X obj 194 114 hsl 128 15 0.01 1 1 1 empty empty gain -2 -6 0 8 -225271 --1 -1 4400 1; -#X obj 89 116 noise~; -#X msg 28 117 reload; -#X obj 16 13 cnv 15 600 40 empty empty py/pyext 10 22 0 24 -260818 --1 0; -#X text 213 32 http://grrrr.org/ext; -#X text 213 16 Python script objects \, (C)2003-2005 Thomas Grill; -#X text 17 66 This demonstrates signal support. See the sig.py file. -; -#X obj 191 131 nbx 5 14 0.001 1 1 0 empty empty empty 0 -6 0 10 -225271 --1 -1 0.0493075 256; -#X obj 67 181 pyext~ 0 0 1 1 sig gain; -#X msg 192 148 set gain \$1; -#X text 123 202 message inlets \, outlets; -#X text 123 217 signal inlets \, outlets; -#X connect 2 0 1 0; -#X connect 3 0 10 0; -#X connect 4 0 11 0; -#X connect 5 0 11 0; -#X connect 10 0 12 0; -#X connect 11 0 0 0; -#X connect 11 0 0 1; -#X connect 12 0 11 0; +#N canvas 52 147 659 311 12; +#X obj 56 234 dac~; +#X msg 523 211 \; pd dsp 1; +#X obj 524 184 loadbang; +#X obj 194 114 hsl 128 15 0.01 1 1 1 empty empty gain -2 -6 0 8 -225271 +-1 -1 0 1; +#X obj 89 116 noise~; +#X msg 28 117 reload; +#X obj 16 13 cnv 15 600 40 empty empty py/pyext 10 22 0 24 -260818 +-1 0; +#X text 213 32 http://grrrr.org/ext; +#X text 213 16 Python script objects \, (C)2003-2005 Thomas Grill; +#X text 17 66 This demonstrates signal support. See the sig.py file. +; +#X obj 191 131 nbx 5 14 0.001 1 1 0 empty empty empty 0 -6 0 10 -225271 +-1 -1 0.001 256; +#X msg 192 148 set gain \$1; +#X text 123 202 message inlets \, outlets; +#X text 123 217 signal inlets \, outlets; +#X obj 67 181 pyext~ 0 0 1 1 sig gain2; +#X connect 2 0 1 0; +#X connect 3 0 10 0; +#X connect 4 0 14 0; +#X connect 5 0 14 0; +#X connect 10 0 11 0; +#X connect 11 0 14 0; +#X connect 14 0 0 0; +#X connect 14 0 0 1; diff --git a/externals/grill/py/pd/thread-1.pd b/externals/grill/py/pd/thread-1.pd index e46f6521..f2160cae 100644 --- a/externals/grill/py/pd/thread-1.pd +++ b/externals/grill/py/pd/thread-1.pd @@ -1,60 +1,62 @@ -#N canvas 135 178 648 405 12; -#X msg 35 292 help; -#X msg 34 317 doc; -#X msg 70 318 doc+; -#X floatatom 142 340 5 0 0 0 - - -; -#X text 17 66 This demonstrates threading. See the threads.py file. -; -#X obj 137 243 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 -1; -#X msg 137 263 detach \$1; -#X floatatom 250 341 5 0 0 0 - - -; -#X obj 272 150 bng 15 250 50 0 empty empty empty 0 -6 0 8 -258699 -1 --1; -#X obj 143 154 bng 15 250 50 0 empty empty empty 0 -6 0 8 -258699 -1 --1; -#X obj 143 181 t b b b; -#X obj 272 177 t b b b; -#X obj 286 206 1; -#X obj 157 208 0; -#X text 84 114 without threads; -#X text 248 112 with threads; -#X text 175 362 watch that!; -#X msg 421 264 stop; -#X text 391 243 you can even stop it; -#X obj 142 306 pyext threads ex1; -#X text 90 128 - blocking!! -; -#X obj 16 13 cnv 15 600 40 empty empty py/pyext 10 22 0 24 -260818 --1 0; -#X obj 407 150 bng 15 250 50 0 empty empty empty 0 -6 0 8 -258699 -1 --1; -#X obj 407 177 t b b b; -#X text 383 112 with threads; -#X text 249 129 non-blocking; -#X text 384 129 parallel; -#X obj 445 205 2; -#X text 213 32 http://grrrr.org/ext; -#X text 213 16 Python script objects \, (C)2003-2005 Thomas Grill; -#X connect 0 0 19 0; -#X connect 1 0 19 0; -#X connect 2 0 19 0; -#X connect 5 0 6 0; -#X connect 6 0 19 0; -#X connect 8 0 11 0; -#X connect 9 0 10 0; -#X connect 10 0 19 1; -#X connect 10 1 19 2; -#X connect 10 2 13 0; -#X connect 11 0 19 1; -#X connect 11 1 19 2; -#X connect 11 2 12 0; -#X connect 12 0 5 0; -#X connect 13 0 5 0; -#X connect 17 0 19 0; -#X connect 19 0 3 0; -#X connect 19 1 7 0; -#X connect 22 0 23 0; -#X connect 23 0 19 1; -#X connect 23 1 19 2; -#X connect 23 2 27 0; -#X connect 27 0 5 0; +#N canvas 135 178 652 409 12; +#X msg 35 292 help; +#X msg 34 317 doc; +#X msg 70 318 doc+; +#X floatatom 142 340 5 0 0 0 - - -; +#X text 17 66 This demonstrates threading. See the threads.py file. +; +#X obj 137 243 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 2 +2; +#X msg 137 263 detach \$1; +#X floatatom 250 341 5 0 0 0 - - -; +#X obj 272 150 bng 15 250 50 0 empty empty empty 0 -6 0 8 -258699 -1 +-1; +#X obj 143 154 bng 15 250 50 0 empty empty empty 0 -6 0 8 -258699 -1 +-1; +#X obj 143 181 t b b b; +#X obj 272 177 t b b b; +#X obj 286 206 1; +#X obj 157 208 0; +#X text 84 114 without threads; +#X text 248 112 with threads; +#X text 175 362 watch that!; +#X msg 421 264 stop; +#X text 391 243 you can even stop it; +#X obj 142 306 pyext threads ex1; +#X text 90 128 - blocking!! -; +#X obj 16 13 cnv 15 600 40 empty empty py/pyext 10 22 0 24 -260818 +-1 0; +#X obj 407 150 bng 15 250 50 0 empty empty empty 0 -6 0 8 -258699 -1 +-1; +#X obj 407 177 t b b b; +#X text 383 112 with threads; +#X text 249 129 non-blocking; +#X text 384 129 parallel; +#X obj 445 205 2; +#X text 213 32 http://grrrr.org/ext; +#X text 213 16 Python script objects \, (C)2003-2005 Thomas Grill; +#X msg 44 195 reload; +#X connect 0 0 19 0; +#X connect 1 0 19 0; +#X connect 2 0 19 0; +#X connect 5 0 6 0; +#X connect 6 0 19 0; +#X connect 8 0 11 0; +#X connect 9 0 10 0; +#X connect 10 0 19 1; +#X connect 10 1 19 2; +#X connect 10 2 13 0; +#X connect 11 0 19 1; +#X connect 11 1 19 2; +#X connect 11 2 12 0; +#X connect 12 0 5 0; +#X connect 13 0 5 0; +#X connect 17 0 19 0; +#X connect 19 0 3 0; +#X connect 19 1 7 0; +#X connect 22 0 23 0; +#X connect 23 0 19 1; +#X connect 23 1 19 2; +#X connect 23 2 27 0; +#X connect 27 0 5 0; +#X connect 30 0 19 0; diff --git a/externals/grill/py/scripts/sig.py b/externals/grill/py/scripts/sig.py index 8dccf5fe..0eac237a 100644 --- a/externals/grill/py/scripts/sig.py +++ b/externals/grill/py/scripts/sig.py @@ -42,6 +42,30 @@ class gain(pyext._class): self._outvec(0)[:] = self._invec(0)*self.gain +class gain2(pyext._class): + """More optimized version""" + + gain = 0 + + def _dsp(self): + # cache vectors + self.invec =self._invec(0) + self.outvec = self._outvec(0) + # initialize _signal method here for optimized version + if self.invec is self.outvec: + self._signal = self.signal1 + else: + self._signal = self.signal2 + + def signal1(self): + # Multiply signal vector in place + self.outvec *= self.gain + + def signal2(self): + # Multiply input vector by gain and copy to output + self.outvec[:] = self.invec*self.gain + + class pan(pyext._class): """Stereo panning""" diff --git a/externals/grill/py/source/main.cpp b/externals/grill/py/source/main.cpp index aa234cc4..252d3408 100644 --- a/externals/grill/py/source/main.cpp +++ b/externals/grill/py/source/main.cpp @@ -24,8 +24,8 @@ static PyObject *gcollect = NULL; typedef std::map PyThrMap; static PyInterpreterState *pymain = NULL; -static PyThreadState *pythrmain = NULL; static PyThrMap pythrmap; +PyThreadState *pybase::pythrsys = NULL; int pybase::lockcount = 0; @@ -62,8 +62,6 @@ void pybase::FreeThreadState() PyObject *pybase::module_obj = NULL; PyObject *pybase::module_dict = NULL; -PyObject *pybase::emptytuple = NULL; - void initsymbol(); void initsamplebuffer(); @@ -95,12 +93,12 @@ void pybase::lib_setup() PyEval_InitThreads(); // get thread state - pythrmain = PyThreadState_Get(); + pythrsys = PyThreadState_Get(); // get main interpreter state - pymain = pythrmain->interp; + pymain = pythrsys->interp; // add thread state of main thread to map - pythrmap[GetThreadId()] = pythrmain; + pythrmap[GetThreadId()] = pythrsys; #endif // sys.argv must be set to empty tuple @@ -143,8 +141,6 @@ void pybase::lib_setup() initsamplebuffer(); PyModule_AddObject(module_obj,"Buffer",(PyObject *)&pySamplebuffer_Type); - emptytuple = PyTuple_New(0); - // ------------------------------------------------------------- FLEXT_SETUP(pyobj); @@ -169,14 +165,14 @@ pybase::pybase() , shouldexit(false),thrcount(0),stoptick(0) #endif { - PyThreadState *state = PyLock(); + PyThreadState *state = PyLockSys(); Py_INCREF(module_obj); PyUnlock(state); } pybase::~pybase() { - PyThreadState *state = PyLock(); + PyThreadState *state = PyLockSys(); Py_XDECREF(module_obj); PyUnlock(state); } @@ -527,13 +523,13 @@ bool pybase::qucall(PyObject *fun,PyObject *args) void pybase::threadworker() { FifoEl *el; - PyThreadState *state; + PyThreadState *my = FindThreadState(),*state; ++thrcount; for(;;) { while(el = qufifo.Get()) { ++thrcount; - state = PyLock(); + state = PyLock(my); callpy(el->fun,el->args); Py_XDECREF(el->fun); Py_XDECREF(el->args); @@ -547,7 +543,7 @@ void pybase::threadworker() qucond.Wait(); } - state = PyLock(); + state = PyLock(my); // unref remaining Python objects while(el = qufifo.Get()) { Py_XDECREF(el->fun); @@ -575,9 +571,7 @@ short pybase::patcher_myvol(t_patcher *x) bool pybase::collect() { if(gcollect) { - Py_INCREF(emptytuple); - PyObject *ret = PyObject_Call(gcollect,emptytuple,NULL); - Py_DECREF(emptytuple); + PyObject *ret = PyObject_CallObject(gcollect,NULL); if(ret) { #ifdef FLEXT_DEBUG int refs = PyInt_AsLong(ret); diff --git a/externals/grill/py/source/main.h b/externals/grill/py/source/main.h index c76d43fa..f9df5807 100644 --- a/externals/grill/py/source/main.h +++ b/externals/grill/py/source/main.h @@ -92,8 +92,6 @@ protected: enum retval { nothing,atom,sequ }; - static PyObject *emptytuple; - // --- module stuff ----- static PyObject *module_obj,*module_dict; @@ -154,9 +152,12 @@ protected: void threadworker(); PyFifo qufifo; ThrCond qucond; + static PyThreadState *pythrsys; static PyThreadState *FindThreadState(); static void FreeThreadState(); +#else + static PyThreadState *FindThreadState() { return NULL; } #endif public: @@ -166,27 +167,35 @@ public: inline void Lock() { mutex.Unlock(); } inline void Unlock() { mutex.Unlock(); } - // this is respecially needed when one py/pyext object calls another one + // this is especially needed when one py/pyext object calls another one // we don't want the message to be queued, but otoh we have to avoid deadlock // (recursive calls can only happen in the system thread) static int lockcount; - inline PyThreadState *PyLock() + inline PyThreadState *PyLock(PyThreadState *st = FindThreadState()) { if(!IsSystemThread() || !lockcount++) PyEval_AcquireLock(); - return PyThreadState_Swap(FindThreadState()); + return PyThreadState_Swap(st); + } + + inline PyThreadState *PyLockSys() + { + if(!lockcount++) PyEval_AcquireLock(); + return PyThreadState_Swap(pythrsys); } inline void PyUnlock(PyThreadState *st) { - PyThreadState_Swap(st); - if(!IsSystemThread() || !--lockcount) PyEval_ReleaseLock(); + PyThreadState *old = PyThreadState_Swap(st); + if(old != pythrsys || !--lockcount) PyEval_ReleaseLock(); } + #else inline void Lock() {} inline void Unlock() {} - inline PyThreadState *PyLock() { return NULL; } + inline PyThreadState *PyLock(PyThreadState *) { return NULL; } + inline PyThreadState *PyLockSys() { return NULL; } inline void PyUnlock(PyThreadState *st) {} #endif diff --git a/externals/grill/py/source/py.cpp b/externals/grill/py/source/py.cpp index bf3ff8fb..eb1d2390 100644 --- a/externals/grill/py/source/py.cpp +++ b/externals/grill/py/source/py.cpp @@ -133,7 +133,7 @@ pyobj::pyobj(int argc,const t_atom *argv): FLEXT_CALLMETHOD(threadworker); #endif - PyThreadState *state = PyLock(); + PyThreadState *state = PyLockSys(); if(argc > 2) SetArgs(argc-2,argv+2); @@ -188,7 +188,7 @@ pyobj::pyobj(int argc,const t_atom *argv): pyobj::~pyobj() { - PyThreadState *state = PyLock(); + PyThreadState *state = PyLockSys(); Unregister("_py"); PyUnlock(state); } @@ -208,7 +208,7 @@ bool pyobj::CbMethodResort(int n,const t_symbol *s,int argc,const t_atom *argv) void pyobj::m_reload() { - PyThreadState *state = PyLock(); + PyThreadState *state = PyLockSys(); Unregister("_py"); @@ -222,7 +222,7 @@ void pyobj::m_reload() void pyobj::m_reload_(int argc,const t_atom *argv) { - PyThreadState *state = PyLock(); + PyThreadState *state = PyLockSys(); SetArgs(argc,argv); PyUnlock(state); @@ -231,7 +231,7 @@ void pyobj::m_reload_(int argc,const t_atom *argv) void pyobj::m_set(int argc,const t_atom *argv) { - PyThreadState *state = PyLock(); + PyThreadState *state = PyLockSys(); int ix = 0; if(argc >= 2) { @@ -328,7 +328,7 @@ void pyobj::Reload() bool pyobj::callpy(PyObject *fun,PyObject *args) { - PyObject *ret = PyObject_Call(fun,args,NULL); + PyObject *ret = PyObject_CallObject(fun,args); if(ret == NULL) { // function not found resp. arguments not matching PyErr_Print(); diff --git a/externals/grill/py/source/pybuffer.cpp b/externals/grill/py/source/pybuffer.cpp index 6e7e571b..f95c4bc6 100644 --- a/externals/grill/py/source/pybuffer.cpp +++ b/externals/grill/py/source/pybuffer.cpp @@ -11,15 +11,25 @@ WARRANTIES, see the file, "license.txt," in this distribution. #include "main.h" #ifdef PY_NUMARRAY +#if FLEXT_OS == FLEXT_OS_MAC +#include +#else #include +#endif static bool nasupport = false; static NumarrayType numtype; #endif // PD defines a T_OBJECT symbol #undef T_OBJECT -#include "structmember.h" + +#if FLEXT_OS == FLEXT_OS_MAC +#include "Python/bufferobject.h" +#include "Python/structmember.h" +#else #include "bufferobject.h" +#include "structmember.h" +#endif static PyObject *buffer_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { diff --git a/externals/grill/py/source/pydsp.cpp b/externals/grill/py/source/pydsp.cpp index b1f50c0d..4c9eea5c 100644 --- a/externals/grill/py/source/pydsp.cpp +++ b/externals/grill/py/source/pydsp.cpp @@ -26,7 +26,7 @@ protected: virtual PyObject *GetSig(int ix,bool in); - void NewBuffers(bool update = false); + void NewBuffers(); void FreeBuffers(); PyObject *dspfun,*sigfun; @@ -46,18 +46,11 @@ bool pydsp::DoInit() if(pyobj) { - NewBuffers(); - dspfun = PyObject_GetAttrString(pyobj,"_dsp"); // get ref if(dspfun && !PyMethod_Check(dspfun)) { Py_DECREF(dspfun); dspfun = NULL; } - sigfun = PyObject_GetAttrString(pyobj,"_signal"); // get ref - if(sigfun && !PyMethod_Check(sigfun)) { - Py_DECREF(sigfun); - sigfun = NULL; - } } return true; } @@ -72,29 +65,28 @@ void pydsp::DoExit() PyObject *NAFromBuffer(PyObject *buf,int c,int n); -void pydsp::NewBuffers(bool update) +void pydsp::NewBuffers() { int i,n = Blocksize(); const int ins = CntInSig(),outs = CntOutSig(); t_sample *const *insigs = InSig(); t_sample *const *outsigs = OutSig(); + // inlet/outlet count can't change so we don't have to deallocate if(!buffers) { int cnt = ins+outs; - if(cnt) { - buffers = new PyObject *[cnt]; - memset(buffers,0,cnt*sizeof(*buffers)); - } + buffers = new PyObject *[cnt]; + memset(buffers,0,cnt*sizeof(*buffers)); } for(i = 0; i < ins; ++i) { - if(update) Py_XDECREF(buffers[i]); + Py_XDECREF(buffers[i]); PyObject *b = PyBuffer_FromReadWriteMemory(insigs[i],n*sizeof(t_sample)); buffers[i] = NAFromBuffer(b,1,n); Py_DECREF(b); } for(i = 0; i < outs; ++i) { - if(update) Py_XDECREF(buffers[ins+i]); + Py_XDECREF(buffers[ins+i]); if(i < ins && outsigs[i] == insigs[i]) { // same vectors - share the objects! buffers[ins+i] = buffers[i]; @@ -120,15 +112,14 @@ void pydsp::FreeBuffers() bool pydsp::CbDsp() { - if(CntInSig() || CntOutSig()) + if(pyobj && (CntInSig() || CntOutSig())) { - NewBuffers(true); + PyThreadState *state = PyLockSys(); + + NewBuffers(); if(dspfun) { - PyThreadState *state = PyLock(); -// Py_INCREF(emptytuple); - PyObject *ret = PyObject_Call(dspfun,emptytuple,NULL); -// Py_DECREF(emptytuple); + PyObject *ret = PyObject_CallObject(dspfun,NULL); if(ret) Py_DECREF(ret); else { @@ -138,9 +129,20 @@ bool pydsp::CbDsp() PyErr_Clear(); #endif } - PyUnlock(state); } - return true; + + // do that here instead of where dspfun is initialized, so that + // _signal can be assigned in _dsp + // optimizations may be done there to assign the right _signal version + Py_XDECREF(sigfun); + sigfun = PyObject_GetAttrString(pyobj,"_signal"); // get ref + if(sigfun && !PyMethod_Check(sigfun)) { + Py_DECREF(sigfun); + sigfun = NULL; + } + + PyUnlock(state); + return sigfun != NULL; } else // switch on dsp only if there are signal inlets or outlets @@ -149,25 +151,19 @@ bool pydsp::CbDsp() void pydsp::CbSignal() { - if(sigfun) { - PyThreadState *state = PyLock(); -// Py_INCREF(emptytuple); - PyObject *ret = PyObject_Call(sigfun,emptytuple,NULL); -// Py_DECREF(emptytuple); - - if(ret) - Py_DECREF(ret); - else { + PyThreadState *state = PyLockSys(); + PyObject *ret = PyObject_CallObject(sigfun,NULL); + + if(ret) + Py_DECREF(ret); + else { #ifdef FLEXT_DEBUG - PyErr_Print(); + PyErr_Print(); #else - PyErr_Clear(); + PyErr_Clear(); #endif - } - PyUnlock(state); } - else - flext_dsp::CbSignal(); + PyUnlock(state); } PyObject *pydsp::GetSig(int ix,bool in) diff --git a/externals/grill/py/source/pyext.cpp b/externals/grill/py/source/pyext.cpp index 0ebeab68..2d772d15 100644 --- a/externals/grill/py/source/pyext.cpp +++ b/externals/grill/py/source/pyext.cpp @@ -131,7 +131,7 @@ pyext::pyext(int argc,const t_atom *argv,bool sig): const t_atom *clname = NULL; - PyThreadState *state = PyLock(); + PyThreadState *state = PyLockSys(); // init script module if(argc > apre) { @@ -188,7 +188,7 @@ pyext::pyext(int argc,const t_atom *argv,bool sig): bool pyext::Init() { - PyThreadState *state = PyLock(); + PyThreadState *state = PyLockSys(); if(methname) { MakeInstance(); @@ -215,7 +215,7 @@ void pyext::Exit() { pybase::Exit(); // exit threads - PyThreadState *state = PyLock(); + PyThreadState *state = PyLockSys(); DoExit(); Unregister("_pyext"); UnimportModule(); @@ -259,15 +259,13 @@ void pyext::DoExit() // try to run del to clean up the class instance PyObject *objdel = PyObject_GetAttrString(pyobj,"_del"); if(objdel) { - Py_INCREF(emptytuple); - PyObject *ret = PyObject_Call(objdel,emptytuple,NULL); + PyObject *ret = PyObject_CallObject(objdel,NULL); if(ret) Py_DECREF(ret); #ifdef FLEXT_DEBUG else post("%s - Could not call _del method",thisName()); #endif - Py_DECREF(emptytuple); Py_DECREF(objdel); } else @@ -381,7 +379,7 @@ void pyext::Reload() void pyext::m_reload() { - PyThreadState *state = PyLock(); + PyThreadState *state = PyLockSys(); Unregister("_pyext"); // self @@ -403,7 +401,7 @@ void pyext::m_reload_(int argc,const t_atom *argv) void pyext::m_get(const t_symbol *s) { - PyThreadState *state = PyLock(); + PyThreadState *state = PyLockSys(); PyObject *pvar = PyObject_GetAttrString(pyobj,const_cast(GetString(s))); /* fetch bound method */ if(!pvar) { @@ -431,7 +429,7 @@ void pyext::m_get(const t_symbol *s) void pyext::m_set(int argc,const t_atom *argv) { - PyThreadState *state = PyLock(); + PyThreadState *state = PyLockSys(); if(argc < 2 || !IsString(argv[0])) post("%s - Syntax: set varname arguments...",thisName()); @@ -506,7 +504,7 @@ void pyext::m_help() bool pyext::callpy(PyObject *fun,PyObject *args) { - PyObject *ret = PyObject_Call(fun,args,NULL); + PyObject *ret = PyObject_CallObject(fun,args); if(ret == NULL) { // function not found resp. arguments not matching PyErr_Print(); -- cgit v1.2.1