python/ext/aubioproxy.c: factorize input checks into PyAubio_IsValidVector
[aubio.git] / python / ext / aubioproxy.c
1 #include "aubio-types.h"
2
3 PyObject *
4 new_py_fvec(uint_t length) {
5     npy_intp dims[] = { length, 1 };
6     return PyArray_ZEROS(1, dims, AUBIO_NPY_SMPL, 0);
7 }
8
9 PyObject *
10 new_py_fmat(uint_t height, uint_t length) {
11     npy_intp dims[] = { height, length, 1 };
12     return PyArray_ZEROS(2, dims, AUBIO_NPY_SMPL, 0);
13 }
14
15 PyObject *
16 PyAubio_CFvecToArray (fvec_t * self)
17 {
18   npy_intp dims[] = { self->length, 1 };
19   return PyArray_SimpleNewFromData (1, dims, AUBIO_NPY_SMPL, self->data);
20 }
21
22 int
23 PyAubio_IsValidVector (PyObject * input) {
24   if (input == NULL) {
25     PyErr_SetString (PyExc_ValueError, "input array is not a python object");
26     return 0;
27   }
28   // parsing input object into a Py_fvec
29   if (PyArray_Check(input)) {
30
31     // we got an array, convert it to an fvec
32     if (PyArray_NDIM ((PyArrayObject *)input) == 0) {
33       PyErr_SetString (PyExc_ValueError, "input array is a scalar");
34       return 0;
35     } else if (PyArray_NDIM ((PyArrayObject *)input) > 1) {
36       PyErr_SetString (PyExc_ValueError,
37           "input array has more than one dimensions");
38       return 0;
39     }
40
41     if (!PyArray_ISFLOAT ((PyArrayObject *)input)) {
42       PyErr_SetString (PyExc_ValueError, "input array should be float");
43       return 0;
44     } else if (PyArray_TYPE ((PyArrayObject *)input) != AUBIO_NPY_SMPL) {
45       PyErr_SetString (PyExc_ValueError, "input array should be " AUBIO_NPY_SMPL_STR);
46       return 0;
47     }
48
49     long length = PyArray_SIZE ((PyArrayObject *)input);
50     if (length <= 0) {
51       PyErr_SetString (PyExc_ValueError, "input array size should be greater than 0");
52       return 0;
53     }
54
55   } else if (PyObject_TypeCheck (input, &PyList_Type)) {
56     PyErr_SetString (PyExc_ValueError, "does not convert from list yet");
57     return 0;
58   } else {
59     PyErr_SetString (PyExc_ValueError, "can only accept vector of float as input");
60     return 0;
61   }
62   return 1;
63 }
64
65 int
66 PyAubio_ArrayToCFvec (PyObject *input, fvec_t *out) {
67
68   if (!PyAubio_IsValidVector(input)){
69     return 0;
70   }
71
72   out->length = (uint_t) PyArray_SIZE ((PyArrayObject *)input);
73   out->data = (smpl_t *) PyArray_GETPTR1 ((PyArrayObject *)input, 0);
74   return 1;
75 }
76
77 PyObject *
78 PyAubio_CFmatToArray (fmat_t * input)
79 {
80   PyObject *array = NULL;
81   uint_t i;
82   npy_intp dims[] = { input->length, 1 };
83   PyObject *concat = PyList_New (0), *tmp = NULL;
84   for (i = 0; i < input->height; i++) {
85     tmp = PyArray_SimpleNewFromData (1, dims, AUBIO_NPY_SMPL, input->data[i]);
86     PyList_Append (concat, tmp);
87     Py_DECREF (tmp);
88   }
89   array = PyArray_FromObject (concat, AUBIO_NPY_SMPL, 2, 2);
90   Py_DECREF (concat);
91   return array;
92 }
93
94 int
95 PyAubio_ArrayToCFmat (PyObject *input, fmat_t *mat) {
96   uint_t i;
97   if (input == NULL) {
98     PyErr_SetString (PyExc_ValueError, "input array is not a python object");
99     return 0;
100   }
101   // parsing input object into a Py_fvec
102   if (PyArray_Check(input)) {
103
104     // we got an array, convert it to an fvec
105     if (PyArray_NDIM ((PyArrayObject *)input) == 0) {
106       PyErr_SetString (PyExc_ValueError, "input array is a scalar");
107       return 0;
108     } else if (PyArray_NDIM ((PyArrayObject *)input) > 2) {
109       PyErr_SetString (PyExc_ValueError,
110           "input array has more than two dimensions");
111       return 0;
112     }
113
114     if (!PyArray_ISFLOAT ((PyArrayObject *)input)) {
115       PyErr_SetString (PyExc_ValueError, "input array should be float");
116       return 0;
117     } else if (PyArray_TYPE ((PyArrayObject *)input) != AUBIO_NPY_SMPL) {
118       PyErr_SetString (PyExc_ValueError, "input array should be " AUBIO_NPY_SMPL_STR);
119       return 0;
120     }
121
122     // no need to really allocate fvec, just its struct member
123     long length = PyArray_DIM ((PyArrayObject *)input, 1);
124     if (length <= 0) {
125       PyErr_SetString (PyExc_ValueError, "input array dimension 1 should be greater than 0");
126       return 0;
127     }
128     long height = PyArray_DIM ((PyArrayObject *)input, 0);
129     if (height <= 0) {
130       PyErr_SetString (PyExc_ValueError, "input array dimension 0 should be greater than 0");
131       return 0;
132     }
133
134   } else if (PyObject_TypeCheck (input, &PyList_Type)) {
135     PyErr_SetString (PyExc_ValueError, "can not convert list to fmat");
136     return 0;
137   } else {
138     PyErr_SetString (PyExc_ValueError, "can only accept matrix of float as input");
139     return 0;
140   }
141
142   uint_t new_height = (uint_t)PyArray_DIM ((PyArrayObject *)input, 0);
143   if (mat->height != new_height) {
144     if (mat->data) {
145       free(mat->data);
146     }
147     mat->data = (smpl_t **)malloc(sizeof(smpl_t*) * new_height);
148   }
149
150   mat->height = new_height;
151   mat->length = (uint_t)PyArray_DIM ((PyArrayObject *)input, 1);
152   for (i=0; i< mat->height; i++) {
153     mat->data[i] = (smpl_t*)PyArray_GETPTR1 ((PyArrayObject *)input, i);
154   }
155   return 1;
156 }