From 569b363d02577c0445fe78385a94fcbedce8ede7 Mon Sep 17 00:00:00 2001 From: Paul Brossier Date: Sun, 24 Apr 2016 18:23:14 +0200 Subject: [PATCH] python/ext: simplify memory allocations, removed unneeded malloc/free calls --- python/ext/aubiomodule.c | 28 ++++++++++------------------ python/ext/aubioproxy.c | 16 +++++++--------- python/ext/py-fft.c | 22 ++++++++++------------ python/ext/py-filter.c | 12 +++++------- python/ext/py-filterbank.c | 31 ++++++++++--------------------- python/ext/py-musicutils.c | 36 ++++++++++++------------------------ python/ext/py-phasevoc.c | 19 ++++++------------- python/ext/py-sink.c | 20 +++++++------------- python/lib/gen_code.py | 16 ++++++++-------- 9 files changed, 75 insertions(+), 125 deletions(-) diff --git a/python/ext/aubiomodule.c b/python/ext/aubiomodule.c index 0d004902..4c724976 100644 --- a/python/ext/aubiomodule.c +++ b/python/ext/aubiomodule.c @@ -83,7 +83,7 @@ static PyObject * Py_alpha_norm (PyObject * self, PyObject * args) { PyObject *input; - fvec_t *vec; + fvec_t vec; smpl_t alpha; PyObject *result; @@ -95,15 +95,12 @@ Py_alpha_norm (PyObject * self, PyObject * args) return NULL; } - vec = (fvec_t *)malloc(sizeof(fvec_t)); - if (!PyAubio_ArrayToCFvec(input, vec)) { - free(vec); + if (!PyAubio_ArrayToCFvec(input, &vec)) { return NULL; } // compute the function - result = Py_BuildValue ("f", fvec_alpha_norm (vec, alpha)); - free(vec); + result = Py_BuildValue ("f", fvec_alpha_norm (&vec, alpha)); if (result == NULL) { return NULL; } @@ -175,7 +172,7 @@ static PyObject * Py_zero_crossing_rate (PyObject * self, PyObject * args) { PyObject *input; - fvec_t *vec; + fvec_t vec; PyObject *result; if (!PyArg_ParseTuple (args, "O:zero_crossing_rate", &input)) { @@ -186,15 +183,12 @@ Py_zero_crossing_rate (PyObject * self, PyObject * args) return NULL; } - vec = (fvec_t *)malloc(sizeof(fvec_t)); - if (!PyAubio_ArrayToCFvec(input, vec)) { - free(vec); + if (!PyAubio_ArrayToCFvec(input, &vec)) { return NULL; } // compute the function - result = Py_BuildValue ("f", aubio_zero_crossing_rate (vec)); - free(vec); + result = Py_BuildValue ("f", aubio_zero_crossing_rate (&vec)); if (result == NULL) { return NULL; } @@ -206,7 +200,7 @@ static PyObject * Py_min_removal(PyObject * self, PyObject * args) { PyObject *input; - fvec_t *vec; + fvec_t vec; if (!PyArg_ParseTuple (args, "O:min_removal", &input)) { return NULL; @@ -216,19 +210,17 @@ Py_min_removal(PyObject * self, PyObject * args) return NULL; } - vec = (fvec_t *)malloc(sizeof(fvec_t)); - if (!PyAubio_ArrayToCFvec(input, vec)) { - free(vec); + if (!PyAubio_ArrayToCFvec(input, &vec)) { return NULL; } // compute the function - fvec_min_removal (vec); + fvec_min_removal (&vec); // since this function does not return, we could return None //Py_RETURN_NONE; // however it is convenient to return the modified vector - return (PyObject *) PyAubio_CFvecToArray(vec); + return (PyObject *) PyAubio_CFvecToArray(&vec); // or even without converting it back to an array //Py_INCREF(vec); //return (PyObject *)vec; diff --git a/python/ext/aubioproxy.c b/python/ext/aubioproxy.c index 8a02a35c..c6755b50 100644 --- a/python/ext/aubioproxy.c +++ b/python/ext/aubioproxy.c @@ -143,17 +143,15 @@ PyAubio_ArrayToCFmat (PyObject *input, fmat_t *mat) { return 0; } - if (mat->height != (uint_t)PyArray_DIM ((PyArrayObject *)input, 0)) { - /* - free(mat->data); - mat->height = (uint_t)PyArray_DIM ((PyArrayObject *)input, 0); - mat->data = (smpl_t **)malloc(sizeof(smpl_t*) * mat->height); - */ - PyErr_Format(PyExc_ValueError, "too many rows, %d but %ld expected", - mat->height, PyArray_DIM ((PyArrayObject *)input, 0) ); - return 0; + uint_t new_height = (uint_t)PyArray_DIM ((PyArrayObject *)input, 0); + if (mat->height != new_height) { + if (mat->data) { + free(mat->data); + } + mat->data = (smpl_t **)malloc(sizeof(smpl_t*) * new_height); } + mat->height = new_height; mat->length = (uint_t)PyArray_DIM ((PyArrayObject *)input, 1); for (i=0; i< mat->height; i++) { mat->data[i] = (smpl_t*)PyArray_GETPTR1 ((PyArrayObject *)input, i); diff --git a/python/ext/py-fft.c b/python/ext/py-fft.c index ae0c87ba..f13c820b 100644 --- a/python/ext/py-fft.c +++ b/python/ext/py-fft.c @@ -7,11 +7,14 @@ typedef struct PyObject_HEAD aubio_fft_t * o; uint_t win_s; - fvec_t *vecin; + // do / rdo input vectors + fvec_t vecin; + cvec_t cvecin; + // do / rdo output results cvec_t *out; - Py_cvec *py_out; - cvec_t *cvecin; fvec_t *rout; + // bridge for cvec output + Py_cvec *py_out; } Py_fft; static PyObject * @@ -56,9 +59,6 @@ Py_fft_init (Py_fft * self, PyObject * args, PyObject * kwds) return -1; } - self->cvecin = (cvec_t *)malloc(sizeof(cvec_t)); - self->vecin = (fvec_t *)malloc(sizeof(fvec_t)); - self->out = new_cvec(self->win_s); self->py_out = (Py_cvec*) PyObject_New (Py_cvec, &Py_cvecType); Py_XINCREF(self->py_out); @@ -74,8 +74,6 @@ Py_fft_del (Py_fft *self, PyObject *unused) del_aubio_fft(self->o); del_cvec(self->out); del_fvec(self->rout); - free(self->cvecin); - free(self->vecin); Py_TYPE(self)->tp_free((PyObject *) self); } @@ -88,12 +86,12 @@ Py_fft_do(Py_fft * self, PyObject * args) return NULL; } - if (!PyAubio_ArrayToCFvec(input, self->vecin)) { + if (!PyAubio_ArrayToCFvec(input, &(self->vecin))) { return NULL; } // compute the function - aubio_fft_do (((Py_fft *)self)->o, self->vecin, self->out); + aubio_fft_do (((Py_fft *)self)->o, &(self->vecin), self->out); #if 0 Py_cvec * py_out = (Py_cvec*) PyObject_New (Py_cvec, &Py_cvecType); PyObject* output = PyAubio_CCvecToPyCvec(self->out, py_out); @@ -119,12 +117,12 @@ Py_fft_rdo(Py_fft * self, PyObject * args) return NULL; } - if (!PyAubio_ArrayToCCvec (input, self->cvecin) ) { + if (!PyAubio_ArrayToCCvec (input, &(self->cvecin)) ) { return NULL; } // compute the function - aubio_fft_rdo (self->o, self->cvecin, self->rout); + aubio_fft_rdo (self->o, &(self->cvecin), self->rout); return PyAubio_CFvecToArray(self->rout); } diff --git a/python/ext/py-filter.c b/python/ext/py-filter.c index fdf0fb05..90b89614 100644 --- a/python/ext/py-filter.c +++ b/python/ext/py-filter.c @@ -5,7 +5,7 @@ typedef struct PyObject_HEAD aubio_filter_t * o; uint_t order; - fvec_t *vec; + fvec_t vec; fvec_t *out; } Py_filter; @@ -50,7 +50,6 @@ Py_filter_init (Py_filter * self, PyObject * args, PyObject * kwds) return -1; } self->out = new_fvec(Py_default_vector_length); - self->vec = (fvec_t *)malloc(sizeof(fvec_t)); return 0; } @@ -59,7 +58,6 @@ Py_filter_del (Py_filter * self) { del_fvec(self->out); del_aubio_filter (self->o); - free(self->vec); Py_TYPE(self)->tp_free ((PyObject *) self); } @@ -76,17 +74,17 @@ Py_filter_do(Py_filter * self, PyObject * args) return NULL; } - if (!PyAubio_ArrayToCFvec(input, self->vec)) { + if (!PyAubio_ArrayToCFvec(input, &(self->vec))) { return NULL; } // reallocate the output if needed - if (self->vec->length != self->out->length) { + if (self->vec.length != self->out->length) { del_fvec(self->out); - self->out = new_fvec(self->vec->length); + self->out = new_fvec(self->vec.length); } // compute the function - aubio_filter_do_outplace (self->o, self->vec, self->out); + aubio_filter_do_outplace (self->o, &(self->vec), self->out); return PyAubio_CFvecToArray(self->out); } diff --git a/python/ext/py-filterbank.c b/python/ext/py-filterbank.c index 612a34f9..f807de55 100644 --- a/python/ext/py-filterbank.c +++ b/python/ext/py-filterbank.c @@ -8,10 +8,10 @@ typedef struct aubio_filterbank_t * o; uint_t n_filters; uint_t win_s; - cvec_t *vec; + cvec_t vec; + fvec_t freqs; + fmat_t coeffs; fvec_t *out; - fvec_t *freqs; - fmat_t *coeffs; } Py_filterbank; static PyObject * @@ -66,14 +66,6 @@ Py_filterbank_init (Py_filterbank * self, PyObject * args, PyObject * kwds) } self->out = new_fvec(self->n_filters); - self->vec = (cvec_t *)malloc(sizeof(cvec_t)); - - self->freqs = (fvec_t *)malloc(sizeof(fvec_t)); - - self->coeffs = (fmat_t *)malloc(sizeof(fmat_t)); - self->coeffs->data = (smpl_t **)malloc(sizeof(smpl_t*) * self->n_filters); - self->coeffs->height = self->n_filters; - return 0; } @@ -82,10 +74,7 @@ Py_filterbank_del (Py_filterbank *self, PyObject *unused) { del_aubio_filterbank(self->o); del_fvec(self->out); - free(self->vec); - free(self->freqs); - free(self->coeffs->data); - free(self->coeffs); + free(self->coeffs.data); Py_TYPE(self)->tp_free((PyObject *) self); } @@ -98,12 +87,12 @@ Py_filterbank_do(Py_filterbank * self, PyObject * args) return NULL; } - if (!PyAubio_ArrayToCCvec(input, self->vec)) { + if (!PyAubio_ArrayToCCvec(input, &(self->vec) )) { return NULL; } // compute the function - aubio_filterbank_do (self->o, self->vec, self->out); + aubio_filterbank_do (self->o, &(self->vec), self->out); return (PyObject *)PyAubio_CFvecToArray(self->out); } @@ -130,12 +119,12 @@ Py_filterbank_set_triangle_bands (Py_filterbank * self, PyObject *args) return NULL; } - if (!PyAubio_ArrayToCFvec(input, self->freqs)) { + if (!PyAubio_ArrayToCFvec(input, &(self->freqs) )) { return NULL; } err = aubio_filterbank_set_triangle_bands (self->o, - self->freqs, samplerate); + &(self->freqs), samplerate); if (err > 0) { PyErr_SetString (PyExc_ValueError, "error when setting filter to A-weighting"); @@ -173,11 +162,11 @@ Py_filterbank_set_coeffs (Py_filterbank * self, PyObject *args) return NULL; } - if (!PyAubio_ArrayToCFmat(input, self->coeffs)) { + if (!PyAubio_ArrayToCFmat(input, &(self->coeffs))) { return NULL; } - err = aubio_filterbank_set_coeffs (self->o, self->coeffs); + err = aubio_filterbank_set_coeffs (self->o, &(self->coeffs)); if (err > 0) { PyErr_SetString (PyExc_ValueError, diff --git a/python/ext/py-musicutils.c b/python/ext/py-musicutils.c index d5a05242..ec266760 100644 --- a/python/ext/py-musicutils.c +++ b/python/ext/py-musicutils.c @@ -25,7 +25,7 @@ PyObject * Py_aubio_level_lin(PyObject *self, PyObject *args) { PyObject *input; - fvec_t *vec; + fvec_t vec; PyObject *level_lin; if (!PyArg_ParseTuple (args, "O:level_lin", &input)) { @@ -37,14 +37,11 @@ Py_aubio_level_lin(PyObject *self, PyObject *args) return NULL; } - vec = (fvec_t *)malloc(sizeof(fvec_t)); - if (!PyAubio_ArrayToCFvec(input, vec)) { - free(vec); + if (!PyAubio_ArrayToCFvec(input, &vec)) { return NULL; } - level_lin = Py_BuildValue("f", aubio_level_lin(vec)); - free(vec); + level_lin = Py_BuildValue("f", aubio_level_lin(&vec)); if (level_lin == NULL) { PyErr_SetString (PyExc_ValueError, "failed computing level_lin"); return NULL; @@ -57,7 +54,7 @@ PyObject * Py_aubio_db_spl(PyObject *self, PyObject *args) { PyObject *input; - fvec_t *vec; + fvec_t vec; PyObject *db_spl; if (!PyArg_ParseTuple (args, "O:db_spl", &input)) { @@ -69,14 +66,11 @@ Py_aubio_db_spl(PyObject *self, PyObject *args) return NULL; } - vec = (fvec_t *)malloc(sizeof(fvec_t)); - if (!PyAubio_ArrayToCFvec(input, vec)) { - free(vec); + if (!PyAubio_ArrayToCFvec(input, &vec)) { return NULL; } - db_spl = Py_BuildValue("f", aubio_db_spl(vec)); - free(vec); + db_spl = Py_BuildValue("f", aubio_db_spl(&vec)); if (db_spl == NULL) { PyErr_SetString (PyExc_ValueError, "failed computing db_spl"); return NULL; @@ -89,7 +83,7 @@ PyObject * Py_aubio_silence_detection(PyObject *self, PyObject *args) { PyObject *input; - fvec_t *vec; + fvec_t vec; PyObject *silence_detection; smpl_t threshold; @@ -102,14 +96,11 @@ Py_aubio_silence_detection(PyObject *self, PyObject *args) return NULL; } - vec = (fvec_t *)malloc(sizeof(fvec_t)); - if (!PyAubio_ArrayToCFvec(input, vec)) { - free(vec); + if (!PyAubio_ArrayToCFvec(input, &vec)) { return NULL; } - silence_detection = Py_BuildValue("I", aubio_silence_detection(vec, threshold)); - free(vec); + silence_detection = Py_BuildValue("I", aubio_silence_detection(&vec, threshold)); if (silence_detection == NULL) { PyErr_SetString (PyExc_ValueError, "failed computing silence_detection"); return NULL; @@ -122,7 +113,7 @@ PyObject * Py_aubio_level_detection(PyObject *self, PyObject *args) { PyObject *input; - fvec_t *vec; + fvec_t vec; PyObject *level_detection; smpl_t threshold; @@ -135,14 +126,11 @@ Py_aubio_level_detection(PyObject *self, PyObject *args) return NULL; } - vec = (fvec_t *)malloc(sizeof(fvec_t)); - if (!PyAubio_ArrayToCFvec(input, vec)) { - free(vec); + if (!PyAubio_ArrayToCFvec(input, &vec)) { return NULL; } - level_detection = Py_BuildValue("f", aubio_level_detection(vec, threshold)); - free(vec); + level_detection = Py_BuildValue("f", aubio_level_detection(&vec, threshold)); if (level_detection == NULL) { PyErr_SetString (PyExc_ValueError, "failed computing level_detection"); return NULL; diff --git a/python/ext/py-phasevoc.c b/python/ext/py-phasevoc.c index e8c96f94..6a4d4df8 100644 --- a/python/ext/py-phasevoc.c +++ b/python/ext/py-phasevoc.c @@ -1,17 +1,15 @@ #include "aubio-types.h" -static char Py_pvoc_doc[] = "pvoc object"; - typedef struct { PyObject_HEAD aubio_pvoc_t * o; uint_t win_s; uint_t hop_s; - fvec_t *vecin; + fvec_t vecin; cvec_t *output; Py_cvec *py_out; - cvec_t *cvecin; + cvec_t cvecin; fvec_t *routput; } Py_pvoc; @@ -71,9 +69,6 @@ Py_pvoc_init (Py_pvoc * self, PyObject * args, PyObject * kwds) return -1; } - self->cvecin = (cvec_t *)malloc(sizeof(cvec_t)); - self->vecin = (fvec_t *)malloc(sizeof(fvec_t)); - self->output = new_cvec(self->win_s); self->py_out = (Py_cvec*) PyObject_New (Py_cvec, &Py_cvecType); self->routput = new_fvec(self->hop_s); @@ -88,8 +83,6 @@ Py_pvoc_del (Py_pvoc *self, PyObject *unused) del_aubio_pvoc(self->o); del_cvec(self->output); del_fvec(self->routput); - free(self->cvecin); - free(self->vecin); Py_TYPE(self)->tp_free((PyObject *) self); } @@ -103,12 +96,12 @@ Py_pvoc_do(Py_pvoc * self, PyObject * args) return NULL; } - if (!PyAubio_ArrayToCFvec (input, self->vecin)) { + if (!PyAubio_ArrayToCFvec (input, &(self->vecin) )) { return NULL; } // compute the function - aubio_pvoc_do (self->o, self->vecin, self->output); + aubio_pvoc_do (self->o, &(self->vecin), self->output); #if 0 Py_cvec * py_out = (Py_cvec*) PyObject_New (Py_cvec, &Py_cvecType); PyObject* output = PyAubio_CCvecToPyCvec(self->output, py_out); @@ -135,12 +128,12 @@ Py_pvoc_rdo(Py_pvoc * self, PyObject * args) return NULL; } - if (!PyAubio_ArrayToCCvec (input, self->cvecin)) { + if (!PyAubio_ArrayToCCvec (input, &(self->cvecin) )) { return NULL; } // compute the function - aubio_pvoc_rdo (self->o, self->cvecin, self->routput); + aubio_pvoc_rdo (self->o, &(self->cvecin), self->routput); return PyAubio_CFvecToArray(self->routput); } diff --git a/python/ext/py-sink.c b/python/ext/py-sink.c index 7e8cce1e..71a0e225 100644 --- a/python/ext/py-sink.c +++ b/python/ext/py-sink.c @@ -7,8 +7,8 @@ typedef struct char_t* uri; uint_t samplerate; uint_t channels; - fvec_t *write_data; - fmat_t *mwrite_data; + fvec_t write_data; + fmat_t mwrite_data; } Py_sink; static char Py_sink_doc[] = "" @@ -123,10 +123,6 @@ Py_sink_init (Py_sink * self, PyObject * args, PyObject * kwds) self->samplerate = aubio_sink_get_samplerate ( self->o ); self->channels = aubio_sink_get_channels ( self->o ); - self->write_data = (fvec_t *)malloc(sizeof(fvec_t)); - self->mwrite_data = (fmat_t *)malloc(sizeof(fmat_t)); - self->mwrite_data->height = self->channels; - self->mwrite_data->data = (smpl_t **)malloc(sizeof(smpl_t*) * self->channels); return 0; } @@ -134,9 +130,7 @@ static void Py_sink_del (Py_sink *self, PyObject *unused) { del_aubio_sink(self->o); - free(self->write_data); - free(self->mwrite_data->data); - free(self->mwrite_data); + free(self->mwrite_data.data); Py_TYPE(self)->tp_free((PyObject *) self); } @@ -156,13 +150,13 @@ Py_sink_do(Py_sink * self, PyObject * args) } /* input vectors parsing */ - if (!PyAubio_ArrayToCFvec(write_data_obj, self->write_data)) { + if (!PyAubio_ArrayToCFvec(write_data_obj, &(self->write_data))) { return NULL; } /* compute _do function */ - aubio_sink_do (self->o, self->write_data, write); + aubio_sink_do (self->o, &(self->write_data), write); Py_RETURN_NONE; } @@ -184,12 +178,12 @@ Py_sink_do_multi(Py_sink * self, PyObject * args) /* input vectors parsing */ - if (!PyAubio_ArrayToCFmat(write_data_obj, self->mwrite_data)) { + if (!PyAubio_ArrayToCFmat(write_data_obj, &(self->mwrite_data))) { return NULL; } /* compute _do function */ - aubio_sink_do_multi (self->o, self->mwrite_data, write); + aubio_sink_do_multi (self->o, &(self->mwrite_data), write); Py_RETURN_NONE; } diff --git a/python/lib/gen_code.py b/python/lib/gen_code.py index 7b755835..d2f54596 100644 --- a/python/lib/gen_code.py +++ b/python/lib/gen_code.py @@ -202,7 +202,9 @@ typedef struct{{ {output_results}; }} Py_{shortname}; """ - return out.format(do_inputs_list = "; ".join(get_input_params(self.do_proto)), **self.__dict__) + # fmat_t* / fvec_t* / cvec_t* inputs -> full fvec_t /.. struct in Py_{shortname} + do_inputs_list = "; ".join(get_input_params(self.do_proto)).replace('fvec_t *','fvec_t').replace('fmat_t *', 'fmat_t').replace('cvec_t *', 'cvec_t') + return out.format(do_inputs_list = do_inputs_list, **self.__dict__) def gen_doc(self): out = """ @@ -310,9 +312,6 @@ Py_{shortname}_init (Py_{shortname} * self, PyObject * args, PyObject * kwds) out += """ // TODO get internal params after actual object creation? """ - for input_param in self.do_inputs: - out += """ - self->{0} = ({1})malloc(sizeof({2}));""".format(input_param['name'], input_param['type'], input_param['type'][:-1]) out += """ // create outputs{output_create} """.format(output_create = output_create) @@ -342,8 +341,9 @@ static void Py_{shortname}_del (Py_{shortname} * self, PyObject * unused) {{""".format(**self.__dict__) for input_param in self.do_inputs: - out += """ - free(self->{0[name]});""".format(input_param) + if input_param['type'] == 'fmat_t *': + out += """ + free(self->{0[name]}.data);""".format(input_param) for o in self.outputs: name = o['name'] del_out = delfromtype_fn[o['type']] @@ -379,11 +379,11 @@ Py_{shortname}_do (Py_{shortname} * self, PyObject * args) }}""".format(refs = refs, pyparamtypes = pyparamtypes, **self.__dict__) for p in input_params: out += """ - if (!{pytoaubio}(py_{0[name]}, self->{0[name]})) {{ + if (!{pytoaubio}(py_{0[name]}, &(self->{0[name]}))) {{ return NULL; }}""".format(input_param, pytoaubio = pytoaubio_fn[input_param['type']]) do_fn = get_name(self.do_proto) - inputs = ", ".join(['self->'+p['name'] for p in input_params]) + inputs = ", ".join(['&(self->'+p['name']+')' for p in input_params]) outputs = ", ".join(["self->%s" % p['name'] for p in self.do_outputs]) out += """ -- 2.11.0