[ccb9fb5] | 1 | aubiodefvalue = { |
---|
| 2 | # we have some clean up to do |
---|
| 3 | 'buf_size': 'Py_default_vector_length', |
---|
| 4 | 'win_s': 'Py_default_vector_length', |
---|
[60583a3] | 5 | 'size': 'Py_default_vector_length', |
---|
[ccb9fb5] | 6 | # and here too |
---|
| 7 | 'hop_size': 'Py_default_vector_length / 2', |
---|
| 8 | 'hop_s': 'Py_default_vector_length / 2', |
---|
| 9 | # these should be alright |
---|
| 10 | 'samplerate': 'Py_aubio_default_samplerate', |
---|
| 11 | # now for the non obvious ones |
---|
| 12 | 'n_filters': '40', |
---|
| 13 | 'n_coeffs': '13', |
---|
| 14 | 'nelems': '10', |
---|
| 15 | 'flow': '0.', |
---|
| 16 | 'fhig': '1.', |
---|
| 17 | 'ilow': '0.', |
---|
| 18 | 'ihig': '1.', |
---|
| 19 | 'thrs': '0.5', |
---|
| 20 | 'ratio': '0.5', |
---|
| 21 | 'method': '"default"', |
---|
| 22 | 'uri': '"none"', |
---|
[a9eb93e] | 23 | 'transpose': '0.', |
---|
[ccb9fb5] | 24 | } |
---|
| 25 | |
---|
| 26 | member_types = { |
---|
| 27 | 'name': 'type', |
---|
| 28 | 'char_t*': 'T_STRING', |
---|
| 29 | 'uint_t': 'T_INT', |
---|
[c6388f4] | 30 | 'smpl_t': 'AUBIO_NPY_SMPL', |
---|
[ccb9fb5] | 31 | } |
---|
| 32 | |
---|
| 33 | pyfromtype_fn = { |
---|
| 34 | 'smpl_t': 'PyFloat_FromDouble', |
---|
| 35 | 'uint_t': 'PyLong_FromLong', # was: 'PyInt_FromLong', |
---|
| 36 | 'fvec_t*': 'PyAubio_CFvecToArray', |
---|
| 37 | 'fmat_t*': 'PyAubio_CFmatToArray', |
---|
| 38 | } |
---|
| 39 | |
---|
| 40 | pytoaubio_fn = { |
---|
| 41 | 'fvec_t*': 'PyAubio_ArrayToCFvec', |
---|
[92a8800] | 42 | 'cvec_t*': 'PyAubio_PyCvecToCCvec', |
---|
[a7f398d] | 43 | #'fmat_t*': 'PyAubio_ArrayToCFmat', |
---|
[ccb9fb5] | 44 | } |
---|
| 45 | |
---|
| 46 | newfromtype_fn = { |
---|
[21e8408] | 47 | 'fvec_t*': 'new_py_fvec', |
---|
| 48 | 'fmat_t*': 'new_py_fmat', |
---|
| 49 | 'cvec_t*': 'new_py_cvec', |
---|
[ccb9fb5] | 50 | } |
---|
| 51 | |
---|
| 52 | delfromtype_fn = { |
---|
[21e8408] | 53 | 'fvec_t*': 'Py_DECREF', |
---|
| 54 | 'fmat_t*': 'Py_DECREF', |
---|
| 55 | 'cvec_t*': 'Py_DECREF', |
---|
[ccb9fb5] | 56 | } |
---|
| 57 | |
---|
| 58 | param_init = { |
---|
| 59 | 'char_t*': 'NULL', |
---|
| 60 | 'uint_t': '0', |
---|
| 61 | 'sint_t': 0, |
---|
| 62 | 'smpl_t': 0., |
---|
| 63 | 'lsmp_t': 0., |
---|
| 64 | } |
---|
| 65 | |
---|
| 66 | pyargparse_chars = { |
---|
[fbcee4f] | 67 | 'smpl_t': 'f', # if not usedouble else 'd', |
---|
[ccb9fb5] | 68 | 'uint_t': 'I', |
---|
| 69 | 'sint_t': 'I', |
---|
| 70 | 'char_t*': 's', |
---|
| 71 | 'fmat_t*': 'O', |
---|
| 72 | 'fvec_t*': 'O', |
---|
[a7f398d] | 73 | 'cvec_t*': 'O', |
---|
[ccb9fb5] | 74 | } |
---|
| 75 | |
---|
| 76 | objoutsize = { |
---|
| 77 | 'onset': '1', |
---|
| 78 | 'pitch': '1', |
---|
[8470144] | 79 | 'notes': '3', |
---|
[ccb9fb5] | 80 | 'wavetable': 'self->hop_size', |
---|
| 81 | 'sampler': 'self->hop_size', |
---|
| 82 | 'mfcc': 'self->n_coeffs', |
---|
| 83 | 'specdesc': '1', |
---|
[de63017] | 84 | 'tempo': '1', |
---|
[ccb9fb5] | 85 | 'filterbank': 'self->n_filters', |
---|
[73e068d] | 86 | 'tss': 'self->buf_size', |
---|
[af24139] | 87 | 'pitchshift': 'self->hop_size', |
---|
[60583a3] | 88 | 'dct': 'self->size', |
---|
[ccb9fb5] | 89 | } |
---|
| 90 | |
---|
[bf54364] | 91 | objinputsize = { |
---|
| 92 | 'mfcc': 'self->buf_size / 2 + 1', |
---|
| 93 | 'notes': 'self->hop_size', |
---|
| 94 | 'onset': 'self->hop_size', |
---|
| 95 | 'pitch': 'self->hop_size', |
---|
| 96 | 'sampler': 'self->hop_size', |
---|
| 97 | 'specdesc': 'self->buf_size / 2 + 1', |
---|
| 98 | 'tempo': 'self->hop_size', |
---|
| 99 | 'wavetable': 'self->hop_size', |
---|
[73e068d] | 100 | 'tss': 'self->buf_size / 2 + 1', |
---|
[af24139] | 101 | 'pitchshift': 'self->hop_size', |
---|
[bf54364] | 102 | } |
---|
| 103 | |
---|
[ccb9fb5] | 104 | def get_name(proto): |
---|
| 105 | name = proto.replace(' *', '* ').split()[1].split('(')[0] |
---|
| 106 | name = name.replace('*','') |
---|
| 107 | if name == '': raise ValueError(proto + "gave empty name") |
---|
| 108 | return name |
---|
| 109 | |
---|
| 110 | def get_return_type(proto): |
---|
| 111 | import re |
---|
| 112 | paramregex = re.compile('(\w+ ?\*?).*') |
---|
| 113 | outputs = paramregex.findall(proto) |
---|
| 114 | assert len(outputs) == 1 |
---|
| 115 | return outputs[0].replace(' ', '') |
---|
| 116 | |
---|
| 117 | def split_type(arg): |
---|
| 118 | """ arg = 'foo *name' |
---|
| 119 | return ['foo*', 'name'] """ |
---|
| 120 | l = arg.split() |
---|
[a7f398d] | 121 | type_arg = {} #'type': l[0], 'name': l[1]} |
---|
| 122 | type_arg['type'] = " ".join(l[:-1]) |
---|
| 123 | type_arg['name'] = l[-1] |
---|
| 124 | # fix up type / name |
---|
| 125 | if type_arg['name'].startswith('*'): |
---|
| 126 | # ['foo', '*name'] -> ['foo*', 'name'] |
---|
| 127 | type_arg['type'] += '*' |
---|
| 128 | type_arg['name'] = type_arg['name'][1:] |
---|
| 129 | if type_arg['type'].endswith(' *'): |
---|
| 130 | # ['foo *', 'name'] -> ['foo*', 'name'] |
---|
| 131 | type_arg['type'] = type_arg['type'].replace(' *','*') |
---|
| 132 | if type_arg['type'].startswith('const '): |
---|
| 133 | # ['foo *', 'name'] -> ['foo*', 'name'] |
---|
| 134 | type_arg['type'] = type_arg['type'].replace('const ','') |
---|
[ccb9fb5] | 135 | return type_arg |
---|
| 136 | |
---|
| 137 | def get_params(proto): |
---|
| 138 | """ get the list of parameters from a function prototype |
---|
| 139 | example: proto = "int main (int argc, char ** argv)" |
---|
| 140 | returns: ['int argc', 'char ** argv'] |
---|
| 141 | """ |
---|
| 142 | import re |
---|
[a7f398d] | 143 | paramregex = re.compile('.*\((.*)\);') |
---|
| 144 | a = paramregex.findall(proto)[0].split(', ') |
---|
| 145 | #a = [i.replace('const ', '') for i in a] |
---|
| 146 | return a |
---|
| 147 | |
---|
| 148 | def get_input_params(proto): |
---|
| 149 | a = get_params(proto) |
---|
| 150 | return [i.replace('const ', '') for i in a if (i.startswith('const ') or i.startswith('uint_t ') or i.startswith('smpl_t '))] |
---|
| 151 | |
---|
| 152 | def get_output_params(proto): |
---|
| 153 | a = get_params(proto) |
---|
| 154 | return [i for i in a if not i.startswith('const ')][1:] |
---|
[ccb9fb5] | 155 | |
---|
| 156 | def get_params_types_names(proto): |
---|
| 157 | """ get the list of parameters from a function prototype |
---|
| 158 | example: proto = "int main (int argc, char ** argv)" |
---|
| 159 | returns: [['int', 'argc'], ['char **','argv']] |
---|
| 160 | """ |
---|
[a7f398d] | 161 | a = list(map(split_type, get_params(proto))) |
---|
| 162 | #print proto, a |
---|
| 163 | #import sys; sys.exit(1) |
---|
| 164 | return a |
---|
[ccb9fb5] | 165 | |
---|
| 166 | class MappedObject(object): |
---|
| 167 | |
---|
[fbcee4f] | 168 | def __init__(self, prototypes, usedouble = False): |
---|
| 169 | if usedouble: |
---|
| 170 | pyargparse_chars['smpl_t'] = 'd' |
---|
[ccb9fb5] | 171 | self.prototypes = prototypes |
---|
| 172 | |
---|
| 173 | self.shortname = prototypes['shortname'] |
---|
| 174 | self.longname = prototypes['longname'] |
---|
| 175 | self.new_proto = prototypes['new'][0] |
---|
| 176 | self.del_proto = prototypes['del'][0] |
---|
| 177 | self.do_proto = prototypes['do'][0] |
---|
| 178 | self.input_params = get_params_types_names(self.new_proto) |
---|
[a7f398d] | 179 | self.input_params_list = "; ".join(get_input_params(self.new_proto)) |
---|
[ccb9fb5] | 180 | self.outputs = get_params_types_names(self.do_proto)[2:] |
---|
[a7f398d] | 181 | self.do_inputs = [get_params_types_names(self.do_proto)[1]] |
---|
| 182 | self.do_outputs = get_params_types_names(self.do_proto)[2:] |
---|
[21e8408] | 183 | struct_output_str = ["PyObject *{0[name]}; {1} c_{0[name]}".format(i, i['type'][:-1]) for i in self.do_outputs] |
---|
[a243d10] | 184 | if len(self.prototypes['rdo']): |
---|
| 185 | rdo_outputs = get_params_types_names(prototypes['rdo'][0])[2:] |
---|
| 186 | struct_output_str += ["PyObject *{0[name]}; {1} c_{0[name]}".format(i, i['type'][:-1]) for i in rdo_outputs] |
---|
| 187 | self.outputs += rdo_outputs |
---|
[21e8408] | 188 | self.struct_outputs = ";\n ".join(struct_output_str) |
---|
[a7f398d] | 189 | |
---|
[950a80c] | 190 | #print ("input_params: ", map(split_type, get_input_params(self.do_proto))) |
---|
| 191 | #print ("output_params", map(split_type, get_output_params(self.do_proto))) |
---|
[ccb9fb5] | 192 | |
---|
| 193 | def gen_code(self): |
---|
| 194 | out = "" |
---|
[ce79a9e] | 195 | try: |
---|
| 196 | out += self.gen_struct() |
---|
| 197 | out += self.gen_doc() |
---|
| 198 | out += self.gen_new() |
---|
| 199 | out += self.gen_init() |
---|
| 200 | out += self.gen_del() |
---|
| 201 | out += self.gen_do() |
---|
[c96e6c0] | 202 | if len(self.prototypes['rdo']): |
---|
| 203 | self.do_proto = self.prototypes['rdo'][0] |
---|
| 204 | self.do_inputs = [get_params_types_names(self.do_proto)[1]] |
---|
| 205 | self.do_outputs = get_params_types_names(self.do_proto)[2:] |
---|
| 206 | out += self.gen_do(method='rdo') |
---|
[ce79a9e] | 207 | out += self.gen_memberdef() |
---|
| 208 | out += self.gen_set() |
---|
| 209 | out += self.gen_get() |
---|
| 210 | out += self.gen_methodef() |
---|
| 211 | out += self.gen_typeobject() |
---|
| 212 | except Exception as e: |
---|
| 213 | print ("Failed generating code for", self.shortname) |
---|
| 214 | raise |
---|
[ccb9fb5] | 215 | return out |
---|
| 216 | |
---|
| 217 | def gen_struct(self): |
---|
| 218 | out = """ |
---|
| 219 | // {shortname} structure |
---|
| 220 | typedef struct{{ |
---|
| 221 | PyObject_HEAD |
---|
| 222 | // pointer to aubio object |
---|
| 223 | {longname} *o; |
---|
| 224 | // input parameters |
---|
| 225 | {input_params_list}; |
---|
[a7f398d] | 226 | // do input vectors |
---|
| 227 | {do_inputs_list}; |
---|
[ccb9fb5] | 228 | // output results |
---|
[21e8408] | 229 | {struct_outputs}; |
---|
[ccb9fb5] | 230 | }} Py_{shortname}; |
---|
| 231 | """ |
---|
[569b363] | 232 | # fmat_t* / fvec_t* / cvec_t* inputs -> full fvec_t /.. struct in Py_{shortname} |
---|
| 233 | 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') |
---|
| 234 | return out.format(do_inputs_list = do_inputs_list, **self.__dict__) |
---|
[ccb9fb5] | 235 | |
---|
| 236 | def gen_doc(self): |
---|
[6342fd1] | 237 | sig = [] |
---|
| 238 | for p in self.input_params: |
---|
| 239 | name = p['name'] |
---|
| 240 | defval = aubiodefvalue[name].replace('"','\\\"') |
---|
| 241 | sig.append("{name}={defval}".format(defval=defval, name=name)) |
---|
[ccb9fb5] | 242 | out = """ |
---|
[6342fd1] | 243 | #ifndef PYAUBIO_{shortname}_doc |
---|
| 244 | #define PYAUBIO_{shortname}_doc "{shortname}({sig})" |
---|
| 245 | #endif /* PYAUBIO_{shortname}_doc */ |
---|
| 246 | |
---|
| 247 | static char Py_{shortname}_doc[] = "" |
---|
| 248 | PYAUBIO_{shortname}_doc |
---|
| 249 | ""; |
---|
[a7f398d] | 250 | """ |
---|
[6342fd1] | 251 | return out.format(sig=', '.join(sig), **self.__dict__) |
---|
[ccb9fb5] | 252 | |
---|
| 253 | def gen_new(self): |
---|
| 254 | out = """ |
---|
| 255 | // new {shortname} |
---|
| 256 | static PyObject * |
---|
| 257 | Py_{shortname}_new (PyTypeObject * pytype, PyObject * args, PyObject * kwds) |
---|
| 258 | {{ |
---|
| 259 | Py_{shortname} *self; |
---|
| 260 | """.format(**self.__dict__) |
---|
| 261 | params = self.input_params |
---|
| 262 | for p in params: |
---|
| 263 | out += """ |
---|
| 264 | {type} {name} = {defval};""".format(defval = param_init[p['type']], **p) |
---|
| 265 | plist = ", ".join(["\"%s\"" % p['name'] for p in params]) |
---|
| 266 | out += """ |
---|
| 267 | static char *kwlist[] = {{ {plist}, NULL }};""".format(plist = plist) |
---|
| 268 | argchars = "".join([pyargparse_chars[p['type']] for p in params]) |
---|
| 269 | arglist = ", ".join(["&%s" % p['name'] for p in params]) |
---|
| 270 | out += """ |
---|
| 271 | if (!PyArg_ParseTupleAndKeywords (args, kwds, "|{argchars}", kwlist, |
---|
| 272 | {arglist})) {{ |
---|
| 273 | return NULL; |
---|
| 274 | }} |
---|
| 275 | """.format(argchars = argchars, arglist = arglist) |
---|
| 276 | out += """ |
---|
| 277 | self = (Py_{shortname} *) pytype->tp_alloc (pytype, 0); |
---|
| 278 | if (self == NULL) {{ |
---|
| 279 | return NULL; |
---|
| 280 | }} |
---|
| 281 | """.format(**self.__dict__) |
---|
| 282 | params = self.input_params |
---|
| 283 | for p in params: |
---|
[a7f398d] | 284 | out += self.check_valid(p) |
---|
[ccb9fb5] | 285 | out += """ |
---|
| 286 | return (PyObject *)self; |
---|
| 287 | } |
---|
| 288 | """ |
---|
| 289 | return out |
---|
| 290 | |
---|
| 291 | def check_valid(self, p): |
---|
| 292 | if p['type'] == 'uint_t': |
---|
| 293 | return self.check_valid_uint(p) |
---|
| 294 | if p['type'] == 'char_t*': |
---|
| 295 | return self.check_valid_char(p) |
---|
[af24139] | 296 | if p['type'] == 'smpl_t': |
---|
| 297 | return self.check_valid_smpl(p) |
---|
[ccb9fb5] | 298 | else: |
---|
| 299 | print ("ERROR, no idea how to check %s for validity" % p['type']) |
---|
| 300 | |
---|
| 301 | def check_valid_uint(self, p): |
---|
| 302 | name = p['name'] |
---|
| 303 | return """ |
---|
| 304 | self->{name} = {defval}; |
---|
| 305 | if ((sint_t){name} > 0) {{ |
---|
| 306 | self->{name} = {name}; |
---|
| 307 | }} else if ((sint_t){name} < 0) {{ |
---|
| 308 | PyErr_SetString (PyExc_ValueError, "can not use negative value for {name}"); |
---|
| 309 | return NULL; |
---|
| 310 | }} |
---|
| 311 | """.format(defval = aubiodefvalue[name], name = name) |
---|
| 312 | |
---|
| 313 | def check_valid_char(self, p): |
---|
| 314 | name = p['name'] |
---|
| 315 | return """ |
---|
| 316 | self->{name} = {defval}; |
---|
[b71e8b6] | 317 | if ({name} != NULL) {{ |
---|
| 318 | self->{name} = {name}; |
---|
| 319 | }} |
---|
[af24139] | 320 | """.format(defval = aubiodefvalue[name], name = name) |
---|
| 321 | |
---|
| 322 | def check_valid_smpl(self, p): |
---|
| 323 | name = p['name'] |
---|
| 324 | return """ |
---|
| 325 | self->{name} = {defval}; |
---|
[f9cca9c] | 326 | if ({name} != 0.) {{ |
---|
[ccb9fb5] | 327 | self->{name} = {name}; |
---|
| 328 | }} |
---|
| 329 | """.format(defval = aubiodefvalue[name], name = name) |
---|
| 330 | |
---|
| 331 | def gen_init(self): |
---|
| 332 | out = """ |
---|
| 333 | // init {shortname} |
---|
| 334 | static int |
---|
| 335 | Py_{shortname}_init (Py_{shortname} * self, PyObject * args, PyObject * kwds) |
---|
| 336 | {{ |
---|
| 337 | """.format(**self.__dict__) |
---|
| 338 | new_name = get_name(self.new_proto) |
---|
| 339 | new_params = ", ".join(["self->%s" % s['name'] for s in self.input_params]) |
---|
| 340 | out += """ |
---|
| 341 | self->o = {new_name}({new_params}); |
---|
| 342 | """.format(new_name = new_name, new_params = new_params) |
---|
| 343 | paramchars = "%s" |
---|
| 344 | paramvals = "self->method" |
---|
| 345 | out += """ |
---|
| 346 | // return -1 and set error string on failure |
---|
| 347 | if (self->o == NULL) {{ |
---|
[6a72ff0] | 348 | PyErr_Format (PyExc_RuntimeError, "failed creating {shortname}"); |
---|
[ccb9fb5] | 349 | return -1; |
---|
| 350 | }} |
---|
| 351 | """.format(paramchars = paramchars, paramvals = paramvals, **self.__dict__) |
---|
| 352 | output_create = "" |
---|
| 353 | for o in self.outputs: |
---|
| 354 | output_create += """ |
---|
| 355 | self->{name} = {create_fn}({output_size});""".format(name = o['name'], create_fn = newfromtype_fn[o['type']], output_size = objoutsize[self.shortname]) |
---|
| 356 | out += """ |
---|
| 357 | // TODO get internal params after actual object creation? |
---|
| 358 | """ |
---|
| 359 | out += """ |
---|
| 360 | // create outputs{output_create} |
---|
| 361 | """.format(output_create = output_create) |
---|
| 362 | out += """ |
---|
| 363 | return 0; |
---|
| 364 | } |
---|
| 365 | """ |
---|
| 366 | return out |
---|
| 367 | |
---|
| 368 | def gen_memberdef(self): |
---|
| 369 | out = """ |
---|
| 370 | static PyMemberDef Py_{shortname}_members[] = {{ |
---|
| 371 | """.format(**self.__dict__) |
---|
| 372 | for p in get_params_types_names(self.new_proto): |
---|
| 373 | tmp = " {{\"{name}\", {ttype}, offsetof (Py_{shortname}, {name}), READONLY, \"TODO documentation\"}},\n" |
---|
| 374 | pytype = member_types[p['type']] |
---|
| 375 | out += tmp.format(name = p['name'], ttype = pytype, shortname = self.shortname) |
---|
| 376 | out += """ {NULL}, // sentinel |
---|
| 377 | }; |
---|
| 378 | """ |
---|
| 379 | return out |
---|
| 380 | |
---|
| 381 | def gen_del(self): |
---|
| 382 | out = """ |
---|
| 383 | // del {shortname} |
---|
| 384 | static void |
---|
| 385 | Py_{shortname}_del (Py_{shortname} * self, PyObject * unused) |
---|
| 386 | {{""".format(**self.__dict__) |
---|
[a7f398d] | 387 | for input_param in self.do_inputs: |
---|
[569b363] | 388 | if input_param['type'] == 'fmat_t *': |
---|
| 389 | out += """ |
---|
[6a72ff0] | 390 | free(self->{0[name]}.data);""".format(input_param) |
---|
[ccb9fb5] | 391 | for o in self.outputs: |
---|
| 392 | name = o['name'] |
---|
| 393 | del_out = delfromtype_fn[o['type']] |
---|
| 394 | out += """ |
---|
[6a72ff0] | 395 | if (self->{name}) {{ |
---|
| 396 | {del_out}(self->{name}); |
---|
| 397 | }}""".format(del_out = del_out, name = name) |
---|
[ccb9fb5] | 398 | del_fn = get_name(self.del_proto) |
---|
| 399 | out += """ |
---|
[6a72ff0] | 400 | if (self->o) {{ |
---|
| 401 | {del_fn}(self->o); |
---|
| 402 | }} |
---|
| 403 | Py_TYPE(self)->tp_free((PyObject *) self); |
---|
[ccb9fb5] | 404 | }} |
---|
| 405 | """.format(del_fn = del_fn) |
---|
| 406 | return out |
---|
| 407 | |
---|
[c96e6c0] | 408 | def gen_do(self, method = 'do'): |
---|
[ccb9fb5] | 409 | out = """ |
---|
| 410 | // do {shortname} |
---|
| 411 | static PyObject* |
---|
[c96e6c0] | 412 | Pyaubio_{shortname}_{method} (Py_{shortname} * self, PyObject * args) |
---|
[a2ed169] | 413 | {{""".format(method = method, **self.__dict__) |
---|
[a7f398d] | 414 | input_params = self.do_inputs |
---|
| 415 | output_params = self.do_outputs |
---|
| 416 | #print input_params |
---|
| 417 | #print output_params |
---|
[73e068d] | 418 | out += """ |
---|
| 419 | PyObject *outputs;""" |
---|
[a7f398d] | 420 | for input_param in input_params: |
---|
| 421 | out += """ |
---|
[bbc62b5] | 422 | PyObject *py_{0};""".format(input_param['name']) |
---|
[a7f398d] | 423 | refs = ", ".join(["&py_%s" % p['name'] for p in input_params]) |
---|
| 424 | pyparamtypes = "".join([pyargparse_chars[p['type']] for p in input_params]) |
---|
| 425 | out += """ |
---|
| 426 | if (!PyArg_ParseTuple (args, "{pyparamtypes}", {refs})) {{ |
---|
[ccb9fb5] | 427 | return NULL; |
---|
[a7f398d] | 428 | }}""".format(refs = refs, pyparamtypes = pyparamtypes, **self.__dict__) |
---|
[21e8408] | 429 | for input_param in input_params: |
---|
[a7f398d] | 430 | out += """ |
---|
[21e8408] | 431 | |
---|
[569b363] | 432 | if (!{pytoaubio}(py_{0[name]}, &(self->{0[name]}))) {{ |
---|
[ccb9fb5] | 433 | return NULL; |
---|
[a7f398d] | 434 | }}""".format(input_param, pytoaubio = pytoaubio_fn[input_param['type']]) |
---|
[bf54364] | 435 | if self.shortname in objinputsize: |
---|
| 436 | out += """ |
---|
| 437 | |
---|
| 438 | if (self->{0[name]}.length != {expected_size}) {{ |
---|
| 439 | PyErr_Format (PyExc_ValueError, |
---|
| 440 | "input size of {shortname} should be %d, not %d", |
---|
| 441 | {expected_size}, self->{0[name]}.length); |
---|
| 442 | return NULL; |
---|
| 443 | }}""".format(input_param, expected_size = objinputsize[self.shortname], **self.__dict__) |
---|
| 444 | else: |
---|
| 445 | out += """ |
---|
[21e8408] | 446 | |
---|
| 447 | // TODO: check input sizes""" |
---|
| 448 | for output_param in output_params: |
---|
| 449 | out += """ |
---|
| 450 | |
---|
| 451 | Py_INCREF(self->{0[name]}); |
---|
| 452 | if (!{pytoaubio}(self->{0[name]}, &(self->c_{0[name]}))) {{ |
---|
| 453 | return NULL; |
---|
| 454 | }}""".format(output_param, pytoaubio = pytoaubio_fn[output_param['type']]) |
---|
[a7f398d] | 455 | do_fn = get_name(self.do_proto) |
---|
[569b363] | 456 | inputs = ", ".join(['&(self->'+p['name']+')' for p in input_params]) |
---|
[21e8408] | 457 | c_outputs = ", ".join(["&(self->c_%s)" % p['name'] for p in self.do_outputs]) |
---|
[a7f398d] | 458 | outputs = ", ".join(["self->%s" % p['name'] for p in self.do_outputs]) |
---|
| 459 | out += """ |
---|
[ccb9fb5] | 460 | |
---|
[21e8408] | 461 | {do_fn}(self->o, {inputs}, {c_outputs}); |
---|
[73e068d] | 462 | """.format( |
---|
| 463 | do_fn = do_fn, |
---|
| 464 | inputs = inputs, c_outputs = c_outputs, |
---|
| 465 | ) |
---|
| 466 | if len(self.do_outputs) > 1: |
---|
| 467 | out += """ |
---|
[31c6010] | 468 | outputs = PyTuple_New({:d});""".format(len(self.do_outputs)) |
---|
[73e068d] | 469 | for i, p in enumerate(self.do_outputs): |
---|
| 470 | out += """ |
---|
| 471 | PyTuple_SetItem( outputs, {i}, self->{p[name]});""".format(i = i, p = p) |
---|
| 472 | else: |
---|
| 473 | out += """ |
---|
| 474 | outputs = self->{p[name]};""".format(p = self.do_outputs[0]) |
---|
| 475 | out += """ |
---|
[ccb9fb5] | 476 | |
---|
[73e068d] | 477 | return outputs; |
---|
[ccb9fb5] | 478 | }} |
---|
[a7f398d] | 479 | """.format( |
---|
[73e068d] | 480 | outputs = outputs, |
---|
[a7f398d] | 481 | ) |
---|
| 482 | return out |
---|
[ccb9fb5] | 483 | |
---|
| 484 | def gen_set(self): |
---|
| 485 | out = """ |
---|
| 486 | // {shortname} setters |
---|
| 487 | """.format(**self.__dict__) |
---|
| 488 | for set_param in self.prototypes['set']: |
---|
[195e22e4] | 489 | params = get_params_types_names(set_param)[1:] |
---|
| 490 | param = self.shortname.split('_set_')[-1] |
---|
| 491 | paramdecls = "".join([""" |
---|
| 492 | {0} {1};""".format(p['type'], p['name']) for p in params]) |
---|
[ccb9fb5] | 493 | method_name = get_name(set_param) |
---|
| 494 | param = method_name.split('aubio_'+self.shortname+'_set_')[-1] |
---|
[195e22e4] | 495 | refs = ", ".join(["&%s" % p['name'] for p in params]) |
---|
| 496 | paramlist = ", ".join(["%s" % p['name'] for p in params]) |
---|
[21067f9] | 497 | if len(params): |
---|
| 498 | paramlist = "," + paramlist |
---|
[195e22e4] | 499 | pyparamtypes = ''.join([pyargparse_chars[p['type']] for p in params]) |
---|
[ccb9fb5] | 500 | out += """ |
---|
| 501 | static PyObject * |
---|
| 502 | Pyaubio_{shortname}_set_{param} (Py_{shortname} *self, PyObject *args) |
---|
| 503 | {{ |
---|
| 504 | uint_t err = 0; |
---|
[195e22e4] | 505 | {paramdecls} |
---|
[21067f9] | 506 | """.format(param = param, paramdecls = paramdecls, **self.__dict__) |
---|
| 507 | |
---|
| 508 | if len(refs) and len(pyparamtypes): |
---|
| 509 | out += """ |
---|
[ccb9fb5] | 510 | |
---|
[195e22e4] | 511 | if (!PyArg_ParseTuple (args, "{pyparamtypes}", {refs})) {{ |
---|
[ccb9fb5] | 512 | return NULL; |
---|
| 513 | }} |
---|
[21067f9] | 514 | """.format(pyparamtypes = pyparamtypes, refs = refs) |
---|
| 515 | |
---|
| 516 | out += """ |
---|
| 517 | err = aubio_{shortname}_set_{param} (self->o {paramlist}); |
---|
[ccb9fb5] | 518 | |
---|
| 519 | if (err > 0) {{ |
---|
[9b23815e] | 520 | if (PyErr_Occurred() == NULL) {{ |
---|
| 521 | PyErr_SetString (PyExc_ValueError, "error running aubio_{shortname}_set_{param}"); |
---|
| 522 | }} else {{ |
---|
| 523 | // change the RuntimeError into ValueError |
---|
| 524 | PyObject *type, *value, *traceback; |
---|
| 525 | PyErr_Fetch(&type, &value, &traceback); |
---|
[2244f00] | 526 | Py_XDECREF(type); |
---|
| 527 | type = PyExc_ValueError; |
---|
| 528 | Py_XINCREF(type); |
---|
| 529 | PyErr_Restore(type, value, traceback); |
---|
[9b23815e] | 530 | }} |
---|
[ccb9fb5] | 531 | return NULL; |
---|
| 532 | }} |
---|
| 533 | Py_RETURN_NONE; |
---|
| 534 | }} |
---|
[195e22e4] | 535 | """.format(param = param, refs = refs, paramdecls = paramdecls, |
---|
| 536 | pyparamtypes = pyparamtypes, paramlist = paramlist, **self.__dict__) |
---|
[ccb9fb5] | 537 | return out |
---|
| 538 | |
---|
| 539 | def gen_get(self): |
---|
| 540 | out = """ |
---|
| 541 | // {shortname} getters |
---|
| 542 | """.format(**self.__dict__) |
---|
| 543 | for method in self.prototypes['get']: |
---|
| 544 | params = get_params_types_names(method) |
---|
| 545 | method_name = get_name(method) |
---|
| 546 | assert len(params) == 1, \ |
---|
| 547 | "get method has more than one parameter %s" % params |
---|
| 548 | param = method_name.split('aubio_'+self.shortname+'_get_')[-1] |
---|
| 549 | paramtype = get_return_type(method) |
---|
| 550 | ptypeconv = pyfromtype_fn[paramtype] |
---|
| 551 | out += """ |
---|
| 552 | static PyObject * |
---|
| 553 | Pyaubio_{shortname}_get_{param} (Py_{shortname} *self, PyObject *unused) |
---|
| 554 | {{ |
---|
| 555 | {ptype} {param} = aubio_{shortname}_get_{param} (self->o); |
---|
| 556 | return (PyObject *){ptypeconv} ({param}); |
---|
| 557 | }} |
---|
| 558 | """.format(param = param, ptype = paramtype, ptypeconv = ptypeconv, |
---|
| 559 | **self.__dict__) |
---|
| 560 | return out |
---|
| 561 | |
---|
| 562 | def gen_methodef(self): |
---|
| 563 | out = """ |
---|
| 564 | static PyMethodDef Py_{shortname}_methods[] = {{""".format(**self.__dict__) |
---|
| 565 | for m in self.prototypes['set']: |
---|
| 566 | name = get_name(m) |
---|
| 567 | shortname = name.replace('aubio_%s_' % self.shortname, '') |
---|
| 568 | out += """ |
---|
| 569 | {{"{shortname}", (PyCFunction) Py{name}, |
---|
| 570 | METH_VARARGS, ""}},""".format(name = name, shortname = shortname) |
---|
| 571 | for m in self.prototypes['get']: |
---|
| 572 | name = get_name(m) |
---|
| 573 | shortname = name.replace('aubio_%s_' % self.shortname, '') |
---|
| 574 | out += """ |
---|
| 575 | {{"{shortname}", (PyCFunction) Py{name}, |
---|
| 576 | METH_NOARGS, ""}},""".format(name = name, shortname = shortname) |
---|
[c96e6c0] | 577 | for m in self.prototypes['rdo']: |
---|
| 578 | name = get_name(m) |
---|
| 579 | shortname = name.replace('aubio_%s_' % self.shortname, '') |
---|
| 580 | out += """ |
---|
| 581 | {{"{shortname}", (PyCFunction) Py{name}, |
---|
| 582 | METH_VARARGS, ""}},""".format(name = name, shortname = shortname) |
---|
[ccb9fb5] | 583 | out += """ |
---|
| 584 | {NULL} /* sentinel */ |
---|
| 585 | }; |
---|
| 586 | """ |
---|
| 587 | return out |
---|
| 588 | |
---|
| 589 | def gen_typeobject(self): |
---|
| 590 | return """ |
---|
| 591 | PyTypeObject Py_{shortname}Type = {{ |
---|
| 592 | //PyObject_HEAD_INIT (NULL) |
---|
| 593 | //0, |
---|
| 594 | PyVarObject_HEAD_INIT (NULL, 0) |
---|
| 595 | "aubio.{shortname}", |
---|
| 596 | sizeof (Py_{shortname}), |
---|
| 597 | 0, |
---|
| 598 | (destructor) Py_{shortname}_del, |
---|
| 599 | 0, |
---|
| 600 | 0, |
---|
| 601 | 0, |
---|
| 602 | 0, |
---|
| 603 | 0, |
---|
| 604 | 0, |
---|
| 605 | 0, |
---|
| 606 | 0, |
---|
| 607 | 0, |
---|
[c96e6c0] | 608 | (ternaryfunc)Pyaubio_{shortname}_do, |
---|
[ccb9fb5] | 609 | 0, |
---|
| 610 | 0, |
---|
| 611 | 0, |
---|
| 612 | 0, |
---|
| 613 | Py_TPFLAGS_DEFAULT, |
---|
| 614 | Py_{shortname}_doc, |
---|
| 615 | 0, |
---|
| 616 | 0, |
---|
| 617 | 0, |
---|
| 618 | 0, |
---|
| 619 | 0, |
---|
| 620 | 0, |
---|
| 621 | Py_{shortname}_methods, |
---|
| 622 | Py_{shortname}_members, |
---|
| 623 | 0, |
---|
| 624 | 0, |
---|
| 625 | 0, |
---|
| 626 | 0, |
---|
| 627 | 0, |
---|
| 628 | 0, |
---|
| 629 | (initproc) Py_{shortname}_init, |
---|
| 630 | 0, |
---|
| 631 | Py_{shortname}_new, |
---|
[0e70ef9] | 632 | 0, |
---|
| 633 | 0, |
---|
| 634 | 0, |
---|
| 635 | 0, |
---|
| 636 | 0, |
---|
| 637 | 0, |
---|
| 638 | 0, |
---|
| 639 | 0, |
---|
| 640 | 0, |
---|
[ccb9fb5] | 641 | }}; |
---|
| 642 | """.format(**self.__dict__) |
---|