Showing the changes to python (1 of 1 file). Show all
Unified · Split
| @@ -1,15 +1,16 @@ | |||
| 1 | from aubio import source, sink | 1 | """utility routines to slice sound files at given timestamps""" |
| 2 | |||
| 2 | import os | 3 | import os |
| 4 | from aubio import source, sink | ||
| 3 | 5 | ||
| 4 | max_timestamp = 1e120 | 6 | _max_timestamp = 1e120 |
| 5 | 7 | ||
| 6 | def slice_source_at_stamps(source_file, timestamps, timestamps_end = None, | 8 | def slice_source_at_stamps(source_file, timestamps, timestamps_end=None, |
| 7 | output_dir = None, | 9 | output_dir=None, samplerate=0, hopsize=256): |
| 8 | samplerate = 0, | 10 | """ slice a sound file at given timestamps """ |
| 9 | hopsize = 256): | ||
| 10 | 11 | ||
| 11 | if timestamps == None or len(timestamps) == 0: | 12 | if timestamps is None or len(timestamps) == 0: |
| 12 | raise ValueError ("no timestamps given") | 13 | raise ValueError("no timestamps given") |
| 13 | 14 | ||
| 14 | if timestamps[0] != 0: | 15 | if timestamps[0] != 0: |
| 15 | timestamps = [0] + timestamps | 16 | timestamps = [0] + timestamps |
| @@ -18,33 +19,34 @@ def slice_source_at_stamps(source_file, timestamps, timestamps_end = None, · 2 unmodified lines | |||
| 18 | 19 | ||
| 19 | if timestamps_end != None: | 20 | if timestamps_end != None: |
| 20 | if len(timestamps_end) != len(timestamps): | 21 | if len(timestamps_end) != len(timestamps): |
| 21 | raise ValueError ("len(timestamps_end) != len(timestamps)") | 22 | raise ValueError("len(timestamps_end) != len(timestamps)") |
| 22 | else: | 23 | else: |
| 23 | timestamps_end = [t - 1 for t in timestamps[1:] ] + [ max_timestamp ] | 24 | timestamps_end = [t - 1 for t in timestamps[1:]] + [_max_timestamp] |
| 24 | 25 | ||
| 25 | regions = list(zip(timestamps, timestamps_end)) | 26 | regions = list(zip(timestamps, timestamps_end)) |
| 26 | #print regions | 27 | #print regions |
| 27 | 28 | ||
| 28 | source_base_name, source_ext = os.path.splitext(os.path.basename(source_file)) | 29 | source_base_name, _ = os.path.splitext(os.path.basename(source_file)) |
| 29 | if output_dir != None: | 30 | if output_dir != None: |
| 30 | if not os.path.isdir(output_dir): | 31 | if not os.path.isdir(output_dir): |
| 31 | os.makedirs(output_dir) | 32 | os.makedirs(output_dir) |
| 32 | source_base_name = os.path.join(output_dir, source_base_name) | 33 | source_base_name = os.path.join(output_dir, source_base_name) |
| 33 | 34 | ||
| 34 | def new_sink_name(source_base_name, timestamp, samplerate): | 35 | def new_sink_name(source_base_name, timestamp, samplerate): |
| 36 | """ create a sink based on a timestamp in samples, converted in seconds """ | ||
| 35 | timestamp_seconds = timestamp / float(samplerate) | 37 | timestamp_seconds = timestamp / float(samplerate) |
| 36 | return source_base_name + "_%011.6f" % timestamp_seconds + '.wav' | 38 | return source_base_name + "_%011.6f" % timestamp_seconds + '.wav' |
| 37 | 39 | ||
| 38 | # reopen source file | 40 | # open source file |
| 39 | s = source(source_file, samplerate, hopsize) | 41 | _source = source(source_file, samplerate, hopsize) |
| 40 | samplerate = s.get_samplerate() | 42 | samplerate = source.get_samplerate() |
| 41 | 43 | ||
| 42 | total_frames = 0 | 44 | total_frames = 0 |
| 43 | slices = [] | 45 | slices = [] |
| 44 | 46 | ||
| 45 | while True: | 47 | while True: |
| 46 | # get hopsize new samples from source | 48 | # get hopsize new samples from source |
| 47 | vec, read = s.do_multi() | 49 | vec, read = _source.do_multi() |
| 48 | # if the total number of frames read will exceed the next region start | 50 | # if the total number of frames read will exceed the next region start |
| 49 | if len(regions) and total_frames + read >= regions[0][0]: | 51 | if len(regions) and total_frames + read >= regions[0][0]: |
| 50 | #print "getting", regions[0], "at", total_frames | 52 | #print "getting", regions[0], "at", total_frames |
| @@ -53,16 +55,16 @@ def slice_source_at_stamps(source_file, timestamps, timestamps_end = None, · 2 unmodified lines | |||
| 53 | # create a name for the sink | 55 | # create a name for the sink |
| 54 | new_sink_path = new_sink_name(source_base_name, start_stamp, samplerate) | 56 | new_sink_path = new_sink_name(source_base_name, start_stamp, samplerate) |
| 55 | # create its sink | 57 | # create its sink |
| 56 | g = sink(new_sink_path, samplerate, s.channels) | 58 | _sink = sink(new_sink_path, samplerate, _source.channels) |
| 57 | # create a dictionary containing all this | 59 | # create a dictionary containing all this |
| 58 | new_slice = {'start_stamp': start_stamp, 'end_stamp': end_stamp, 'sink': g} | 60 | new_slice = {'start_stamp': start_stamp, 'end_stamp': end_stamp, 'sink': _sink} |
| 59 | # append the dictionary to the current list of slices | 61 | # append the dictionary to the current list of slices |
| 60 | slices.append(new_slice) | 62 | slices.append(new_slice) |
| 61 | 63 | ||
| 62 | for current_slice in slices: | 64 | for current_slice in slices: |
| 63 | start_stamp = current_slice['start_stamp'] | 65 | start_stamp = current_slice['start_stamp'] |
| 64 | end_stamp = current_slice['end_stamp'] | 66 | end_stamp = current_slice['end_stamp'] |
| 65 | g = current_slice['sink'] | 67 | _sink = current_slice['sink'] |
| 66 | # sample index to start writing from new source vector | 68 | # sample index to start writing from new source vector |
| 67 | start = max(start_stamp - total_frames, 0) | 69 | start = max(start_stamp - total_frames, 0) |
| 68 | # number of samples yet to written be until end of region | 70 | # number of samples yet to written be until end of region |
| @@ -72,12 +74,13 @@ def slice_source_at_stamps(source_file, timestamps, timestamps_end = None, · 3 unmodified lines | |||
| 72 | if remaining < read: | 74 | if remaining < read: |
| 73 | if remaining > start: | 75 | if remaining > start: |
| 74 | # write remaining samples from current region | 76 | # write remaining samples from current region |
| 75 | g.do_multi(vec[:,start:remaining], remaining - start) | 77 | _sink.do_multi(vec[:, start:remaining], remaining - start) |
| 76 | #print "closing region", "remaining", remaining | 78 | #print "closing region", "remaining", remaining |
| 77 | # close this file | 79 | # close this file |
| 78 | g.close() | 80 | _sink.close() |
| 79 | elif read > start: | 81 | elif read > start: |
| 80 | # write all the samples | 82 | # write all the samples |
| 81 | g.do_multi(vec[:,start:read], read - start) | 83 | _sink.do_multi(vec[:, start:read], read - start) |
| 82 | total_frames += read | 84 | total_frames += read |
| 83 | if read < hopsize: break | 85 | if read < hopsize: |
| 86 | break | ||