Changeset 0b2892f


Ignore:
Timestamp:
Jul 14, 2012, 3:39:07 AM (8 years ago)
Author:
Paul Brossier <piem@piem.org>
Branches:
feature/autosink, feature/constantq, feature/pitchshift, feature/pydocstrings, feature/timestretch, master, pitchshift, sampler, timestretch, yinfft+
Children:
6192ce7
Parents:
c00f17d
Message:

gen_pyobject.py: improve, also parse io/source

File:
1 edited

Legend:

Unmodified
Added
Removed
  • interfaces/python/gen_pyobject.py

    rc00f17d r0b2892f  
    1818maintaining this bizarre file.
    1919"""
     20
     21param_numbers = {
     22  'source': [0, 2],
     23}
    2024
    2125# TODO
     
    8185# move into the C library at some point.
    8286defaultsizes = {
    83     'resampler':    'input->length * self->ratio',
    84     'specdesc':     '1',
    85     'onset':        '1',
    86     'pitchyin':     '1',
    87     'pitchyinfft':  '1',
    88     'pitchschmitt': '1',
    89     'pitchmcomb':   '1',
    90     'pitchfcomb':   '1',
    91     'pitch':        '1',
    92     'tss':          'self->hop_size',
    93     'mfcc':         'self->n_coeffs',
    94     'beattracking': 'self->hop_size',
    95     'tempo':        '1',
    96     'peakpicker':   '1',
     87    'resampler':    ['input->length * self->ratio'],
     88    'specdesc':     ['1'],
     89    'onset':        ['1'],
     90    'pitchyin':     ['1'],
     91    'pitchyinfft':  ['1'],
     92    'pitchschmitt': ['1'],
     93    'pitchmcomb':   ['1'],
     94    'pitchfcomb':   ['1'],
     95    'pitch':        ['1'],
     96    'tss':          ['self->hop_size', 'self->hop_size'],
     97    'mfcc':         ['self->n_coeffs'],
     98    'beattracking': ['self->hop_size'],
     99    'tempo':        ['1'],
     100    'peakpicker':   ['1'],
     101    'source':       ['self->hop_size', '1'],
    97102}
    98103
     
    123128    'ratio': '0.5',
    124129    'method': '"default"',
     130    'uri': '"none"',
    125131    }
    126132
     
    146152    'cvec_t*': 'PyAubio_CCvecToPyCvec',
    147153    'smpl_t': 'PyFloat_FromDouble',
     154    'uint_t*': 'PyInt_FromLong',
    148155}
    149156
     
    257264    return s
    258265
     266def gen_do_input_params(inputparams):
     267  inputdefs = ''
     268  parseinput = ''
     269  inputrefs = ''
     270  inputvecs = ''
     271  pytypes = ''
     272
     273  if len(inputparams):
     274    # build the parsing string for PyArg_ParseTuple
     275    pytypes = "".join([aubio2pytypes[p['type']] for p in inputparams])
     276
     277    inputdefs = "/* input vectors python prototypes */\n  "
     278    inputdefs += "\n  ".join(["PyObject * " + p['name'] + "_obj;" for p in inputparams])
     279
     280    inputvecs = "/* input vectors prototypes */\n  "
     281    inputvecs += "\n  ".join(map(lambda p: p['type'] + ' ' + p['name'] + ";", inputparams))
     282
     283    parseinput = "/* input vectors parsing */\n  "
     284    for p in inputparams:
     285        inputvec = p['name']
     286        inputdef = p['name'] + "_obj"
     287        converter = aubiovecfrompyobj[p['type']]
     288        parseinput += """%(inputvec)s = %(converter)s (%(inputdef)s);
     289
     290  if (%(inputvec)s == NULL) {
     291    return NULL;
     292  }""" % locals()
     293
     294    # build the string for the input objects references
     295    inputrefs = ", ".join(["&" + p['name'] + "_obj" for p in inputparams])
     296    # end of inputs strings
     297  return inputdefs, parseinput, inputrefs, inputvecs, pytypes
     298
     299def gen_do_output_params(outputparams, name):
     300  outputvecs = ""
     301  outputcreate = ""
     302  if len(outputparams):
     303    outputvecs = "  /* output vectors prototypes */\n"
     304    for p in outputparams:
     305      params = {
     306        'name': p['name'], 'pytype': p['type'], 'autype': p['type'][:-3],
     307        'length': defaultsizes[name].pop(0) }
     308      if (p['type'] == 'uint_t*'):
     309        outputvecs += '  uint_t' + ' ' + p['name'] + ";\n"
     310        outputcreate += "  %(name)s = 0;\n" % params
     311      else:
     312        outputvecs += "  " + p['type'] + ' ' + p['name'] + ";\n"
     313        outputcreate += "  /* creating output %(name)s as a new_%(autype)s of length %(length)s */\n" % params
     314        outputcreate += "  %(name)s = new_%(autype)s (%(length)s);\n" % params
     315
     316  returnval = "";
     317  if len(outputparams) > 1:
     318    returnval += "  PyObject *outputs = PyList_New(0);\n"
     319    for p in outputparams:
     320      returnval += "  PyList_Append( outputs, (PyObject *)" + aubiovectopyobj[p['type']] + " (" + p['name'] + ")" +");\n"
     321    returnval += "  return outputs;"
     322  elif len(outputparams) == 1:
     323    if defaultsizes[name] == '1':
     324      returnval += "  return (PyObject *)PyFloat_FromDouble(" + p['name'] + "->data[0])"
     325    else:
     326      returnval += "  return (PyObject *)" + aubiovectopyobj[p['type']] + " (" + p['name'] + ")"
     327  else:
     328    returnval = "  return Py_None;";
     329  # end of output strings
     330  return outputvecs, outputcreate, returnval
     331
    259332def gen_do(dofunc, name):
    260333    funcname = dofunc.split()[1].split('(')[0]
     
    265338    # and remove it
    266339    doparams = doparams[1:]
    267     # guess the input/output params, assuming we have less than 3
    268     assert len(doparams) > 0, \
    269         "no parameters for function do in object %s" % name
    270     #assert (len(doparams) <= 2), \
    271     #    "more than 3 parameters for do in object %s" % name
    272 
    273     # build strings for inputs, assuming there is only one input
    274     inputparams = [doparams[0]]
    275     # build the parsing string for PyArg_ParseTuple
    276     pytypes = "".join([aubio2pytypes[p['type']] for p in doparams[0:1]])
    277 
    278     inputdefs = "/* input vectors python prototypes */\n  "
    279     inputdefs += "\n  ".join(["PyObject * " + p['name'] + "_obj;" for p in inputparams])
    280 
    281     inputvecs = "/* input vectors prototypes */\n  "
    282     inputvecs += "\n  ".join(map(lambda p: p['type'] + ' ' + p['name'] + ";", inputparams))
    283 
    284     parseinput = "/* input vectors parsing */\n  "
    285     for p in inputparams:
    286         inputvec = p['name']
    287         inputdef = p['name'] + "_obj"
    288         converter = aubiovecfrompyobj[p['type']]
    289         parseinput += """%(inputvec)s = %(converter)s (%(inputdef)s);
    290 
    291   if (%(inputvec)s == NULL) {
    292     return NULL;
    293   }""" % locals()
    294 
    295     # build the string for the input objects references
    296     inputrefs = ", ".join(["&" + p['name'] + "_obj" for p in inputparams])
    297     # end of inputs strings
     340
     341    n_param = len(doparams)
     342
     343    if name in param_numbers.keys():
     344      n_input_param, n_output_param = param_numbers[name]
     345    else:
     346      n_input_param, n_output_param = 1, n_param - 1
     347
     348    assert n_output_param + n_input_param == n_param, "n_output_param + n_input_param != n_param for %s" % name
     349
     350    inputparams = doparams[:n_input_param]
     351    outputparams = doparams[n_input_param:n_input_param + n_output_param]
     352
     353    inputdefs, parseinput, inputrefs, inputvecs, pytypes = gen_do_input_params(inputparams);
     354    outputvecs, outputcreate, returnval = gen_do_output_params(outputparams, name)
    298355
    299356    # build strings for outputs
    300     outputparams = doparams[1:]
    301     if len(outputparams) >= 1:
    302         #assert len(outputparams) == 1, \
    303         #    "too many output parameters"
    304         outputvecs = "\n  /* output vectors prototypes */\n  "
    305         outputvecs += "\n  ".join([p['type'] + ' ' + p['name'] + ";" for p in outputparams])
    306         params = {
    307           'name': p['name'], 'pytype': p['type'], 'autype': p['type'][:-3],
    308           'length': defaultsizes[name]}
    309         outputcreate = "\n  ".join(["""/* creating output %(name)s as a new_%(autype)s of length %(length)s */""" % \
    310             params for p in outputparams])
    311         outputcreate += "\n"
    312         outputcreate += "\n  ".join(["""  %(name)s = new_%(autype)s (%(length)s);""" % \
    313             params for p in outputparams])
    314         returnval = ""
    315         if len(outputparams) > 1:
    316             returnval += "PyObject *outputs = PyList_New(0);\n"
    317             for p in outputparams:
    318                 returnval += "  PyList_Append( outputs, (PyObject *)" + aubiovectopyobj[p['type']] + " (" + p['name'] + ")" +");\n"
    319             returnval += "  return outputs;"
    320         else:
    321             if defaultsizes[name] == '1':
    322                 returnval += "return (PyObject *)PyFloat_FromDouble(" + p['name'] + "->data[0])"
    323             else:
    324                 returnval += "return (PyObject *)" + aubiovectopyobj[p['type']] + " (" + p['name'] + ")"
     357    # build the parameters for the  _do() call
     358    doparams_string = "self->o"
     359    for p in doparams:
     360      if p['type'] == 'uint_t*':
     361        doparams_string += ", &" + p['name']
     362      else:
     363        doparams_string += ", " + p['name']
     364
     365    if n_input_param:
     366      arg_parse_tuple = """\
     367  if (!PyArg_ParseTuple (args, "%(pytypes)s", %(inputrefs)s)) {
     368    return NULL;
     369  }
     370""" % locals()
    325371    else:
    326         # no output
    327         outputvecs = ""
    328         outputcreate = ""
    329         #returnval = "Py_None";
    330         returnval = "return (PyObject *)" + aubiovectopyobj[p['type']] + " (" + p['name'] + ")"
    331     # end of output strings
    332 
    333     # build the parameters for the  _do() call
    334     doparams_string = "self->o, " + ", ".join([p['name'] for p in doparams])
    335 
     372      arg_parse_tuple = ""
    336373    # put it all together
    337374    s = """\
     
    340377Py_%(name)s_do(Py_%(name)s * self, PyObject * args)
    341378{
    342   %(inputdefs)s
    343   %(inputvecs)s
    344   %(outputvecs)s
    345 
    346   if (!PyArg_ParseTuple (args, "%(pytypes)s", %(inputrefs)s)) {
    347     return NULL;
    348   }
    349 
    350   %(parseinput)s
     379%(inputdefs)s
     380%(inputvecs)s
     381%(outputvecs)s
     382
     383%(arg_parse_tuple)s
     384
     385%(parseinput)s
    351386 
    352   %(outputcreate)s
     387%(outputcreate)s
    353388
    354389  /* compute _do function */
    355390  %(funcname)s (%(doparams_string)s);
    356391
    357   %(returnval)s;
     392%(returnval)s;
    358393}
    359394""" % locals()
Note: See TracChangeset for help on using the changeset viewer.