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