History

Merge branch 'master' into dct

Paul Brossier committed 9 years ago

Commit 7b7a58e2 parents b99e2a5 cfb7fb715 files · +469 −254Browse files

Showing the changes to python (9 of 15 files). Show all

Unified · Split

9 files
  1. python/demos/demo_bpm_extract.py +44 −27
  2. python/demos/demo_tapthebeat.py +1 −1
  3. python/ext/py-phasevoc.c +19 −0
  4. python/lib/aubio/cmd.py +251 −113
  5. python/lib/aubio/cut.py +57 −88
  6. python/tests/test_aubio_cmd.py +27 −0
  7. python/tests/test_aubio_cut.py +16 −0
  8. python/tests/test_filterbank.py +11 −4
  9. python/tests/test_filterbank_mel.py +15 −12
python/demos/demo_bpm_extract.py+44−27
@@ -3,26 +3,33 @@ · 2 unmodified lines
3from aubio import source, tempo3from aubio import source, tempo
4from numpy import median, diff4from numpy import median, diff
5 5
6def get_file_bpm(path, params = None):6def get_file_bpm(path, params=None):
7 """ Calculate the beats per minute (bpm) of a given file.7 """ Calculate the beats per minute (bpm) of a given file.
8 path: path to the file8 path: path to the file
9 param: dictionary of parameters9 param: dictionary of parameters
10 """10 """
11 if params is None:11 if params is None:
12 params = {}12 params = {}
13 try:13 # default:
14 win_s = params['win_s']14 samplerate, win_s, hop_s = 44100, 1024, 512
15 samplerate = params['samplerate']15 if 'mode' in params:
16 hop_s = params['hop_s']16 if params.mode in ['super-fast']:
17 except KeyError:17 # super fast
18 """18 samplerate, win_s, hop_s = 4000, 128, 64
19 # super fast19 elif params.mode in ['fast']:
20 samplerate, win_s, hop_s = 4000, 128, 64 20 # fast
21 # fast21 samplerate, win_s, hop_s = 8000, 512, 128
22 samplerate, win_s, hop_s = 8000, 512, 12822 elif params.mode in ['default']:
23 """23 pass
24 # default:24 else:
25 samplerate, win_s, hop_s = 44100, 1024, 51225 print("unknown mode {:s}".format(params.mode))
26 # manual settings
27 if 'samplerate' in params:
28 samplerate = params.samplerate
29 if 'win_s' in params:
30 win_s = params.win_s
31 if 'hop_s' in params:
32 hop_s = params.hop_s
26 33
27 s = source(path, samplerate, hop_s)34 s = source(path, samplerate, hop_s)
28 samplerate = s.samplerate35 samplerate = s.samplerate
@@ -44,19 +51,29 @@ def get_file_bpm(path, params = None): · 15 unmodified lines
44 if read < hop_s:51 if read < hop_s:
45 break52 break
46 53
47 # Convert to periods and to bpm 54 def beats_to_bpm(beats, path):
48 if len(beats) > 1:55 # if enough beats are found, convert to periods then to bpm
49 if len(beats) < 4:56 if len(beats) > 1:
50 print("few beats found in {:s}".format(path))57 if len(beats) < 4:
51 bpms = 60./diff(beats)58 print("few beats found in {:s}".format(path))
52 b = median(bpms)59 bpms = 60./diff(beats)
53 else:60 return median(bpms)
54 b = 061 else:
55 print("not enough beats found in {:s}".format(path))62 print("not enough beats found in {:s}".format(path))
56 return b63 return 0
64
65 return beats_to_bpm(beats, path)
57 66
58if __name__ == '__main__':67if __name__ == '__main__':
59 import sys68 import argparse
60 for f in sys.argv[1:]:69 parser = argparse.ArgumentParser()
61 bpm = get_file_bpm(f)70 parser.add_argument('-m', '--mode',
71 help="mode [default|fast|super-fast]",
72 dest="mode")
73 parser.add_argument('sources',
74 nargs='*',
75 help="input_files")
76 args = parser.parse_args()
77 for f in args.sources:
78 bpm = get_file_bpm(f, params = args)
62 print("{:6s} {:s}".format("{:2f}".format(bpm), f))79 print("{:6s} {:s}".format("{:2f}".format(bpm), f))
python/demos/demo_tapthebeat.py+1−1
@@ -44,7 +44,7 @@ a_tempo = aubio.tempo("default", win_s, hop_s, samplerate) · 43 unmodified lines
44click = 0.7 * np.sin(2. * np.pi * np.arange(hop_s) / hop_s * samplerate / 3000.)44click = 0.7 * np.sin(2. * np.pi * np.arange(hop_s) / hop_s * samplerate / 3000.)
45 45
46# pyaudio callback46# pyaudio callback
47def pyaudio_callback(in_data, frame_count, time_info, status):47def pyaudio_callback(_in_data, _frame_count, _time_info, _status):
48 samples, read = a_source()48 samples, read = a_source()
49 is_beat = a_tempo(samples)49 is_beat = a_tempo(samples)
50 if is_beat:50 if is_beat:
python/ext/py-phasevoc.c+19−0
@@ -155,9 +155,28 @@ Py_pvoc_rdo(Py_pvoc * self, PyObject * args) · 154 unmodified lines
155 return self->routput;155 return self->routput;
156}156}
157 157
158static PyObject *
159Pyaubio_pvoc_set_window (Py_pvoc *self, PyObject *args)
160{
161 uint_t err = 0;
162 char_t *window = NULL;
163
164 if (!PyArg_ParseTuple (args, "s", &window)) {
165 return NULL;
166 }
167 err = aubio_pvoc_set_window (self->o, window);
168
169 if (err > 0) {
170 PyErr_SetString (PyExc_ValueError, "error running aubio_pvoc_set_window");
171 return NULL;
172 }
173 Py_RETURN_NONE;
174}
175
158static PyMethodDef Py_pvoc_methods[] = {176static PyMethodDef Py_pvoc_methods[] = {
159 {"rdo", (PyCFunction) Py_pvoc_rdo, METH_VARARGS,177 {"rdo", (PyCFunction) Py_pvoc_rdo, METH_VARARGS,
160 "synthesis of spectral grain"},178 "synthesis of spectral grain"},
179 {"set_window", (PyCFunction) Pyaubio_pvoc_set_window, METH_VARARGS, ""},
161 {NULL}180 {NULL}
162};181};
163 182
python/lib/aubio/cmd.py+251−113
@@ -20,153 +20,233 @@ def aubio_parser(): · 19 unmodified lines
20 action="store_true", dest="show_version")20 action="store_true", dest="show_version")
21 21
22 subparsers = parser.add_subparsers(title='commands', dest='command',22 subparsers = parser.add_subparsers(title='commands', dest='command',
23 parser_class= AubioArgumentParser,
23 metavar="")24 metavar="")
24 25
26 parser_add_subcommand_help(subparsers)
27
28 parser_add_subcommand_onset(subparsers)
29 parser_add_subcommand_pitch(subparsers)
30 parser_add_subcommand_beat(subparsers)
31 parser_add_subcommand_tempo(subparsers)
32 parser_add_subcommand_notes(subparsers)
33 parser_add_subcommand_mfcc(subparsers)
34 parser_add_subcommand_melbands(subparsers)
35 parser_add_subcommand_quiet(subparsers)
36 parser_add_subcommand_cut(subparsers)
37
38 return parser
39
40def parser_add_subcommand_help(subparsers):
41 # global help subcommand
42 subparsers.add_parser('help',
43 help='show help message',
44 formatter_class = argparse.ArgumentDefaultsHelpFormatter)
45
46def parser_add_subcommand_onset(subparsers):
25 # onset subcommand47 # onset subcommand
26 subparser = subparsers.add_parser('onset',48 subparser = subparsers.add_parser('onset',
27 help='estimate time of onsets (beginning of sound event)',49 help='estimate time of onsets (beginning of sound event)',
28 formatter_class = argparse.ArgumentDefaultsHelpFormatter)50 formatter_class = argparse.ArgumentDefaultsHelpFormatter)
29 parser_add_input(subparser)51 subparser.add_input()
30 parser_add_buf_hop_size(subparser)52 subparser.add_buf_hop_size()
31 helpstr = "onset novelty function"53 helpstr = "onset novelty function"
32 helpstr += " <default|energy|hfc|complex|phase|specdiff|kl|mkl|specflux>"54 helpstr += " <default|energy|hfc|complex|phase|specdiff|kl|mkl|specflux>"
33 parser_add_method(subparser, helpstr=helpstr)55 subparser.add_method(helpstr=helpstr)
34 parser_add_threshold(subparser)56 subparser.add_threshold()
35 parser_add_silence(subparser)57 subparser.add_silence()
36 parser_add_minioi(subparser)58 subparser.add_minioi()
37 parser_add_time_format(subparser)59 subparser.add_time_format()
38 parser_add_verbose_help(subparser)60 subparser.add_verbose_help()
39 subparser.set_defaults(process=process_onset)61 subparser.set_defaults(process=process_onset)
40 62
63def parser_add_subcommand_pitch(subparsers):
41 # pitch subcommand64 # pitch subcommand
42 subparser = subparsers.add_parser('pitch',65 subparser = subparsers.add_parser('pitch',
43 help='estimate fundamental frequency (monophonic)')66 help='estimate fundamental frequency (monophonic)')
44 parser_add_input(subparser)67 subparser.add_input()
45 parser_add_buf_hop_size(subparser, buf_size=2048)68 subparser.add_buf_hop_size(buf_size=2048)
46 helpstr = "pitch detection method <default|yinfft|yin|mcomb|fcomb|schmitt>"69 helpstr = "pitch detection method <default|yinfft|yin|mcomb|fcomb|schmitt>"
47 parser_add_method(subparser, helpstr=helpstr)70 subparser.add_method(helpstr=helpstr)
48 parser_add_threshold(subparser)71 subparser.add_threshold()
49 parser_add_pitch_unit(subparser)72 subparser.add_pitch_unit()
50 parser_add_silence(subparser)73 subparser.add_silence()
51 parser_add_time_format(subparser)74 subparser.add_time_format()
52 parser_add_verbose_help(subparser)75 subparser.add_verbose_help()
53 subparser.set_defaults(process=process_pitch)76 subparser.set_defaults(process=process_pitch)
54 77
78def parser_add_subcommand_beat(subparsers):
55 # beat subcommand79 # beat subcommand
56 subparser = subparsers.add_parser('beat',80 subparser = subparsers.add_parser('beat',
57 help='estimate location of beats')81 help='estimate location of beats')
58 parser_add_input(subparser)82 subparser.add_input()
59 parser_add_buf_hop_size(subparser, buf_size=1024, hop_size=512)83 subparser.add_buf_hop_size(buf_size=1024, hop_size=512)
60 parser_add_time_format(subparser)84 subparser.add_time_format()
61 parser_add_verbose_help(subparser)85 subparser.add_verbose_help()
62 subparser.set_defaults(process=process_beat)86 subparser.set_defaults(process=process_beat)
63 87
88def parser_add_subcommand_tempo(subparsers):
64 # tempo subcommand89 # tempo subcommand
65 subparser = subparsers.add_parser('tempo',90 subparser = subparsers.add_parser('tempo',
66 help='estimate overall tempo in bpm')91 help='estimate overall tempo in bpm')
67 parser_add_input(subparser)92 subparser.add_input()
68 parser_add_buf_hop_size(subparser, buf_size=1024, hop_size=512)93 subparser.add_buf_hop_size(buf_size=1024, hop_size=512)
69 parser_add_time_format(subparser)94 subparser.add_time_format()
70 parser_add_verbose_help(subparser)95 subparser.add_verbose_help()
71 subparser.set_defaults(process=process_tempo)96 subparser.set_defaults(process=process_tempo)
72 97
98def parser_add_subcommand_notes(subparsers):
73 # notes subcommand99 # notes subcommand
74 subparser = subparsers.add_parser('notes',100 subparser = subparsers.add_parser('notes',
75 help='estimate midi-like notes (monophonic)')101 help='estimate midi-like notes (monophonic)')
76 parser_add_input(subparser)102 subparser.add_input()
77 parser_add_buf_hop_size(subparser)103 subparser.add_buf_hop_size()
78 parser_add_time_format(subparser)104 subparser.add_time_format()
79 parser_add_verbose_help(subparser)105 subparser.add_verbose_help()
80 subparser.set_defaults(process=process_notes)106 subparser.set_defaults(process=process_notes)
81 107
108def parser_add_subcommand_mfcc(subparsers):
82 # mfcc subcommand109 # mfcc subcommand
83 subparser = subparsers.add_parser('mfcc',110 subparser = subparsers.add_parser('mfcc',
84 help='extract Mel-Frequency Cepstrum Coefficients')111 help='extract Mel-Frequency Cepstrum Coefficients')
85 parser_add_input(subparser)112 subparser.add_input()
86 parser_add_buf_hop_size(subparser)113 subparser.add_buf_hop_size()
87 parser_add_time_format(subparser)114 subparser.add_time_format()
88 parser_add_verbose_help(subparser)115 subparser.add_verbose_help()
89 subparser.set_defaults(process=process_mfcc)116 subparser.set_defaults(process=process_mfcc)
90 117
118def parser_add_subcommand_melbands(subparsers):
91 # melbands subcommand119 # melbands subcommand
92 subparser = subparsers.add_parser('melbands',120 subparser = subparsers.add_parser('melbands',
93 help='extract energies in Mel-frequency bands')121 help='extract energies in Mel-frequency bands')
94 parser_add_input(subparser)122 subparser.add_input()
95 parser_add_buf_hop_size(subparser)123 subparser.add_buf_hop_size()
96 parser_add_time_format(subparser)124 subparser.add_time_format()
97 parser_add_verbose_help(subparser)125 subparser.add_verbose_help()
98 subparser.set_defaults(process=process_melbands)126 subparser.set_defaults(process=process_melbands)
99 127
100 return parser128def parser_add_subcommand_quiet(subparsers):
101 129 # quiet subcommand
102def parser_add_input(parser):130 subparser = subparsers.add_parser('quiet',
103 parser.add_argument("source_uri", default=None, nargs='?',131 help='extract timestamps of quiet and loud regions')
104 help="input sound file to analyse", metavar = "<source_uri>")132 subparser.add_input()
105 parser.add_argument("-i", "--input", dest = "source_uri2",133 subparser.add_hop_size()
106 help="input sound file to analyse", metavar = "<source_uri>")134 subparser.add_silence()
107 parser.add_argument("-r", "--samplerate",135 subparser.add_time_format()
108 metavar = "<freq>", type=int,136 subparser.add_verbose_help()
109 action="store", dest="samplerate", default=0,137 subparser.set_defaults(process=process_quiet)
110 help="samplerate at which the file should be represented")138
111 139def parser_add_subcommand_cut(subparsers):
112def parser_add_verbose_help(parser):140 # quiet subcommand
113 parser.add_argument("-v","--verbose",141 subparser = subparsers.add_parser('cut',
114 action="count", dest="verbose", default=1,142 help='slice at timestamps')
115 help="make lots of noise [default]")143 subparser.add_input()
116 parser.add_argument("-q","--quiet",144 helpstr = "onset novelty function"
117 action="store_const", dest="verbose", const=0,145 helpstr += " <default|energy|hfc|complex|phase|specdiff|kl|mkl|specflux>"
118 help="be quiet")146 subparser.add_method(helpstr=helpstr)
119 147 subparser.add_buf_hop_size()
120def parser_add_buf_hop_size(parser, buf_size=512, hop_size=256):148 subparser.add_silence()
121 parser.add_argument("-B","--bufsize",149 subparser.add_threshold(default=0.3)
122 action="store", dest="buf_size", default=buf_size,150 subparser.add_minioi()
123 metavar = "<size>", type=int,151 subparser.add_slicer_options()
124 help="buffer size [default=%d]" % buf_size)152 subparser.add_time_format()
125 parser.add_argument("-H","--hopsize",153 subparser.add_verbose_help()
126 metavar = "<size>", type=int,154 subparser.set_defaults(process=process_cut)
127 action="store", dest="hop_size", default=hop_size,155
128 help="overlap size [default=%d]" % hop_size)156class AubioArgumentParser(argparse.ArgumentParser):
129 157
130def parser_add_method(parser, method='default', helpstr='method'):158 def add_input(self):
131 parser.add_argument("-m","--method",159 self.add_argument("source_uri", default=None, nargs='?',
132 metavar = "<method>", type=str,160 help="input sound file to analyse", metavar = "<source_uri>")
133 action="store", dest="method", default=method,161 self.add_argument("-i", "--input", dest = "source_uri2",
134 help="%s [default=%s]" % (helpstr, method))162 help="input sound file to analyse", metavar = "<source_uri>")
135 163 self.add_argument("-r", "--samplerate",
136def parser_add_threshold(parser, default=None):164 metavar = "<freq>", type=int,
137 parser.add_argument("-t","--threshold",165 action="store", dest="samplerate", default=0,
138 metavar = "<threshold>", type=float,166 help="samplerate at which the file should be represented")
139 action="store", dest="threshold", default=default,167
140 help="threshold [default=%s]" % default)168 def add_verbose_help(self):
141 169 self.add_argument("-v","--verbose",
142def parser_add_silence(parser):170 action="count", dest="verbose", default=1,
143 parser.add_argument("-s", "--silence",171 help="make lots of noise [default]")
144 metavar = "<value>", type=float,172 self.add_argument("-q","--quiet",
145 action="store", dest="silence", default=-70,173 action="store_const", dest="verbose", const=0,
146 help="silence threshold")174 help="be quiet")
147 175
148def parser_add_minioi(parser):176 def add_buf_hop_size(self, buf_size=512, hop_size=256):
149 parser.add_argument("-M", "--minioi",177 self.add_buf_size(buf_size=buf_size)
150 metavar = "<value>", type=str,178 self.add_hop_size(hop_size=hop_size)
151 action="store", dest="minioi", default="12ms",179
152 help="minimum Inter-Onset Interval")180 def add_buf_size(self, buf_size=512):
153 181 self.add_argument("-B","--bufsize",
154def parser_add_pitch_unit(parser, default="Hz"):182 action="store", dest="buf_size", default=buf_size,
155 help_str = "frequency unit, should be one of Hz, midi, bin, cent"183 metavar = "<size>", type=int,
156 help_str += " [default=%s]" % default184 help="buffer size [default=%d]" % buf_size)
157 parser.add_argument("-u", "--pitch-unit",185
158 metavar = "<value>", type=str,186 def add_hop_size(self, hop_size=256):
159 action="store", dest="pitch_unit", default=default,187 self.add_argument("-H","--hopsize",
160 help=help_str)188 metavar = "<size>", type=int,
161 189 action="store", dest="hop_size", default=hop_size,
162def parser_add_time_format(parser):190 help="overlap size [default=%d]" % hop_size)
163 helpstr = "select time values output format (samples, ms, seconds)"191
164 helpstr += " [default=seconds]"192 def add_method(self, method='default', helpstr='method'):
165 parser.add_argument("-T", "--time-format",193 self.add_argument("-m","--method",
166 metavar='format',194 metavar = "<method>", type=str,
167 dest="time_format",195 action="store", dest="method", default=method,
168 default=None,196 help="%s [default=%s]" % (helpstr, method))
169 help=helpstr)197
198 def add_threshold(self, default=None):
199 self.add_argument("-t","--threshold",
200 metavar = "<threshold>", type=float,
201 action="store", dest="threshold", default=default,
202 help="threshold [default=%s]" % default)
203
204 def add_silence(self):
205 self.add_argument("-s", "--silence",
206 metavar = "<value>", type=float,
207 action="store", dest="silence", default=-70,
208 help="silence threshold")
209
210 def add_minioi(self, default="12ms"):
211 self.add_argument("-M", "--minioi",
212 metavar = "<value>", type=str,
213 action="store", dest="minioi", default=default,
214 help="minimum Inter-Onset Interval [default=%s]" % default)
215
216 def add_pitch_unit(self, default="Hz"):
217 help_str = "frequency unit, should be one of Hz, midi, bin, cent"
218 help_str += " [default=%s]" % default
219 self.add_argument("-u", "--pitch-unit",
220 metavar = "<value>", type=str,
221 action="store", dest="pitch_unit", default=default,
222 help=help_str)
223
224 def add_time_format(self):
225 helpstr = "select time values output format (samples, ms, seconds)"
226 helpstr += " [default=seconds]"
227 self.add_argument("-T", "--time-format",
228 metavar='format',
229 dest="time_format",
230 default=None,
231 help=helpstr)
232
233 def add_slicer_options(self):
234 self.add_argument("-o","--output", type = str,
235 metavar = "<outputdir>",
236 action="store", dest="output_directory", default=None,
237 help="specify path where slices of the original file should be created")
238 self.add_argument("--cut-until-nsamples", type = int,
239 metavar = "<samples>",
240 action = "store", dest = "cut_until_nsamples", default = None,
241 help="how many extra samples should be added at the end of each slice")
242 self.add_argument("--cut-every-nslices", type = int,
243 metavar = "<samples>",
244 action = "store", dest = "cut_every_nslices", default = None,
245 help="how many slices should be groupped together at each cut")
246 self.add_argument("--cut-until-nslices", type = int,
247 metavar = "<slices>",
248 action = "store", dest = "cut_until_nslices", default = None,
249 help="how many extra slices should be added at the end of each slice")
170 250
171# some utilities251# some utilities
172 252
@@ -176,7 +256,7 @@ def samples2seconds(n_frames, samplerate): · 3 unmodified lines
176def samples2milliseconds(n_frames, samplerate):256def samples2milliseconds(n_frames, samplerate):
177 return "%f\t" % (1000. * n_frames / float(samplerate))257 return "%f\t" % (1000. * n_frames / float(samplerate))
178 258
179def samples2samples(n_frames, samplerate):259def samples2samples(n_frames, _samplerate):
180 return "%d\t" % n_frames260 return "%d\t" % n_frames
181 261
182def timefunc(mode):262def timefunc(mode):
@@ -199,7 +279,7 @@ class default_process(object): · 16 unmodified lines
199 name = type(self).__name__.split('_')[1]279 name = type(self).__name__.split('_')[1]
200 optstr = ' '.join(['running', name, 'with options', repr(self.options), '\n'])280 optstr = ' '.join(['running', name, 'with options', repr(self.options), '\n'])
201 sys.stderr.write(optstr)281 sys.stderr.write(optstr)
202 def flush(self, n_frames, samplerate):282 def flush(self, frames_read, samplerate):
203 # optionally called at the end of process283 # optionally called at the end of process
204 pass284 pass
205 285
@@ -238,7 +318,7 @@ class process_onset(default_process): · 32 unmodified lines
238 super(process_onset, self).__init__(args)318 super(process_onset, self).__init__(args)
239 def __call__(self, block):319 def __call__(self, block):
240 return self.onset(block)320 return self.onset(block)
241 def repr_res(self, res, frames_read, samplerate):321 def repr_res(self, res, _frames_read, samplerate):
242 if res[0] != 0:322 if res[0] != 0:
243 outstr = self.time2string(self.onset.get_last(), samplerate)323 outstr = self.time2string(self.onset.get_last(), samplerate)
244 sys.stdout.write(outstr + '\n')324 sys.stdout.write(outstr + '\n')
@@ -269,7 +349,7 @@ class process_beat(default_process): · 24 unmodified lines
269 super(process_beat, self).__init__(args)349 super(process_beat, self).__init__(args)
270 def __call__(self, block):350 def __call__(self, block):
271 return self.tempo(block)351 return self.tempo(block)
272 def repr_res(self, res, frames_read, samplerate):352 def repr_res(self, res, _frames_read, samplerate):
273 if res[0] != 0:353 if res[0] != 0:
274 outstr = self.time2string(self.tempo.get_last(), samplerate)354 outstr = self.time2string(self.tempo.get_last(), samplerate)
275 sys.stdout.write(outstr + '\n')355 sys.stdout.write(outstr + '\n')
@@ -278,7 +358,7 @@ class process_tempo(process_beat): · 2 unmodified lines
278 def __init__(self, args):358 def __init__(self, args):
279 super(process_tempo, self).__init__(args)359 super(process_tempo, self).__init__(args)
280 self.beat_locations = []360 self.beat_locations = []
281 def repr_res(self, res, frames_read, samplerate):361 def repr_res(self, res, _frames_read, samplerate):
282 if res[0] != 0:362 if res[0] != 0:
283 self.beat_locations.append(self.tempo.get_last_s())363 self.beat_locations.append(self.tempo.get_last_s())
284 def flush(self, frames_read, samplerate):364 def flush(self, frames_read, samplerate):
@@ -362,6 +442,61 @@ class process_melbands(default_process): · 77 unmodified lines
362 fmt_out += ' '.join(["% 9.7f" % f for f in res.tolist()])442 fmt_out += ' '.join(["% 9.7f" % f for f in res.tolist()])
363 sys.stdout.write(fmt_out + '\n')443 sys.stdout.write(fmt_out + '\n')
364 444
445class process_quiet(default_process):
446 def __init__(self, args):
447 self.args = args
448 valid_opts = ['hop_size', 'silence']
449 self.parse_options(args, valid_opts)
450 self.wassilence = 1
451
452 if args.silence is not None:
453 self.silence = args.silence
454 super(process_quiet, self).__init__(args)
455
456 def __call__(self, block):
457 if aubio.silence_detection(block, self.silence) == 1:
458 if self.wassilence != 1:
459 self.wassilence = 1
460 return 2 # newly found silence
461 return 1 # silence again
462 else:
463 if self.wassilence != 0:
464 self.wassilence = 0
465 return -1 # newly found noise
466 return 0 # noise again
467
468 def repr_res(self, res, frames_read, samplerate):
469 fmt_out = None
470 if res == -1:
471 fmt_out = "NOISY: "
472 if res == 2:
473 fmt_out = "QUIET: "
474 if fmt_out is not None:
475 fmt_out += self.time2string(frames_read, samplerate)
476 sys.stdout.write(fmt_out + '\n')
477
478class process_cut(process_onset):
479 def __init__(self, args):
480 super(process_cut, self).__init__(args)
481 self.slices = []
482 self.options = args
483
484 def __call__(self, block):
485 ret = super(process_cut, self).__call__(block)
486 if ret: self.slices.append(self.onset.get_last())
487 return ret
488
489 def flush(self, frames_read, samplerate):
490 from aubio.cut import _cut_slice
491 _cut_slice(self.options, self.slices)
492 duration = float (frames_read) / float(samplerate)
493 base_info = '%(source_file)s' % {'source_file': self.options.source_uri}
494 base_info += ' (total %(duration).2fs at %(samplerate)dHz)\n' % \
495 {'duration': duration, 'samplerate': samplerate}
496 info = "created %d slices from " % len(self.slices)
497 info += base_info
498 sys.stderr.write(info)
499
365def main():500def main():
366 parser = aubio_parser()501 parser = aubio_parser()
367 args = parser.parse_args()502 args = parser.parse_args()
@@ -370,10 +505,13 @@ def main(): · 2 unmodified lines
370 sys.exit(0)505 sys.exit(0)
371 elif 'verbose' in args and args.verbose > 3:506 elif 'verbose' in args and args.verbose > 3:
372 sys.stderr.write('aubio version ' + aubio.version + '\n')507 sys.stderr.write('aubio version ' + aubio.version + '\n')
373 if 'command' not in args or args.command is None:508 if 'command' not in args or args.command is None or args.command in ['help']:
374 # no command given, print help and return 1509 # no command given, print help and return 1
375 parser.print_help()510 parser.print_help()
376 sys.exit(1)511 if args.command and args.command in ['help']:
512 sys.exit(0)
513 else:
514 sys.exit(1)
377 elif not args.source_uri and not args.source_uri2:515 elif not args.source_uri and not args.source_uri2:
378 sys.stderr.write("Error: a source is required\n")516 sys.stderr.write("Error: a source is required\n")
379 parser.print_help()517 parser.print_help()
python/lib/aubio/cut.py+57−88
@@ -5,16 +5,11 @@ · 4 unmodified lines
5"""5"""
6 6
7import sys7import sys
8import argparse8from aubio.cmd import AubioArgumentParser
9 9
10def parse_args():10def aubio_cut_parser():
11 usage = "usage: %s [options] -i soundfile" % sys.argv[0]11 parser = AubioArgumentParser()
12 usage += "\n help: %s -h" % sys.argv[0]12 parser.add_input()
13 parser = argparse.ArgumentParser()
14 parser.add_argument("source_file", default=None, nargs='?',
15 help="input sound file to analyse", metavar = "<source_file>")
16 parser.add_argument("-i", "--input", action = "store", dest = "source_file2",
17 help="input sound file to analyse", metavar = "<source_file>")
18 parser.add_argument("-O","--onset-method",13 parser.add_argument("-O","--onset-method",
19 action="store", dest="onset_method", default='default',14 action="store", dest="onset_method", default='default',
20 metavar = "<onset_method>",15 metavar = "<onset_method>",
@@ -23,7 +18,7 @@ def parse_args(): · 2 unmodified lines
23 # cutting methods18 # cutting methods
24 parser.add_argument("-b","--beat",19 parser.add_argument("-b","--beat",
25 action="store_true", dest="beat", default=False,20 action="store_true", dest="beat", default=False,
26 help="use beat locations")21 help="slice at beat locations")
27 """22 """
28 parser.add_argument("-S","--silencecut",23 parser.add_argument("-S","--silencecut",
29 action="store_true", dest="silencecut", default=False,24 action="store_true", dest="silencecut", default=False,
@@ -34,32 +29,15 @@ def parse_args(): · 4 unmodified lines
34 help="silence threshold [default=-70]")29 help="silence threshold [default=-70]")
35 """30 """
36 # algorithm parameters31 # algorithm parameters
37 parser.add_argument("-r", "--samplerate",32 parser.add_buf_hop_size()
38 metavar = "<freq>", type=int,33 parser.add_argument("-t","--threshold", "--onset-threshold",
39 action="store", dest="samplerate", default=0,34 metavar = "<threshold>", type=float,
40 help="samplerate at which the file should be represented")
41 parser.add_argument("-B","--bufsize",
42 action="store", dest="bufsize", default=512,
43 metavar = "<size>", type=int,
44 help="buffer size [default=512]")
45 parser.add_argument("-H","--hopsize",
46 metavar = "<size>", type=int,
47 action="store", dest="hopsize", default=256,
48 help="overlap size [default=256]")
49 parser.add_argument("-t","--onset-threshold",
50 metavar = "<value>", type=float,
51 action="store", dest="threshold", default=0.3,35 action="store", dest="threshold", default=0.3,
52 help="onset peak picking threshold [default=0.3]")36 help="onset peak picking threshold [default=0.3]")
53 parser.add_argument("-c","--cut",37 parser.add_argument("-c","--cut",
54 action="store_true", dest="cut", default=False,38 action="store_true", dest="cut", default=False,
55 help="cut input sound file at detected labels \39 help="cut input sound file at detected labels")
56 best used with option -L")40 parser.add_minioi()
57
58 # minioi
59 parser.add_argument("-M","--minioi",
60 metavar = "<value>", type=str,
61 action="store", dest="minioi", default="12ms",
62 help="minimum inter onset interval [default=12ms]")
63 41
64 """42 """
65 parser.add_argument("-D","--delay",43 parser.add_argument("-D","--delay",
@@ -81,9 +59,7 @@ def parse_args(): · 15 unmodified lines
81 metavar = "<value>",59 metavar = "<value>",
82 action="store", dest="zerothres", default=0.008,60 action="store", dest="zerothres", default=0.008,
83 help="zero-crossing threshold for slicing [default=0.00008]")61 help="zero-crossing threshold for slicing [default=0.00008]")
84 """
85 # plotting functions62 # plotting functions
86 """
87 parser.add_argument("-p","--plot",63 parser.add_argument("-p","--plot",
88 action="store_true", dest="plot", default=False,64 action="store_true", dest="plot", default=False,
89 help="draw plot")65 help="draw plot")
@@ -109,51 +85,24 @@ def parse_args(): · 19 unmodified lines
109 action="store_true", dest="spectro", default=False,85 action="store_true", dest="spectro", default=False,
110 help="add spectrogram to the plot")86 help="add spectrogram to the plot")
111 """87 """
112 parser.add_argument("-o","--output", type = str,88 parser.add_slicer_options()
113 metavar = "<outputdir>",89 parser.add_verbose_help()
114 action="store", dest="output_directory", default=None,90 return parser
115 help="specify path where slices of the original file should be created")
116 parser.add_argument("--cut-until-nsamples", type = int,
117 metavar = "<samples>",
118 action = "store", dest = "cut_until_nsamples", default = None,
119 help="how many extra samples should be added at the end of each slice")
120 parser.add_argument("--cut-every-nslices", type = int,
121 metavar = "<samples>",
122 action = "store", dest = "cut_every_nslices", default = None,
123 help="how many slices should be groupped together at each cut")
124 parser.add_argument("--cut-until-nslices", type = int,
125 metavar = "<slices>",
126 action = "store", dest = "cut_until_nslices", default = None,
127 help="how many extra slices should be added at the end of each slice")
128
129 parser.add_argument("-v","--verbose",
130 action="store_true", dest="verbose", default=True,
131 help="make lots of noise [default]")
132 parser.add_argument("-q","--quiet",
133 action="store_false", dest="verbose", default=True,
134 help="be quiet")
135 args = parser.parse_args()
136 if not args.source_file and not args.source_file2:
137 sys.stderr.write("Error: no file name given\n")
138 parser.print_help()
139 sys.exit(1)
140 elif args.source_file2 is not None:
141 args.source_file = args.source_file2
142 return args
143 91
144def main():
145 options = parse_args()
146 92
147 source_file = options.source_file93def _cut_analyze(options):
148 hopsize = options.hopsize94 hopsize = options.hop_size
149 bufsize = options.bufsize95 bufsize = options.buf_size
150 samplerate = options.samplerate96 samplerate = options.samplerate
151 source_file = options.source_file97 source_uri = options.source_uri
152 98
99 # analyze pass
153 from aubio import onset, tempo, source100 from aubio import onset, tempo, source
154 101
155 s = source(source_file, samplerate, hopsize)102 s = source(source_uri, samplerate, hopsize)
156 if samplerate == 0: samplerate = s.get_samplerate()103 if samplerate == 0:
104 samplerate = s.get_samplerate()
105 options.samplerate = samplerate
157 106
158 if options.beat:107 if options.beat:
159 o = tempo(options.onset_method, bufsize, hopsize, samplerate=samplerate)108 o = tempo(options.onset_method, bufsize, hopsize, samplerate=samplerate)
@@ -170,7 +119,6 @@ def main(): · 10 unmodified lines
170 119
171 timestamps = []120 timestamps = []
172 total_frames = 0121 total_frames = 0
173 # analyze pass
174 while True:122 while True:
175 samples, read = s()123 samples, read = s()
176 if o(samples):124 if o(samples):
@@ -179,15 +127,12 @@ def main(): · 2 unmodified lines
179 total_frames += read127 total_frames += read
180 if read < hopsize: break128 if read < hopsize: break
181 del s129 del s
182 # print some info130 return timestamps, total_frames
183 nstamps = len(timestamps)
184 duration = float (total_frames) / float(samplerate)
185 info = 'found %(nstamps)d timestamps in %(source_file)s' % locals()
186 info += ' (total %(duration).2fs at %(samplerate)dHz)\n' % locals()
187 sys.stderr.write(info)
188 131
132def _cut_slice(options, timestamps):
189 # cutting pass133 # cutting pass
190 if options.cut and nstamps > 0:134 nstamps = len(timestamps)
135 if nstamps > 0:
191 # generate output files136 # generate output files
192 from aubio.slicing import slice_source_at_stamps137 from aubio.slicing import slice_source_at_stamps
193 timestamps_end = None138 timestamps_end = None
@@ -202,12 +147,36 @@ def main(): · 8 unmodified lines
202 if options.cut_until_nslices:147 if options.cut_until_nslices:
203 timestamps_end = [t for t in timestamps[1 + options.cut_until_nslices:]]148 timestamps_end = [t for t in timestamps[1 + options.cut_until_nslices:]]
204 timestamps_end += [ 1e120 ] * (options.cut_until_nslices + 1)149 timestamps_end += [ 1e120 ] * (options.cut_until_nslices + 1)
205 slice_source_at_stamps(source_file, timestamps, timestamps_end = timestamps_end,150 slice_source_at_stamps(options.source_uri,
151 timestamps, timestamps_end = timestamps_end,
206 output_dir = options.output_directory,152 output_dir = options.output_directory,
207 samplerate = samplerate)153 samplerate = options.samplerate)
154
155def main():
156 parser = aubio_cut_parser()
157 options = parser.parse_args()
158 if not options.source_uri and not options.source_uri2:
159 sys.stderr.write("Error: no file name given\n")
160 parser.print_help()
161 sys.exit(1)
162 elif options.source_uri2 is not None:
163 options.source_uri = options.source_uri2
164
165 # analysis
166 timestamps, total_frames = _cut_analyze(options)
167
168 # print some info
169 duration = float (total_frames) / float(options.samplerate)
170 base_info = '%(source_uri)s' % {'source_uri': options.source_uri}
171 base_info += ' (total %(duration).2fs at %(samplerate)dHz)\n' % \
172 {'duration': duration, 'samplerate': options.samplerate}
173
174 info = "found %d timestamps in " % len(timestamps)
175 info += base_info
176 sys.stderr.write(info)
208 177
209 # print some info178 if options.cut:
210 duration = float (total_frames) / float(samplerate)179 _cut_slice(options, timestamps)
211 info = 'created %(nstamps)d slices from %(source_file)s' % locals()180 info = "created %d slices from " % len(timestamps)
212 info += ' (total %(duration).2fs at %(samplerate)dHz)\n' % locals()181 info += base_info
213 sys.stderr.write(info)182 sys.stderr.write(info)
python/tests/test_aubio_cmd.py+27−0
@@ -0,0 +1,27 @@
1#! /usr/bin/env python
2
3import aubio.cmd
4from nose2 import main
5from numpy.testing import TestCase
6
7class aubio_cmd(TestCase):
8
9 def setUp(self):
10 self.a_parser = aubio.cmd.aubio_parser()
11
12 def test_default_creation(self):
13 assert self.a_parser.parse_args(['-V']).show_version
14
15class aubio_cmd_utils(TestCase):
16
17 def test_samples2seconds(self):
18 self.assertEqual(aubio.cmd.samples2seconds(3200, 32000), "0.100000\t")
19
20 def test_samples2milliseconds(self):
21 self.assertEqual(aubio.cmd.samples2milliseconds(3200, 32000), "100.000000\t")
22
23 def test_samples2samples(self):
24 self.assertEqual(aubio.cmd.samples2samples(3200, 32000), "3200\t")
25
26if __name__ == '__main__':
27 main()
python/tests/test_aubio_cut.py+16−0
@@ -0,0 +1,16 @@
1#! /usr/bin/env python
2
3import aubio.cut
4from nose2 import main
5from numpy.testing import TestCase
6
7class aubio_cut(TestCase):
8
9 def setUp(self):
10 self.a_parser = aubio.cut.aubio_cut_parser()
11
12 def test_default_creation(self):
13 assert self.a_parser.parse_args(['-v']).verbose
14
15if __name__ == '__main__':
16 main()
python/tests/test_filterbank.py+11−4
@@ -1,9 +1,8 @@
1#! /usr/bin/env python1#! /usr/bin/env python
2 2
3from unittest import main
4from numpy.testing import TestCase
5from numpy.testing import assert_equal, assert_almost_equal
6import numpy as np3import numpy as np
4from numpy.testing import TestCase, assert_equal, assert_almost_equal
5
7from aubio import cvec, filterbank, float_type6from aubio import cvec, filterbank, float_type
8from .utils import array_from_text_file7from .utils import array_from_text_file
9 8
@@ -62,6 +61,13 @@ class aubio_filterbank_test_case(TestCase): · 52 unmodified lines
62 f.set_mel_coeffs_slaney(16000)61 f.set_mel_coeffs_slaney(16000)
63 assert_almost_equal ( expected, f.get_coeffs() )62 assert_almost_equal ( expected, f.get_coeffs() )
64 63
64 def test_mfcc_coeffs_get_coeffs(self):
65 f = filterbank(40, 512)
66 coeffs = f.get_coeffs()
67 self.assertIsInstance(coeffs, np.ndarray)
68 assert_equal (coeffs, 0)
69 assert_equal (np.shape(coeffs), (40, 512 / 2 + 1))
70
65class aubio_filterbank_wrong_values(TestCase):71class aubio_filterbank_wrong_values(TestCase):
66 72
67 def test_negative_window(self):73 def test_negative_window(self):
@@ -81,4 +87,5 @@ class aubio_filterbank_wrong_values(TestCase): · 13 unmodified lines
81 f(cvec(256))87 f(cvec(256))
82 88
83if __name__ == '__main__':89if __name__ == '__main__':
84 main()90 import nose2
91 nose2.main()
python/tests/test_filterbank_mel.py+15−12
@@ -1,44 +1,46 @@
1#! /usr/bin/env python1#! /usr/bin/env python
2 2
3from unittest import main3import numpy as np
4from numpy.testing import TestCase4from numpy.testing import TestCase, assert_equal, assert_almost_equal
5from numpy.testing import assert_equal, assert_almost_equal5
6from numpy import array, shape
7from aubio import cvec, filterbank, float_type6from aubio import cvec, filterbank, float_type
8 7
8import warnings
9warnings.filterwarnings('ignore', category=UserWarning, append=True)
10
9class aubio_filterbank_mel_test_case(TestCase):11class aubio_filterbank_mel_test_case(TestCase):
10 12
11 def test_slaney(self):13 def test_slaney(self):
12 f = filterbank(40, 512)14 f = filterbank(40, 512)
13 f.set_mel_coeffs_slaney(16000)15 f.set_mel_coeffs_slaney(16000)
14 a = f.get_coeffs()16 a = f.get_coeffs()
15 assert_equal(shape (a), (40, 512/2 + 1) )17 assert_equal(np.shape (a), (40, 512/2 + 1) )
16 18
17 def test_other_slaney(self):19 def test_other_slaney(self):
18 f = filterbank(40, 512*2)20 f = filterbank(40, 512*2)
19 f.set_mel_coeffs_slaney(44100)21 f.set_mel_coeffs_slaney(44100)
20 _ = f.get_coeffs()22 self.assertIsInstance(f.get_coeffs(), np.ndarray)
21 #print "sum is", sum(sum(a))23 #print "sum is", sum(sum(a))
22 for win_s in [256, 512, 1024, 2048, 4096]:24 for win_s in [256, 512, 1024, 2048, 4096]:
23 f = filterbank(40, win_s)25 f = filterbank(40, win_s)
24 f.set_mel_coeffs_slaney(32000)26 f.set_mel_coeffs_slaney(32000)
25 _ = f.get_coeffs()
26 #print "sum is", sum(sum(a))27 #print "sum is", sum(sum(a))
28 self.assertIsInstance(f.get_coeffs(), np.ndarray)
27 29
28 def test_triangle_freqs_zeros(self):30 def test_triangle_freqs_zeros(self):
29 f = filterbank(9, 1024)31 f = filterbank(9, 1024)
30 freq_list = [40, 80, 200, 400, 800, 1600, 3200, 6400, 12800, 15000, 24000]32 freq_list = [40, 80, 200, 400, 800, 1600, 3200, 6400, 12800, 15000, 24000]
31 freqs = array(freq_list, dtype = float_type)33 freqs = np.array(freq_list, dtype = float_type)
32 f.set_triangle_bands(freqs, 48000)34 f.set_triangle_bands(freqs, 48000)
33 _ = f.get_coeffs().T
34 assert_equal ( f(cvec(1024)), 0)35 assert_equal ( f(cvec(1024)), 0)
36 self.assertIsInstance(f.get_coeffs(), np.ndarray)
35 37
36 def test_triangle_freqs_ones(self):38 def test_triangle_freqs_ones(self):
37 f = filterbank(9, 1024)39 f = filterbank(9, 1024)
38 freq_list = [40, 80, 200, 400, 800, 1600, 3200, 6400, 12800, 15000, 24000]40 freq_list = [40, 80, 200, 400, 800, 1600, 3200, 6400, 12800, 15000, 24000]
39 freqs = array(freq_list, dtype = float_type)41 freqs = np.array(freq_list, dtype = float_type)
40 f.set_triangle_bands(freqs, 48000)42 f.set_triangle_bands(freqs, 48000)
41 _ = f.get_coeffs().T43 self.assertIsInstance(f.get_coeffs(), np.ndarray)
42 spec = cvec(1024)44 spec = cvec(1024)
43 spec.norm[:] = 145 spec.norm[:] = 1
44 assert_almost_equal ( f(spec),46 assert_almost_equal ( f(spec),
@@ -46,4 +48,5 @@ class aubio_filterbank_mel_test_case(TestCase): · 1 unmodified line
46 0.02133301, 0.02133301, 0.02133311, 0.02133334, 0.02133345])48 0.02133301, 0.02133301, 0.02133311, 0.02133334, 0.02133345])
47 49
48if __name__ == '__main__':50if __name__ == '__main__':
49 main()51 import nose2
52 nose2.main()

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