aboutsummaryrefslogtreecommitdiff
path: root/externals/grill/py
diff options
context:
space:
mode:
authorThomas Grill <xovo@users.sourceforge.net>2005-03-10 04:59:00 +0000
committerThomas Grill <xovo@users.sourceforge.net>2005-03-10 04:59:00 +0000
commitec67ac9af1c9a02130347c4ed6f32fa03f55eba2 (patch)
treed2a1f6e129e9179c695ec6c0f5c3b9dffa46815c /externals/grill/py
parent5e3101f8a1a5cf78f86635da6a78d8564aa85483 (diff)
more buffer functionality (support sequence and number protocols)
more examples preset sys.argv for module loading support for buffer objects (preliminary) svn path=/trunk/; revision=2615
Diffstat (limited to 'externals/grill/py')
-rw-r--r--externals/grill/py/pd/buffer-1.pd63
-rw-r--r--externals/grill/py/readme.txt5
-rw-r--r--externals/grill/py/scripts/buffer.py50
-rw-r--r--externals/grill/py/source/main.cpp32
-rw-r--r--externals/grill/py/source/pybuffer.cpp496
5 files changed, 552 insertions, 94 deletions
diff --git a/externals/grill/py/pd/buffer-1.pd b/externals/grill/py/pd/buffer-1.pd
index 2309ca30..ca799385 100644
--- a/externals/grill/py/pd/buffer-1.pd
+++ b/externals/grill/py/pd/buffer-1.pd
@@ -1,39 +1,40 @@
-#N canvas 123 58 692 472 12;
+#N canvas 123 58 712 492 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;
+#A 0 0 0 0 0 0 0 0 0 0 0 0.00285713 0.00471427 0.00514284 0.00557141
+0.00599998 0.00642855 0.00228571 0.00242857 0.00257143 -0.00542855
+-0.0114285 -0.0209999 -0.0377142 -0.0427142 -0.0479998 -0.067857 -0.0891426
+-0.104143 -0.108 -0.111857 -0.115714 -0.119571 -0.123428 -0.127285
+-0.131142 -0.125 -0.128571 -0.132143 -0.127571 -0.122571 -0.12 -0.117142
+-0.114 -0.110571 -0.106857 -0.102857 -0.0985711 -0.0872856 -0.0754282
+-0.0629998 -0.0499999 -0.0437141 -0.0371427 -0.0227142 -0.00771428
+0.00785714 0.0239999 0.0298571 0.0359047 0.0421427 0.068571 0.0915
+0.132857 0.161999 0.146285 0.134642 0.122571 0.105285 0.0582855 0.00985713
+0.00999999 0.0101428 -0.0411427 -0.0417142 -0.0739998 -0.0749998 -0.0759998
+-0.132 -0.133714 -0.12533 -0.113684 -0.101707 -0.089398 -0.0767592
+-0.0637893 -0.0504886 -0.036857 -0.0152967 0.0067692 0.0293405 0.0524174
+0.0759997 0.100088 0.12468 0.14978 0.175384 0.201493 0.228109 0.25523
+0.325284;
#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;
+#A 0 0 0 0 0 0 0 0.0285712 0.0428568 0.0571424 0.12857 0.171427 0.185712
+0.199998 0.242854 0.342853 0.342853 0.364281 0.41428 0.41428 0.357138
+0.314282 0.278568 0.314282 0.328567 0.342853 0.378567 0.41428 0.457137
+0.49285 0.528564 0.54285 0.557135 0.599992 0.614277 0.671419 0.671419
+0.599992 0.614276 0.59999 0.585705 0.571419 0.499991 0.482135 0.464278
+0.446421 0.428564 0.408564 0.388565 0.368565 0.348565 0.328566 0.305709
+0.282852 0.259995 0.237138 0.214282 0.194282 0.174282 0.154282 0.134283
+0.114283 0.0914263 0.0685695 0.0457127 0.0228559 8.84384e-007 0.0142864
+0.0285719 0.0428574 0.0571429 0.0714284 0.096428 0.121428 0.146427
+0.171427 0.181631 0.191835 0.202039 0.212243 0.222446 0.23265 0.242854
+0.25714 0.271425 0.285711 0.299996 0.314282 0.33571 0.357138 0.385709
+0.407138 0.428566 0.457137 0.457137 0.12857 0.514279 0.557135 0.604754
+0.652372 0.814274;
#X coords 0 1 99 -1 200 140 1;
#X restore 421 305 graph;
#N canvas 0 0 450 300 graph3 0;
@@ -41,16 +42,20 @@
#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 msg 192 127 mul array3 array1 array2;
+#X msg 192 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 msg 193 176 fadein array1;
+#X msg 191 200 neg array2;
#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;
+#X connect 13 0 6 1;
+#X connect 14 0 6 1;
diff --git a/externals/grill/py/readme.txt b/externals/grill/py/readme.txt
index ff2266dd..60260706 100644
--- a/externals/grill/py/readme.txt
+++ b/externals/grill/py/readme.txt
@@ -83,7 +83,7 @@ Version history:
- ADD: Python symbol type
- ADD: _del method in pyext-derived class can be used to clean up things on exit
- FIX: solved py->py messaging problem with lock count instead of message queuing
-- ADD: numarray support for buffer handling
+- ADD: buffer handling with optional numarray support (if present)
0.1.4:
- ADD: better (and independent) handling of inlet and outlet count (as class variables or dynamically initialized in __init__)
@@ -146,6 +146,9 @@ Version history:
TODO list:
+bugs:
+- crashes with long Python printouts
+
general:
- Documentation and better example patches
- better error reporting for runtime errors
diff --git a/externals/grill/py/scripts/buffer.py b/externals/grill/py/scripts/buffer.py
index 4c81caab..19b6f5d3 100644
--- a/externals/grill/py/scripts/buffer.py
+++ b/externals/grill/py/scripts/buffer.py
@@ -7,12 +7,9 @@
"""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.
+PD/Max buffers can be mapped to 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
+It will probably once be replaced by Numeric(3)
"""
import sys
@@ -20,7 +17,7 @@ import sys
try:
import pyext
except:
- print "ERROR: This script must be loaded by the PD/Max pyext external"
+ print "ERROR: This script must be loaded by the PD/Max py/pyext external"
try:
from numarray import *
@@ -28,19 +25,36 @@ except:
print "Failed importing numarray module:",sys.exc_value
def mul(*args):
+ # create buffer objects
+ # as long as these variables live the underlying buffers are locked
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()
+ a = pyext.Buffer(args[1])
+ b = pyext.Buffer(args[2])
+
+ # slicing causes numarrays (mapped to buffers) to be created
+ # note the c[:] - to assign contents you must assign to a slice of the buffer
+ c[:] = a[:]*b[:]
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()
+ a = pyext.Buffer(args[1])
+ b = pyext.Buffer(args[2])
+
+ # this is also possible, but is probably slower
+ # the + converts a into a numarray, the argument b is taken as a sequence
+ # depending on the implementation in numarray this may be as fast
+ # as above or not
+ c[:] = a+b
+
+def fadein(target):
+ a = pyext.Buffer(target)
+ # in place operations are ok
+ a *= arange(len(a),type=Float32)/len(a)
+
+def neg(target):
+ a = pyext.Buffer(target)
+ # in place transformation (see numarray ufuncs)
+ negative(a[:],a[:])
+ # must mark buffer content as dirty to update graph
+ # (no explicit assignment occurred)
+ a.dirty()
diff --git a/externals/grill/py/source/main.cpp b/externals/grill/py/source/main.cpp
index c24f998c..e32b9ba8 100644
--- a/externals/grill/py/source/main.cpp
+++ b/externals/grill/py/source/main.cpp
@@ -97,12 +97,30 @@ void py::lib_setup()
pythrmap[GetThreadId()] = pythrmain;
#endif
+ // sys.argv must be set to empty tuple
+ char *nothing = "";
+ PySys_SetArgv(0,&nothing);
+
// register/initialize pyext module only once!
module_obj = Py_InitModule(PYEXT_MODULE, func_tbl);
module_dict = PyModule_GetDict(module_obj); // borrowed reference
PyModule_AddStringConstant(module_obj,"__doc__",(char *)py_doc);
+ // redirect stdout
+ PyObject* py_out;
+ py_out = Py_InitModule("stdout", StdOut_Methods);
+ PySys_SetObject("stdout", py_out);
+ py_out = Py_InitModule("stderr", StdOut_Methods);
+ PySys_SetObject("stderr", py_out);
+
+ // get garbage collector function
+ PyObject *gcobj = PyImport_ImportModule("gc");
+ if(gcobj) {
+ gcollect = PyObject_GetAttrString(gcobj,"collect");
+ Py_DECREF(gcobj);
+ }
+
// add symbol type
initsymbol();
PyModule_AddObject(module_obj,"Symbol",(PyObject *)&pySymbol_Type);
@@ -119,20 +137,6 @@ void py::lib_setup()
initsamplebuffer();
PyModule_AddObject(module_obj,"Buffer",(PyObject *)&pySamplebuffer_Type);
- // redirect stdout
- PyObject* py_out;
- py_out = Py_InitModule("stdout", StdOut_Methods);
- PySys_SetObject("stdout", py_out);
- py_out = Py_InitModule("stderr", StdOut_Methods);
- PySys_SetObject("stderr", py_out);
-
- // get garbage collector function
- PyObject *gcobj = PyImport_ImportModule("gc");
- if(gcobj) {
- gcollect = PyObject_GetAttrString(gcobj,"collect");
- Py_DECREF(gcobj);
- }
-
// -------------------------------------------------------------
FLEXT_SETUP(pyobj);
diff --git a/externals/grill/py/source/pybuffer.cpp b/externals/grill/py/source/pybuffer.cpp
index ed1b2749..96f2efae 100644
--- a/externals/grill/py/source/pybuffer.cpp
+++ b/externals/grill/py/source/pybuffer.cpp
@@ -101,31 +101,6 @@ static PyGetSetDef buffer_getseters[] = {
{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;
@@ -134,7 +109,6 @@ static PyObject *buffer_dirty(PyObject *obj)
}
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 */
};
@@ -170,13 +144,470 @@ static int buffer_charbuffer(PyObject *obj, int segment, const char **ptrptr)
return b->Channels()*b->Frames()*sizeof(t_sample);
}
-static PyBufferProcs bufferprocs = {
+static PyBufferProcs buffer_as_buffer = {
buffer_readbuffer,
buffer_writebuffer,
buffer_segcount,
buffer_charbuffer
};
+static int buffer_length(pySamplebuffer *self)
+{
+ return self->buf?self->buf->Frames():0;
+}
+
+static PyObject *buffer_item(pySamplebuffer *self, int i)
+{
+ PyObject *ret;
+ if(self->buf) {
+ if (i < 0 || i >= self->buf->Frames()) {
+ PyErr_SetString(PyExc_IndexError,"Index out of range");
+ ret = NULL;
+ }
+ else {
+ if(self->buf->Channels() == 1)
+ ret = PyFloat_FromDouble(self->buf->Data()[i]);
+ else {
+ PyErr_SetString(PyExc_NotImplementedError,"Multiple channels not implemented yet");
+ ret = NULL;
+ }
+ }
+ }
+ else
+ Py_INCREF(ret = Py_None);
+ return ret;
+}
+
+static PyObject *buffer_slice(pySamplebuffer *self,int ilow = 0,int ihigh = 1<<(sizeof(int)*8-2))
+{
+ PyObject *ret;
+#ifdef PY_NUMARRAY
+ if(nasupport) {
+ if(self->buf) {
+ const int n = self->buf->Frames();
+ const int c = self->buf->Channels();
+ if(ilow < 0) ilow += n;
+ if(ilow >= n) ilow = n-1;
+ if(ihigh < 0) ihigh += n;
+ if(ihigh > n) ihigh = n;
+
+ maybelong shape[2];
+ shape[0] = n;
+ shape[1] = c;
+ PyObject *nobj = (PyObject *)NA_NewAllFromBuffer(c == 1?1:2,shape,numtype,(PyObject *)self,0,0,NA_ByteOrder(),1,1);
+ if(ilow != 0 || ihigh != n) {
+ ret = PySequence_GetSlice(nobj,ilow,ihigh);
+ Py_DECREF(nobj);
+ }
+ else
+ ret = nobj;
+ }
+ else
+ Py_INCREF(ret = Py_None);
+ }
+ else
+#endif
+ {
+ PyErr_SetString(PyExc_RuntimeError,"No numarray support");
+ ret = NULL;
+ }
+ return ret;
+}
+
+static int buffer_ass_item(pySamplebuffer *self,int i,PyObject *v)
+{
+ int ret;
+ if(self->buf) {
+ if (i < 0 || i >= self->buf->Frames()) {
+ PyErr_Format(PyExc_IndexError,"Index out of range");
+ ret = -1;
+ }
+ else {
+ if(self->buf->Channels() == 1) {
+ self->buf->Data()[i] = (t_sample)PyFloat_AsDouble(v);
+ if(PyErr_Occurred()) {
+ // cast to double failed
+ PyErr_SetString(PyExc_TypeError,"Value must be a numarray");
+ ret = -1;
+ }
+ else {
+ self->dirty = true;
+ ret = 0;
+ }
+ }
+ else {
+ PyErr_SetString(PyExc_NotImplementedError,"Multiple channels not implemented yet");
+ ret = -1;
+ }
+ }
+ }
+ else
+ ret = -1;
+ return ret;
+}
+
+static int buffer_ass_slice(pySamplebuffer *self,int ilow,int ihigh,PyObject *value)
+{
+ int ret;
+#ifdef PY_NUMARRAY
+ if(nasupport) {
+ if(!value) {
+ PyErr_SetString(PyExc_TypeError,"Object doesn't support item deletion");
+ ret = -1;
+ }
+ else if(self->buf) {
+ const int n = self->buf->Frames();
+ const int c = self->buf->Channels();
+ if(ilow < 0) ilow += n;
+ if(ilow >= n) ilow = n-1;
+ if(ihigh < 0) ihigh += n;
+ if(ihigh > n) ihigh = n;
+
+ PyArrayObject *out = NA_InputArray(value,numtype,NUM_C_ARRAY);
+ if(!out) {
+ PyErr_SetString(PyExc_TypeError,"Assigned object must be a numarray");
+ ret = -1;
+ }
+ else if(out->nd != 1) {
+ PyErr_SetString(PyExc_NotImplementedError,"Multiple dimensions not supported yet");
+ ret = -1;
+ }
+ else {
+ int dlen = ihigh-ilow;
+ int slen = out->dimensions[0];
+ flext::CopySamples(self->buf->Data()+ilow,(t_sample *)NA_OFFSETDATA(out),slen < dlen?slen:dlen);
+ self->dirty = true;
+ ret = 0;
+ }
+
+ Py_XDECREF(out);
+ }
+ else {
+ PyErr_SetString(PyExc_ValueError,"Buffer is not assigned");
+ ret = -1;
+ }
+ }
+ else
+#endif
+ {
+ PyErr_SetString(PyExc_RuntimeError,"No numarray support");
+ ret = -1;
+ }
+ return ret;
+}
+
+static PyObject *buffer_concat(pySamplebuffer *self,PyObject *op)
+{
+ PyObject *nobj = buffer_slice(self);
+ if(nobj) {
+ PyObject *ret = PySequence_Concat(nobj,op);
+ if(ret == nobj) self->dirty = true;
+ Py_DECREF(nobj);
+ return ret;
+ }
+ else
+ return NULL;
+}
+
+static PyObject *buffer_repeat(pySamplebuffer *self,int rep)
+{
+ PyObject *nobj = buffer_slice(self);
+ if(nobj) {
+ PyObject *ret = PySequence_Repeat(nobj,rep);
+ if(ret == nobj) self->dirty = true;
+ Py_DECREF(nobj);
+ return ret;
+ }
+ else
+ return NULL;
+}
+
+
+static PySequenceMethods buffer_as_seq = {
+ (inquiry)buffer_length, /* inquiry sq_length; /* __len__ */
+ (binaryfunc)buffer_concat, /* __add__ */
+ (intargfunc)buffer_repeat, /* __mul__ */
+ (intargfunc)buffer_item, /* intargfunc sq_item; /* __getitem__ */
+ (intintargfunc)buffer_slice, /* intintargfunc sq_slice; /* __getslice__ */
+ (intobjargproc)buffer_ass_item, /* intobjargproc sq_ass_item; /* __setitem__ */
+ (intintobjargproc)buffer_ass_slice, /* intintobjargproc sq_ass_slice; /* __setslice__ */
+};
+
+static PyObject *buffer_iter(PyObject *obj)
+{
+ pySamplebuffer *self = (pySamplebuffer *)obj;
+ PyObject *nobj = buffer_slice(self);
+ if(nobj) {
+ PyObject *it = PyObject_GetIter(nobj);
+ Py_DECREF(nobj);
+ return it;
+ }
+ else
+ return NULL;
+}
+
+
+static PyObject *buffer_add(pySamplebuffer *self,PyObject *op)
+{
+ PyObject *nobj = buffer_slice(self);
+ if(nobj) {
+ PyObject *ret = PyNumber_Add(nobj,op);
+ if(ret == nobj) self->dirty = true;
+ Py_DECREF(nobj);
+ return ret;
+ }
+ else
+ return NULL;
+}
+
+static PyObject *buffer_subtract(pySamplebuffer *self,PyObject *op)
+{
+ PyObject *nobj = buffer_slice(self);
+ if(nobj) {
+ PyObject *ret = PyNumber_Subtract(nobj,op);
+ if(ret == nobj) self->dirty = true;
+ Py_DECREF(nobj);
+ return ret;
+ }
+ else
+ return NULL;
+}
+
+static PyObject *buffer_multiply(pySamplebuffer *self,PyObject *op)
+{
+ PyObject *nobj = buffer_slice(self);
+ if(nobj) {
+ PyObject *ret = PyNumber_Multiply(nobj,op);
+ if(ret == nobj) self->dirty = true;
+ Py_DECREF(nobj);
+ return ret;
+ }
+ else
+ return NULL;
+}
+
+static PyObject *buffer_divide(pySamplebuffer *self,PyObject *op)
+{
+ PyObject *nobj = buffer_slice(self);
+ if(nobj) {
+ PyObject *ret = PyNumber_Divide(nobj,op);
+ if(ret == nobj) self->dirty = true;
+ Py_DECREF(nobj);
+ return ret;
+ }
+ else
+ return NULL;
+}
+
+static PyObject *buffer_remainder(pySamplebuffer *self,PyObject *op)
+{
+ PyObject *nobj = buffer_slice(self);
+ if(nobj) {
+ PyObject *ret = PyNumber_Remainder(nobj,op);
+ if(ret == nobj) self->dirty = true;
+ Py_DECREF(nobj);
+ return ret;
+ }
+ else
+ return NULL;
+}
+
+static PyObject *buffer_divmod(pySamplebuffer *self,PyObject *op)
+{
+ PyObject *nobj = buffer_slice(self);
+ if(nobj) {
+ PyObject *ret = PyNumber_Divmod(nobj,op);
+ if(ret == nobj) self->dirty = true;
+ Py_DECREF(nobj);
+ return ret;
+ }
+ else
+ return NULL;
+}
+
+static PyObject *buffer_power(pySamplebuffer *self,PyObject *op1,PyObject *op2)
+{
+ PyObject *nobj = buffer_slice(self);
+ if(nobj) {
+ PyObject *ret = PyNumber_Power(nobj,op1,op2);
+ if(ret == nobj) self->dirty = true;
+ Py_DECREF(nobj);
+ return ret;
+ }
+ else
+ return NULL;
+}
+
+static PyObject *buffer_negative(pySamplebuffer *self)
+{
+ PyObject *nobj = buffer_slice(self);
+ if(nobj) {
+ PyObject *ret = PyNumber_Negative(nobj);
+ if(ret == nobj) self->dirty = true;
+ Py_DECREF(nobj);
+ return ret;
+ }
+ else
+ return NULL;
+}
+
+static PyObject *buffer_pos(pySamplebuffer *self)
+{
+ PyObject *nobj = buffer_slice(self);
+ if(nobj) {
+ PyObject *ret = PyNumber_Positive(nobj);
+ Py_DECREF(nobj);
+ return ret;
+ }
+ else
+ return NULL;
+}
+
+static PyObject *buffer_absolute(pySamplebuffer *self)
+{
+ PyObject *nobj = buffer_slice(self);
+ if(nobj) {
+ PyObject *ret = PyNumber_Absolute(nobj);
+ if(ret == nobj) self->dirty = true;
+ Py_DECREF(nobj);
+ return ret;
+ }
+ else
+ return NULL;
+}
+
+static int buffer_coerce(pySamplebuffer **pm, PyObject **pw)
+{
+ if(pySamplebuffer_Check(*pw)) {
+ Py_INCREF(*pm);
+ Py_INCREF(*pw);
+ return 0;
+ }
+ else
+ return 1;
+}
+
+static PyObject *buffer_inplace_add(pySamplebuffer *self,PyObject *op)
+{
+ PyObject *nobj = buffer_slice(self);
+ if(nobj) {
+ PyObject *ret = PyNumber_InPlaceAdd(nobj,op);
+ if(ret == nobj) self->dirty = true;
+ Py_DECREF(nobj);
+ return ret;
+ }
+ else
+ return NULL;
+}
+
+static PyObject *buffer_inplace_subtract(pySamplebuffer *self,PyObject *op)
+{
+ PyObject *nobj = buffer_slice(self);
+ if(nobj) {
+ PyObject *ret = PyNumber_InPlaceSubtract(nobj,op);
+ if(ret == nobj) self->dirty = true;
+ Py_DECREF(nobj);
+ return ret;
+ }
+ else
+ return NULL;
+}
+
+static PyObject *buffer_inplace_multiply(pySamplebuffer *self,PyObject *op)
+{
+ PyObject *nobj = buffer_slice(self);
+ if(nobj) {
+ PyObject *ret = PyNumber_InPlaceMultiply(nobj,op);
+ if(ret == nobj) self->dirty = true;
+ Py_DECREF(nobj);
+ return ret;
+ }
+ else
+ return NULL;
+}
+
+static PyObject *buffer_inplace_divide(pySamplebuffer *self,PyObject *op)
+{
+ PyObject *nobj = buffer_slice(self);
+ if(nobj) {
+ PyObject *ret = PyNumber_InPlaceDivide(nobj,op);
+ if(ret == nobj) self->dirty = true;
+ Py_DECREF(nobj);
+ return ret;
+ }
+ else
+ return NULL;
+}
+
+static PyObject *buffer_inplace_remainder(pySamplebuffer *self,PyObject *op)
+{
+ PyObject *nobj = buffer_slice(self);
+ if(nobj) {
+ PyObject *ret = PyNumber_InPlaceRemainder(nobj,op);
+ if(ret == nobj) self->dirty = true;
+ Py_DECREF(nobj);
+ return ret;
+ }
+ else
+ return NULL;
+}
+
+static PyObject *buffer_inplace_power(pySamplebuffer *self,PyObject *op1,PyObject *op2)
+{
+ PyObject *nobj = buffer_slice(self);
+ if(nobj) {
+ PyObject *ret = PyNumber_InPlacePower(nobj,op1,op2);
+ if(ret == nobj) self->dirty = true;
+ Py_DECREF(nobj);
+ return ret;
+ }
+ else
+ return NULL;
+}
+
+
+
+static PyNumberMethods buffer_as_number = {
+ (binaryfunc)buffer_add, /*nb_add*/
+ (binaryfunc)buffer_subtract, /*nb_subtract*/
+ (binaryfunc)buffer_multiply, /*nb_multiply*/
+ (binaryfunc)buffer_divide, /*nb_divide*/
+ (binaryfunc)buffer_remainder, /*nb_remainder*/
+ (binaryfunc)buffer_divmod, /*nb_divmod*/
+ (ternaryfunc)buffer_power, /*nb_power*/
+ (unaryfunc)buffer_negative,
+ (unaryfunc)buffer_pos, /*nb_pos*/
+ (unaryfunc)buffer_absolute, /* (unaryfunc)buffer_abs, */
+ 0, //(inquiry)buffer_nonzero, /*nb_nonzero*/
+ 0, /*nb_invert*/
+ 0, /*nb_lshift*/
+ 0, /*nb_rshift*/
+ 0, /*nb_and*/
+ 0, /*nb_xor*/
+ 0, /*nb_or*/
+ (coercion)buffer_coerce, /*nb_coerce*/
+ 0, /*nb_int*/
+ 0, /*nb_long*/
+ 0, /*nb_float*/
+ 0, /*nb_oct*/
+ 0, /*nb_hex*/
+ (binaryfunc)buffer_inplace_add, /* nb_inplace_add */
+ (binaryfunc)buffer_inplace_subtract, /* nb_inplace_subtract */
+ (binaryfunc)buffer_inplace_multiply, /* nb_inplace_multiply */
+ (binaryfunc)buffer_inplace_divide, /* nb_inplace_divide */
+ (binaryfunc)buffer_inplace_remainder, /* nb_inplace_remainder */
+ (ternaryfunc)buffer_inplace_power, /* nb_inplace_power */
+ 0, /* nb_inplace_lshift */
+ 0, /* nb_inplace_rshift */
+ 0, /* nb_inplace_and */
+ 0, /* nb_inplace_xor */
+ 0, /* nb_inplace_or */
+// buffer_floor_div, /* nb_floor_divide */
+// buffer_div, /* nb_true_divide */
+// buffer_inplace_floor_div, /* nb_inplace_floor_divide */
+// buffer_inplace_div, /* nb_inplace_true_divide */
+};
+
PyTypeObject pySamplebuffer_Type = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
@@ -189,22 +620,22 @@ PyTypeObject pySamplebuffer_Type = {
0, /*tp_setattr*/
0, /*tp_compare*/
buffer_repr, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
+ &buffer_as_number, /*tp_as_number*/
+ &buffer_as_seq, /*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*/
+ &buffer_as_buffer, /*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 */
+ buffer_iter, /* tp_iter */
0, /* tp_iternext */
buffer_methods, /* tp_methods */
0, /* tp_members */
@@ -222,10 +653,11 @@ PyTypeObject pySamplebuffer_Type = {
void initsamplebuffer()
{
#ifdef PY_NUMARRAY
+ PyErr_Clear();
import_libnumarray();
if(PyErr_Occurred())
// catch import error
- PyErr_Clear();
+ PyErr_Print();
else {
// numarray support ok
nasupport = true;