# we have some clean up to do
'buf_size': 'Py_default_vector_length',
'win_s': 'Py_default_vector_length',
+ 'size': 'Py_default_vector_length',
# and here too
'hop_size': 'Py_default_vector_length / 2',
'hop_s': 'Py_default_vector_length / 2',
'name': 'type',
'char_t*': 'T_STRING',
'uint_t': 'T_INT',
- 'smpl_t': 'T_FLOAT',
+ 'smpl_t': 'AUBIO_NPY_SMPL',
}
pyfromtype_fn = {
pytoaubio_fn = {
'fvec_t*': 'PyAubio_ArrayToCFvec',
- 'cvec_t*': 'PyAubio_ArrayToCCvec',
+ 'cvec_t*': 'PyAubio_PyCvecToCCvec',
#'fmat_t*': 'PyAubio_ArrayToCFmat',
}
-pyfromaubio_fn = {
- 'fvec_t*': 'PyAubio_CFvecToArray',
- 'cvec_t*': 'PyAubio_CCvecToArray',
- 'fmat_t*': 'PyAubio_CFmatToArray',
- }
-
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',
}
param_init = {
}
pyargparse_chars = {
- 'smpl_t': 'f',
+ 'smpl_t': 'f', # if not usedouble else 'd',
'uint_t': 'I',
'sint_t': 'I',
'char_t*': 's',
objoutsize = {
'onset': '1',
'pitch': '1',
+ 'notes': '3',
'wavetable': 'self->hop_size',
'sampler': 'self->hop_size',
'mfcc': 'self->n_coeffs',
'specdesc': '1',
- 'tempo': '2',
+ 'tempo': '1',
'filterbank': 'self->n_filters',
- 'tss': 'self->hop_size',
+ 'tss': 'self->buf_size',
+ 'dct': 'self->size',
+ }
+
+objinputsize = {
+ 'mfcc': 'self->buf_size / 2 + 1',
+ 'notes': 'self->hop_size',
+ 'onset': 'self->hop_size',
+ 'pitch': 'self->hop_size',
+ 'sampler': 'self->hop_size',
+ 'specdesc': 'self->buf_size / 2 + 1',
+ 'tempo': 'self->hop_size',
+ 'wavetable': 'self->hop_size',
+ 'tss': 'self->buf_size / 2 + 1',
}
def get_name(proto):
class MappedObject(object):
- def __init__(self, prototypes):
+ def __init__(self, prototypes, usedouble = False):
+ if usedouble:
+ pyargparse_chars['smpl_t'] = 'd'
self.prototypes = prototypes
self.shortname = prototypes['shortname']
self.outputs = get_params_types_names(self.do_proto)[2:]
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]
+ if len(self.prototypes['rdo']):
+ rdo_outputs = get_params_types_names(prototypes['rdo'][0])[2:]
+ struct_output_str += ["PyObject *{0[name]}; {1} c_{0[name]}".format(i, i['type'][:-1]) for i in rdo_outputs]
+ self.outputs += rdo_outputs
+ self.struct_outputs = ";\n ".join(struct_output_str)
#print ("input_params: ", map(split_type, get_input_params(self.do_proto)))
#print ("output_params", map(split_type, get_output_params(self.do_proto)))
def gen_code(self):
out = ""
- out += self.gen_struct()
- out += self.gen_doc()
- out += self.gen_new()
- out += self.gen_init()
- out += self.gen_del()
- out += self.gen_do()
- out += self.gen_memberdef()
- out += self.gen_set()
- out += self.gen_get()
- out += self.gen_methodef()
- out += self.gen_typeobject()
+ try:
+ out += self.gen_struct()
+ out += self.gen_doc()
+ out += self.gen_new()
+ out += self.gen_init()
+ out += self.gen_del()
+ out += self.gen_do()
+ if len(self.prototypes['rdo']):
+ self.do_proto = self.prototypes['rdo'][0]
+ self.do_inputs = [get_params_types_names(self.do_proto)[1]]
+ self.do_outputs = get_params_types_names(self.do_proto)[2:]
+ out += self.gen_do(method='rdo')
+ out += self.gen_memberdef()
+ out += self.gen_set()
+ out += self.gen_get()
+ out += self.gen_methodef()
+ out += self.gen_typeobject()
+ except Exception as e:
+ print ("Failed generating code for", self.shortname)
+ raise
return out
def gen_struct(self):
// do input vectors
{do_inputs_list};
// output results
- {output_results};
+ {struct_outputs};
}} 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):
+ sig = []
+ for p in self.input_params:
+ name = p['name']
+ defval = aubiodefvalue[name].replace('"','\\\"')
+ sig.append("{name}={defval}".format(defval=defval, name=name))
out = """
-// TODO: add documentation
-static char Py_{shortname}_doc[] = \"undefined\";
+#ifndef PYAUBIO_{shortname}_doc
+#define PYAUBIO_{shortname}_doc "{shortname}({sig})"
+#endif /* PYAUBIO_{shortname}_doc */
+
+static char Py_{shortname}_doc[] = ""
+PYAUBIO_{shortname}_doc
+"";
"""
- return out.format(**self.__dict__)
+ return out.format(sig=', '.join(sig), **self.__dict__)
def gen_new(self):
out = """
out += """
// return -1 and set error string on failure
if (self->o == NULL) {{
- //char_t errstr[30 + strlen(self->uri)];
- //sprintf(errstr, "error creating {shortname} with params {paramchars}", {paramvals});
- char_t errstr[60];
- sprintf(errstr, "error creating {shortname} with given params");
- PyErr_SetString (PyExc_Exception, errstr);
+ PyErr_Format (PyExc_RuntimeError, "failed creating {shortname}");
return -1;
}}
""".format(paramchars = paramchars, paramvals = paramvals, **self.__dict__)
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)
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']]
out += """
- {del_out}(self->{name});""".format(del_out = del_out, name = name)
+ if (self->{name}) {{
+ {del_out}(self->{name});
+ }}""".format(del_out = del_out, name = name)
del_fn = get_name(self.del_proto)
out += """
+ if (self->o) {{
{del_fn}(self->o);
- Py_TYPE(self)->tp_free((PyObject *) self);
+ }}
+ Py_TYPE(self)->tp_free((PyObject *) self);
}}
""".format(del_fn = del_fn)
return out
- def gen_do(self):
- output = self.outputs[0]
+ def gen_do(self, method = 'do'):
out = """
// do {shortname}
static PyObject*
-Py_{shortname}_do (Py_{shortname} * self, PyObject * args)
-{{""".format(**self.__dict__)
+Pyaubio_{shortname}_{method} (Py_{shortname} * self, PyObject * args)
+{{""".format(method = method, **self.__dict__)
input_params = self.do_inputs
output_params = self.do_outputs
#print input_params
#print output_params
+ out += """
+ PyObject *outputs;"""
for input_param in input_params:
out += """
- PyObject *py_{0};""".format(input_param['name'], input_param['type'])
+ PyObject *py_{0};""".format(input_param['name'])
refs = ", ".join(["&py_%s" % p['name'] for p in input_params])
pyparamtypes = "".join([pyargparse_chars[p['type']] for p in input_params])
out += """
if (!PyArg_ParseTuple (args, "{pyparamtypes}", {refs})) {{
return NULL;
}}""".format(refs = refs, pyparamtypes = pyparamtypes, **self.__dict__)
- for p in input_params:
+ for input_param 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']])
+ if self.shortname in objinputsize:
+ out += """
+
+ if (self->{0[name]}.length != {expected_size}) {{
+ PyErr_Format (PyExc_ValueError,
+ "input size of {shortname} should be %d, not %d",
+ {expected_size}, self->{0[name]}.length);
+ return NULL;
+ }}""".format(input_param, expected_size = objinputsize[self.shortname], **self.__dict__)
+ else:
+ 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])
+ 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});
+ {do_fn}(self->o, {inputs}, {c_outputs});
+""".format(
+ do_fn = do_fn,
+ inputs = inputs, c_outputs = c_outputs,
+ )
+ if len(self.do_outputs) > 1:
+ out += """
+ outputs = PyTuple_New({:d});""".format(len(self.do_outputs))
+ for i, p in enumerate(self.do_outputs):
+ out += """
+ PyTuple_SetItem( outputs, {i}, self->{p[name]});""".format(i = i, p = p)
+ else:
+ out += """
+ outputs = self->{p[name]};""".format(p = self.do_outputs[0])
+ out += """
- return (PyObject *) {aubiotonumpy} ({outputs});
+ return outputs;
}}
""".format(
- do_fn = do_fn,
- aubiotonumpy = pyfromaubio_fn[output['type']],
- inputs = inputs, outputs = outputs,
+ outputs = outputs,
)
return out
// {shortname} setters
""".format(**self.__dict__)
for set_param in self.prototypes['set']:
- params = get_params_types_names(set_param)[1]
- paramtype = params['type']
+ params = get_params_types_names(set_param)[1:]
+ param = self.shortname.split('_set_')[-1]
+ paramdecls = "".join(["""
+ {0} {1};""".format(p['type'], p['name']) for p in params])
method_name = get_name(set_param)
param = method_name.split('aubio_'+self.shortname+'_set_')[-1]
- pyparamtype = pyargparse_chars[paramtype]
+ refs = ", ".join(["&%s" % p['name'] for p in params])
+ paramlist = ", ".join(["%s" % p['name'] for p in params])
+ if len(params):
+ paramlist = "," + paramlist
+ pyparamtypes = ''.join([pyargparse_chars[p['type']] for p in params])
out += """
static PyObject *
Pyaubio_{shortname}_set_{param} (Py_{shortname} *self, PyObject *args)
{{
uint_t err = 0;
- {paramtype} {param};
+ {paramdecls}
+""".format(param = param, paramdecls = paramdecls, **self.__dict__)
+
+ if len(refs) and len(pyparamtypes):
+ out += """
- if (!PyArg_ParseTuple (args, "{pyparamtype}", &{param})) {{
+ if (!PyArg_ParseTuple (args, "{pyparamtypes}", {refs})) {{
return NULL;
}}
- err = aubio_{shortname}_set_{param} (self->o, {param});
+""".format(pyparamtypes = pyparamtypes, refs = refs)
+
+ out += """
+ err = aubio_{shortname}_set_{param} (self->o {paramlist});
if (err > 0) {{
- PyErr_SetString (PyExc_ValueError, "error running aubio_{shortname}_set_{param}");
+ if (PyErr_Occurred() == NULL) {{
+ PyErr_SetString (PyExc_ValueError, "error running aubio_{shortname}_set_{param}");
+ }} else {{
+ // change the RuntimeError into ValueError
+ PyObject *type, *value, *traceback;
+ PyErr_Fetch(&type, &value, &traceback);
+ PyErr_Restore(PyExc_ValueError, value, traceback);
+ }}
return NULL;
}}
Py_RETURN_NONE;
}}
-""".format(param = param, paramtype = paramtype, pyparamtype = pyparamtype, **self.__dict__)
+""".format(param = param, refs = refs, paramdecls = paramdecls,
+ pyparamtypes = pyparamtypes, paramlist = paramlist, **self.__dict__)
return out
def gen_get(self):
out += """
{{"{shortname}", (PyCFunction) Py{name},
METH_NOARGS, ""}},""".format(name = name, shortname = shortname)
+ for m in self.prototypes['rdo']:
+ name = get_name(m)
+ shortname = name.replace('aubio_%s_' % self.shortname, '')
+ out += """
+ {{"{shortname}", (PyCFunction) Py{name},
+ METH_VARARGS, ""}},""".format(name = name, shortname = shortname)
out += """
{NULL} /* sentinel */
};
0,
0,
0,
- (ternaryfunc)Py_{shortname}_do,
+ (ternaryfunc)Pyaubio_{shortname}_do,
0,
0,
0,
(initproc) Py_{shortname}_init,
0,
Py_{shortname}_new,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
}};
""".format(**self.__dict__)