source: python/lib/generator.py @ 52ca8a3

feature/autosinkfeature/constantqfeature/pitchshiftfeature/pydocstringsfeature/timestretchpitchshiftsamplertimestretchyinfft+
Last change on this file since 52ca8a3 was 52ca8a3, checked in by Paul Brossier <piem@piem.org>, 6 years ago

src/io/sink_wavwrite.c: add native basic wav writer

  • Property mode set to 100755
File size: 7.0 KB
Line 
1#! /usr/bin/python
2
3""" This file generates a c file from a list of cpp prototypes. """
4
5import os, sys, shutil
6from gen_pyobject import write_msg, gen_new_init, gen_do, gen_members, gen_methods, gen_finish
7
8def get_cpp_objects():
9
10  cpp_output = [l.strip() for l in os.popen('cpp -DAUBIO_UNSTABLE=1 -I../build/src ../src/aubio.h').readlines()]
11
12  cpp_output = filter(lambda y: len(y) > 1, cpp_output)
13  cpp_output = filter(lambda y: not y.startswith('#'), cpp_output)
14
15  i = 1
16  while 1:
17      if i >= len(cpp_output): break
18      if cpp_output[i-1].endswith(',') or cpp_output[i-1].endswith('{') or cpp_output[i].startswith('}'):
19          cpp_output[i] = cpp_output[i-1] + ' ' + cpp_output[i]
20          cpp_output.pop(i-1)
21      else:
22          i += 1
23
24  typedefs = filter(lambda y: y.startswith ('typedef struct _aubio'), cpp_output)
25
26  cpp_objects = [a.split()[3][:-1] for a in typedefs]
27
28  return cpp_output, cpp_objects
29
30def generate_object_files(output_path):
31  if os.path.isdir(output_path): shutil.rmtree(output_path)
32  os.mkdir(output_path)
33
34  generated_objects = []
35  cpp_output, cpp_objects = get_cpp_objects()
36  skip_objects = [
37      # already in ext/
38      'fft',
39      'pvoc',
40      'filter',
41      'filterbank',
42      #'resampler',
43      # AUBIO_UNSTABLE
44      'hist',
45      'parameter',
46      'scale',
47      'beattracking',
48      'resampler',
49      'sndfile',
50      'peakpicker',
51      'pitchfcomb',
52      'pitchmcomb',
53      'pitchschmitt',
54      'pitchspecacf',
55      'pitchyin',
56      'pitchyinfft',
57      'sink',
58      'sink_apple_audio',
59      'sink_sndfile',
60      'sink_wavwrite',
61      'source',
62      'source_apple_audio',
63      'source_sndfile',
64      'source_avcodec',
65      'source_wavread',
66      #'sampler',
67      'audio_unit',
68      ]
69
70  write_msg("-- INFO: %d objects in total" % len(cpp_objects))
71
72  for this_object in cpp_objects:
73      lint = 0
74
75      if this_object[-2:] == '_t':
76          object_name = this_object[:-2]
77      else:
78          object_name = this_object
79          write_msg("-- WARNING: %s does not end in _t" % this_object)
80
81      if object_name[:len('aubio_')] != 'aubio_':
82          write_msg("-- WARNING: %s does not start n aubio_" % this_object)
83
84      write_msg("-- INFO: looking at", object_name)
85      object_methods = filter(lambda x: this_object in x, cpp_output)
86      object_methods = [a.strip() for a in object_methods]
87      object_methods = filter(lambda x: not x.startswith('typedef'), object_methods)
88      #for method in object_methods:
89      #    write_msg(method)
90      new_methods = filter(lambda x: 'new_'+object_name in x, object_methods)
91      if len(new_methods) > 1:
92          write_msg("-- WARNING: more than one new method for", object_name)
93          for method in new_methods:
94              write_msg(method)
95      elif len(new_methods) < 1:
96          write_msg("-- WARNING: no new method for", object_name)
97      elif 0:
98          for method in new_methods:
99              write_msg(method)
100
101      del_methods = filter(lambda x: 'del_'+object_name in x, object_methods)
102      if len(del_methods) > 1:
103          write_msg("-- WARNING: more than one del method for", object_name)
104          for method in del_methods:
105              write_msg(method)
106      elif len(del_methods) < 1:
107          write_msg("-- WARNING: no del method for", object_name)
108
109      do_methods = filter(lambda x: object_name+'_do' in x, object_methods)
110      if len(do_methods) > 1:
111          pass
112          #write_msg("-- WARNING: more than one do method for", object_name)
113          #for method in do_methods:
114          #    write_msg(method)
115      elif len(do_methods) < 1:
116          write_msg("-- WARNING: no do method for", object_name)
117      elif 0:
118          for method in do_methods:
119              write_msg(method)
120
121      # check do methods return void
122      for method in do_methods:
123          if (method.split()[0] != 'void'):
124              write_msg("-- ERROR: _do method does not return void:", method )
125
126      get_methods = filter(lambda x: object_name+'_get_' in x, object_methods)
127
128      set_methods = filter(lambda x: object_name+'_set_' in x, object_methods)
129      for method in set_methods:
130          if (method.split()[0] != 'uint_t'):
131              write_msg("-- ERROR: _set method does not return uint_t:", method )
132
133      other_methods = filter(lambda x: x not in new_methods, object_methods)
134      other_methods = filter(lambda x: x not in del_methods, other_methods)
135      other_methods = filter(lambda x: x not in    do_methods, other_methods)
136      other_methods = filter(lambda x: x not in get_methods, other_methods)
137      other_methods = filter(lambda x: x not in set_methods, other_methods)
138
139      if len(other_methods) > 0:
140          write_msg("-- WARNING: some methods for", object_name, "were unidentified")
141          for method in other_methods:
142              write_msg(method)
143
144
145      # generate this_object
146      short_name = object_name[len('aubio_'):]
147      if short_name in skip_objects:
148              write_msg("-- INFO: skipping object", short_name )
149              continue
150      if 1: #try:
151          s = gen_new_init(new_methods[0], short_name)
152          s += gen_do(do_methods[0], short_name)
153          s += gen_members(new_methods[0], short_name)
154          s += gen_methods(get_methods, set_methods, short_name)
155          s += gen_finish(short_name)
156          generated_filepath = os.path.join(output_path,'gen-'+short_name+'.c')
157          fd = open(generated_filepath, 'w')
158          fd.write(s)
159      #except Exception, e:
160      #        write_msg("-- ERROR:", type(e), str(e), "in", short_name)
161      #        continue
162      generated_objects += [this_object]
163
164  s = """// generated list of objects created with generator.py
165
166"""
167
168  types_ready = []
169  for each in generated_objects:
170      types_ready.append("  PyType_Ready (&Py_%sType) < 0" % \
171              each.replace('aubio_','').replace('_t','') )
172
173  s = """// generated list of objects created with generator.py
174
175#include "aubio-generated.h"
176"""
177
178  s += """
179int generated_types_ready (void)
180{
181  return (
182"""
183  s += ('\n     ||').join(types_ready)
184  s += """);
185}
186"""
187
188  s += """
189void add_generated_objects ( PyObject *m )
190{"""
191  for each in generated_objects:
192    s += """
193  Py_INCREF (&Py_%(name)sType);
194  PyModule_AddObject (m, "%(name)s", (PyObject *) & Py_%(name)sType);""" % \
195          { 'name': ( each.replace('aubio_','').replace('_t','') ) }
196
197  s += """
198}"""
199
200  fd = open(os.path.join(output_path,'aubio-generated.c'), 'w')
201  fd.write(s)
202
203  s = """// generated list of objects created with generator.py
204
205#include <Python.h>
206
207"""
208
209  for each in generated_objects:
210      s += "extern PyTypeObject Py_%sType;\n" % \
211              each.replace('aubio_','').replace('_t','')
212
213  s+= "int generated_objects ( void );\n"
214  s+= "void add_generated_objects( PyObject *m );\n"
215
216  fd = open(os.path.join(output_path,'aubio-generated.h'), 'w')
217  fd.write(s)
218
219  from os import listdir
220  generated_files = listdir(output_path)
221  generated_files = filter(lambda x: x.endswith('.c'), generated_files)
222  generated_files = [output_path+'/'+f for f in generated_files]
223  return generated_files
224
225if __name__ == '__main__':
226  generate_object_files('gen')
Note: See TracBrowser for help on using the repository browser.