Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • interfaces/python/py-cvec.c

    reb93592 r474f297  
    44
    55class cvec():
    6     def __init__(self, length = 1024, channels = 1):
     6    def __init__(self, length = 1024):
    77        self.length = length
    8         self.channels = channels
    9         self.norm = array(length, channels)
    10         self.phas = array(length, channels)
     8        self.norm = array(length)
     9        self.phas = array(length)
     10
    1111*/
    12 
    1312
    1413static char Py_cvec_doc[] = "cvec object";
     
    1716Py_cvec_new (PyTypeObject * type, PyObject * args, PyObject * kwds)
    1817{
    19   int length= 0, channels = 0;
     18  int length= 0;
    2019  Py_cvec *self;
    21   static char *kwlist[] = { "length", "channels", NULL };
    22 
    23   if (!PyArg_ParseTupleAndKeywords (args, kwds, "|II", kwlist,
    24           &length, &channels)) {
     20  static char *kwlist[] = { "length", NULL };
     21
     22  if (!PyArg_ParseTupleAndKeywords (args, kwds, "|I", kwlist,
     23          &length)) {
    2524    return NULL;
    2625  }
     
    3029
    3130  self->length = Py_default_vector_length / 2 + 1;
    32   self->channels = Py_default_vector_channels;
    3331
    3432  if (self == NULL) {
     
    4442  }
    4543
    46   if (channels > 0) {
    47     self->channels = channels;
    48   } else if (channels < 0) {
    49     PyErr_SetString (PyExc_ValueError,
    50         "can not use negative number of channels");
    51     return NULL;
    52   }
    53 
    5444  return (PyObject *) self;
    5545}
     
    5848Py_cvec_init (Py_cvec * self, PyObject * args, PyObject * kwds)
    5949{
    60   self->o = new_cvec ((self->length - 1) * 2, self->channels);
     50  self->o = new_cvec ((self->length - 1) * 2);
    6151  if (self->o == NULL) {
    6252    return -1;
     
    8070  PyObject *result = NULL;
    8171
    82   format = PyString_FromString ("aubio cvec of %d elements with %d channels");
     72  format = PyString_FromString ("aubio cvec of %d elements");
    8373  if (format == NULL) {
    8474    goto fail;
    8575  }
    8676
    87   args = Py_BuildValue ("II", self->length, self->channels);
     77  args = Py_BuildValue ("I", self->length);
    8878  if (args == NULL) {
    8979    goto fail;
    9080  }
    91   //cvec_print ( self->o );
     81  cvec_print ( self->o );
    9282
    9383  result = PyString_Format (format, args);
     
    10090}
    10191
    102 Py_cvec *
    103 PyAubio_ArrayToCvec (PyObject *input) {
    104   PyObject *array;
    105   Py_cvec *vec;
    106   uint_t i;
    107   // parsing input object into a Py_cvec
    108   if (PyObject_TypeCheck (input, &Py_cvecType)) {
    109     // input is an cvec, nothing else to do
    110     vec = (Py_cvec *) input;
    111   } else if (PyArray_Check(input)) {
    112 
    113     // we got an array, convert it to an cvec
    114     if (PyArray_NDIM (input) == 0) {
    115       PyErr_SetString (PyExc_ValueError, "input array is a scalar");
    116       goto fail;
    117     } else if (PyArray_NDIM (input) > 2) {
    118       PyErr_SetString (PyExc_ValueError,
    119           "input array has more than two dimensions");
    120       goto fail;
    121     }
    122 
    123     if (!PyArray_ISFLOAT (input)) {
    124       PyErr_SetString (PyExc_ValueError, "input array should be float");
    125       goto fail;
    126 #if AUBIO_DO_CASTING
    127     } else if (PyArray_TYPE (input) != AUBIO_NPY_SMPL) {
    128       // input data type is not float32, casting
    129       array = PyArray_Cast ( (PyArrayObject*) input, AUBIO_NPY_SMPL);
    130       if (array == NULL) {
    131         PyErr_SetString (PyExc_IndexError, "failed converting to NPY_FLOAT");
    132         goto fail;
    133       }
    134 #else
    135     } else if (PyArray_TYPE (input) != AUBIO_NPY_SMPL) {
    136       PyErr_SetString (PyExc_ValueError, "input array should be float32");
    137       goto fail;
    138 #endif
    139     } else {
    140       // input data type is float32, nothing else to do
    141       array = input;
    142     }
    143 
    144     // create a new cvec object
    145     vec = (Py_cvec*) PyObject_New (Py_cvec, &Py_cvecType);
    146     if (PyArray_NDIM (array) == 1) {
    147       PyErr_SetString (PyExc_ValueError,
    148           "input array should be have at least two rows for norm and phas");
    149       goto fail;
    150     } else if (PyArray_NDIM (array) == 2) {
    151       vec->channels = 1;
    152       vec->length = PyArray_SIZE (array);
    153     } else {
    154       vec->channels = PyArray_DIM (array, 0) / 2;
    155       vec->length = PyArray_DIM (array, 1);
    156     }
    157 
    158     // no need to really allocate cvec, just its struct member
    159     // vec->o = new_cvec (vec->length, vec->channels);
    160     vec->o = (cvec_t *)malloc(sizeof(cvec_t));
    161     vec->o->length = vec->length; vec->o->channels = vec->channels;
    162     vec->o->norm = (smpl_t**)malloc(vec->o->channels * sizeof(smpl_t*));
    163     vec->o->phas = (smpl_t**)malloc(vec->o->channels * sizeof(smpl_t*));
    164     // hat data[i] point to array line
    165     for (i = 0; i < vec->channels; i+=2) {
    166       vec->o->norm[i] = (smpl_t *) PyArray_GETPTR1 (array, i);
    167       vec->o->phas[i] = (smpl_t *) PyArray_GETPTR1 (array, i+1);
    168     }
    169 
    170   } else {
    171     PyErr_SetString (PyExc_ValueError, "can only accept array or cvec as input");
    172     return NULL;
    173   }
    174 
    175   return vec;
    176 
    177 fail:
    178   return NULL;
    179 }
    180 
    181 PyObject *
    182 PyAubio_CvecToArray (Py_cvec * self)
    183 {
    184   PyObject *array = NULL;
    185   uint_t i;
     92PyObject *
     93PyAubio_CvecNormToArray (Py_cvec * self)
     94{
    18695  npy_intp dims[] = { self->o->length, 1 };
    187   PyObject *concat = PyList_New (0), *tmp = NULL;
    188   for (i = 0; i < self->channels; i++) {
    189     tmp = PyArray_SimpleNewFromData (1, dims, NPY_FLOAT, self->o->norm[i]);
    190     PyList_Append (concat, tmp);
    191     Py_DECREF (tmp);
    192     tmp = PyArray_SimpleNewFromData (1, dims, NPY_FLOAT, self->o->phas[i]);
    193     PyList_Append (concat, tmp);
    194     Py_DECREF (tmp);
    195   }
    196   array = PyArray_FromObject (concat, NPY_FLOAT, 2, 2);
    197   Py_DECREF (concat);
    198   return array;
    199 }
    200 
    201 PyObject *
    202 PyAubio_CvecNormToArray (Py_cvec * self)
    203 {
    204   PyObject *array = NULL;
    205   uint_t i;
     96  return PyArray_SimpleNewFromData (1, dims, NPY_FLOAT, self->o->norm);
     97}
     98
     99
     100PyObject *
     101PyAubio_CvecPhasToArray (Py_cvec * self)
     102{
    206103  npy_intp dims[] = { self->o->length, 1 };
    207   PyObject *concat = PyList_New (0), *tmp = NULL;
    208   for (i = 0; i < self->channels; i++) {
    209     tmp = PyArray_SimpleNewFromData (1, dims, NPY_FLOAT, self->o->norm[i]);
    210     PyList_Append (concat, tmp);
    211     Py_DECREF (tmp);
    212   }
    213   array = PyArray_FromObject (concat, NPY_FLOAT, 2, 2);
    214   Py_DECREF (concat);
    215   return array;
    216 }
    217 
    218 
    219 PyObject *
    220 PyAubio_CvecPhasToArray (Py_cvec * self)
    221 {
    222   PyObject *array = NULL;
    223   uint_t i;
    224   npy_intp dims[] = { self->o->length, 1 };
    225   PyObject *concat = PyList_New (0), *tmp = NULL;
    226   for (i = 0; i < self->channels; i++) {
    227     tmp = PyArray_SimpleNewFromData (1, dims, NPY_FLOAT, self->o->phas[i]);
    228     PyList_Append (concat, tmp);
    229     Py_DECREF (tmp);
    230   }
    231   array = PyArray_FromObject (concat, NPY_FLOAT, 2, 2);
    232   Py_DECREF (concat);
    233   return array;
     104  return PyArray_SimpleNewFromData (1, dims, NPY_FLOAT, self->o->phas);
    234105}
    235106
     
    255126Py_cvec_set_norm (Py_cvec * vec, PyObject *input, void * closure)
    256127{
    257   uint_t i;
    258128  PyObject * array;
    259129  if (input == NULL) {
     
    283153
    284154    // check input array dimensions
    285     if (PyArray_NDIM (array) == 1) {
    286       if (vec->channels != 1) {
    287           PyErr_SetString (PyExc_ValueError,
    288                   "input array should have more than one channel");
    289           goto fail;
    290       }
     155    if (PyArray_NDIM (array) != 1) {
     156      PyErr_Format (PyExc_ValueError,
     157          "input array has %d dimensions, not 1",
     158          PyArray_NDIM (array));
     159      goto fail;
     160    } else {
    291161      if (vec->o->length != PyArray_SIZE (array)) {
    292162          PyErr_Format (PyExc_ValueError,
     
    295165          goto fail;
    296166      }
    297     } else {
    298       if (vec->channels != PyArray_DIM (array, 0)) {
    299           PyErr_Format (PyExc_ValueError,
    300                   "input array has %d channels, but vector has %d channels",
    301                   PyArray_DIM (array, 0), vec->channels);
    302           goto fail;
    303       }
    304       if (vec->o->length != PyArray_DIM (array, 1)) {
    305           PyErr_Format (PyExc_ValueError,
    306                   "input array has length %d, but vector has length %d",
    307                   PyArray_DIM (array, 1), vec->o->length);
    308           goto fail;
    309       }
    310     }
    311 
    312     for (i = 0; i < vec->channels; i++) {
    313       vec->o->norm[i] = (smpl_t *) PyArray_GETPTR1 (array, i);
    314     }
     167    }
     168
     169    vec->o->norm = (smpl_t *) PyArray_GETPTR1 (array, 0);
    315170
    316171  } else {
     
    329184Py_cvec_set_phas (Py_cvec * vec, PyObject *input, void * closure)
    330185{
    331   uint_t i;
    332186  PyObject * array;
    333187  if (input == NULL) {
     
    357211
    358212    // check input array dimensions
    359     if (PyArray_NDIM (array) == 1) {
    360       if (vec->channels != 1) {
    361           PyErr_SetString (PyExc_ValueError,
    362                   "input array should have more than one channel");
    363           goto fail;
    364       }
     213    if (PyArray_NDIM (array) != 1) {
     214      PyErr_Format (PyExc_ValueError,
     215          "input array has %d dimensions, not 1",
     216          PyArray_NDIM (array));
     217      goto fail;
     218    } else {
    365219      if (vec->o->length != PyArray_SIZE (array)) {
    366220          PyErr_Format (PyExc_ValueError,
     
    369223          goto fail;
    370224      }
    371     } else {
    372       if (vec->channels != PyArray_DIM (array, 0)) {
    373           PyErr_Format (PyExc_ValueError,
    374                   "input array has %d channels, but vector has %d channels",
    375                   PyArray_DIM (array, 0), vec->channels);
    376           goto fail;
    377       }
    378       if (vec->o->length != PyArray_DIM (array, 1)) {
    379           PyErr_Format (PyExc_ValueError,
    380                   "input array has length %d, but vector has length %d",
    381                   PyArray_DIM (array, 1), vec->o->length);
    382           goto fail;
    383       }
    384     }
    385 
    386     for (i = 0; i < vec->channels; i++) {
    387       vec->o->phas[i] = (smpl_t *) PyArray_GETPTR1 (array, i);
    388     }
     225    }
     226
     227    vec->o->phas = (smpl_t *) PyArray_GETPTR1 (array, 0);
    389228
    390229  } else {
     
    398237fail:
    399238  return 1;
    400 }
    401 
    402 static Py_ssize_t
    403 Py_cvec_getchannels (Py_cvec * self)
    404 {
    405   return self->channels;
    406 }
    407 
    408 static PyObject *
    409 Py_cvec_getitem (Py_cvec * self, Py_ssize_t index)
    410 {
    411   PyObject *array;
    412 
    413   if (index < 0 || index >= self->channels) {
    414     PyErr_SetString (PyExc_IndexError, "no such channel");
    415     return NULL;
    416   }
    417 
    418   npy_intp dims[] = { self->length, 1 };
    419   array = PyArray_SimpleNewFromData (1, dims, NPY_FLOAT, self->o->norm[index]);
    420   return array;
    421 }
    422 
    423 static int
    424 Py_cvec_setitem (Py_cvec * self, Py_ssize_t index, PyObject * o)
    425 {
    426   PyObject *array;
    427 
    428   if (index < 0 || index >= self->channels) {
    429     PyErr_SetString (PyExc_IndexError, "no such channel");
    430     return -1;
    431   }
    432 
    433   array = PyArray_FROM_OT (o, NPY_FLOAT);
    434   if (array == NULL) {
    435     PyErr_SetString (PyExc_ValueError, "should be an array of float");
    436     goto fail;
    437   }
    438 
    439   if (PyArray_NDIM (array) != 1) {
    440     PyErr_SetString (PyExc_ValueError, "should be a one-dimensional array");
    441     goto fail;
    442   }
    443 
    444   if (PyArray_SIZE (array) != self->length) {
    445     PyErr_SetString (PyExc_ValueError,
    446         "should be an array of same length as target cvec");
    447     goto fail;
    448   }
    449 
    450   self->o->norm[index] = (smpl_t *) PyArray_GETPTR1 (array, 0);
    451 
    452   return 0;
    453 
    454 fail:
    455   return -1;
    456239}
    457240
     
    460243  {"length", T_INT, offsetof (Py_cvec, length), READONLY,
    461244      "length attribute"},
    462   {"channels", T_INT, offsetof (Py_cvec, channels), READONLY,
    463       "channels attribute"},
    464245  {NULL}                        /* Sentinel */
    465246};
    466247
    467248static PyMethodDef Py_cvec_methods[] = {
    468   {"__array__", (PyCFunction) PyAubio_CvecToArray, METH_NOARGS,
    469       "Returns the content of this cvec as a numpy array"},
    470249  {NULL}
    471250};
     
    473252static PyGetSetDef Py_cvec_getseters[] = {
    474253  {"norm", (getter)Py_cvec_get_norm, (setter)Py_cvec_set_norm,
    475       "Content of the magnitude of this cvec",
     254      "Numpy vector of shape (length,) containing the magnitude",
    476255      NULL},
    477256  {"phas", (getter)Py_cvec_get_phas, (setter)Py_cvec_set_phas,
    478       "Content of the magnitude of this cvec",
     257      "Numpy vector of shape (length,) containing the phase",
    479258      NULL},
    480259  {NULL} /* sentinel */
    481260};
    482 
    483 static PySequenceMethods Py_cvec_tp_as_sequence = {
    484   (lenfunc) Py_cvec_getchannels,        /* sq_length         */
    485   0,                                    /* sq_concat         */
    486   0,                                    /* sq_repeat         */
    487   (ssizeargfunc) Py_cvec_getitem,       /* sq_item           */
    488   0,                                    /* sq_slice          */
    489   (ssizeobjargproc) Py_cvec_setitem,    /* sq_ass_item       */
    490   0,                                    /* sq_ass_slice      */
    491   0,                                    /* sq_contains       */
    492   0,                                    /* sq_inplace_concat */
    493   0,                                    /* sq_inplace_repeat */
    494 };
    495 
    496261
    497262PyTypeObject Py_cvecType = {
     
    508273  (reprfunc) Py_cvec_repr,      /* tp_repr           */
    509274  0,                            /* tp_as_number      */
    510   &Py_cvec_tp_as_sequence,      /* tp_as_sequence    */
     275  0, //&Py_cvec_tp_as_sequence,      /* tp_as_sequence    */
    511276  0,                            /* tp_as_mapping     */
    512277  0,                            /* tp_hash           */
Note: See TracChangeset for help on using the changeset viewer.