History

Merge branch 'master' into yinfast

Paul Brossier committed 9 years ago

Commit 9fa0ed12 parents 482641d ddea34b7 files · +405 −228Browse files

Showing the changes to python (2 of 7 files). Show all

Unified · Split

2 files
  1. python/lib/aubio/cmd.py +1 −1
  2. python/lib/gen_external.py +140 −80
python/lib/aubio/cmd.py+1−1
@@ -187,7 +187,7 @@ def timefunc(mode): · 186 unmodified lines
187 elif mode == 'samples':187 elif mode == 'samples':
188 return samples2samples188 return samples2samples
189 else:189 else:
190 raise ValueError('invalid time format %s' % mode)190 raise ValueError("invalid time format '%s'" % mode)
191 191
192# definition of processing classes192# definition of processing classes
193 193
python/lib/gen_external.py+140−80
@@ -1,5 +1,8 @@
1import distutils.ccompiler1import distutils.ccompiler
2import sys, os, subprocess, glob2import sys
3import os
4import subprocess
5import glob
3 6
4header = os.path.join('src', 'aubio.h')7header = os.path.join('src', 'aubio.h')
5output_path = os.path.join('python', 'gen')8output_path = os.path.join('python', 'gen')
@@ -8,40 +11,41 @@ source_header = """// this file is generated! do not modify · 2 unmodified lines
8#include "aubio-types.h"11#include "aubio-types.h"
9"""12"""
10 13
11skip_objects = [14default_skip_objects = [
12 # already in ext/15 # already in ext/
13 'fft',16 'fft',
14 'pvoc',17 'pvoc',
15 'filter',18 'filter',
16 'filterbank',19 'filterbank',
17 # AUBIO_UNSTABLE20 # AUBIO_UNSTABLE
18 'hist',21 'hist',
19 'parameter',22 'parameter',
20 'scale',23 'scale',
21 'beattracking',24 'beattracking',
22 'resampler',25 'resampler',
23 'peakpicker',26 'peakpicker',
24 'pitchfcomb',27 'pitchfcomb',
25 'pitchmcomb',28 'pitchmcomb',
26 'pitchschmitt',29 'pitchschmitt',
27 'pitchspecacf',30 'pitchspecacf',
28 'pitchyin',31 'pitchyin',
29 'pitchyinfft',32 'pitchyinfft',
30 'pitchyinfast',33 'pitchyinfast',
31 'sink',34 'sink',
32 'sink_apple_audio',35 'sink_apple_audio',
33 'sink_sndfile',36 'sink_sndfile',
34 'sink_wavwrite',37 'sink_wavwrite',
35 #'mfcc',38 #'mfcc',
36 'source',39 'source',
37 'source_apple_audio',40 'source_apple_audio',
38 'source_sndfile',41 'source_sndfile',
39 'source_avcodec',42 'source_avcodec',
40 'source_wavread',43 'source_wavread',
41 #'sampler',44 #'sampler',
42 'audio_unit',45 'audio_unit',
43 'spectral_whitening',46 'spectral_whitening',
44 ]47]
48
45 49
46def get_preprocessor():50def get_preprocessor():
47 # findout which compiler to use51 # findout which compiler to use
@@ -60,12 +64,12 @@ def get_preprocessor(): · 12 unmodified lines
60 print("Warning: failed initializing compiler ({:s})".format(repr(e)))64 print("Warning: failed initializing compiler ({:s})".format(repr(e)))
61 65
62 cpp_cmd = None66 cpp_cmd = None
63 if hasattr(compiler, 'preprocessor'): # for unixccompiler67 if hasattr(compiler, 'preprocessor'): # for unixccompiler
64 cpp_cmd = compiler.preprocessor68 cpp_cmd = compiler.preprocessor
65 elif hasattr(compiler, 'compiler'): # for ccompiler69 elif hasattr(compiler, 'compiler'): # for ccompiler
66 cpp_cmd = compiler.compiler.split()70 cpp_cmd = compiler.compiler.split()
67 cpp_cmd += ['-E']71 cpp_cmd += ['-E']
68 elif hasattr(compiler, 'cc'): # for msvccompiler72 elif hasattr(compiler, 'cc'): # for msvccompiler
69 cpp_cmd = compiler.cc.split()73 cpp_cmd = compiler.cc.split()
70 cpp_cmd += ['-E']74 cpp_cmd += ['-E']
71 75
@@ -73,10 +77,13 @@ def get_preprocessor(): · 1 unmodified line
73 print("Warning: could not guess preprocessor, using env's CC")77 print("Warning: could not guess preprocessor, using env's CC")
74 cpp_cmd = os.environ.get('CC', 'cc').split()78 cpp_cmd = os.environ.get('CC', 'cc').split()
75 cpp_cmd += ['-E']79 cpp_cmd += ['-E']
76 80 cpp_cmd += ['-x', 'c'] # force C language (emcc defaults to c++)
77 return cpp_cmd81 return cpp_cmd
78 82
79def get_cpp_objects(header=header, usedouble=False):83
84def get_c_declarations(header=header, usedouble=False):
85 ''' return a dense and preprocessed string of all c declarations implied by aubio.h
86 '''
80 cpp_cmd = get_preprocessor()87 cpp_cmd = get_preprocessor()
81 88
82 macros = [('AUBIO_UNSTABLE', 1)]89 macros = [('AUBIO_UNSTABLE', 1)]
@@ -92,15 +99,15 @@ def get_cpp_objects(header=header, usedouble=False): · 9 unmodified lines
92 99
93 print("Running command: {:s}".format(" ".join(cpp_cmd)))100 print("Running command: {:s}".format(" ".join(cpp_cmd)))
94 proc = subprocess.Popen(cpp_cmd,101 proc = subprocess.Popen(cpp_cmd,
95 stderr=subprocess.PIPE,102 stderr=subprocess.PIPE,
96 stdout=subprocess.PIPE)103 stdout=subprocess.PIPE)
97 assert proc, 'Proc was none'104 assert proc, 'Proc was none'
98 cpp_output = proc.stdout.read()105 cpp_output = proc.stdout.read()
99 err_output = proc.stderr.read()106 err_output = proc.stderr.read()
100 if not cpp_output:107 if not cpp_output:
101 raise Exception("preprocessor output is empty:\n%s" % err_output)108 raise Exception("preprocessor output is empty:\n%s" % err_output)
102 elif err_output:109 elif err_output:
103 print ("Warning: preprocessor produced warnings:\n%s" % err_output)110 print("Warning: preprocessor produced warnings:\n%s" % err_output)
104 if not isinstance(cpp_output, list):111 if not isinstance(cpp_output, list):
105 cpp_output = [l.strip() for l in cpp_output.decode('utf8').split('\n')]112 cpp_output = [l.strip() for l in cpp_output.decode('utf8').split('\n')]
106 113
@@ -109,35 +116,82 @@ def get_cpp_objects(header=header, usedouble=False): · 2 unmodified lines
109 116
110 i = 1117 i = 1
111 while 1:118 while 1:
112 if i >= len(cpp_output): break119 if i >= len(cpp_output):
113 if cpp_output[i-1].endswith(',') or cpp_output[i-1].endswith('{') or cpp_output[i].startswith('}'):120 break
114 cpp_output[i] = cpp_output[i-1] + ' ' + cpp_output[i]121 if ('{' in cpp_output[i - 1]) and (not '}' in cpp_output[i - 1]) or (not ';' in cpp_output[i - 1]):
115 cpp_output.pop(i-1)122 cpp_output[i] = cpp_output[i - 1] + ' ' + cpp_output[i]
123 cpp_output.pop(i - 1)
124 elif ('}' in cpp_output[i]):
125 cpp_output[i] = cpp_output[i - 1] + ' ' + cpp_output[i]
126 cpp_output.pop(i - 1)
116 else:127 else:
117 i += 1128 i += 1
118 129
119 typedefs = filter(lambda y: y.startswith ('typedef struct _aubio'), cpp_output)130 # clean pointer notations
131 tmp = []
132 for l in cpp_output:
133 tmp += [l.replace(' *', ' * ')]
134 cpp_output = tmp
120 135
136 return cpp_output
137
138
139def get_cpp_objects_from_c_declarations(c_declarations, skip_objects=None):
140 if skip_objects == None:
141 skip_objects = default_skip_objects
142 typedefs = filter(lambda y: y.startswith('typedef struct _aubio'), c_declarations)
121 cpp_objects = [a.split()[3][:-1] for a in typedefs]143 cpp_objects = [a.split()[3][:-1] for a in typedefs]
144 cpp_objects_filtered = filter(lambda y: not y[6:-2] in skip_objects, cpp_objects)
145 return cpp_objects_filtered
146
147
148def get_all_func_names_from_lib(lib, depth=0):
149 ''' return flat string of all function used in lib
150 '''
151 res = []
152 indent = " " * depth
153 for k, v in lib.items():
154 if isinstance(v, dict):
155 res += get_all_func_names_from_lib(v, depth + 1)
156 elif isinstance(v, list):
157 for elem in v:
158 e = elem.split('(')
159 if len(e) < 2:
160 continue # not a function
161 fname_part = e[0].strip().split(' ')
162 fname = fname_part[-1]
163 if fname:
164 res += [fname]
165 else:
166 raise NameError('gen_lib : weird function: ' + str(e))
122 167
123 return cpp_output, cpp_objects168 return res
124 169
125 170
126def analyze_cpp_output(cpp_objects, cpp_output):171def generate_lib_from_c_declarations(cpp_objects, c_declarations):
172 ''' returns a lib from given cpp_object names
173
174 a lib is a dict grouping functions by family (onset,pitch...)
175 each eement is itself a dict of functions grouped by puposes as :
176 struct, new, del, do, get, set and other
177 '''
127 lib = {}178 lib = {}
128 179
129 for o in cpp_objects:180 for o in cpp_objects:
130 if o[:6] != 'aubio_':181 shortname = o
131 continue182 if o[:6] == 'aubio_':
132 shortname = o[6:-2]183 shortname = o[6:-2] # without aubio_ prefix and _t suffix
133 if shortname in skip_objects:184
134 continue
135 lib[shortname] = {'struct': [], 'new': [], 'del': [], 'do': [], 'get': [], 'set': [], 'other': []}185 lib[shortname] = {'struct': [], 'new': [], 'del': [], 'do': [], 'get': [], 'set': [], 'other': []}
136 lib[shortname]['longname'] = o186 lib[shortname]['longname'] = o
137 lib[shortname]['shortname'] = shortname187 lib[shortname]['shortname'] = shortname
138 for fn in cpp_output:188
139 if o[:-1] in fn:189 fullshortname = o[:-2] # name without _t suffix
140 #print "found", o[:-1], "in", fn190
191 for fn in c_declarations:
192 func_name = fn.split('(')[0].strip().split(' ')[-1]
193 if func_name.startswith(fullshortname + '_') or func_name.endswith(fullshortname):
194 # print "found", shortname, "in", fn
141 if 'typedef struct ' in fn:195 if 'typedef struct ' in fn:
142 lib[shortname]['struct'].append(fn)196 lib[shortname]['struct'].append(fn)
143 elif '_do' in fn:197 elif '_do' in fn:
@@ -151,38 +205,42 @@ def analyze_cpp_output(cpp_objects, cpp_output): · 7 unmodified lines
151 elif '_set_' in fn:205 elif '_set_' in fn:
152 lib[shortname]['set'].append(fn)206 lib[shortname]['set'].append(fn)
153 else:207 else:
154 #print "no idea what to do about", fn208 # print "no idea what to do about", fn
155 lib[shortname]['other'].append(fn)209 lib[shortname]['other'].append(fn)
156 return lib210 return lib
157 211
158def print_cpp_output_results(lib, cpp_output):212
159 for fn in cpp_output:213def print_c_declarations_results(lib, c_declarations):
214 for fn in c_declarations:
160 found = 0215 found = 0
161 for o in lib:216 for o in lib:
162 for family in lib[o]:217 for family in lib[o]:
163 if fn in lib[o][family]:218 if fn in lib[o][family]:
164 found = 1219 found = 1
165 if found == 0:220 if found == 0:
166 print ("missing", fn)221 print("missing", fn)
167 222
168 for o in lib:223 for o in lib:
169 for family in lib[o]:224 for family in lib[o]:
170 if type(lib[o][family]) == str:225 if type(lib[o][family]) == str:
171 print ( "{:15s} {:10s} {:s}".format(o, family, lib[o][family] ) )226 print("{:15s} {:10s} {:s}".format(o, family, lib[o][family]))
172 elif len(lib[o][family]) == 1:227 elif len(lib[o][family]) == 1:
173 print ( "{:15s} {:10s} {:s}".format(o, family, lib[o][family][0] ) )228 print("{:15s} {:10s} {:s}".format(o, family, lib[o][family][0]))
174 else:229 else:
175 print ( "{:15s} {:10s} {:s}".format(o, family, lib[o][family] ) )230 print("{:15s} {:10s} {:s}".format(o, family, lib[o][family]))
176 231
177 232
178def generate_external(header=header, output_path=output_path, usedouble=False, overwrite=True):233def generate_external(header=header, output_path=output_path, usedouble=False, overwrite=True):
179 if not os.path.isdir(output_path): os.mkdir(output_path)234 if not os.path.isdir(output_path):
180 elif not overwrite: return sorted(glob.glob(os.path.join(output_path, '*.c')))235 os.mkdir(output_path)
236 elif not overwrite:
237 return sorted(glob.glob(os.path.join(output_path, '*.c')))
181 238
182 cpp_output, cpp_objects = get_cpp_objects(header, usedouble=usedouble)239 c_declarations = get_c_declarations(header, usedouble=usedouble)
240 cpp_objects = get_cpp_objects_from_c_declarations(c_declarations)
183 241
184 lib = analyze_cpp_output(cpp_objects, cpp_output)242 lib = generate_lib_from_c_declarations(cpp_objects, c_declarations)
185 # print_cpp_output_results(lib, cpp_output)243 # print_c_declarations_results(lib, c_declarations)
186 244
187 sources_list = []245 sources_list = []
188 try:246 try:
@@ -191,12 +249,12 @@ def generate_external(header=header, output_path=output_path, usedouble=False, o · 2 unmodified lines
191 from gen_code import MappedObject249 from gen_code import MappedObject
192 for o in lib:250 for o in lib:
193 out = source_header251 out = source_header
194 mapped = MappedObject(lib[o], usedouble = usedouble)252 mapped = MappedObject(lib[o], usedouble=usedouble)
195 out += mapped.gen_code()253 out += mapped.gen_code()
196 output_file = os.path.join(output_path, 'gen-%s.c' % o)254 output_file = os.path.join(output_path, 'gen-%s.c' % o)
197 with open(output_file, 'w') as f:255 with open(output_file, 'w') as f:
198 f.write(out)256 f.write(out)
199 print ("wrote %s" % output_file )257 print("wrote %s" % output_file)
200 sources_list.append(output_file)258 sources_list.append(output_file)
201 259
202 out = source_header260 out = source_header
@@ -208,23 +266,23 @@ int generated_types_ready (void) · 5 unmodified lines
208{{266{{
209 return ({pycheck_types});267 return ({pycheck_types});
210}}268}}
211""".format(pycheck_types = check_types)269""".format(pycheck_types=check_types)
212 270
213 add_types = "".join(["""271 add_types = "".join(["""
214 Py_INCREF (&Py_{name}Type);272 Py_INCREF (&Py_{name}Type);
215 PyModule_AddObject(m, "{name}", (PyObject *) & Py_{name}Type);""".format(name = o) for o in lib])273 PyModule_AddObject(m, "{name}", (PyObject *) & Py_{name}Type);""".format(name=o) for o in lib])
216 out += """274 out += """
217 275
218void add_generated_objects ( PyObject *m )276void add_generated_objects ( PyObject *m )
219{{277{{
220{add_types}278{add_types}
221}}279}}
222""".format(add_types = add_types)280""".format(add_types=add_types)
223 281
224 output_file = os.path.join(output_path, 'aubio-generated.c')282 output_file = os.path.join(output_path, 'aubio-generated.c')
225 with open(output_file, 'w') as f:283 with open(output_file, 'w') as f:
226 f.write(out)284 f.write(out)
227 print ("wrote %s" % output_file )285 print("wrote %s" % output_file)
228 sources_list.append(output_file)286 sources_list.append(output_file)
229 287
230 objlist = "".join(["extern PyTypeObject Py_%sType;\n" % p for p in lib])288 objlist = "".join(["extern PyTypeObject Py_%sType;\n" % p for p in lib])
@@ -242,17 +300,19 @@ void add_generated_objects ( PyObject *m ) · 11 unmodified lines
242{objlist}300{objlist}
243int generated_objects ( void );301int generated_objects ( void );
244void add_generated_objects( PyObject *m );302void add_generated_objects( PyObject *m );
245""".format(objlist = objlist)303""".format(objlist=objlist)
246 304
247 output_file = os.path.join(output_path, 'aubio-generated.h')305 output_file = os.path.join(output_path, 'aubio-generated.h')
248 with open(output_file, 'w') as f:306 with open(output_file, 'w') as f:
249 f.write(out)307 f.write(out)
250 print ("wrote %s" % output_file )308 print("wrote %s" % output_file)
251 # no need to add header to list of sources309 # no need to add header to list of sources
252 310
253 return sorted(sources_list)311 return sorted(sources_list)
254 312
255if __name__ == '__main__':313if __name__ == '__main__':
256 if len(sys.argv) > 1: header = sys.argv[1]314 if len(sys.argv) > 1:
257 if len(sys.argv) > 2: output_path = sys.argv[2]315 header = sys.argv[1]
316 if len(sys.argv) > 2:
317 output_path = sys.argv[2]
258 generate_external(header, output_path)318 generate_external(header, output_path)

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t