Index: python/ext/py-filter.c
===================================================================
--- python/ext/py-filter.c	(revision b055b4ec0a94cd0cf9ffa051ef46acd6588df831)
+++ python/ext/py-filter.c	(revision 21e8408a89a7cffad5b58e4cc2c64779d9e96628)
@@ -7,5 +7,6 @@
   uint_t order;
   fvec_t vec;
-  fvec_t *out;
+  PyObject *out;
+  fvec_t c_out;
 } Py_filter;
 
@@ -50,5 +51,5 @@
     return -1;
   }
-  self->out = new_fvec(Py_default_vector_length);
+  self->out = NULL;
   return 0;
 }
@@ -57,10 +58,10 @@
 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)
 {
@@ -79,15 +80,19 @@
   }
 
-  // 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);
-}
-
-static PyObject * 
+  aubio_filter_do_outplace (self->o, &(self->vec), &(self->c_out));
+  return self->out;
+}
+
+static PyObject *
 Py_filter_set_c_weighting (Py_filter * self, PyObject *args)
 {
@@ -107,5 +112,5 @@
 }
 
-static PyObject * 
+static PyObject *
 Py_filter_set_a_weighting (Py_filter * self, PyObject *args)
 {
Index: python/lib/gen_code.py
===================================================================
--- python/lib/gen_code.py	(revision b055b4ec0a94cd0cf9ffa051ef46acd6588df831)
+++ python/lib/gen_code.py	(revision 21e8408a89a7cffad5b58e4cc2c64779d9e96628)
@@ -49,13 +49,13 @@
 
 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',
         }
 
@@ -169,6 +169,6 @@
         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)))
@@ -202,5 +202,5 @@
     {do_inputs_list};
     // output results
-    {output_results};
+    {struct_outputs};
 }} Py_{shortname};
 """
@@ -380,22 +380,33 @@
         return NULL;
     }}""".format(refs = refs, pyparamtypes = pyparamtypes, **self.__dict__)
-        for p in input_params:
-            out += """
+        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});
-
-    return (PyObject *) {aubiotonumpy} ({outputs});
+    {do_fn}(self->o, {inputs}, {c_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
