From e854889b99b9e515dc69d237b1031b5705e83b60 Mon Sep 17 00:00:00 2001 From: Thomas Grill Date: Wed, 9 Mar 2005 04:58:11 +0000 Subject: fixes for detached operation and single-threaded version use lock count instead of message queuing to avoid py->py messaging deadlock support for buffer objects (preliminary) updated build system little restructuring fixes for single-threaded compilation added support for numarray svn path=/trunk/; revision=2610 --- externals/grill/py/build/config-lnx.def | 3 + externals/grill/py/build/config-mac.def | 3 +- externals/grill/py/build/config-win.def | 3 + externals/grill/py/build/gnumake-lnx-gcc.inc | 4 + externals/grill/py/build/gnumake-mac-gcc.inc | 3 + externals/grill/py/build/nmake-win-msvc.inc | 4 + externals/grill/py/package.txt | 8 +- externals/grill/py/pd/buffer-1.pd | 56 ++++++ externals/grill/py/py.vcproj | 10 +- externals/grill/py/readme.txt | 1 + externals/grill/py/scripts/buffer.py | 46 +++++ externals/grill/py/scripts/threads.py | 4 +- externals/grill/py/source/main.cpp | 25 ++- externals/grill/py/source/main.h | 7 + externals/grill/py/source/modmeth.cpp | 3 - externals/grill/py/source/py.cpp | 2 +- externals/grill/py/source/pybuffer.cpp | 244 +++++++++++++++++++++++++++ externals/grill/py/source/pybuffer.h | 79 +++++++++ externals/grill/py/source/pysymbol.h | 2 +- 19 files changed, 488 insertions(+), 19 deletions(-) create mode 100644 externals/grill/py/pd/buffer-1.pd create mode 100644 externals/grill/py/scripts/buffer.py create mode 100644 externals/grill/py/source/pybuffer.cpp create mode 100644 externals/grill/py/source/pybuffer.h (limited to 'externals/grill/py') diff --git a/externals/grill/py/build/config-lnx.def b/externals/grill/py/build/config-lnx.def index 121d2cb5..3eba0d96 100644 --- a/externals/grill/py/build/config-lnx.def +++ b/externals/grill/py/build/config-lnx.def @@ -3,3 +3,6 @@ PYTHONPREFIX=/usr # which Python version do you want to compile against? PYTHONVERSION=2.3 + +# uncomment if numarray support should be compiled in +# PY_NUMARRAY=1 diff --git a/externals/grill/py/build/config-mac.def b/externals/grill/py/build/config-mac.def index be94b713..a966f137 100644 --- a/externals/grill/py/build/config-mac.def +++ b/externals/grill/py/build/config-mac.def @@ -1 +1,2 @@ -# nothing to adjust! \ No newline at end of file +# uncomment if numarray support should be compiled in +# PY_NUMARRAY=1 diff --git a/externals/grill/py/build/config-win.def b/externals/grill/py/build/config-win.def index afa2f649..f587116d 100644 --- a/externals/grill/py/build/config-win.def +++ b/externals/grill/py/build/config-win.def @@ -1,2 +1,5 @@ # where is the Python installation? PYTHONPATH=c:\programme\prog\python24 + +# uncomment if numarray support should be compiled in +# PY_NUMARRAY=1 diff --git a/externals/grill/py/build/gnumake-lnx-gcc.inc b/externals/grill/py/build/gnumake-lnx-gcc.inc index bdb375f1..ff0a8bfa 100644 --- a/externals/grill/py/build/gnumake-lnx-gcc.inc +++ b/externals/grill/py/build/gnumake-lnx-gcc.inc @@ -1,3 +1,7 @@ DEFS += -DPY_EXPORTS INCPATH += -I$(PYTHONPREFIX)/include/python$(PYTHONVERSION) LIBS += -lpython$(PYTHONVERSION) + +ifdef PY_NUMARRAY +DEFS += -DPY_NUMARRAY +endif \ No newline at end of file diff --git a/externals/grill/py/build/gnumake-mac-gcc.inc b/externals/grill/py/build/gnumake-mac-gcc.inc index 16e9df6f..c7268557 100644 --- a/externals/grill/py/build/gnumake-mac-gcc.inc +++ b/externals/grill/py/build/gnumake-mac-gcc.inc @@ -1,3 +1,6 @@ DEFS += -DPY_EXPORTS LIBS += -framework Python +ifdef PY_NUMARRAY +DEFS += -DPY_NUMARRAY +endif diff --git a/externals/grill/py/build/nmake-win-msvc.inc b/externals/grill/py/build/nmake-win-msvc.inc index 373f98a7..e9334065 100644 --- a/externals/grill/py/build/nmake-win-msvc.inc +++ b/externals/grill/py/build/nmake-win-msvc.inc @@ -1,3 +1,7 @@ DEFS = $(DEFS) /DPY_EXPORTS INCPATH=/I$(PYTHONPATH)\include LIBPATH=/LIBPATH:$(PYTHONPATH)\libs + +!ifdef PY_NUMARRAY +DEFS = $(DEFS) /DPY_NUMARRAY +!endif diff --git a/externals/grill/py/package.txt b/externals/grill/py/package.txt index 8cbd70d6..208fe827 100644 --- a/externals/grill/py/package.txt +++ b/externals/grill/py/package.txt @@ -6,6 +6,10 @@ BUILDDIR=build SRCDIR=source PRECOMPILE=pyprefix.h -SRCS= main.cpp py.cpp pyext.cpp modmeth.cpp clmeth.cpp register.cpp pyargs.cpp bound.cpp pysymbol.cpp +SRCS= \ + main.cpp \ + py.cpp pyext.cpp modmeth.cpp clmeth.cpp \ + register.cpp bound.cpp pyargs.cpp \ + pysymbol.cpp pybuffer.cpp -HDRS= pyprefix.h main.h pyext.h pysymbol.h +HDRS= pyprefix.h main.h pyext.h pysymbol.h pybuffer.h diff --git a/externals/grill/py/pd/buffer-1.pd b/externals/grill/py/pd/buffer-1.pd new file mode 100644 index 00000000..2309ca30 --- /dev/null +++ b/externals/grill/py/pd/buffer-1.pd @@ -0,0 +1,56 @@ +#N canvas 123 58 692 472 12; +#X obj 37 240 print; +#X obj 107 241 print A; +#X msg 30 139 reload; +#N canvas 0 0 450 300 graph1 0; +#X array array1 100 float 3; +#A 0 0 0 0 0 0 0 0 0 0 0 0.0285713 0.042857 0.042857 0.042857 0.042857 +0.042857 0.0142857 0.0142857 0.0142857 -0.0285713 -0.0571427 -0.0999997 +-0.171428 -0.185714 -0.199999 -0.271428 -0.342856 -0.385713 -0.385713 +-0.385713 -0.385713 -0.385713 -0.385713 -0.385713 -0.385713 -0.357142 +-0.357142 -0.357142 -0.335713 -0.314285 -0.299999 -0.285713 -0.271428 +-0.257142 -0.242856 -0.228571 -0.214285 -0.185714 -0.157142 -0.128571 +-0.0999997 -0.085714 -0.0714283 -0.042857 -0.0142857 0.0142857 0.042857 +0.0523808 0.0619046 0.0714283 0.114285 0.15 0.214285 0.257142 0.228571 +0.207142 0.185714 0.157142 0.085714 0.0142857 0.0142857 0.0142857 -0.0571427 +-0.0571427 -0.0999997 -0.0999997 -0.0999997 -0.171428 -0.171428 -0.158646 +-0.142105 -0.125564 -0.109022 -0.092481 -0.0759397 -0.0593984 -0.042857 +-0.0175824 0.00769227 0.0329669 0.0582416 0.0835162 0.108791 0.134065 +0.15934 0.184615 0.209889 0.235164 0.260439 0.32857; +#X coords 0 1 99 -1 200 140 1; +#X restore 421 156 graph; +#N canvas 0 0 450 300 graph2 0; +#X array array2 100 float 3; +#A 0 0 0 0 0 0 0 0.0285712 0.0428568 0.0571424 0.0999993 0.114285 0.128571 +0.142856 0.157142 0.171427 0.185713 0.199999 0.242855 0.257141 0.271426 +0.314283 0.342854 0.385711 0.421425 0.485711 0.557139 0.599995 0.671424 +0.680947 0.690471 0.699995 0.742852 0.752375 0.761899 0.771423 0.771423 +0.771423 0.81428 0.81428 0.81428 0.81428 0.828565 0.842851 0.842851 +0.842851 0.842851 0.842851 0.842851 0.864279 0.885708 0.885708 0.885708 +0.885708 0.876184 0.86666 0.857136 0.857136 0.857137 0.842851 0.828565 +0.81428 0.799994 0.785708 0.76428 0.742852 0.728566 0.71428 0.671424 +0.599995 0.428568 0.40714 -0.328569 -0.428569 -0.428569 -0.471425 -0.471425 +-0.471425 -0.442854 -0.442854 -0.399997 -0.385712 -0.371426 -0.335712 +-0.299998 -0.257141 -0.242856 -0.22857 -0.157142 -0.114285 -0.0857139 +-0.0857139 -0.042857 -0.042857 0.028571 0.0571425 0.0571425 0.0999993 +0.128571 0.128571 0.128571; +#X coords 0 1 99 -1 200 140 1; +#X restore 421 305 graph; +#N canvas 0 0 450 300 graph3 0; +#X array array3 100 float 2; +#X coords 0 1 99 -1 200 140 1; +#X restore 65 301 graph; +#X obj 36 199 py buffer @detach 1; +#X msg 123 127 mul array3 array1 array2; +#X msg 123 149 add array3 array1 array2; +#X obj 16 13 cnv 15 650 40 empty empty py/pyext 10 22 0 24 -260818 +-1 0; +#X text 235 16 Python script objects \, (C)2003-2005 Thomas Grill; +#X text 235 32 http://grrrr.org/ext; +#X text 17 67 This demonstrates the usage of buffers. See the buffer.py +script.; +#X connect 2 0 6 0; +#X connect 6 0 0 0; +#X connect 6 1 1 0; +#X connect 7 0 6 1; +#X connect 8 0 6 1; diff --git a/externals/grill/py/py.vcproj b/externals/grill/py/py.vcproj index 7c006dfe..1541f6b0 100644 --- a/externals/grill/py/py.vcproj +++ b/externals/grill/py/py.vcproj @@ -86,7 +86,7 @@ Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories=""c:\data\prog\pd\pd-cvs\src";..\flext\source;c:\programme\prog\Python24\include" - PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;PY_EXPORTS;FLEXT_SYS=2;FLEXT_THREADS" + PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;PY_EXPORTS;FLEXT_SYS=2;FLEXT_THREADS;PY_NUMARRAY" BasicRuntimeChecks="3" RuntimeLibrary="1" RuntimeTypeInfo="TRUE" @@ -152,7 +152,7 @@ Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="c:\programme\audio\pd\src;c:\data\pdmax\flext\source;C:\Programme\prog\Python24\include" - PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;PY_EXPORTS;FLEXT_SYS=2;FLEXT_THREADS" + PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;PY_EXPORTS;FLEXT_SYS=2;FLEXT_THREADS;PY_NUMARRAY" StringPooling="TRUE" RuntimeLibrary="0" EnableFunctionLevelLinking="TRUE" @@ -1125,6 +1125,12 @@ BrowseInformation="1"/> + + + + py messaging problem with lock count instead of message queuing +- ADD: numarray support for buffer handling 0.1.4: - ADD: better (and independent) handling of inlet and outlet count (as class variables or dynamically initialized in __init__) diff --git a/externals/grill/py/scripts/buffer.py b/externals/grill/py/scripts/buffer.py new file mode 100644 index 00000000..4c81caab --- /dev/null +++ b/externals/grill/py/scripts/buffer.py @@ -0,0 +1,46 @@ +# py/pyext - python script objects for PD and MaxMSP +# +# Copyright (c) 2002-2005 Thomas Grill (gr@grrrr.org) +# For information on usage and redistribution, and for a DISCLAIMER OF ALL +# WARRANTIES, see the file, "license.txt," in this distribution. +# + +"""This is an example script for the py/pyext object's buffer support. + +PD/Max buffers can be imported to and exported from numarray arrays. +For numarray see http://numeric.scipy.org +It will probably once be replaced by Numeric + +- _import(buffer): copy contents from the buffer to a new numarray object +- _export(buffer,numarray): export contents of numarray object to the buffer +""" + +import sys + +try: + import pyext +except: + print "ERROR: This script must be loaded by the PD/Max pyext external" + +try: + from numarray import * +except: + print "Failed importing numarray module:",sys.exc_value + +def mul(*args): + c = pyext.Buffer(args[0]) + dst = c.array() + dst[:] = 0 + a = pyext.Buffer(args[1]).array() + b = pyext.Buffer(args[2]).array() + dst += a*b + c.dirty() + +def add(*args): + c = pyext.Buffer(args[0]) + dst = c.array() + dst[:] = 0 + a = pyext.Buffer(args[1]).array() + b = pyext.Buffer(args[2]).array() + dst += a+b + c.dirty() diff --git a/externals/grill/py/scripts/threads.py b/externals/grill/py/scripts/threads.py index e1a91351..b0299101 100644 --- a/externals/grill/py/scripts/threads.py +++ b/externals/grill/py/scripts/threads.py @@ -39,7 +39,9 @@ class ex1(pyext._class): def bang_(self,n): for i in xrange(self.loops): # if _shouldexit is true, the thread ought to stop - if self._shouldexit: break + if self._shouldexit: + print "BREAK" + break self._outlet(n,i) sleep(self.sltime) diff --git a/externals/grill/py/source/main.cpp b/externals/grill/py/source/main.cpp index 01dc0afa..c24f998c 100644 --- a/externals/grill/py/source/main.cpp +++ b/externals/grill/py/source/main.cpp @@ -60,6 +60,7 @@ void py::FreeThreadState() void initsymbol(); +void initsamplebuffer(); void py::lib_setup() { @@ -69,12 +70,11 @@ void py::lib_setup() post("(C)2002-2005 Thomas Grill - http://grrrr.org/ext"); post(""); post("using Python %s",Py_GetVersion()); + #ifdef FLEXT_DEBUG post(""); post("DEBUG version compiled on %s %s",__DATE__,__TIME__); #endif - post("------------------------------------------------"); - post(""); // ------------------------------------------------------------- @@ -115,6 +115,10 @@ void py::lib_setup() PyModule_AddObject(module_obj,"_s_float",(PyObject *)pySymbol_float); PyModule_AddObject(module_obj,"_s_int",(PyObject *)pySymbol_int); + // add samplebuffer type + initsamplebuffer(); + PyModule_AddObject(module_obj,"Buffer",(PyObject *)&pySamplebuffer_Type); + // redirect stdout PyObject* py_out; py_out = Py_InitModule("stdout", StdOut_Methods); @@ -138,6 +142,9 @@ void py::lib_setup() // release global lock PyEval_ReleaseLock(); #endif + + post("------------------------------------------------"); + post(""); } FLEXT_LIB_SETUP(py,py::lib_setup) @@ -189,12 +196,14 @@ void py::Exit() qucond.Signal(); if(thrcount) { // Wait for a certain time - for(int i = 0; i < (PY_STOP_WAIT/PY_STOP_TICK) && thrcount; ++i) Sleep(PY_STOP_TICK/1000.f); - - // Wait forever - post("%s - Waiting for thread termination!",thisName()); - while(thrcount) Sleep(PY_STOP_TICK/1000.f); - post("%s - Okay, all threads have terminated",thisName()); + for(int i = 0; i < (PY_STOP_WAIT/PY_STOP_TICK) && thrcount; ++i) + Sleep(PY_STOP_TICK*0.001f); + if(thrcount) { + // Wait forever + post("%s - Waiting for thread termination!",thisName()); + while(thrcount) Sleep(PY_STOP_TICK*0.001f); + post("%s - Okay, all threads have terminated",thisName()); + } } #endif flext_base::Exit(); diff --git a/externals/grill/py/source/main.h b/externals/grill/py/source/main.h index 2d495461..7079dc2f 100644 --- a/externals/grill/py/source/main.h +++ b/externals/grill/py/source/main.h @@ -13,6 +13,7 @@ WARRANTIES, see the file, "license.txt," in this distribution. #include "pyprefix.h" #include "pysymbol.h" +#include "pybuffer.h" #include #if FLEXT_OS == FLEXT_LINUX || FLEXT_OS == FLEXT_IRIX @@ -107,6 +108,12 @@ protected: static PyObject *py_setvalue(PyObject *,PyObject *args); #endif +#ifdef PY_NUMARRAY + static void setupNumarray(); + static PyObject *py_import(PyObject *,PyObject *args); + static PyObject *py_export(PyObject *,PyObject *args); +#endif + // ----thread stuff ------------ virtual void m_stop(int argc,const t_atom *argv); diff --git a/externals/grill/py/source/modmeth.cpp b/externals/grill/py/source/modmeth.cpp index 70eb536a..4054d3ce 100644 --- a/externals/grill/py/source/modmeth.cpp +++ b/externals/grill/py/source/modmeth.cpp @@ -26,7 +26,6 @@ PyMethodDef py::func_tbl[] = { "_getvalue", py::py_getvalue, METH_VARARGS,"Get value of a 'value' object" }, { "_setvalue", py::py_setvalue, METH_VARARGS,"Set value of a 'value' object" }, #endif - {NULL, NULL, 0, NULL} // sentinel }; @@ -221,5 +220,3 @@ PyObject *py::py_setvalue(PyObject *self,PyObject *args) return Py_None; } #endif - - diff --git a/externals/grill/py/source/py.cpp b/externals/grill/py/source/py.cpp index 68f805b8..3856739e 100644 --- a/externals/grill/py/source/py.cpp +++ b/externals/grill/py/source/py.cpp @@ -331,7 +331,7 @@ void pyobj::callwork(const t_symbol *s,int argc,const t_atom *argv) else post("%s: no valid function defined",thisName()); } - else { + else if(module) { // no function defined as creation argument -> use message tag PyObject *func = PyObject_GetAttrString(module,const_cast(GetString(s))); if(func) { diff --git a/externals/grill/py/source/pybuffer.cpp b/externals/grill/py/source/pybuffer.cpp new file mode 100644 index 00000000..ed1b2749 --- /dev/null +++ b/externals/grill/py/source/pybuffer.cpp @@ -0,0 +1,244 @@ +/* + +py/pyext - python script object for PD and Max/MSP + +Copyright (c)2002-2005 Thomas Grill (gr@grrrr.org) +For information on usage and redistribution, and for a DISCLAIMER OF ALL +WARRANTIES, see the file, "license.txt," in this distribution. + +*/ + +#include "main.h" + +#ifdef PY_NUMARRAY +#include +static bool nasupport = false; +static NumarrayType numtype; +#endif + +// PD defines a T_OBJECT symbol +#undef T_OBJECT +#include "structmember.h" +#include "bufferobject.h" + +static PyObject *buffer_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + pySamplebuffer *self = (pySamplebuffer *)pySamplebuffer_Type.tp_alloc(&pySamplebuffer_Type, 0); + self->sym = NULL; + self->buf = NULL; + self->dirty = false; + return (PyObject *)self; +} + +static void buffer_dealloc(PyObject *obj) +{ + pySamplebuffer *self = (pySamplebuffer *)obj; + + if(self->buf) { + self->buf->Unlock(self->lock); + if(self->dirty) self->buf->Dirty(true); + delete self->buf; + } + + obj->ob_type->tp_free(obj); +} + +static int buffer_init(PyObject *obj, PyObject *args, PyObject *kwds) +{ + FLEXT_ASSERT(pySamplebuffer_Check(obj)); + + PyObject *arg = PySequence_GetItem(args,0); // new reference + if(!arg) return -1; + + int ret = 0; + + pySamplebuffer *self = (pySamplebuffer *)obj; + FLEXT_ASSERT(!self->sym && !self->buf); + + if(pySymbol_Check(arg)) + self->sym = pySymbol_AS_SYMBOL(arg); + else if(PyString_Check(arg)) + self->sym = flext::MakeSymbol(PyString_AS_STRING(arg)); + else + ret = -1; + Py_DECREF(arg); + + if(self->sym) { + flext::buffer *b = new flext::buffer(self->sym); + if(b->Ok() && b->Valid()) + self->lock = (self->buf = b)->Lock(); + else + delete b; + } + + return ret; +} + +static PyObject *buffer_repr(PyObject *self) +{ + FLEXT_ASSERT(pySamplebuffer_Check(self)); + return (PyObject *)PyString_FromFormat("",pySamplebuffer_AS_STRING(self)); +} + +static long buffer_hash(PyObject *self) +{ + FLEXT_ASSERT(pySamplebuffer_Check(self)); + return (long)(((pySamplebuffer *)self)->buf); +} + +static PyObject *buffer_getsymbol(pySamplebuffer* self,void *closure) +{ + if(self->sym) + return pySymbol_FromSymbol(self->sym); + else { + Py_INCREF(Py_None); + return Py_None; + } +} + +static PyGetSetDef buffer_getseters[] = { + {"symbol",(getter)buffer_getsymbol, NULL, NULL}, + {NULL} /* Sentinel */ +}; + +static PyObject *buffer_array(PyObject *obj) +{ + PyObject *ret; +#ifdef PY_NUMARRAY + if(nasupport) { + pySamplebuffer *self = (pySamplebuffer *)obj; + if(self->buf) { + maybelong shape[2]; + shape[0] = self->buf->Frames(); + shape[1] = self->buf->Channels(); + ret = (PyObject *)NA_NewAllFromBuffer(2,shape,numtype,(PyObject *)self,0,sizeof(t_sample *),NA_ByteOrder(),1,1); + } + else + Py_INCREF(ret = Py_None); + } + else { + PyErr_Format(PyExc_RuntimeError,"No numarray support"); + ret = NULL; + } +#else + Py_INCREF(ret = Py_None); +#endif + return ret; +} + +static PyObject *buffer_dirty(PyObject *obj) +{ + ((pySamplebuffer *)obj)->dirty = true; + Py_INCREF(Py_None); + return Py_None; +} + +static PyMethodDef buffer_methods[] = { + {"array", (PyCFunction)buffer_array,METH_NOARGS,"Return a numarray object"}, + {"dirty", (PyCFunction)buffer_dirty,METH_NOARGS,"Mark buffer as dirty"}, + {NULL} /* Sentinel */ +}; + + + +// support the buffer protocol +static int buffer_readbuffer(PyObject *obj, int segment, void **ptrptr) +{ + flext::buffer *b = ((pySamplebuffer *)obj)->buf; + ptrptr[0] = b->Data(); + return b->Channels()*b->Frames()*sizeof(t_sample); +} + +static int buffer_writebuffer(PyObject *obj, int segment, void **ptrptr) +{ + flext::buffer *b = ((pySamplebuffer *)obj)->buf; + ptrptr[0] = b->Data(); + return b->Channels()*b->Frames()*sizeof(t_sample); +} + +static int buffer_segcount(PyObject *obj, int *lenp) +{ + flext::buffer *b = ((pySamplebuffer *)obj)->buf; + if(lenp) lenp[0] = b->Channels()*b->Frames()*sizeof(t_sample); + return 1; +} + +static int buffer_charbuffer(PyObject *obj, int segment, const char **ptrptr) +{ + flext::buffer *b = ((pySamplebuffer *)obj)->buf; + ptrptr[0] = (char *)b->Data(); + return b->Channels()*b->Frames()*sizeof(t_sample); +} + +static PyBufferProcs bufferprocs = { + buffer_readbuffer, + buffer_writebuffer, + buffer_segcount, + buffer_charbuffer +}; + +PyTypeObject pySamplebuffer_Type = { + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "Buffer", /*tp_name*/ + sizeof(pySamplebuffer), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + buffer_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + buffer_repr, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + buffer_hash, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + &bufferprocs, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT /*| Py_TPFLAGS_BASETYPE*/, /*tp_flags*/ + "Samplebuffer objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0 /*buffer_richcompare*/, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + buffer_methods, /* tp_methods */ + 0, /* tp_members */ + buffer_getseters, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + buffer_init, /* tp_init */ + 0, /* tp_alloc */ + buffer_new, /* tp_new */ +}; + +void initsamplebuffer() +{ +#ifdef PY_NUMARRAY + import_libnumarray(); + if(PyErr_Occurred()) + // catch import error + PyErr_Clear(); + else { + // numarray support ok + nasupport = true; + post(""); + post("Numarray support enabled"); + } + + numtype = sizeof(t_sample) == 4?tFloat32:tFloat64; +#endif + + if(PyType_Ready(&pySamplebuffer_Type) < 0) + FLEXT_ASSERT(false); + else + Py_INCREF(&pySamplebuffer_Type); +} + diff --git a/externals/grill/py/source/pybuffer.h b/externals/grill/py/source/pybuffer.h new file mode 100644 index 00000000..1d59dd95 --- /dev/null +++ b/externals/grill/py/source/pybuffer.h @@ -0,0 +1,79 @@ +/* + +py/pyext - python script object for PD and Max/MSP + +Copyright (c)2002-2005 Thomas Grill (gr@grrrr.org) +For information on usage and redistribution, and for a DISCLAIMER OF ALL +WARRANTIES, see the file, "license.txt," in this distribution. + +*/ + +#ifndef __PYBUFFER_H +#define __PYBUFFER_H + +#include + +#if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 500) +#error You need at least flext version 0.5.0 +#endif + +#if FLEXT_OS == FLEXT_OS_MAC +#include +#else +#include +#endif + + +#ifdef _MSC_VER + #ifdef PY_EXPORTS + #define PY_EXPORT __declspec(dllexport) + #else + #define PY_EXPORT __declspec(dllimport) + #endif +#else + #define PY_EXPORT +#endif + +typedef struct { + PyObject_HEAD + /* Type-specific fields go here. */ + const t_symbol *sym; + flext::buffer *buf; + flext::buffer::lock_t lock; + bool dirty; +} pySamplebuffer; + +PY_EXPORT extern PyTypeObject pySamplebuffer_Type; + +#define pySamplebuffer_Check(op) PyObject_TypeCheck(op, &pySamplebuffer_Type) +#define pySamplebuffer_CheckExact(op) ((op)->ob_type == &PySamplebuffer_Type) + + +PY_EXPORT PyObject *pySamplebuffer_FromSymbol(const t_symbol *sym); + +inline PyObject *pySamplebuffer_FromString(const char *str) +{ + return pySamplebuffer_FromSymbol(flext::MakeSymbol(str)); +} + +inline PyObject *pySamplebuffer_FromString(PyObject *str) +{ + return pySamplebuffer_FromString(PyString_AsString(str)); +} + +inline const t_symbol *pySamplebuffer_AS_SYMBOL(PyObject *op) +{ + return ((pySamplebuffer *)op)->sym; +} + +inline const t_symbol *pySamplebuffer_AsSymbol(PyObject *op) +{ + return pySamplebuffer_Check(op)?pySamplebuffer_AS_SYMBOL(op):NULL; +} + +inline const char *pySamplebuffer_AS_STRING(PyObject *op) +{ + return flext::GetString(pySamplebuffer_AS_SYMBOL(op)); +} + +#endif diff --git a/externals/grill/py/source/pysymbol.h b/externals/grill/py/source/pysymbol.h index c6e057d4..e711f424 100644 --- a/externals/grill/py/source/pysymbol.h +++ b/externals/grill/py/source/pysymbol.h @@ -63,7 +63,7 @@ inline PyObject *pySymbol_FromString(const char *str) inline PyObject *pySymbol_FromString(PyObject *str) { - return pySymbol_FromSymbol(flext::MakeSymbol(PyString_AsString(str))); + return pySymbol_FromString(PyString_AsString(str)); } inline const t_symbol *pySymbol_AS_SYMBOL(PyObject *op) -- cgit v1.2.1