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
255255 metavar = "<slices>",
256256 action = "store", dest = "cut_until_nslices", default = None,
257257 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")
258261
259262 # some utilities
260263
@@ -511,7 +514,24 @@ class process_cut(process_onset): · 250 unmodified lines
511514
512515 def main():
513516 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()
515535 if 'show_version' in args and args.show_version:
516536 sys.stdout.write('aubio version ' + aubio.version + '\n')
517537 sys.exit(0)
python/lib/aubio/cut.py+3−2
@@ -101,7 +101,7 @@ def _cut_analyze(options): · 100 unmodified lines
101101
102102 s = source(source_uri, samplerate, hopsize)
103103 if samplerate == 0:
104− samplerate = s.get_samplerate()
104+ samplerate = s.samplerate
105105 options.samplerate = samplerate
106106
107107 if options.beat:
@@ -150,7 +150,8 @@ def _cut_slice(options, timestamps): · 42 unmodified lines
150150 slice_source_at_stamps(options.source_uri,
151151 timestamps, timestamps_end = timestamps_end,
152152 output_dir = options.output_directory,
153− samplerate = options.samplerate)
153+ samplerate = options.samplerate,
154+ create_first = options.create_first)
154155
155156 def main():
156157 parser = aubio_cut_parser()
python/lib/aubio/midiconv.py+38−9
@@ -1,9 +1,11 @@
11 # -*- coding: utf-8 -*-
22 """ utilities to convert midi note number to and from note names """
33
4−__all__ = ['note2midi', 'midi2note', 'freq2note']
4+__all__ = ['note2midi', 'midi2note', 'freq2note', 'note2freq']
55
66 import sys
7+from ._aubio import freqtomidi, miditofreq
8+
79 py3 = sys.version_info[0] == 3
810 if py3:
911 str_instances = str
@@ -24,10 +26,11 @@ def note2midi(note): · 14 unmodified lines
2426 }
2527 _valid_octaves = range(-1, 10)
2628 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)))
2831 if len(note) not in range(2, 5):
29− raise ValueError("string of 2 to 4 characters expected, got %d (%s)" \
30− % (len(note), note))
32+ msg = "string of 2 to 4 characters expected, got {:d} ({:s})"
33+ raise ValueError(msg.format(len(note), note))
3134 notename, modifier, octave = [None]*3
3235
3336 if len(note) == 4:
@@ -51,7 +54,8 @@ def note2midi(note): · 17 unmodified lines
5154 if octave not in _valid_octaves:
5255 raise ValueError("%s is not a valid octave" % octave)
5356
54− midi = 12 + octave * 12 + _valid_notenames[notename] + _valid_modifiers[modifier]
57+ midi = 12 + octave * 12 + _valid_notenames[notename] \
58+ + _valid_modifiers[modifier]
5559 if midi > 127:
5660 raise ValueError("%s is outside of the range C-2 to G8" % note)
5761 return midi
@@ -61,11 +65,36 @@ def midi2note(midi): · 3 unmodified lines
6165 if not isinstance(midi, int_instances):
6266 raise TypeError("an integer is required, got %s" % midi)
6367 if midi not in range(0, 128):
64− raise ValueError("an integer between 0 and 127 is excepted, got %d" % midi)
65− _valid_notenames = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B']
68+ msg = "an integer between 0 and 127 is excepted, got {:d}"
69+ raise ValueError(msg.format(midi))
70+ _valid_notenames = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#',
71+ 'A', 'A#', 'B']
6672 return _valid_notenames[midi % 12] + str(int(midi / 12) - 1)
6773
6874 def freq2note(freq):
6975 " convert frequency in Hz to nearest note name, e.g. [0, 22050.] -> [C-1, G9] "
70− from aubio import freqtomidi
71− return midi2note(int(freqtomidi(freq)))
76+ nearest_note = int(freqtomidi(freq) + .5)
77+ return midi2note(nearest_note)
78+
79+def 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
66 _max_timestamp = 1e120
77
88 def 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):
1011 """ slice a sound file at given timestamps """
1112
1213 if timestamps is None or len(timestamps) == 0:
1314 raise ValueError("no timestamps given")
1415
15− if timestamps[0] != 0:
16+ if timestamps[0] != 0 and create_first:
1617 timestamps = [0] + timestamps
1718 if timestamps_end is not None:
1819 timestamps_end = [timestamps[1] - 1] + timestamps_end
1920
2021 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):
2225 raise ValueError("len(timestamps_end) != len(timestamps)")
2326 else:
2427 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
4851 # get hopsize new samples from source
4952 vec, read = _source.do_multi()
5053 # 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]:
5255 #print "getting", regions[0], "at", total_frames
5356 # get next region
5457 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
7578 if remaining > start:
7679 # write remaining samples from current region
7780 _sink.do_multi(vec[:, start:remaining], remaining - start)
78− #print "closing region", "remaining", remaining
81+ #print("closing region", "remaining", remaining)
7982 # close this file
8083 _sink.close()
8184 elif read > start:
8285 # write all the samples
8386 _sink.do_multi(vec[:, start:read], read - start)
8487 total_frames += read
88+ # remove old slices
89+ slices = list(filter(lambda s: s['end_stamp'] > total_frames,
90+ slices))
8591 if read < hopsize:
8692 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