Changeset 90077e4
- Timestamp:
- Nov 15, 2009, 3:19:45 PM (15 years ago)
- Branches:
- feature/autosink, feature/cnn, feature/cnn_org, feature/constantq, feature/crepe, feature/crepe_org, feature/pitchshift, feature/pydocstrings, feature/timestretch, fix/ffmpeg5, master, pitchshift, sampler, timestretch, yinfft+
- Children:
- 449bff6
- Parents:
- 4bc098c
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
interfaces/python/gen_pyobject.py
r4bc098c r90077e4 26 26 # const could be used for the inputs in the C prototypes. 27 27 28 def split_type(arg): 29 """ arg = 'foo *name' 30 return ['foo*', 'name'] """ 31 l = arg.split() 32 # ['foo', '*name'] -> ['foo*', 'name'] 33 if l[-1].startswith('*'): 34 return [l[0]+'*', l[1][1:]] 35 # ['foo', '*', 'name'] -> ['foo*', 'name'] 36 if len(l) == 3: 37 return [l[0]+l[1], l[2]] 38 else: 39 return l 40 41 def get_params(proto): 42 """ get the list of parameters from a function prototype 43 example: proto = "int main (int argc, char ** argv)" 44 returns: ['int argc', 'char ** argv'] 45 """ 46 import re 47 paramregex = re.compile('[\(, ](\w+ \*?\*? ?\w+)[, \)]') 48 return paramregex.findall(proto) 49 50 def get_params_types_names(proto): 51 """ get the list of parameters from a function prototype 52 example: proto = "int main (int argc, char ** argv)" 53 returns: [['int', 'argc'], ['char **','argv']] 54 """ 55 return map(split_type, get_params(proto)) 56 57 def get_return_type(proto): 58 import re 59 paramregex = re.compile('(\w+ ?\*?).*') 60 outputs = paramregex.findall(proto) 61 assert len(outputs) == 1 62 return outputs[0].replace(' ', '') 63 64 def get_name(proto): 65 name = proto.split()[1].split('(')[0] 66 return name.replace('*','') 67 28 68 # the important bits: the size of the output for each objects. this data should 29 69 # move into the C library at some point. 30 70 defaultsizes = { 31 71 'resampler': ('input->length * self->ratio', 'input->channels'), 32 'specdesc': ('1', ' self->channels'),72 'specdesc': ('1', 'fftgrain->channels'), 33 73 'onset': ('1', 'self->channels'), 34 74 'pitchyin': ('1', 'in->channels'), … … 79 119 'smpl_t': 'I', 80 120 'lsmp_t': 'I', 81 'fvec_t ': 'O',82 'cvec_t ': 'O',121 'fvec_t*': 'O', 122 'cvec_t*': 'O', 83 123 'char_t*': 's', 84 124 } … … 86 126 # aubio to pyaubio 87 127 aubio2pyaubio = { 88 'fvec_t ': 'Py_fvec',89 'cvec_t ': 'Py_cvec',128 'fvec_t*': 'Py_fvec', 129 'cvec_t*': 'Py_cvec', 90 130 } 91 131 92 132 # array to aubio 93 133 aubiovecfrompyobj = { 94 'fvec_t ': 'PyAubio_ArrayToFvec',95 'cvec_t ': 'PyAubio_ArrayToCvec',134 'fvec_t*': 'PyAubio_ArrayToFvec', 135 'cvec_t*': 'PyAubio_ArrayToCvec', 96 136 } 97 137 98 138 # aubio to array 99 139 aubiovectopyobj = { 100 'fvec_t ': 'PyAubio_FvecToArray',101 'cvec_t ': 'PyAubio_CvecToArray',102 } 103 104 def get_newparams(newfunc): 105 newparams = [[p.split()[0], p.split()[-1]]106 for p in newfunc.split('(')[1].split(')')[0].split(',')]107 # make char_t a pointer108 return map(lambda x: [x[0].replace('char_t', 'char_t*'), x[1]], newparams) 140 'fvec_t*': 'PyAubio_FvecToArray', 141 'cvec_t*': 'PyAubio_CvecToArray', 142 } 143 144 aubiovectopyobj_new = { 145 'fvec_t*': 'PyAubio_CFvecToArray', 146 'cvec_t*': 'PyAubio_CCvecToArray', 147 'smpl_t': 'PyFloat_FromDouble', 148 } 109 149 110 150 def gen_new_init(newfunc, name): 111 newparams = get_ newparams(newfunc)151 newparams = get_params_types_names(newfunc) 112 152 # self->param1, self->param2, self->param3 113 153 selfparams = ', self->'.join([p[1] for p in newparams]) … … 118 158 s = """\ 119 159 // WARNING: this file is generated, DO NOT EDIT 160 161 // WARNING: if you haven't read the first line yet, please do so 120 162 #include "aubiowraphell.h" 121 163 … … 159 201 } 160 202 """ % locals() 161 # TODO add parameters default values162 203 for ptype, pname in newparams: 163 204 defval = aubiodefvalue[pname] … … 206 247 def gen_do(dofunc, name): 207 248 funcname = dofunc.split()[1].split('(')[0] 208 doparams = [p.split() for p in dofunc.split('(')[1].split(')')[0].split(',')]249 doparams = get_params_types_names(dofunc) 209 250 # make sure the first parameter is the object 210 assert doparams[0][0] == "aubio_"+name+"_t ", \251 assert doparams[0][0] == "aubio_"+name+"_t*", \ 211 252 "method is not in 'aubio_<name>_t" 212 253 # and remove it … … 241 282 # build strings for outputs 242 283 outputparams = doparams[1:] 243 if len( doparams) >1:284 if len(outputparams) >= 1: 244 285 #assert len(outputparams) == 1, \ 245 286 # "too many output parameters" 246 287 outputvecs = "\n ".join([aubio2pyaubio[p[0]]+" * " + p[-1] + ";" for p in outputparams]) 247 outputcreate = " ""\288 outputcreate = "\n ".join(["""\ 248 289 AUBIO_NEW_VEC(%(name)s, %(pytype)s, %(length)s, %(channels)s) 249 290 %(name)s->o = new_%(autype)s (%(length)s, %(channels)s);""" % \ 250 {'name': p[-1], 'pytype': aubio2pyaubio[p[0]], 'autype': p[0][:-2], 251 'length': defaultsizes[name][0], 'channels': defaultsizes[name][1]} 252 returnval = "(PyObject *)" + aubiovectopyobj[p[0]] + " (" + p[-1] + ")" 291 {'name': p[-1], 'pytype': aubio2pyaubio[p[0]], 'autype': p[0][:-3], 292 'length': defaultsizes[name][0], 'channels': defaultsizes[name][1]} \ 293 for p in outputparams]) 294 if len(outputparams) > 1: 295 returnval = "PyObject *outputs = PyList_New(0);\n" 296 for p in outputparams: 297 returnval += " PyList_Append( outputs, (PyObject *)" + aubiovectopyobj[p[0]] + " (" + p[-1] + ")" +");\n" 298 returnval += " return outputs;" 299 else: 300 returnval = "return (PyObject *)" + aubiovectopyobj[p[0]] + " (" + p[-1] + ")" 253 301 else: 254 302 # no output … … 256 304 outputcreate = "" 257 305 #returnval = "Py_None"; 258 returnval = " (PyObject *)" + aubiovectopyobj[p[0]] + " (" + p[-1] + ")"306 returnval = "return (PyObject *)" + aubiovectopyobj[p[0]] + " (" + p[-1] + ")" 259 307 # end of output strings 260 308 … … 282 330 %(funcname)s (%(doparams_string)s); 283 331 284 return%(returnval)s;332 %(returnval)s; 285 333 } 286 334 """ % locals() … … 288 336 289 337 def gen_members(new_method, name): 290 newparams = get_ newparams(new_method)338 newparams = get_params_types_names(new_method) 291 339 s = """ 292 340 AUBIO_MEMBERS_START(%(name)s)""" % locals() … … 312 360 return s 313 361 362 314 363 def gen_methods(get_methods, set_methods, name): 315 # TODO add methods 316 s = """\ 364 s = "" 365 method_defs = "" 366 for method in set_methods: 367 method_name = get_name(method) 368 params = get_params_types_names(method) 369 out_type = get_return_type(method) 370 assert params[0][0] == "aubio_"+name+"_t*", \ 371 "get method is not in 'aubio_<name>_t" 372 print method 373 print params[1:] 374 setter_args = "self->o, " +",".join([p[1] for p in params[1:]]) 375 parse_args = "" 376 for p in params[1:]: 377 parse_args += p[0] + " " + p[1] + ";\n" 378 argmap = "".join([aubio2pytypes[p[0]] for p in params[1:]]) 379 arglist = ", ".join(["&"+p[1] for p in params[1:]]) 380 parse_args += """ 381 if (!PyArg_ParseTuple (args, "%(argmap)s", %(arglist)s)) { 382 return NULL; 383 } """ % locals() 384 s += """ 385 static PyObject * 386 Py%(funcname)s (Py_%(objname)s *self, PyObject *args) 387 { 388 uint_t err = 0; 389 390 %(parse_args)s 391 392 err = %(funcname)s (%(setter_args)s); 393 394 if (err > 0) { 395 PyErr_SetString (PyExc_ValueError, 396 "error running %(funcname)s"); 397 return NULL; 398 } 399 return Py_None; 400 } 401 """ % {'funcname': method_name, 'objname': name, 402 'out_type': out_type, 'setter_args': setter_args, 'parse_args': parse_args } 403 shortname = method_name.split(name+'_')[-1] 404 method_defs += """\ 405 {"%(shortname)s", (PyCFunction) Py%(method_name)s, 406 METH_VARARGS, ""}, 407 """ % locals() 408 409 for method in get_methods: 410 method_name = get_name(method) 411 params = get_params_types_names(method) 412 out_type = get_return_type(method) 413 assert params[0][0] == "aubio_"+name+"_t*", \ 414 "get method is not in 'aubio_<name>_t %s" % params[0][0] 415 assert len(params) == 1, \ 416 "get method has more than one parameter %s" % params 417 getter_args = "self->o" 418 returnval = "(PyObject *)" + aubiovectopyobj_new[out_type] + " (tmp)" 419 shortname = method_name.split(name+'_')[-1] 420 method_defs += """\ 421 {"%(shortname)s", (PyCFunction) Py%(method_name)s, 422 METH_NOARGS, ""}, 423 """ % locals() 424 s += """ 425 static PyObject * 426 Py%(funcname)s (Py_%(objname)s *self, PyObject *unused) 427 { 428 %(out_type)s tmp = %(funcname)s (%(getter_args)s); 429 return %(returnval)s; 430 } 431 """ % {'funcname': method_name, 'objname': name, 432 'out_type': out_type, 'getter_args': getter_args, 'returnval': returnval } 433 434 s += """ 317 435 static PyMethodDef Py_%(name)s_methods[] = { 318 436 """ % locals() 319 # TODO add PyMethodDefs437 s += method_defs 320 438 s += """\ 321 439 {NULL} /* sentinel */
Note: See TracChangeset
for help on using the changeset viewer.