ref: 0b2892fa076aea21f128617f7d21b826f53797a8
parent: c00f17df1ff17102ec0f36d1313b5d8772172fb2
author: Paul Brossier <piem@piem.org>
date: Fri Jul 13 15:39:07 EDT 2012
gen_pyobject.py: improve, also parse io/source
--- a/interfaces/python/gen_pyobject.py
+++ b/interfaces/python/gen_pyobject.py
@@ -18,6 +18,10 @@
maintaining this bizarre file.
"""
+param_numbers = {
+ 'source': [0, 2],
+}
+
# TODO
# do function: for now, only the following pattern is supported:
# void aubio_<foo>_do (aubio_foo_t * o,
@@ -80,20 +84,21 @@
# the important bits: the size of the output for each objects. this data should
# move into the C library at some point.
defaultsizes = {
- 'resampler': 'input->length * self->ratio',
- 'specdesc': '1',
- 'onset': '1',
- 'pitchyin': '1',
- 'pitchyinfft': '1',
- 'pitchschmitt': '1',
- 'pitchmcomb': '1',
- 'pitchfcomb': '1',
- 'pitch': '1',
- 'tss': 'self->hop_size',
- 'mfcc': 'self->n_coeffs',
- 'beattracking': 'self->hop_size',
- 'tempo': '1',
- 'peakpicker': '1',
+ 'resampler': ['input->length * self->ratio'],
+ 'specdesc': ['1'],
+ 'onset': ['1'],
+ 'pitchyin': ['1'],
+ 'pitchyinfft': ['1'],
+ 'pitchschmitt': ['1'],
+ 'pitchmcomb': ['1'],
+ 'pitchfcomb': ['1'],
+ 'pitch': ['1'],
+ 'tss': ['self->hop_size', 'self->hop_size'],
+ 'mfcc': ['self->n_coeffs'],
+ 'beattracking': ['self->hop_size'],
+ 'tempo': ['1'],
+ 'peakpicker': ['1'],
+ 'source': ['self->hop_size', '1'],
}
# default value for variables
@@ -122,6 +127,7 @@
'thrs': '0.5',
'ratio': '0.5',
'method': '"default"',
+ 'uri': '"none"',
}
# aubio to python
@@ -145,6 +151,7 @@
'fvec_t*': 'PyAubio_CFvecToArray',
'cvec_t*': 'PyAubio_CCvecToPyCvec',
'smpl_t': 'PyFloat_FromDouble',
+ 'uint_t*': 'PyInt_FromLong',
}
def gen_new_init(newfunc, name):
@@ -256,24 +263,16 @@
""" % locals()
return s
-def gen_do(dofunc, name):
- funcname = dofunc.split()[1].split('(')[0]
- doparams = get_params_types_names(dofunc)
- # make sure the first parameter is the object
- assert doparams[0]['type'] == "aubio_"+name+"_t*", \
- "method is not in 'aubio_<name>_t"
- # and remove it
- doparams = doparams[1:]
- # guess the input/output params, assuming we have less than 3
- assert len(doparams) > 0, \
- "no parameters for function do in object %s" % name
- #assert (len(doparams) <= 2), \
- # "more than 3 parameters for do in object %s" % name
+def gen_do_input_params(inputparams):
+ inputdefs = ''
+ parseinput = ''
+ inputrefs = ''
+ inputvecs = ''
+ pytypes = ''
- # build strings for inputs, assuming there is only one input
- inputparams = [doparams[0]]
+ if len(inputparams):
# build the parsing string for PyArg_ParseTuple
- pytypes = "".join([aubio2pytypes[p['type']] for p in doparams[0:1]])
+ pytypes = "".join([aubio2pytypes[p['type']] for p in inputparams])
inputdefs = "/* input vectors python prototypes */\n "
inputdefs += "\n ".join(["PyObject * " + p['name'] + "_obj;" for p in inputparams])
@@ -295,44 +294,82 @@
# build the string for the input objects references
inputrefs = ", ".join(["&" + p['name'] + "_obj" for p in inputparams])
# end of inputs strings
+ return inputdefs, parseinput, inputrefs, inputvecs, pytypes
- # build strings for outputs
- outputparams = doparams[1:]
- if len(outputparams) >= 1:
- #assert len(outputparams) == 1, \
- # "too many output parameters"
- outputvecs = "\n /* output vectors prototypes */\n "
- outputvecs += "\n ".join([p['type'] + ' ' + p['name'] + ";" for p in outputparams])
- params = {
- 'name': p['name'], 'pytype': p['type'], 'autype': p['type'][:-3],
- 'length': defaultsizes[name]}
- outputcreate = "\n ".join(["""/* creating output %(name)s as a new_%(autype)s of length %(length)s */""" % \
- params for p in outputparams])
- outputcreate += "\n"
- outputcreate += "\n ".join([""" %(name)s = new_%(autype)s (%(length)s);""" % \
- params for p in outputparams])
- returnval = ""
- if len(outputparams) > 1:
- returnval += "PyObject *outputs = PyList_New(0);\n"
- for p in outputparams:
- returnval += " PyList_Append( outputs, (PyObject *)" + aubiovectopyobj[p['type']] + " (" + p['name'] + ")" +");\n"
- returnval += " return outputs;"
- else:
- if defaultsizes[name] == '1':
- returnval += "return (PyObject *)PyFloat_FromDouble(" + p['name'] + "->data[0])"
- else:
- returnval += "return (PyObject *)" + aubiovectopyobj[p['type']] + " (" + p['name'] + ")"
+def gen_do_output_params(outputparams, name):
+ outputvecs = ""
+ outputcreate = ""
+ if len(outputparams):
+ outputvecs = " /* output vectors prototypes */\n"
+ for p in outputparams:
+ params = {
+ 'name': p['name'], 'pytype': p['type'], 'autype': p['type'][:-3],
+ 'length': defaultsizes[name].pop(0) }
+ if (p['type'] == 'uint_t*'):
+ outputvecs += ' uint_t' + ' ' + p['name'] + ";\n"
+ outputcreate += " %(name)s = 0;\n" % params
+ else:
+ outputvecs += " " + p['type'] + ' ' + p['name'] + ";\n"
+ outputcreate += " /* creating output %(name)s as a new_%(autype)s of length %(length)s */\n" % params
+ outputcreate += " %(name)s = new_%(autype)s (%(length)s);\n" % params
+
+ returnval = "";
+ if len(outputparams) > 1:
+ returnval += " PyObject *outputs = PyList_New(0);\n"
+ for p in outputparams:
+ returnval += " PyList_Append( outputs, (PyObject *)" + aubiovectopyobj[p['type']] + " (" + p['name'] + ")" +");\n"
+ returnval += " return outputs;"
+ elif len(outputparams) == 1:
+ if defaultsizes[name] == '1':
+ returnval += " return (PyObject *)PyFloat_FromDouble(" + p['name'] + "->data[0])"
else:
- # no output
- outputvecs = ""
- outputcreate = ""
- #returnval = "Py_None";
- returnval = "return (PyObject *)" + aubiovectopyobj[p['type']] + " (" + p['name'] + ")"
- # end of output strings
+ returnval += " return (PyObject *)" + aubiovectopyobj[p['type']] + " (" + p['name'] + ")"
+ else:
+ returnval = " return Py_None;";
+ # end of output strings
+ return outputvecs, outputcreate, returnval
+def gen_do(dofunc, name):
+ funcname = dofunc.split()[1].split('(')[0]
+ doparams = get_params_types_names(dofunc)
+ # make sure the first parameter is the object
+ assert doparams[0]['type'] == "aubio_"+name+"_t*", \
+ "method is not in 'aubio_<name>_t"
+ # and remove it
+ doparams = doparams[1:]
+
+ n_param = len(doparams)
+
+ if name in param_numbers.keys():
+ n_input_param, n_output_param = param_numbers[name]
+ else:
+ n_input_param, n_output_param = 1, n_param - 1
+
+ assert n_output_param + n_input_param == n_param, "n_output_param + n_input_param != n_param for %s" % name
+
+ inputparams = doparams[:n_input_param]
+ outputparams = doparams[n_input_param:n_input_param + n_output_param]
+
+ inputdefs, parseinput, inputrefs, inputvecs, pytypes = gen_do_input_params(inputparams);
+ outputvecs, outputcreate, returnval = gen_do_output_params(outputparams, name)
+
+ # build strings for outputs
# build the parameters for the _do() call
- doparams_string = "self->o, " + ", ".join([p['name'] for p in doparams])
+ doparams_string = "self->o"
+ for p in doparams:
+ if p['type'] == 'uint_t*':
+ doparams_string += ", &" + p['name']
+ else:
+ doparams_string += ", " + p['name']
+ if n_input_param:
+ arg_parse_tuple = """\
+ if (!PyArg_ParseTuple (args, "%(pytypes)s", %(inputrefs)s)) {
+ return NULL;
+ }
+""" % locals()
+ else:
+ arg_parse_tuple = ""
# put it all together
s = """\
/* function Py_%(name)s_do */
@@ -339,22 +376,20 @@
static PyObject *
Py_%(name)s_do(Py_%(name)s * self, PyObject * args)
{
- %(inputdefs)s
- %(inputvecs)s
- %(outputvecs)s
+%(inputdefs)s
+%(inputvecs)s
+%(outputvecs)s
- if (!PyArg_ParseTuple (args, "%(pytypes)s", %(inputrefs)s)) {
- return NULL;
- }
+%(arg_parse_tuple)s
- %(parseinput)s
+%(parseinput)s
- %(outputcreate)s
+%(outputcreate)s
/* compute _do function */
%(funcname)s (%(doparams_string)s);
- %(returnval)s;
+%(returnval)s;
}
""" % locals()
return s