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
33 from aubio import source, tempo
44 from numpy import median, diff
55
6−def get_file_bpm(path, params = None):
6+def get_file_bpm(path, params=None):
77 """ Calculate the beats per minute (bpm) of a given file.
88 path: path to the file
99 param: dictionary of parameters
1010 """
1111 if params is None:
1212 params = {}
13− try:
14− win_s = params['win_s']
15− samplerate = params['samplerate']
16− hop_s = params['hop_s']
17− except KeyError:
18− """
19− # super fast
20− samplerate, win_s, hop_s = 4000, 128, 64
21− # fast
22− samplerate, win_s, hop_s = 8000, 512, 128
23− """
24− # default:
25− samplerate, win_s, hop_s = 44100, 1024, 512
13+ # default:
14+ samplerate, win_s, hop_s = 44100, 1024, 512
15+ if 'mode' in params:
16+ if params.mode in ['super-fast']:
17+ # super fast
18+ samplerate, win_s, hop_s = 4000, 128, 64
19+ elif params.mode in ['fast']:
20+ # fast
21+ samplerate, win_s, hop_s = 8000, 512, 128
22+ elif params.mode in ['default']:
23+ pass
24+ else:
25+ 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
2633
2734 s = source(path, samplerate, hop_s)
2835 samplerate = s.samplerate
@@ -44,19 +51,29 @@ def get_file_bpm(path, params = None): · 15 unmodified lines
4451 if read < hop_s:
4552 break
4653
47− # Convert to periods and to bpm
48− if len(beats) > 1:
49− if len(beats) < 4:
50− print("few beats found in {:s}".format(path))
51− bpms = 60./diff(beats)
52− b = median(bpms)
53− else:
54− b = 0
55− print("not enough beats found in {:s}".format(path))
56− return b
54+ def beats_to_bpm(beats, path):
55+ # if enough beats are found, convert to periods then to bpm
56+ if len(beats) > 1:
57+ if len(beats) < 4:
58+ print("few beats found in {:s}".format(path))
59+ bpms = 60./diff(beats)
60+ return median(bpms)
61+ else:
62+ print("not enough beats found in {:s}".format(path))
63+ return 0
64+
65+ return beats_to_bpm(beats, path)
5766
5867 if __name__ == '__main__':
59− import sys
60− for f in sys.argv[1:]:
61− bpm = get_file_bpm(f)
68+ import argparse
69+ parser = argparse.ArgumentParser()
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)
6279 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
4444 click = 0.7 * np.sin(2. * np.pi * np.arange(hop_s) / hop_s * samplerate / 3000.)
4545
4646 # pyaudio callback
47−def pyaudio_callback(in_data, frame_count, time_info, status):
47+def pyaudio_callback(_in_data, _frame_count, _time_info, _status):
4848 samples, read = a_source()
4949 is_beat = a_tempo(samples)
5050 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
155155 return self->routput;
156156 }
157157
158+static PyObject *
159+Pyaubio_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+
158176 static PyMethodDef Py_pvoc_methods[] = {
159177 {"rdo", (PyCFunction) Py_pvoc_rdo, METH_VARARGS,
160178 "synthesis of spectral grain"},
179+ {"set_window", (PyCFunction) Pyaubio_pvoc_set_window, METH_VARARGS, ""},
161180 {NULL}
162181 };
163182
python/lib/aubio/cmd.py+251−113
@@ -20,153 +20,233 @@ def aubio_parser(): · 19 unmodified lines
2020 action="store_true", dest="show_version")
2121
2222 subparsers = parser.add_subparsers(title='commands', dest='command',
23+ parser_class= AubioArgumentParser,
2324 metavar="")
2425
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+
40+def 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+
46+def parser_add_subcommand_onset(subparsers):
2547 # onset subcommand
2648 subparser = subparsers.add_parser('onset',
2749 help='estimate time of onsets (beginning of sound event)',
2850 formatter_class = argparse.ArgumentDefaultsHelpFormatter)
29− parser_add_input(subparser)
30− parser_add_buf_hop_size(subparser)
51+ subparser.add_input()
52+ subparser.add_buf_hop_size()
3153 helpstr = "onset novelty function"
3254 helpstr += " <default|energy|hfc|complex|phase|specdiff|kl|mkl|specflux>"
33− parser_add_method(subparser, helpstr=helpstr)
34− parser_add_threshold(subparser)
35− parser_add_silence(subparser)
36− parser_add_minioi(subparser)
37− parser_add_time_format(subparser)
38− parser_add_verbose_help(subparser)
55+ subparser.add_method(helpstr=helpstr)
56+ subparser.add_threshold()
57+ subparser.add_silence()
58+ subparser.add_minioi()
59+ subparser.add_time_format()
60+ subparser.add_verbose_help()
3961 subparser.set_defaults(process=process_onset)
4062
63+def parser_add_subcommand_pitch(subparsers):
4164 # pitch subcommand
4265 subparser = subparsers.add_parser('pitch',
4366 help='estimate fundamental frequency (monophonic)')
44− parser_add_input(subparser)
45− parser_add_buf_hop_size(subparser, buf_size=2048)
67+ subparser.add_input()
68+ subparser.add_buf_hop_size(buf_size=2048)
4669 helpstr = "pitch detection method <default|yinfft|yin|mcomb|fcomb|schmitt>"
47− parser_add_method(subparser, helpstr=helpstr)
48− parser_add_threshold(subparser)
49− parser_add_pitch_unit(subparser)
50− parser_add_silence(subparser)
51− parser_add_time_format(subparser)
52− parser_add_verbose_help(subparser)
70+ subparser.add_method(helpstr=helpstr)
71+ subparser.add_threshold()
72+ subparser.add_pitch_unit()
73+ subparser.add_silence()
74+ subparser.add_time_format()
75+ subparser.add_verbose_help()
5376 subparser.set_defaults(process=process_pitch)
5477
78+def parser_add_subcommand_beat(subparsers):
5579 # beat subcommand
5680 subparser = subparsers.add_parser('beat',
5781 help='estimate location of beats')
58− parser_add_input(subparser)
59− parser_add_buf_hop_size(subparser, buf_size=1024, hop_size=512)
60− parser_add_time_format(subparser)
61− parser_add_verbose_help(subparser)
82+ subparser.add_input()
83+ subparser.add_buf_hop_size(buf_size=1024, hop_size=512)
84+ subparser.add_time_format()
85+ subparser.add_verbose_help()
6286 subparser.set_defaults(process=process_beat)
6387
88+def parser_add_subcommand_tempo(subparsers):
6489 # tempo subcommand
6590 subparser = subparsers.add_parser('tempo',
6691 help='estimate overall tempo in bpm')
67− parser_add_input(subparser)
68− parser_add_buf_hop_size(subparser, buf_size=1024, hop_size=512)
69− parser_add_time_format(subparser)
70− parser_add_verbose_help(subparser)
92+ subparser.add_input()
93+ subparser.add_buf_hop_size(buf_size=1024, hop_size=512)
94+ subparser.add_time_format()
95+ subparser.add_verbose_help()
7196 subparser.set_defaults(process=process_tempo)
7297
98+def parser_add_subcommand_notes(subparsers):
7399 # notes subcommand
74100 subparser = subparsers.add_parser('notes',
75101 help='estimate midi-like notes (monophonic)')
76− parser_add_input(subparser)
77− parser_add_buf_hop_size(subparser)
78− parser_add_time_format(subparser)
79− parser_add_verbose_help(subparser)
102+ subparser.add_input()
103+ subparser.add_buf_hop_size()
104+ subparser.add_time_format()
105+ subparser.add_verbose_help()
80106 subparser.set_defaults(process=process_notes)
81107
108+def parser_add_subcommand_mfcc(subparsers):
82109 # mfcc subcommand
83110 subparser = subparsers.add_parser('mfcc',
84111 help='extract Mel-Frequency Cepstrum Coefficients')
85− parser_add_input(subparser)
86− parser_add_buf_hop_size(subparser)
87− parser_add_time_format(subparser)
88− parser_add_verbose_help(subparser)
112+ subparser.add_input()
113+ subparser.add_buf_hop_size()
114+ subparser.add_time_format()
115+ subparser.add_verbose_help()
89116 subparser.set_defaults(process=process_mfcc)
90117
118+def parser_add_subcommand_melbands(subparsers):
91119 # melbands subcommand
92120 subparser = subparsers.add_parser('melbands',
93121 help='extract energies in Mel-frequency bands')
94− parser_add_input(subparser)
95− parser_add_buf_hop_size(subparser)
96− parser_add_time_format(subparser)
97− parser_add_verbose_help(subparser)
122+ subparser.add_input()
123+ subparser.add_buf_hop_size()
124+ subparser.add_time_format()
125+ subparser.add_verbose_help()
98126 subparser.set_defaults(process=process_melbands)
99127
100− return parser
101−
102−def parser_add_input(parser):
103− parser.add_argument("source_uri", default=None, nargs='?',
104− help="input sound file to analyse", metavar = "<source_uri>")
105− parser.add_argument("-i", "--input", dest = "source_uri2",
106− help="input sound file to analyse", metavar = "<source_uri>")
107− parser.add_argument("-r", "--samplerate",
108− metavar = "<freq>", type=int,
109− action="store", dest="samplerate", default=0,
110− help="samplerate at which the file should be represented")
111−
112−def parser_add_verbose_help(parser):
113− parser.add_argument("-v","--verbose",
114− action="count", dest="verbose", default=1,
115− help="make lots of noise [default]")
116− parser.add_argument("-q","--quiet",
117− action="store_const", dest="verbose", const=0,
118− help="be quiet")
119−
120−def parser_add_buf_hop_size(parser, buf_size=512, hop_size=256):
121− parser.add_argument("-B","--bufsize",
122− action="store", dest="buf_size", default=buf_size,
123− metavar = "<size>", type=int,
124− help="buffer size [default=%d]" % buf_size)
125− parser.add_argument("-H","--hopsize",
126− metavar = "<size>", type=int,
127− action="store", dest="hop_size", default=hop_size,
128− help="overlap size [default=%d]" % hop_size)
129−
130−def parser_add_method(parser, method='default', helpstr='method'):
131− parser.add_argument("-m","--method",
132− metavar = "<method>", type=str,
133− action="store", dest="method", default=method,
134− help="%s [default=%s]" % (helpstr, method))
135−
136−def parser_add_threshold(parser, default=None):
137− parser.add_argument("-t","--threshold",
138− metavar = "<threshold>", type=float,
139− action="store", dest="threshold", default=default,
140− help="threshold [default=%s]" % default)
141−
142−def parser_add_silence(parser):
143− parser.add_argument("-s", "--silence",
144− metavar = "<value>", type=float,
145− action="store", dest="silence", default=-70,
146− help="silence threshold")
147−
148−def parser_add_minioi(parser):
149− parser.add_argument("-M", "--minioi",
150− metavar = "<value>", type=str,
151− action="store", dest="minioi", default="12ms",
152− help="minimum Inter-Onset Interval")
153−
154−def parser_add_pitch_unit(parser, default="Hz"):
155− help_str = "frequency unit, should be one of Hz, midi, bin, cent"
156− help_str += " [default=%s]" % default
157− parser.add_argument("-u", "--pitch-unit",
158− metavar = "<value>", type=str,
159− action="store", dest="pitch_unit", default=default,
160− help=help_str)
161−
162−def parser_add_time_format(parser):
163− helpstr = "select time values output format (samples, ms, seconds)"
164− helpstr += " [default=seconds]"
165− parser.add_argument("-T", "--time-format",
166− metavar='format',
167− dest="time_format",
168− default=None,
169− help=helpstr)
128+def parser_add_subcommand_quiet(subparsers):
129+ # quiet subcommand
130+ subparser = subparsers.add_parser('quiet',
131+ help='extract timestamps of quiet and loud regions')
132+ subparser.add_input()
133+ subparser.add_hop_size()
134+ subparser.add_silence()
135+ subparser.add_time_format()
136+ subparser.add_verbose_help()
137+ subparser.set_defaults(process=process_quiet)
138+
139+def parser_add_subcommand_cut(subparsers):
140+ # quiet subcommand
141+ subparser = subparsers.add_parser('cut',
142+ help='slice at timestamps')
143+ subparser.add_input()
144+ helpstr = "onset novelty function"
145+ helpstr += " <default|energy|hfc|complex|phase|specdiff|kl|mkl|specflux>"
146+ subparser.add_method(helpstr=helpstr)
147+ subparser.add_buf_hop_size()
148+ subparser.add_silence()
149+ subparser.add_threshold(default=0.3)
150+ subparser.add_minioi()
151+ subparser.add_slicer_options()
152+ subparser.add_time_format()
153+ subparser.add_verbose_help()
154+ subparser.set_defaults(process=process_cut)
155+
156+class AubioArgumentParser(argparse.ArgumentParser):
157+
158+ def add_input(self):
159+ self.add_argument("source_uri", default=None, nargs='?',
160+ help="input sound file to analyse", metavar = "<source_uri>")
161+ self.add_argument("-i", "--input", dest = "source_uri2",
162+ help="input sound file to analyse", metavar = "<source_uri>")
163+ self.add_argument("-r", "--samplerate",
164+ metavar = "<freq>", type=int,
165+ action="store", dest="samplerate", default=0,
166+ help="samplerate at which the file should be represented")
167+
168+ def add_verbose_help(self):
169+ self.add_argument("-v","--verbose",
170+ action="count", dest="verbose", default=1,
171+ help="make lots of noise [default]")
172+ self.add_argument("-q","--quiet",
173+ action="store_const", dest="verbose", const=0,
174+ help="be quiet")
175+
176+ def add_buf_hop_size(self, buf_size=512, hop_size=256):
177+ self.add_buf_size(buf_size=buf_size)
178+ self.add_hop_size(hop_size=hop_size)
179+
180+ def add_buf_size(self, buf_size=512):
181+ self.add_argument("-B","--bufsize",
182+ action="store", dest="buf_size", default=buf_size,
183+ metavar = "<size>", type=int,
184+ help="buffer size [default=%d]" % buf_size)
185+
186+ def add_hop_size(self, hop_size=256):
187+ self.add_argument("-H","--hopsize",
188+ metavar = "<size>", type=int,
189+ action="store", dest="hop_size", default=hop_size,
190+ help="overlap size [default=%d]" % hop_size)
191+
192+ def add_method(self, method='default', helpstr='method'):
193+ self.add_argument("-m","--method",
194+ metavar = "<method>", type=str,
195+ action="store", dest="method", default=method,
196+ help="%s [default=%s]" % (helpstr, method))
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")
170250
171251 # some utilities
172252
@@ -176,7 +256,7 @@ def samples2seconds(n_frames, samplerate): · 3 unmodified lines
176256 def samples2milliseconds(n_frames, samplerate):
177257 return "%f\t" % (1000. * n_frames / float(samplerate))
178258
179−def samples2samples(n_frames, samplerate):
259+def samples2samples(n_frames, _samplerate):
180260 return "%d\t" % n_frames
181261
182262 def timefunc(mode):
@@ -199,7 +279,7 @@ class default_process(object): · 16 unmodified lines
199279 name = type(self).__name__.split('_')[1]
200280 optstr = ' '.join(['running', name, 'with options', repr(self.options), '\n'])
201281 sys.stderr.write(optstr)
202− def flush(self, n_frames, samplerate):
282+ def flush(self, frames_read, samplerate):
203283 # optionally called at the end of process
204284 pass
205285
@@ -238,7 +318,7 @@ class process_onset(default_process): · 32 unmodified lines
238318 super(process_onset, self).__init__(args)
239319 def __call__(self, block):
240320 return self.onset(block)
241− def repr_res(self, res, frames_read, samplerate):
321+ def repr_res(self, res, _frames_read, samplerate):
242322 if res[0] != 0:
243323 outstr = self.time2string(self.onset.get_last(), samplerate)
244324 sys.stdout.write(outstr + '\n')
@@ -269,7 +349,7 @@ class process_beat(default_process): · 24 unmodified lines
269349 super(process_beat, self).__init__(args)
270350 def __call__(self, block):
271351 return self.tempo(block)
272− def repr_res(self, res, frames_read, samplerate):
352+ def repr_res(self, res, _frames_read, samplerate):
273353 if res[0] != 0:
274354 outstr = self.time2string(self.tempo.get_last(), samplerate)
275355 sys.stdout.write(outstr + '\n')
@@ -278,7 +358,7 @@ class process_tempo(process_beat): · 2 unmodified lines
278358 def __init__(self, args):
279359 super(process_tempo, self).__init__(args)
280360 self.beat_locations = []
281− def repr_res(self, res, frames_read, samplerate):
361+ def repr_res(self, res, _frames_read, samplerate):
282362 if res[0] != 0:
283363 self.beat_locations.append(self.tempo.get_last_s())
284364 def flush(self, frames_read, samplerate):
@@ -362,6 +442,61 @@ class process_melbands(default_process): · 77 unmodified lines
362442 fmt_out += ' '.join(["% 9.7f" % f for f in res.tolist()])
363443 sys.stdout.write(fmt_out + '\n')
364444
445+class 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+
478+class 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+
365500 def main():
366501 parser = aubio_parser()
367502 args = parser.parse_args()
@@ -370,10 +505,13 @@ def main(): · 2 unmodified lines
370505 sys.exit(0)
371506 elif 'verbose' in args and args.verbose > 3:
372507 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']:
374509 # no command given, print help and return 1
375510 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)
377515 elif not args.source_uri and not args.source_uri2:
378516 sys.stderr.write("Error: a source is required\n")
379517 parser.print_help()
python/lib/aubio/cut.py+57−88
@@ -5,16 +5,11 @@ · 4 unmodified lines
55 """
66
77 import sys
8−import argparse
9−
10−def parse_args():
11− usage = "usage: %s [options] -i soundfile" % sys.argv[0]
12− usage += "\n help: %s -h" % sys.argv[0]
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>")
8+from aubio.cmd import AubioArgumentParser
9+
10+def aubio_cut_parser():
11+ parser = AubioArgumentParser()
12+ parser.add_input()
1813 parser.add_argument("-O","--onset-method",
1914 action="store", dest="onset_method", default='default',
2015 metavar = "<onset_method>",
@@ -23,7 +18,7 @@ def parse_args(): · 2 unmodified lines
2318 # cutting methods
2419 parser.add_argument("-b","--beat",
2520 action="store_true", dest="beat", default=False,
26− help="use beat locations")
21+ help="slice at beat locations")
2722 """
2823 parser.add_argument("-S","--silencecut",
2924 action="store_true", dest="silencecut", default=False,
@@ -34,32 +29,15 @@ def parse_args(): · 4 unmodified lines
3429 help="silence threshold [default=-70]")
3530 """
3631 # algorithm parameters
37− parser.add_argument("-r", "--samplerate",
38− metavar = "<freq>", type=int,
39− action="store", dest="samplerate", default=0,
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,
32+ parser.add_buf_hop_size()
33+ parser.add_argument("-t","--threshold", "--onset-threshold",
34+ metavar = "<threshold>", type=float,
5135 action="store", dest="threshold", default=0.3,
5236 help="onset peak picking threshold [default=0.3]")
5337 parser.add_argument("-c","--cut",
5438 action="store_true", dest="cut", default=False,
55− help="cut input sound file at detected labels \
56− best used with option -L")
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]")
39+ help="cut input sound file at detected labels")
40+ parser.add_minioi()
6341
6442 """
6543 parser.add_argument("-D","--delay",
@@ -81,9 +59,7 @@ def parse_args(): · 15 unmodified lines
8159 metavar = "<value>",
8260 action="store", dest="zerothres", default=0.008,
8361 help="zero-crossing threshold for slicing [default=0.00008]")
84− """
8562 # plotting functions
86− """
8763 parser.add_argument("-p","--plot",
8864 action="store_true", dest="plot", default=False,
8965 help="draw plot")
@@ -109,51 +85,24 @@ def parse_args(): · 19 unmodified lines
10985 action="store_true", dest="spectro", default=False,
11086 help="add spectrogram to the plot")
11187 """
112− parser.add_argument("-o","--output", type = str,
113− metavar = "<outputdir>",
114− action="store", dest="output_directory", default=None,
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
88+ parser.add_slicer_options()
89+ parser.add_verbose_help()
90+ return parser
14391
144−def main():
145− options = parse_args()
14692
147− source_file = options.source_file
148− hopsize = options.hopsize
149− bufsize = options.bufsize
93+def _cut_analyze(options):
94+ hopsize = options.hop_size
95+ bufsize = options.buf_size
15096 samplerate = options.samplerate
151− source_file = options.source_file
97+ source_uri = options.source_uri
15298
99+ # analyze pass
153100 from aubio import onset, tempo, source
154101
155− s = source(source_file, samplerate, hopsize)
156− if samplerate == 0: samplerate = s.get_samplerate()
102+ s = source(source_uri, samplerate, hopsize)
103+ if samplerate == 0:
104+ samplerate = s.get_samplerate()
105+ options.samplerate = samplerate
157106
158107 if options.beat:
159108 o = tempo(options.onset_method, bufsize, hopsize, samplerate=samplerate)
@@ -170,7 +119,6 @@ def main(): · 10 unmodified lines
170119
171120 timestamps = []
172121 total_frames = 0
173− # analyze pass
174122 while True:
175123 samples, read = s()
176124 if o(samples):
@@ -179,15 +127,12 @@ def main(): · 2 unmodified lines
179127 total_frames += read
180128 if read < hopsize: break
181129 del s
182− # print some info
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)
130+ return timestamps, total_frames
188131
132+def _cut_slice(options, timestamps):
189133 # cutting pass
190− if options.cut and nstamps > 0:
134+ nstamps = len(timestamps)
135+ if nstamps > 0:
191136 # generate output files
192137 from aubio.slicing import slice_source_at_stamps
193138 timestamps_end = None
@@ -202,12 +147,36 @@ def main(): · 8 unmodified lines
202147 if options.cut_until_nslices:
203148 timestamps_end = [t for t in timestamps[1 + options.cut_until_nslices:]]
204149 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,
206152 output_dir = options.output_directory,
207− samplerate = samplerate)
153+ samplerate = options.samplerate)
154+
155+def 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)
208177
209− # print some info
210− duration = float (total_frames) / float(samplerate)
211− info = 'created %(nstamps)d slices from %(source_file)s' % locals()
212− info += ' (total %(duration).2fs at %(samplerate)dHz)\n' % locals()
178+ if options.cut:
179+ _cut_slice(options, timestamps)
180+ info = "created %d slices from " % len(timestamps)
181+ info += base_info
213182 sys.stderr.write(info)
python/tests/test_aubio_cmd.py+27−0
@@ -0,0 +1,27 @@
1+#! /usr/bin/env python
2+
3+import aubio.cmd
4+from nose2 import main
5+from numpy.testing import TestCase
6+
7+class 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+
15+class 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+
26+if __name__ == '__main__':
27+ main()
python/tests/test_aubio_cut.py+16−0
@@ -0,0 +1,16 @@
1+#! /usr/bin/env python
2+
3+import aubio.cut
4+from nose2 import main
5+from numpy.testing import TestCase
6+
7+class 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+
15+if __name__ == '__main__':
16+ main()
python/tests/test_filterbank.py+11−4
@@ -1,9 +1,8 @@
11 #! /usr/bin/env python
22
3−from unittest import main
4−from numpy.testing import TestCase
5−from numpy.testing import assert_equal, assert_almost_equal
63 import numpy as np
4+from numpy.testing import TestCase, assert_equal, assert_almost_equal
5+
76 from aubio import cvec, filterbank, float_type
87 from .utils import array_from_text_file
98
@@ -62,6 +61,13 @@ class aubio_filterbank_test_case(TestCase): · 52 unmodified lines
6261 f.set_mel_coeffs_slaney(16000)
6362 assert_almost_equal ( expected, f.get_coeffs() )
6463
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+
6571 class aubio_filterbank_wrong_values(TestCase):
6672
6773 def test_negative_window(self):
@@ -81,4 +87,5 @@ class aubio_filterbank_wrong_values(TestCase): · 13 unmodified lines
8187 f(cvec(256))
8288
8389 if __name__ == '__main__':
84− main()
90+ import nose2
91+ nose2.main()
python/tests/test_filterbank_mel.py+15−12
@@ -1,44 +1,46 @@
11 #! /usr/bin/env python
22
3−from unittest import main
4−from numpy.testing import TestCase
5−from numpy.testing import assert_equal, assert_almost_equal
6−from numpy import array, shape
3+import numpy as np
4+from numpy.testing import TestCase, assert_equal, assert_almost_equal
5+
76 from aubio import cvec, filterbank, float_type
87
8+import warnings
9+warnings.filterwarnings('ignore', category=UserWarning, append=True)
10+
911 class aubio_filterbank_mel_test_case(TestCase):
1012
1113 def test_slaney(self):
1214 f = filterbank(40, 512)
1315 f.set_mel_coeffs_slaney(16000)
1416 a = f.get_coeffs()
15− assert_equal(shape (a), (40, 512/2 + 1) )
17+ assert_equal(np.shape (a), (40, 512/2 + 1) )
1618
1719 def test_other_slaney(self):
1820 f = filterbank(40, 512*2)
1921 f.set_mel_coeffs_slaney(44100)
20− _ = f.get_coeffs()
22+ self.assertIsInstance(f.get_coeffs(), np.ndarray)
2123 #print "sum is", sum(sum(a))
2224 for win_s in [256, 512, 1024, 2048, 4096]:
2325 f = filterbank(40, win_s)
2426 f.set_mel_coeffs_slaney(32000)
25− _ = f.get_coeffs()
2627 #print "sum is", sum(sum(a))
28+ self.assertIsInstance(f.get_coeffs(), np.ndarray)
2729
2830 def test_triangle_freqs_zeros(self):
2931 f = filterbank(9, 1024)
3032 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)
3234 f.set_triangle_bands(freqs, 48000)
33− _ = f.get_coeffs().T
3435 assert_equal ( f(cvec(1024)), 0)
36+ self.assertIsInstance(f.get_coeffs(), np.ndarray)
3537
3638 def test_triangle_freqs_ones(self):
3739 f = filterbank(9, 1024)
3840 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)
4042 f.set_triangle_bands(freqs, 48000)
41− _ = f.get_coeffs().T
43+ self.assertIsInstance(f.get_coeffs(), np.ndarray)
4244 spec = cvec(1024)
4345 spec.norm[:] = 1
4446 assert_almost_equal ( f(spec),
@@ -46,4 +48,5 @@ class aubio_filterbank_mel_test_case(TestCase): · 1 unmodified line
4648 0.02133301, 0.02133301, 0.02133311, 0.02133334, 0.02133345])
4749
4850 if __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