History

Merge branch 'master' into feature/earlynoteoff

Paul Brossier committed 8 years ago

Commit 4bc10e22 parents 357f81e cefa29d28 files · +384 −117Browse files

Showing the changes to python/lib (4 of 28 files). Show all

Unified · Split

4 files
  1. python/lib/aubio/cmd.py +21 −1
  2. python/lib/aubio/cut.py +3 −2
  3. python/lib/aubio/midiconv.py +38 −9
  4. python/lib/aubio/slicing.py +11 −5
python/lib/aubio/cmd.py+21−1
@@ -255,6 +255,9 @@ class AubioArgumentParser(argparse.ArgumentParser): · 254 unmodified lines
255 metavar = "<slices>",255 metavar = "<slices>",
256 action = "store", dest = "cut_until_nslices", default = None,256 action = "store", dest = "cut_until_nslices", default = None,
257 help="how many extra slices should be added at the end of each slice")257 help="how many extra slices should be added at the end of each slice")
258 self.add_argument("--create-first",
259 action = "store_true", dest = "create_first", default = False,
260 help="always include first slice")
258 261
259# some utilities262# some utilities
260 263
@@ -511,7 +514,24 @@ class process_cut(process_onset): · 250 unmodified lines
511 514
512def main():515def main():
513 parser = aubio_parser()516 parser = aubio_parser()
514 args = parser.parse_args()517 if sys.version_info[0] != 3:
518 # on py2, create a dummy ArgumentParser to workaround the
519 # optional subcommand issue. See https://bugs.python.org/issue9253
520 # This ensures that:
521 # - version string is shown when only '-V' is passed
522 # - help is printed if '-V' is passed with any other argument
523 # - any other argument get forwarded to the real parser
524 parser_root = argparse.ArgumentParser(add_help=False)
525 parser_root.add_argument('-V', '--version', help="show version",
526 action="store_true", dest="show_version")
527 args, extras = parser_root.parse_known_args()
528 if args.show_version == False: # no -V, forward to parser
529 args = parser.parse_args(extras, namespace=args)
530 elif len(extras) != 0: # -V with other arguments, print help
531 parser.print_help()
532 sys.exit(1)
533 else: # in py3, we can simply use parser directly
534 args = parser.parse_args()
515 if 'show_version' in args and args.show_version:535 if 'show_version' in args and args.show_version:
516 sys.stdout.write('aubio version ' + aubio.version + '\n')536 sys.stdout.write('aubio version ' + aubio.version + '\n')
517 sys.exit(0)537 sys.exit(0)
python/lib/aubio/cut.py+3−2
@@ -101,7 +101,7 @@ def _cut_analyze(options): · 100 unmodified lines
101 101
102 s = source(source_uri, samplerate, hopsize)102 s = source(source_uri, samplerate, hopsize)
103 if samplerate == 0:103 if samplerate == 0:
104 samplerate = s.get_samplerate()104 samplerate = s.samplerate
105 options.samplerate = samplerate105 options.samplerate = samplerate
106 106
107 if options.beat:107 if options.beat:
@@ -150,7 +150,8 @@ def _cut_slice(options, timestamps): · 42 unmodified lines
150 slice_source_at_stamps(options.source_uri,150 slice_source_at_stamps(options.source_uri,
151 timestamps, timestamps_end = timestamps_end,151 timestamps, timestamps_end = timestamps_end,
152 output_dir = options.output_directory,152 output_dir = options.output_directory,
153 samplerate = options.samplerate)153 samplerate = options.samplerate,
154 create_first = options.create_first)
154 155
155def main():156def main():
156 parser = aubio_cut_parser()157 parser = aubio_cut_parser()
python/lib/aubio/midiconv.py+38−9
@@ -1,9 +1,11 @@
1# -*- coding: utf-8 -*-1# -*- coding: utf-8 -*-
2""" utilities to convert midi note number to and from note names """2""" utilities to convert midi note number to and from note names """
3 3
4__all__ = ['note2midi', 'midi2note', 'freq2note']4__all__ = ['note2midi', 'midi2note', 'freq2note', 'note2freq']
5 5
6import sys6import sys
7from ._aubio import freqtomidi, miditofreq
8
7py3 = sys.version_info[0] == 39py3 = sys.version_info[0] == 3
8if py3:10if py3:
9 str_instances = str11 str_instances = str
@@ -24,10 +26,11 @@ def note2midi(note): · 14 unmodified lines
24 }26 }
25 _valid_octaves = range(-1, 10)27 _valid_octaves = range(-1, 10)
26 if not isinstance(note, str_instances):28 if not isinstance(note, str_instances):
27 raise TypeError("a string is required, got %s (%s)" % (note, str(type(note))))29 msg = "a string is required, got {:s} ({:s})"
30 raise TypeError(msg.format(str(type(note)), repr(note)))
28 if len(note) not in range(2, 5):31 if len(note) not in range(2, 5):
29 raise ValueError("string of 2 to 4 characters expected, got %d (%s)" \32 msg = "string of 2 to 4 characters expected, got {:d} ({:s})"
30 % (len(note), note))33 raise ValueError(msg.format(len(note), note))
31 notename, modifier, octave = [None]*334 notename, modifier, octave = [None]*3
32 35
33 if len(note) == 4:36 if len(note) == 4:
@@ -51,7 +54,8 @@ def note2midi(note): · 17 unmodified lines
51 if octave not in _valid_octaves:54 if octave not in _valid_octaves:
52 raise ValueError("%s is not a valid octave" % octave)55 raise ValueError("%s is not a valid octave" % octave)
53 56
54 midi = 12 + octave * 12 + _valid_notenames[notename] + _valid_modifiers[modifier]57 midi = 12 + octave * 12 + _valid_notenames[notename] \
58 + _valid_modifiers[modifier]
55 if midi > 127:59 if midi > 127:
56 raise ValueError("%s is outside of the range C-2 to G8" % note)60 raise ValueError("%s is outside of the range C-2 to G8" % note)
57 return midi61 return midi
@@ -61,11 +65,36 @@ def midi2note(midi): · 3 unmodified lines
61 if not isinstance(midi, int_instances):65 if not isinstance(midi, int_instances):
62 raise TypeError("an integer is required, got %s" % midi)66 raise TypeError("an integer is required, got %s" % midi)
63 if midi not in range(0, 128):67 if midi not in range(0, 128):
64 raise ValueError("an integer between 0 and 127 is excepted, got %d" % midi)68 msg = "an integer between 0 and 127 is excepted, got {:d}"
65 _valid_notenames = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B']69 raise ValueError(msg.format(midi))
70 _valid_notenames = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#',
71 'A', 'A#', 'B']
66 return _valid_notenames[midi % 12] + str(int(midi / 12) - 1)72 return _valid_notenames[midi % 12] + str(int(midi / 12) - 1)
67 73
68def freq2note(freq):74def freq2note(freq):
69 " convert frequency in Hz to nearest note name, e.g. [0, 22050.] -> [C-1, G9] "75 " convert frequency in Hz to nearest note name, e.g. [0, 22050.] -> [C-1, G9] "
70 from aubio import freqtomidi76 nearest_note = int(freqtomidi(freq) + .5)
71 return midi2note(int(freqtomidi(freq)))77 return midi2note(nearest_note)
78
79def note2freq(note):
80 """Convert note name to corresponding frequency, in Hz.
81
82 Parameters
83 ----------
84 note : str
85 input note name
86
87 Returns
88 -------
89 freq : float [0, 23000[
90 frequency, in Hz
91
92 Example
93 -------
94 >>> aubio.note2freq('A4')
95 440
96 >>> aubio.note2freq('A3')
97 220.1
98 """
99 midi = note2midi(note)
100 return miditofreq(midi)
python/lib/aubio/slicing.py+11−5
@@ -6,19 +6,22 @@ from aubio import source, sink · 5 unmodified lines
6_max_timestamp = 1e1206_max_timestamp = 1e120
7 7
8def slice_source_at_stamps(source_file, timestamps, timestamps_end=None,8def slice_source_at_stamps(source_file, timestamps, timestamps_end=None,
9 output_dir=None, samplerate=0, hopsize=256):9 output_dir=None, samplerate=0, hopsize=256,
10 create_first=False):
10 """ slice a sound file at given timestamps """11 """ slice a sound file at given timestamps """
11 12
12 if timestamps is None or len(timestamps) == 0:13 if timestamps is None or len(timestamps) == 0:
13 raise ValueError("no timestamps given")14 raise ValueError("no timestamps given")
14 15
15 if timestamps[0] != 0:16 if timestamps[0] != 0 and create_first:
16 timestamps = [0] + timestamps17 timestamps = [0] + timestamps
17 if timestamps_end is not None:18 if timestamps_end is not None:
18 timestamps_end = [timestamps[1] - 1] + timestamps_end19 timestamps_end = [timestamps[1] - 1] + timestamps_end
19 20
20 if timestamps_end is not None:21 if timestamps_end is not None:
21 if len(timestamps_end) != len(timestamps):22 if len(timestamps_end) == len(timestamps) - 1:
23 timestamps_end = timestamps_end + [_max_timestamp]
24 elif len(timestamps_end) != len(timestamps):
22 raise ValueError("len(timestamps_end) != len(timestamps)")25 raise ValueError("len(timestamps_end) != len(timestamps)")
23 else:26 else:
24 timestamps_end = [t - 1 for t in timestamps[1:]] + [_max_timestamp]27 timestamps_end = [t - 1 for t in timestamps[1:]] + [_max_timestamp]
@@ -48,7 +51,7 @@ def slice_source_at_stamps(source_file, timestamps, timestamps_end=None, · 23 unmodified lines
48 # get hopsize new samples from source51 # get hopsize new samples from source
49 vec, read = _source.do_multi()52 vec, read = _source.do_multi()
50 # if the total number of frames read will exceed the next region start53 # if the total number of frames read will exceed the next region start
51 if len(regions) and total_frames + read >= regions[0][0]:54 while len(regions) and total_frames + read >= regions[0][0]:
52 #print "getting", regions[0], "at", total_frames55 #print "getting", regions[0], "at", total_frames
53 # get next region56 # get next region
54 start_stamp, end_stamp = regions.pop(0)57 start_stamp, end_stamp = regions.pop(0)
@@ -75,12 +78,15 @@ def slice_source_at_stamps(source_file, timestamps, timestamps_end=None, · 20 unmodified lines
75 if remaining > start:78 if remaining > start:
76 # write remaining samples from current region79 # write remaining samples from current region
77 _sink.do_multi(vec[:, start:remaining], remaining - start)80 _sink.do_multi(vec[:, start:remaining], remaining - start)
78 #print "closing region", "remaining", remaining81 #print("closing region", "remaining", remaining)
79 # close this file82 # close this file
80 _sink.close()83 _sink.close()
81 elif read > start:84 elif read > start:
82 # write all the samples85 # write all the samples
83 _sink.do_multi(vec[:, start:read], read - start)86 _sink.do_multi(vec[:, start:read], read - start)
84 total_frames += read87 total_frames += read
88 # remove old slices
89 slices = list(filter(lambda s: s['end_stamp'] > total_frames,
90 slices))
85 if read < hopsize:91 if read < hopsize:
86 break92 break

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