.
authorPaul Brossier <piem@piem.org>
Mon, 19 Oct 2009 13:08:43 +0000 (15:08 +0200)
committerPaul Brossier <piem@piem.org>
Mon, 19 Oct 2009 13:08:43 +0000 (15:08 +0200)
interfaces/python/aubio-types.h
interfaces/python/aubiomodule.c
interfaces/python/py-cvec.c
interfaces/python/py-fft.c [new file with mode: 0644]
interfaces/python/py-filter.c
interfaces/python/py-filterbank.c [new file with mode: 0644]
interfaces/python/py-fvec.c
interfaces/python/py-phasevoc.c [new file with mode: 0644]
interfaces/python/setup.py
interfaces/python/test_filter.py

index d5609e7b1c46d11975d9d29c1b8507727a648d8d..cbab5a0b7c2bb6dea554d587171afbde052eed8c 100644 (file)
@@ -9,10 +9,11 @@
 
 #define Py_aubio_default_samplerate 44100
 
-#ifdef HAVE_AUBIO_DOUBLE
-#define AUBIO_FLOAT NPY_FLOAT
+#if HAVE_AUBIO_DOUBLE
+#error "Ouch! Python interface for aubio has not been much tested yet."
+#define AUBIO_NPY_SMPL NPY_DOUBLE
 #else
-#define AUBIO_FLOAT NPY_LONG
+#define AUBIO_NPY_SMPL NPY_FLOAT
 #endif
 
 /**
@@ -32,11 +33,24 @@ typedef struct
   uint_t channels;
 } Py_fvec;
 extern PyTypeObject Py_fvecType;
+extern PyObject *PyAubio_FvecToArray (Py_fvec * self);
+extern Py_fvec *PyAubio_ArrayToFvec (PyObject * self);
 
+typedef struct
+{
+  PyObject_HEAD
+  cvec_t * o;
+  uint_t length;
+  uint_t channels;
+} Py_cvec;
 extern PyTypeObject Py_cvecType;
+extern PyObject *PyAubio_CvecToArray (Py_cvec * self);
+extern Py_cvec *PyAubio_ArrayToCvec (PyObject * self);
 
 extern PyTypeObject Py_filterType;
 
-extern PyObject *PyAubio_FvecToArray (Py_fvec * self);
+extern PyTypeObject Py_filterbankType;
 
-extern Py_fvec *PyAubio_ArrayToFvec (PyObject * self);
+extern PyTypeObject Py_fftType;
+
+extern PyTypeObject Py_pvocType;
index 4bd665f5f68418140201a06ab3b924d2447eb270..5dcac23fc9f75ba188139c84f74ef7759f63a661 100644 (file)
@@ -93,6 +93,7 @@ Py_min_removal(PyObject * self, PyObject * args)
 
   // compute the function
   fvec_min_removal (vec->o);
+
   // since this function does not return, we could return None
   //return Py_None;
   // however it is convenient to return the modified vector 
@@ -118,9 +119,13 @@ init_aubio (void)
   PyObject *m;
   int err;
 
-  if ((PyType_Ready (&Py_fvecType) < 0) ||
-      (PyType_Ready (&Py_cvecType) < 0) ||
-      (PyType_Ready (&Py_filterType) < 0)) {
+  if ((PyType_Ready (&Py_fvecType) < 0) 
+      || (PyType_Ready (&Py_cvecType) < 0) 
+      || (PyType_Ready (&Py_filterType) < 0) 
+      || (PyType_Ready (&Py_filterbankType) < 0) 
+      || (PyType_Ready (&Py_fftType) < 0) 
+      || (PyType_Ready (&Py_pvocType) < 0) 
+  ) {
     return;
   }
 
@@ -143,4 +148,10 @@ init_aubio (void)
   PyModule_AddObject (m, "cvec", (PyObject *) & Py_cvecType);
   Py_INCREF (&Py_filterType);
   PyModule_AddObject (m, "digital_filter", (PyObject *) & Py_filterType);
+  Py_INCREF (&Py_filterbankType);
+  PyModule_AddObject (m, "filterbank", (PyObject *) & Py_filterbankType);
+  Py_INCREF (&Py_fftType);
+  PyModule_AddObject (m, "fft", (PyObject *) & Py_fftType);
+  Py_INCREF (&Py_pvocType);
+  PyModule_AddObject (m, "pvoc", (PyObject *) & Py_pvocType);
 }
index ec25546dccf678468761c2dc1207b722c143bb99..5472a93754e80beba9fb622f8c8373fc62a1b3c0 100644 (file)
@@ -8,16 +8,8 @@ class cvec():
         self.channels = channels 
         self.norm = array(length, channels)
         self.phas = array(length, channels)
-
 */
 
-typedef struct
-{
-  PyObject_HEAD
-  cvec_t * o;
-  uint_t length;
-  uint_t channels;
-} Py_cvec;
 
 static char Py_cvec_doc[] = "cvec object";
 
