shithub: aubio

Download patch

ref: 21e8408a89a7cffad5b58e4cc2c64779d9e96628
parent: b055b4ec0a94cd0cf9ffa051ef46acd6588df831
author: Paul Brossier <piem@piem.org>
date: Fri Apr 29 19:48:39 EDT 2016

python/lib/gen_code.py: switch to using PyObjects instead of fvec, cvec, fmat

--- a/python/ext/py-filter.c
+++ b/python/ext/py-filter.c
@@ -6,7 +6,8 @@
   aubio_filter_t * o;
   uint_t order;
   fvec_t vec;
-  fvec_t *out;
+  PyObject *out;
+  fvec_t c_out;
 } Py_filter;
 
 static char Py_filter_doc[] = "filter object";
@@ -49,7 +50,7 @@
   if (self->o == NULL) {
     return -1;
   }
-  self->out = new_fvec(Py_default_vector_length);
+  self->out = NULL;
   return 0;
 }
 
@@ -56,12 +57,12 @@
 static void
 Py_filter_del (Py_filter * self)
 {
-  del_fvec(self->out);
+  Py_XDECREF(self->out);
   del_aubio_filter (self->o);
   Py_TYPE(self)->tp_free ((PyObject *) self);
 }
 
-static PyObject * 
+static PyObject *
 Py_filter_do(Py_filter * self, PyObject * args)
 {
   PyObject *input;
@@ -78,17 +79,21 @@
     return NULL;
   }
 
-  // reallocate the output if needed
-  if (self->vec.length != self->out->length) {
-    del_fvec(self->out);
-    self->out = new_fvec(self->vec.length);
+  // initialize output now
+  if (self->out == NULL) {
+    self->out = new_py_fvec(self->vec.length);
   }
+
+  Py_INCREF(self->out);
+  if (!PyAubio_ArrayToCFvec(self->out, &(self->c_out)) ) {
+    return NULL;
+  }
   // compute the function
-  aubio_filter_do_outplace (self->o, &(self->vec), self->out);
-  return PyAubio_CFvecToArray(self->out);
+  aubio_filter_do_outplace (self->o, &(self->vec), &(self->c_out));
+  return self->out;
 }
 
-static PyObject * 
+static PyObject *
 Py_filter_set_c_weighting (Py_filter * self, PyObject *args)
 {
   uint_t err = 0;
@@ -106,7 +111,7 @@
   Py_RETURN_NONE;
 }
 
-static PyObject * 
+static PyObject *
 Py_filter_set_a_weighting (Py_filter * self, PyObject *args)
 {
   uint_t err = 0;
--- a/python/lib/gen_code.py
+++ b/python/lib/gen_code.py
@@ -48,15 +48,15 @@
         }
 
 newfromtype_fn = {
-        'fvec_t*': 'new_fvec',
-        'fmat_t*': 'new_fmat',
-        'cvec_t*': 'new_cvec',
+        'fvec_t*': 'new_py_fvec',
+        'fmat_t*': 'new_py_fmat',
+        'cvec_t*': 'new_py_cvec',
         }
 
 delfromtype_fn = {
-        'fvec_t*': 'del_fvec',
-        'fmat_t*': 'del_fmat',
-        'cvec_t*': 'del_cvec',
+        'fvec_t*': 'Py_DECREF',
+        'fmat_t*': 'Py_DECREF',
+        'cvec_t*': 'Py_DECREF',
         }
 
 param_init = {
@@ -168,8 +168,8 @@
         self.outputs = get_params_types_names(self.do_proto)[2:]
         self.do_inputs = [get_params_types_names(self.do_proto)[1]]
         self.do_outputs = get_params_types_names(self.do_proto)[2:]
-        self.outputs_flat = get_output_params(self.do_proto)
-        self.output_results = "; ".join(self.outputs_flat)
+        struct_output_str = ["PyObject *{0[name]}; {1} c_{0[name]}".format(i, i['type'][:-1]) for i in self.do_outputs]
+        self.struct_outputs = ";\n    ".join(struct_output_str)
 
         #print ("input_params: ", map(split_type, get_input_params(self.do_proto)))
         #print ("output_params", map(split_type, get_output_params(self.do_proto)))
@@ -201,7 +201,7 @@
     // do input vectors
     {do_inputs_list};
     // output results
-    {output_results};
+    {struct_outputs};
 }} Py_{shortname};
 """
         # fmat_t* / fvec_t* / cvec_t* inputs -> full fvec_t /.. struct in Py_{shortname}
@@ -379,24 +379,35 @@
     if (!PyArg_ParseTuple (args, "{pyparamtypes}", {refs})) {{
         return NULL;
     }}""".format(refs = refs, pyparamtypes = pyparamtypes, **self.__dict__)
-        for p in input_params:
+        for input_param in input_params:
             out += """
+
     if (!{pytoaubio}(py_{0[name]}, &(self->{0[name]}))) {{
         return NULL;
     }}""".format(input_param, pytoaubio = pytoaubio_fn[input_param['type']])
+        out += """
+
+    // TODO: check input sizes"""
+        for output_param in output_params:
+            out += """
+
+    Py_INCREF(self->{0[name]});
+    if (!{pytoaubio}(self->{0[name]}, &(self->c_{0[name]}))) {{
+        return NULL;
+    }}""".format(output_param, pytoaubio = pytoaubio_fn[output_param['type']])
         do_fn = get_name(self.do_proto)
         inputs = ", ".join(['&(self->'+p['name']+')' for p in input_params])
+        c_outputs = ", ".join(["&(self->c_%s)" % p['name'] for p in self.do_outputs])
         outputs = ", ".join(["self->%s" % p['name'] for p in self.do_outputs])
         out += """
 
-    {do_fn}(self->o, {inputs}, {outputs});
+    {do_fn}(self->o, {inputs}, {c_outputs});
 
-    return (PyObject *) {aubiotonumpy} ({outputs});
+    return {outputs};
 }}
 """.format(
         do_fn = do_fn,
-        aubiotonumpy = pyfromaubio_fn[output['type']], 
-        inputs = inputs, outputs = outputs,
+        inputs = inputs, outputs = outputs, c_outputs = c_outputs,
         )
         return out