@@ -96,7 +88,7 @@ Py_cvec_repr (Py_cvec * self, PyObject * unused)
   if (args == NULL) {
     goto fail;
   }
-  cvec_print ( self->o );
+  //cvec_print ( self->o );
 
   result = PyString_Format (format, args);
 
@@ -132,15 +124,15 @@ PyAubio_ArrayToCvec (PyObject *input) {
       PyErr_SetString (PyExc_ValueError, "input array should be float");
       goto fail;
 #if AUBIO_DO_CASTING
-    } else if (PyArray_TYPE (input) != AUBIO_FLOAT) {
+    } else if (PyArray_TYPE (input) != AUBIO_NPY_SMPL) {
       // input data type is not float32, casting 
-      array = PyArray_Cast ( (PyArrayObject*) input, AUBIO_FLOAT);
+      array = PyArray_Cast ( (PyArrayObject*) input, AUBIO_NPY_SMPL);
       if (array == NULL) {
         PyErr_SetString (PyExc_IndexError, "failed converting to NPY_FLOAT");
         goto fail;
       }
 #else
-    } else if (PyArray_TYPE (input) != AUBIO_FLOAT) {
+    } else if (PyArray_TYPE (input) != AUBIO_NPY_SMPL) {
       PyErr_SetString (PyExc_ValueError, "input array should be float32");
       goto fail;
 #endif
@@ -152,10 +144,14 @@ PyAubio_ArrayToCvec (PyObject *input) {
     // create a new cvec object
     vec = (Py_cvec*) PyObject_New (Py_cvec, &Py_cvecType); 
     if (PyArray_NDIM (array) == 1) {
+      PyErr_SetString (PyExc_ValueError,
+          "input array should be have at least two rows for norm and phas");
+      goto fail;
+    } else if (PyArray_NDIM (array) == 2) {
       vec->channels = 1;
       vec->length = PyArray_SIZE (array);
     } else {
-      vec->channels = PyArray_DIM (array, 0);
+      vec->channels = PyArray_DIM (array, 0) / 2;
       vec->length = PyArray_DIM (array, 1);
     }
 
@@ -166,8 +162,9 @@ PyAubio_ArrayToCvec (PyObject *input) {
     vec->o->norm = (smpl_t**)malloc(vec->o->channels * sizeof(smpl_t*));
     vec->o->phas = (smpl_t**)malloc(vec->o->channels * sizeof(smpl_t*));
     // hat data[i] point to array line
-    for (i = 0; i < vec->channels; i++) {
+    for (i = 0; i < vec->channels; i+=2) {
       vec->o->norm[i] = (smpl_t *) PyArray_GETPTR1 (array, i);
+      vec->o->phas[i] = (smpl_t *) PyArray_GETPTR1 (array, i+1);
     }
 
   } else {
@@ -185,24 +182,92 @@ PyObject *
 PyAubio_CvecToArray (Py_cvec * self)
 {
   PyObject *array = NULL;
-  if (self->channels == 1) {
-    npy_intp dims[] = { self->length, 1 };
-    array = PyArray_SimpleNewFromData (1, dims, NPY_FLOAT, self->o->norm[0]);
-  } else {
-    uint_t i;
-    npy_intp dims[] = { self->length, 1 };
-    PyObject *concat = PyList_New (0), *tmp = NULL;
-    for (i = 0; i < self->channels; i++) {
-      tmp = PyArray_SimpleNewFromData (1, dims, NPY_FLOAT, self->o->norm[i]);
-      PyList_Append (concat, tmp);
-      Py_DECREF (tmp);
-    }
-    array = PyArray_FromObject (concat, NPY_FLOAT, 2, 2);
-    Py_DECREF (concat);
+  uint_t i;
+  npy_intp dims[] = { self->o->length, 1 };
+  PyObject *concat = PyList_New (0), *tmp = NULL;
+  for (i = 0; i < self->channels; i++) {
+    tmp = PyArray_SimpleNewFromData (1, dims, NPY_FLOAT, self->o->norm[i]);
+    PyList_Append (concat, tmp);
+    Py_DECREF (tmp);
+    tmp = PyArray_SimpleNewFromData (1, dims, NPY_FLOAT, self->o->phas[i]);
+    PyList_Append (concat, tmp);
+    Py_DECREF (tmp);
+  }
+  array = PyArray_FromObject (concat, NPY_FLOAT, 2, 2);
+  Py_DECREF (concat);
+  return array;
+}
+
+PyObject *
+PyAubio_CvecNormToArray (Py_cvec * self)
+{
+  PyObject *array = NULL;
+  uint_t i;
+  npy_intp dims[] = { self->o->length, 1 };
+  PyObject *concat = PyList_New (0), *tmp = NULL;
+  for (i = 0; i < self->channels; i++) {
+    tmp = PyArray_SimpleNewFromData (1, dims, NPY_FLOAT, self->o->norm[i]);
+    PyList_Append (concat, tmp);
+    Py_DECREF (tmp);
+  }
+  array = PyArray_FromObject (concat, NPY_FLOAT, 2, 2);
+  Py_DECREF (concat);
+  return array;
+}
+
+PyObject *
+PyAubio_ArrayToCvecNorm (PyObject * self)
+{
+  return NULL;
+}
+
+PyObject *
+PyAubio_CvecPhasToArray (Py_cvec * self)
+{
+  PyObject *array = NULL;
+  uint_t i;
+  npy_intp dims[] = { self->o->length, 1 };
+  PyObject *concat = PyList_New (0), *tmp = NULL;
+  for (i = 0; i < self->channels; i++) {
+    tmp = PyArray_SimpleNewFromData (1, dims, NPY_FLOAT, self->o->phas[i]);
+    PyList_Append (concat, tmp);
+    Py_DECREF (tmp);
   }
+  array = PyArray_FromObject (concat, NPY_FLOAT, 2, 2);
+  Py_DECREF (concat);
   return array;
 }
 
+PyObject *
+PyAubio_ArrayToCvecPhas (PyObject * self)
+{
+  return NULL;
+}
+
+PyObject *
+Py_cvec_get_norm (Py_cvec * self, void *closure)
+{
+  return PyAubio_CvecNormToArray(self);
+}
+
+PyObject *
+Py_cvec_get_phas (Py_cvec * self, void *closure)
+{
+  return PyAubio_CvecPhasToArray(self);
+}
+
+static int
+Py_cvec_set_norm (Py_cvec * self, PyObject *value, void * closure)
+{
+  return 0;
+}
+
+static int
+Py_cvec_set_phas (Py_cvec * self, PyObject *value, void * closure)
+{
+  return 0;
+}
+
 static Py_ssize_t
 Py_cvec_getchannels (Py_cvec * self)
 {
@@ -269,11 +334,27 @@ static PyMemberDef Py_cvec_members[] = {
 };
 
 static PyMethodDef Py_cvec_methods[] = {
-  {"__array__", (PyCFunction) PyAubio_FvecToArray, METH_NOARGS,
-      "Returns the first channel as a numpy array."},
+  {"__array__", (PyCFunction) PyAubio_CvecToArray, METH_NOARGS,
+      "Returns the content of this cvec as a numpy array"},
+/*
+  {"norm", (PyCFunction) PyAubio_CvecNormToArray, METH_NOARGS,
+      "Returns the content of the magnitude of this cvec as a numpy array."},
+  {"phas", (PyCFunction) PyAubio_CvecPhasToArray, METH_NOARGS,
+      "Returns the content of the phase of this cvec as a numpy array."},
+*/
   {NULL}
 };
 
+static PyGetSetDef Py_cvec_getseters[] = {
+  {"norm", (getter)Py_cvec_get_norm, (setter)Py_cvec_set_norm, 
+      "Content of the magnitude of this cvec",
+      NULL},
+  {"phas", (getter)Py_cvec_get_phas, (setter)Py_cvec_set_phas, 
+      "Content of the magnitude of this cvec",
+      NULL},
+  {NULL} /* sentinel */
+};
+
 static PySequenceMethods Py_cvec_tp_as_sequence = {
   (lenfunc) Py_cvec_getchannels,        /* sq_length         */
   0,                                    /* sq_concat         */
@@ -319,7 +400,7 @@ PyTypeObject Py_cvecType = {
   0,                            /* tp_iternext       */
   Py_cvec_methods,              /* tp_methods        */
   Py_cvec_members,              /* tp_members        */
-  0,                            /* tp_getset         */
+  Py_cvec_getseters,            /* tp_getset         */
   0,                            /* tp_base           */
   0,                            /* tp_dict           */
   0,                            /* tp_descr_get      */
diff --git a/interfaces/python/py-fft.c b/interfaces/python/py-fft.c
new file mode 100644 (file)
index 0000000..acbeb67
--- /dev/null
@@ -0,0 +1,126 @@
+#include "aubiowraphell.h"
+
+static char Py_fft_doc[] = "fft object";
+
+AUBIO_DECLARE(fft, uint_t win_s; uint_t channels)
+
+//AUBIO_NEW(fft)
+static PyObject *
+Py_fft_new (PyTypeObject * type, PyObject * args, PyObject * kwds)
+{
+  int win_s = 0, channels = 0;
+  Py_fft *self;
+  static char *kwlist[] = { "win_s", "channels", NULL };
+
+  if (!PyArg_ParseTupleAndKeywords (args, kwds, "|II", kwlist,
+          &win_s, &channels)) {
+    return NULL;
+  }
+
+  self = (Py_fft *) type->tp_alloc (type, 0);
+
+  if (self == NULL) {
+    return NULL;
+  }
+
+  self->win_s = Py_default_vector_length;
+  self->channels = Py_default_vector_channels;
+
+  if (self == NULL) {
+    return NULL;
+  }
+
+  if (win_s > 0) {
+    self->win_s = win_s;
+  } else if (win_s < 0) {
+    PyErr_SetString (PyExc_ValueError,
+        "can not use negative window size");
+    return NULL;
+  }
+
+  if (channels > 0) {
+    self->channels = channels;
+  } else if (channels < 0) {
+    PyErr_SetString (PyExc_ValueError,
+        "can not use negative number of filters");
+    return NULL;
+  }
+
+  return (PyObject *) self;
+}
+
+
+AUBIO_INIT(fft, self->win_s, self->channels)
+
+AUBIO_DEL(fft)
+
+static PyObject * 
+Py_fft_do(PyObject * self, PyObject * args)
+{
+  PyObject *input;
+  Py_fvec *vec;
+  Py_cvec *output;
+
+  if (!PyArg_ParseTuple (args, "O", &input)) {
+    return NULL;
+  }
+
+  vec = PyAubio_ArrayToFvec (input);
+
+  if (vec == NULL) {
+    return NULL;
+  }
+
+  output = (Py_cvec*) PyObject_New (Py_cvec, &Py_cvecType);
+  output->channels = vec->channels;
+  output->length = ((Py_fft *) self)->win_s;
+  output->o = new_cvec(((Py_fft *) self)->win_s, vec->channels);
+
+  // compute the function
+  aubio_fft_do (((Py_fft *)self)->o, vec->o, output->o);
+  Py_INCREF(output);
+  return (PyObject *)output;
+  //return (PyObject *)PyAubio_CvecToArray(output);
+}
+
+AUBIO_MEMBERS_START(fft) 
+  {"win_s", T_INT, offsetof (Py_fft, win_s), READONLY,
+    "size of the window"},
+  {"channels", T_INT, offsetof (Py_fft, channels), READONLY,
+    "number of channels"},
+AUBIO_MEMBERS_STOP(fft)
+
+static PyObject * 
+Py_fft_rdo(PyObject * self, PyObject * args)
+{
+  PyObject *input;
+  Py_cvec *vec;
+  Py_fvec *output;
+
+  if (!PyArg_ParseTuple (args, "O", &input)) {
+    return NULL;
+  }
+
+  vec = PyAubio_ArrayToCvec (input);
+
+  if (vec == NULL) {
+    return NULL;
+  }
+
+  output = (Py_fvec*) PyObject_New (Py_fvec, &Py_fvecType);
+  output->channels = vec->channels;
+  output->length = ((Py_fft *) self)->win_s;
+  output->o = new_fvec(output->length, output->channels);
+
+  // compute the function
+  aubio_fft_rdo (((Py_fft *)self)->o, vec->o, output->o);
+  return (PyObject *)PyAubio_FvecToArray(output);
+}
+
+static PyMethodDef Py_fft_methods[] = {
+  {"rdo", (PyCFunction) Py_fft_rdo, METH_VARARGS,
+    "synthesis of spectral grain"},
+  {NULL}
+};
+
+AUBIO_TYPEOBJECT(fft, "aubio.fft")
index b7d4e86c731803a04b0cc184e821729742fe6f73..8d24a072fd4c7090e10f28285cf1ccb7f58ff485 100644 (file)
@@ -4,7 +4,6 @@ typedef struct
 {
   PyObject_HEAD
   aubio_filter_t * o;
-  uint_t samplerate;
   uint_t order;
   uint_t channels;
 } Py_filter;
@@ -14,32 +13,23 @@ static char Py_filter_doc[] = "filter object";
 static PyObject *
 Py_filter_new (PyTypeObject * type, PyObject * args, PyObject * kwds)
 {
-  int samplerate= 0, order= 0, channels = 0;
+  int order= 0, channels = 0;
   Py_filter *self;
-  static char *kwlist[] = { "samplerate", "order", "channels", NULL };
+  static char *kwlist[] = { "order", "channels", NULL };
 
-  if (!PyArg_ParseTupleAndKeywords (args, kwds, "|III", kwlist,
-          &samplerate, &order, &channels)) {
+  if (!PyArg_ParseTupleAndKeywords (args, kwds, "|II", kwlist,
+          &order, &channels)) {
     return NULL;
   }
 
   self = (Py_filter *) type->tp_alloc (type, 0);
 
-  self->samplerate = Py_aubio_default_samplerate;
-  self->order = 7;
-  self->channels = Py_default_vector_channels;
-
   if (self == NULL) {
     return NULL;
   }
 
-  if (samplerate > 0) {
-    self->samplerate = samplerate;
-  } else if (samplerate < 0) {
-    PyErr_SetString (PyExc_ValueError,
-        "can not use negative samplerate");
-    return NULL;
-  }
+  self->order = 7;
+  self->channels = Py_default_vector_channels;
 
   if (order > 0) {
     self->order = order;
@@ -63,7 +53,7 @@ Py_filter_new (PyTypeObject * type, PyObject * args, PyObject * kwds)
 static int
 Py_filter_init (Py_filter * self, PyObject * args, PyObject * kwds)
 {
-  self->o = new_aubio_filter (self->samplerate, self->order, self->channels);
+  self->o = new_aubio_filter (self->order, self->channels);
   if (self->o == NULL) {
     return -1;
   }
@@ -112,21 +102,33 @@ Py_filter_do(PyObject * self, PyObject * args)
 }
 
 static PyObject * 
-Py_filter_set_c_weighting (Py_filter * self, PyObject *unused)
+Py_filter_set_c_weighting (Py_filter * self, PyObject *args)
 {
-  uint_t err = aubio_filter_set_c_weighting (((Py_filter *)self)->o);
+  uint_t err = 0;
+  uint_t samplerate;
+  if (!PyArg_ParseTuple (args, "I", &samplerate)) {
+    return NULL;
+  }
+
+  err = aubio_filter_set_c_weighting (self->o, samplerate);
   if (err > 0) {
     PyErr_SetString (PyExc_ValueError,
-        "error when setting filter to C-weighting");
+        "error when setting filter to A-weighting");
     return NULL;
   }
   return Py_None;
 }
 
 static PyObject * 
-Py_filter_set_a_weighting (Py_filter * self, PyObject *unused)
+Py_filter_set_a_weighting (Py_filter * self, PyObject *args)
 {
-  uint_t err = aubio_filter_set_a_weighting (((Py_filter *)self)->o);
+  uint_t err = 0;
+  uint_t samplerate;
+  if (!PyArg_ParseTuple (args, "I", &samplerate)) {
+    return NULL;
+  }
+
+  err = aubio_filter_set_a_weighting (self->o, samplerate);
   if (err > 0) {
     PyErr_SetString (PyExc_ValueError,
         "error when setting filter to A-weighting");
@@ -137,8 +139,6 @@ Py_filter_set_a_weighting (Py_filter * self, PyObject *unused)
 
 static PyMemberDef Py_filter_members[] = {
   // TODO remove READONLY flag and define getter/setter
-  {"samplerate", T_INT, offsetof (Py_filter, samplerate), READONLY,
-      "sampling rate"},
   {"order", T_INT, offsetof (Py_filter, order), READONLY,
       "order of the filter"},
   {"channels", T_INT, offsetof (Py_filter, channels), READONLY,
@@ -147,8 +147,6 @@ static PyMemberDef Py_filter_members[] = {
 };
 
 static PyMethodDef Py_filter_methods[] = {
-  {"do", (PyCFunction) Py_filter_do, METH_VARARGS,
-      "filter input vector"},
   {"set_c_weighting", (PyCFunction) Py_filter_set_c_weighting, METH_NOARGS,
       "set filter coefficients to C-weighting"},
   {"set_a_weighting", (PyCFunction) Py_filter_set_a_weighting, METH_NOARGS,
diff --git a/interfaces/python/py-filterbank.c b/interfaces/python/py-filterbank.c
new file mode 100644 (file)
index 0000000..f8a1307
--- /dev/null
@@ -0,0 +1,157 @@
+#include "aubiowraphell.h"
+
+static char Py_filterbank_doc[] = "filterbank object";
+
+AUBIO_DECLARE(filterbank, uint_t n_filters; uint_t win_s)
+
+//AUBIO_NEW(filterbank)
+static PyObject *
+Py_filterbank_new (PyTypeObject * type, PyObject * args, PyObject * kwds)
+{
+  int win_s = 0, n_filters = 0;
+  Py_filterbank *self;
+  static char *kwlist[] = { "n_filters", "win_s", NULL };
+
+  if (!PyArg_ParseTupleAndKeywords (args, kwds, "|II", kwlist,
+          &n_filters, &win_s)) {
+    return NULL;
+  }
+
+  self = (Py_filterbank *) type->tp_alloc (type, 0);
+
+  if (self == NULL) {
+    return NULL;
+  }
+
+  self->win_s = Py_default_vector_length;
+  if (win_s > 0) {
+    self->win_s = win_s;
+  } else if (win_s < 0) {
+    PyErr_SetString (PyExc_ValueError,
+        "can not use negative window size");
+    return NULL;
+  }
+
+  self->n_filters = 40;
+  if (n_filters > 0) {
+    self->n_filters = n_filters;
+  } else if (n_filters < 0) {
+    PyErr_SetString (PyExc_ValueError,
+        "can not use negative number of filters");
+    return NULL;
+  }
+
+  return (PyObject *) self;
+}
+
+
+AUBIO_INIT(filterbank, self->n_filters, self->win_s)
+
+AUBIO_DEL(filterbank)
+
+static PyObject * 
+Py_filterbank_do(Py_filterbank * self, PyObject * args)
+{
+  PyObject *input;
+  Py_cvec *vec;
+  Py_fvec *output;
+
+  if (!PyArg_ParseTuple (args, "O", &input)) {
+    return NULL;
+  }
+
+  vec = PyAubio_ArrayToCvec (input);
+
+  if (vec == NULL) {
+    return NULL;
+  }
+
+  output = (Py_fvec*) PyObject_New (Py_fvec, &Py_fvecType);
+  output->channels = vec->channels;
+  output->length = self->n_filters;
+  output->o = new_fvec(self->n_filters, vec->channels);
+
+  // compute the function
+  aubio_filterbank_do (self->o, vec->o, output->o);
+  return (PyObject *)PyAubio_FvecToArray(output);
+}
+
+AUBIO_MEMBERS_START(filterbank) 
+  {"win_s", T_INT, offsetof (Py_filterbank, win_s), READONLY,
+    "size of the window"},
+  {"n_filters", T_INT, offsetof (Py_filterbank, n_filters), READONLY,
+    "number of filters"},
+AUBIO_MEMBERS_STOP(filterbank)
+
+static PyObject * 
+Py_filterbank_set_triangle_bands (Py_filterbank * self, PyObject *args)
+{
+  uint_t err = 0;
+
+  PyObject *input;
+  uint_t samplerate;
+  Py_fvec *freqs;
+  if (!PyArg_ParseTuple (args, "OI", &input, &samplerate)) {
+    return NULL;
+  }
+
+  if (input == NULL) {
+    return NULL;
+  }
+
+  freqs = PyAubio_ArrayToFvec (input);
+
+  if (freqs == NULL) {
+    return NULL;
+  }
+
+  err = aubio_filterbank_set_triangle_bands (self->o,
+      freqs->o, samplerate);
+  if (err > 0) {
+    PyErr_SetString (PyExc_ValueError,
+        "error when setting filter to A-weighting");
+    return NULL;
+  }
+  return Py_None;
+}
+
+static PyObject * 
+Py_filterbank_set_mel_coeffs_slaney (Py_filterbank * self, PyObject *args)
+{
+  uint_t err = 0;
+
+  uint_t samplerate;
+  if (!PyArg_ParseTuple (args, "I", &samplerate)) {
+    return NULL;
+  }
+
+  err = aubio_filterbank_set_mel_coeffs_slaney (self->o, samplerate);
+  if (err > 0) {
+    PyErr_SetString (PyExc_ValueError,
+        "error when setting filter to A-weighting");
+    return NULL;
+  }
+  return Py_None;
+}
+
+static PyObject * 
+Py_filterbank_get_coeffs (Py_filterbank * self, PyObject *unused)
+{
+  Py_fvec *output = (Py_fvec *) PyObject_New (Py_fvec, &Py_fvecType);
+  output->channels = self->n_filters;
+  output->length = self->win_s / 2 + 1;
+  output->o = aubio_filterbank_get_coeffs (self->o);
+  return (PyObject *)PyAubio_FvecToArray(output);
+}
+
+static PyMethodDef Py_filterbank_methods[] = {
+  {"set_triangle_bands", (PyCFunction) Py_filterbank_set_triangle_bands,
+    METH_VARARGS, "set coefficients of filterbanks"},
+  {"set_mel_coeffs_slaney", (PyCFunction) Py_filterbank_set_mel_coeffs_slaney,
+    METH_VARARGS, "set coefficients of filterbank as in Auditory Toolbox"},
+  {"get_coeffs", (PyCFunction) Py_filterbank_get_coeffs,
+    METH_NOARGS, "get coefficients of filterbank"},
+  {NULL}
+};
+
+AUBIO_TYPEOBJECT(filterbank, "aubio.filterbank")
index 88b131b7edf23071554d1396261c7b48ce63c18a..bb68df33aa0a332f68d5eddc5d28448085631ee5 100644 (file)
@@ -127,15 +127,15 @@ PyAubio_ArrayToFvec (PyObject *input) {
       PyErr_SetString (PyExc_ValueError, "input array should be float");
       goto fail;
 #if AUBIO_DO_CASTING
-    } else if (PyArray_TYPE (input) != AUBIO_FLOAT) {
+    } else if (PyArray_TYPE (input) != AUBIO_NPY_SMPL) {
       // input data type is not float32, casting 
-      array = PyArray_Cast ( (PyArrayObject*) input, AUBIO_FLOAT);
+      array = PyArray_Cast ( (PyArrayObject*) input, AUBIO_NPY_SMPL);
       if (array == NULL) {
-        PyErr_SetString (PyExc_IndexError, "failed converting to NPY_FLOAT");
+        PyErr_SetString (PyExc_IndexError, "failed converting to AUBIO_NPY_SMPL");
         goto fail;
       }
 #else
-    } else if (PyArray_TYPE (input) != AUBIO_FLOAT) {
+    } else if (PyArray_TYPE (input) != AUBIO_NPY_SMPL) {
       PyErr_SetString (PyExc_ValueError, "input array should be float32");
       goto fail;
 #endif
@@ -181,17 +181,17 @@ PyAubio_FvecToArray (Py_fvec * self)
   PyObject *array = NULL;
   if (self->channels == 1) {
     npy_intp dims[] = { self->length, 1 };
-    array = PyArray_SimpleNewFromData (1, dims, NPY_FLOAT, self->o->data[0]);
+    array = PyArray_SimpleNewFromData (1, dims, AUBIO_NPY_SMPL, self->o->data[0]);
   } else {
     uint_t i;
     npy_intp dims[] = { self->length, 1 };
     PyObject *concat = PyList_New (0), *tmp = NULL;
     for (i = 0; i < self->channels; i++) {
-      tmp = PyArray_SimpleNewFromData (1, dims, NPY_FLOAT, self->o->data[i]);
+      tmp = PyArray_SimpleNewFromData (1, dims, AUBIO_NPY_SMPL, self->o->data[i]);
       PyList_Append (concat, tmp);
       Py_DECREF (tmp);
     }
-    array = PyArray_FromObject (concat, NPY_FLOAT, 2, 2);
+    array = PyArray_FromObject (concat, AUBIO_NPY_SMPL, 2, 2);
     Py_DECREF (concat);
   }
   return array;
@@ -214,7 +214,7 @@ Py_fvec_getitem (Py_fvec * self, Py_ssize_t index)
   }
 
   npy_intp dims[] = { self->length, 1 };
-  array = PyArray_SimpleNewFromData (1, dims, NPY_FLOAT, self->o->data[index]);
+  array = PyArray_SimpleNewFromData (1, dims, AUBIO_NPY_SMPL, self->o->data[index]);
   return array;
 }
 
@@ -228,7 +228,7 @@ Py_fvec_setitem (Py_fvec * self, Py_ssize_t index, PyObject * o)
     return -1;
   }
 
-  array = PyArray_FROM_OT (o, NPY_FLOAT);
+  array = PyArray_FROM_OT (o, AUBIO_NPY_SMPL);
   if (array == NULL) {
     PyErr_SetString (PyExc_ValueError, "should be an array of float");
     goto fail;
diff --git a/interfaces/python/py-phasevoc.c b/interfaces/python/py-phasevoc.c
new file mode 100644 (file)
index 0000000..245152c
--- /dev/null
@@ -0,0 +1,137 @@
+#include "aubiowraphell.h"
+
+static char Py_pvoc_doc[] = "pvoc object";
+
+AUBIO_DECLARE(pvoc, uint_t win_s; uint_t hop_s; uint_t channels)
+
+//AUBIO_NEW(pvoc)
+static PyObject *
+Py_pvoc_new (PyTypeObject * type, PyObject * args, PyObject * kwds)
+{
+  int win_s = 0, hop_s = 0, channels = 0;
+  Py_pvoc *self;
+  static char *kwlist[] = { "win_s", "hop_s", "channels", NULL };
+
+  if (!PyArg_ParseTupleAndKeywords (args, kwds, "|III", kwlist,
+          &win_s, &hop_s, &channels)) {
+    return NULL;
+  }
+
+  self = (Py_pvoc *) type->tp_alloc (type, 0);
+
+  if (self == NULL) {
+    return NULL;
+  }
+
+  self->win_s = Py_default_vector_length;
+  self->hop_s = Py_default_vector_length/2;
+  self->channels = Py_default_vector_channels;
+
+  if (self == NULL) {
+    return NULL;
+  }
+
+  if (win_s > 0) {
+    self->win_s = win_s;
+  } else if (win_s < 0) {
+    PyErr_SetString (PyExc_ValueError,
+        "can not use negative window size");
+    return NULL;
+  }
+
+  if (hop_s > 0) {
+    self->hop_s = hop_s;
+  } else if (hop_s < 0) {
+    PyErr_SetString (PyExc_ValueError,
+        "can not use negative hop size");
+    return NULL;
+  }
+
+  if (channels > 0) {
+    self->channels = channels;
+  } else if (channels < 0) {
+    PyErr_SetString (PyExc_ValueError,
+        "can not use negative number of filters");
+    return NULL;
+  }
+
+  return (PyObject *) self;
+}
+
+
+AUBIO_INIT(pvoc, self->win_s, self->hop_s, self->channels)
+
+AUBIO_DEL(pvoc)
+
+static PyObject * 
+Py_pvoc_do(PyObject * self, PyObject * args)
+{
+  PyObject *input;
+  Py_fvec *vec;
+  Py_cvec *output;
+
+  if (!PyArg_ParseTuple (args, "O", &input)) {
+    return NULL;
+  }
+
+  vec = PyAubio_ArrayToFvec (input);
+
+  if (vec == NULL) {
+    return NULL;
+  }
+
+  output = (Py_cvec*) PyObject_New (Py_cvec, &Py_cvecType);
+  output->channels = vec->channels;
+  output->length = ((Py_pvoc *) self)->win_s;
+  output->o = new_cvec(((Py_pvoc *) self)->win_s, vec->channels);
+
+  // compute the function
+  aubio_pvoc_do (((Py_pvoc *)self)->o, vec->o, output->o);
+  Py_INCREF(output);
+  return (PyObject *)output;
+  //return (PyObject *)PyAubio_CvecToArray(output);
+}
+
+AUBIO_MEMBERS_START(pvoc) 
+  {"win_s", T_INT, offsetof (Py_pvoc, win_s), READONLY,
+    "size of the window"},
+  {"hop_s", T_INT, offsetof (Py_pvoc, hop_s), READONLY,
+    "size of the hop"},
+  {"channels", T_INT, offsetof (Py_pvoc, channels), READONLY,
+    "number of channels"},
+AUBIO_MEMBERS_STOP(pvoc)
+
+static PyObject * 
+Py_pvoc_rdo(PyObject * self, PyObject * args)
+{
+  PyObject *input;
+  Py_cvec *vec;
+  Py_fvec *output;
+
+  if (!PyArg_ParseTuple (args, "O", &input)) {
+    return NULL;
+  }
+
+  vec = PyAubio_ArrayToCvec (input);
+
+  if (vec == NULL) {
+    return NULL;
+  }
+
+  output = (Py_fvec*) PyObject_New (Py_fvec, &Py_fvecType);
+  output->channels = vec->channels;
+  output->length = ((Py_pvoc *) self)->hop_s;
+  output->o = new_fvec(output->length, output->channels);
+
+  // compute the function
+  aubio_pvoc_rdo (((Py_pvoc *)self)->o, vec->o, output->o);
+  return (PyObject *)PyAubio_FvecToArray(output);
+}
+
+static PyMethodDef Py_pvoc_methods[] = {
+  {"rdo", (PyCFunction) Py_pvoc_rdo, METH_VARARGS,
+    "synthesis of spectral grain"},
+  {NULL}
+};
+
+AUBIO_TYPEOBJECT(pvoc, "aubio.pvoc")
index 6645bcf0211b80caf21947639d356b6c6fa26d28..d9f392f2a23c2e58b97348d7cef52302b330af30 100644 (file)
@@ -1,10 +1,23 @@
 from distutils.core import setup, Extension
 
+from os import listdir
+generated_files = listdir('generated')
+generated_files = ['generated/'+f for f in generated_files]
+
 setup(name="_aubio", version="1.0",
       ext_modules = [ 
         Extension("_aubio",
-            ["aubiomodule.c", "py-fvec.c", "py-cvec.c", "py-filter.c"],
-            include_dirs=['../../build/default/src', '../../src' ],
+            ["aubiomodule.c",
+            "py-fvec.c",
+            "py-cvec.c",
+            "py-filter.c",
+            # macroised 
+            "py-filterbank.c",
+            "py-fft.c",
+            "py-phasevoc.c",
+            # generated files
+            ] + generated_files,
+            include_dirs=['../../build/default/src', '../../src', '.' ],
             library_dirs=['../../build/default/src', '../../src/.libs' ],
             libraries=['aubio'])])
 
index 23964c04175600a57a1b910902f898fed142b081..3007a9873d0605314ead18b1263da43533ea2ace 100644 (file)
@@ -11,9 +11,9 @@ class aubio_filter_test_case(TestCase):
 
   def test_members(self):
     f = digital_filter()
-    assert_equal ([f.channels, f.order, f.samplerate], [1, 7, 44100])
-    f = digital_filter(48000, 5, 2)
-    assert_equal ([f.channels, f.order, f.samplerate], [2, 5, 48000])
+    assert_equal ([f.channels, f.order], [1, 7])
+    f = digital_filter(5, 2)
+    assert_equal ([f.channels, f.order], [2, 5])
     f(fvec())
   
   def test_cweighting_error(self):
@@ -32,8 +32,8 @@ class aubio_filter_test_case(TestCase):
 
   def test_c_weighting(self):
     expected = array_from_text_file('c_weighting_test_simple.expected')
-    f = digital_filter(44100, 5, 1)
-    f.set_c_weighting()
+    f = digital_filter(5, 1)
+    f.set_c_weighting(44100)
     v = fvec(32)
     v[0][12] = .5
     u = f(v)
@@ -41,8 +41,8 @@ class aubio_filter_test_case(TestCase):
 
   def test_a_weighting(self):
     expected = array_from_text_file('a_weighting_test_simple.expected')
-    f = digital_filter(44100, 7, 1)
-    f.set_a_weighting()
+    f = digital_filter(7, 1)
+    f.set_a_weighting(44100)
     v = fvec(32)
     v[0][12] = .5
     u = f(v)
@@ -50,8 +50,8 @@ class aubio_filter_test_case(TestCase):
 
   def test_a_weighting_parted(self):
     expected = array_from_text_file('a_weighting_test_simple.expected')
-    f = digital_filter(44100, 7, 1)
-    f.set_a_weighting()
+    f = digital_filter(7, 1)
+    f.set_a_weighting(44100)
     v = fvec(16)
     v[0][12] = .5
     u = f(v)