Showing the changes to python (10 of 15 files). Show all
Unified · Split
| @@ -4,6 +4,7 @@ import sys · 3 unmodified lines | |||
| 4 | import os.path | 4 | import os.path |
| 5 | import aubio | 5 | import aubio |
| 6 | 6 | ||
| 7 | |||
| 7 | def apply_filter(path, target): | 8 | def apply_filter(path, target): |
| 8 | # open input file, get its samplerate | 9 | # open input file, get its samplerate |
| 9 | s = aubio.source(path) | 10 | s = aubio.source(path) |
| @@ -27,19 +28,20 @@ def apply_filter(path, target): · 17 unmodified lines | |||
| 27 | # count frames read | 28 | # count frames read |
| 28 | total_frames += read | 29 | total_frames += read |
| 29 | # end of file reached | 30 | # end of file reached |
| 30 | if read < s.hop_size: break | 31 | if read < s.hop_size: |
| 32 | break | ||
| 31 | 33 | ||
| 32 | # print some info | 34 | # print some info |
| 33 | duration = total_frames / float(samplerate) | 35 | duration = total_frames / float(samplerate) |
| 34 | input_str = "input: {:s} ({:.2f} s, {:d} Hz)" | 36 | input_str = "input: {:s} ({:.2f} s, {:d} Hz)" |
| 35 | output_str = "output: {:s}, A-weighting filtered ({:d} frames total)" | 37 | output_str = "output: {:s}, A-weighting filtered ({:d} frames total)" |
| 36 | print (input_str.format(s.uri, duration, samplerate)) | 38 | print(input_str.format(s.uri, duration, samplerate)) |
| 37 | print (output_str.format(o.uri, total_frames)) | 39 | print(output_str.format(o.uri, total_frames)) |
| 38 | 40 | ||
| 39 | if __name__ == '__main__': | 41 | if __name__ == '__main__': |
| 40 | usage = "{:s} <input_file> [output_file]".format(sys.argv[0]) | 42 | usage = "{:s} <input_file> [output_file]".format(sys.argv[0]) |
| 41 | if not 1 < len(sys.argv) < 4: | 43 | if not 1 < len(sys.argv) < 4: |
| 42 | print (usage) | 44 | print(usage) |
| 43 | sys.exit(1) | 45 | sys.exit(1) |
| 44 | if len(sys.argv) < 3: | 46 | if len(sys.argv) < 3: |
| 45 | input_path = sys.argv[1] | 47 | input_path = sys.argv[1] |
| @@ -1,30 +1,44 @@ | |||
| 1 | #! /usr/bin/env python | 1 | #! /usr/bin/env python |
| 2 | 2 | ||
| 3 | from aubio import filterbank, fvec | 3 | """Create a filterbank from a list of frequencies. |
| 4 | from pylab import loglog, show, xlim, ylim, xlabel, ylabel, title | ||
| 5 | from numpy import vstack, arange | ||
| 6 | 4 | ||
| 7 | win_s = 2048 | 5 | This demo uses `aubio.filterbank.set_triangle_bands` to build a set of |
| 6 | triangular filters from a list of frequencies. | ||
| 7 | |||
| 8 | The filterbank coefficients are then modified before being displayed.""" | ||
| 9 | |||
| 10 | import aubio | ||
| 11 | import numpy as np | ||
| 12 | import matplotlib.pyplot as plt | ||
| 13 | |||
| 14 | # sampling rate and size of the fft | ||
| 8 | samplerate = 48000 | 15 | samplerate = 48000 |
| 16 | win_s = 2048 | ||
| 9 | 17 | ||
| 18 | # define a list of custom frequency | ||
| 10 | freq_list = [60, 80, 200, 400, 800, 1600, 3200, 6400, 12800, 24000] | 19 | freq_list = [60, 80, 200, 400, 800, 1600, 3200, 6400, 12800, 24000] |
| 20 | # number of filters to create | ||
| 11 | n_filters = len(freq_list) - 2 | 21 | n_filters = len(freq_list) - 2 |
| 12 | 22 | ||
| 13 | f = filterbank(n_filters, win_s) | 23 | # create a new filterbank |
| 14 | freqs = fvec(freq_list) | 24 | f = aubio.filterbank(n_filters, win_s) |
| 25 | freqs = aubio.fvec(freq_list) | ||
| 15 | f.set_triangle_bands(freqs, samplerate) | 26 | f.set_triangle_bands(freqs, samplerate) |
| 16 | 27 | ||
| 28 | # get the coefficients from the filterbank | ||
| 17 | coeffs = f.get_coeffs() | 29 | coeffs = f.get_coeffs() |
| 18 | coeffs[4] *= 5. | 30 | # apply a gain to fifth band |
| 19 | 31 | coeffs[4] *= 6. | |
| 32 | # load the modified coeffs into the filterbank | ||
| 20 | f.set_coeffs(coeffs) | 33 | f.set_coeffs(coeffs) |
| 21 | 34 | ||
| 22 | times = vstack([arange(win_s // 2 + 1) * samplerate / win_s] * n_filters) | 35 | # display the band gains in a loglog plot |
| 23 | title('Bank of filters built using a simple list of boundaries\nThe middle band has been amplified by 2.') | 36 | freqs = np.vstack([np.arange(win_s // 2 + 1) * samplerate / win_s] * n_filters) |
| 24 | loglog(times.T, f.get_coeffs().T, '.-') | 37 | plt.title('filterbank built from a list of frequencies\n' |
| 25 | xlim([50, samplerate/2]) | 38 | 'The 5th band has been amplified by a factor 6.') |
| 26 | ylim([1.0e-6, 2.0e-2]) | 39 | plt.loglog(freqs.T, f.get_coeffs().T, '.-') |
| 27 | xlabel('log frequency (Hz)') | 40 | plt.xlim([50, samplerate/2]) |
| 28 | ylabel('log amplitude') | 41 | plt.ylim([1.0e-6, 2.0e-2]) |
| 29 | 42 | plt.xlabel('log frequency (Hz)') | |
| 30 | show() | 43 | plt.ylabel('log amplitude') |
| 44 | plt.show() | ||
| @@ -1,16 +1,20 @@ | |||
| 1 | #! /usr/bin/env python | 1 | #! /usr/bin/env python |
| 2 | |||
| 3 | """A simple example using aubio.source.""" | ||
| 4 | |||
| 2 | import sys | 5 | import sys |
| 3 | import aubio | 6 | import aubio |
| 4 | 7 | ||
| 5 | samplerate = 0 # use original source samplerate | 8 | samplerate = 0 # use original source samplerate |
| 6 | hop_size = 256 # number of frames to read in one block | 9 | hop_size = 256 # number of frames to read in one block |
| 7 | src = aubio.source(sys.argv[1], samplerate, hop_size) | 10 | src = aubio.source(sys.argv[1], samplerate, hop_size) |
| 8 | total_frames = 0 | 11 | total_frames = 0 |
| 9 | 12 | ||
| 10 | while True: | 13 | while True: |
| 11 | samples, read = src() # read hop_size new samples from source | 14 | samples, read = src() # read hop_size new samples from source |
| 12 | total_frames += read # increment total number of frames | 15 | total_frames += read # increment total number of frames |
| 13 | if read < hop_size: break # end of file reached | 16 | if read < hop_size: # end of file reached |
| 17 | break | ||
| 14 | 18 | ||
| 15 | fmt_string = "read {:d} frames at {:d}Hz from {:s}" | 19 | fmt_string = "read {:d} frames at {:d}Hz from {:s}" |
| 16 | print (fmt_string.format(total_frames, src.samplerate, src.uri)) | 20 | print(fmt_string.format(total_frames, src.samplerate, src.uri)) |
| @@ -14,7 +14,7 @@ typedef struct · 13 unmodified lines | |||
| 14 | static char Py_sink_doc[] = "" | 14 | static char Py_sink_doc[] = "" |
| 15 | "sink(path, samplerate=44100, channels=1)\n" | 15 | "sink(path, samplerate=44100, channels=1)\n" |
| 16 | "\n" | 16 | "\n" |
| 17 | "Open `path` to write a WAV file.\n" | 17 | "Write audio samples to file.\n" |
| 18 | "\n" | 18 | "\n" |
| 19 | "Parameters\n" | 19 | "Parameters\n" |
| 20 | "----------\n" | 20 | "----------\n" |
| @@ -18,7 +18,7 @@ typedef struct · 17 unmodified lines | |||
| 18 | static char Py_source_doc[] = "" | 18 | static char Py_source_doc[] = "" |
| 19 | "source(path, samplerate=0, hop_size=512, channels=0)\n" | 19 | "source(path, samplerate=0, hop_size=512, channels=0)\n" |
| 20 | "\n" | 20 | "\n" |
| 21 | "Create a new source, opening the given pathname for reading.\n" | 21 | "Read audio samples from a media file.\n" |
| 22 | "\n" | 22 | "\n" |
| 23 | "`source` open the file specified in `path` and creates a callable\n" | 23 | "`source` open the file specified in `path` and creates a callable\n" |
| 24 | "returning `hop_size` new audio samples at each invocation.\n" | 24 | "returning `hop_size` new audio samples at each invocation.\n" |
| @@ -247,7 +247,7 @@ static char Py_source_do_doc[] = "" · 222 unmodified lines | |||
| 247 | "\n" | 247 | "\n" |
| 248 | "Returns\n" | 248 | "Returns\n" |
| 249 | "-------\n" | 249 | "-------\n" |
| 250 | "samples : numpy.ndarray, shape `(hop_size,)`, dtype aubio.float_type\n" | 250 | "samples : numpy.ndarray\n" |
| 251 | " `fvec` of size `hop_size` containing the new samples.\n" | 251 | " `fvec` of size `hop_size` containing the new samples.\n" |
| 252 | "read : int\n" | 252 | "read : int\n" |
| 253 | " Number of samples read from the source, equals to `hop_size`\n" | 253 | " Number of samples read from the source, equals to `hop_size`\n" |
| @@ -283,7 +283,7 @@ static char Py_source_do_multi_doc[] = "" · 29 unmodified lines | |||
| 283 | "\n" | 283 | "\n" |
| 284 | "Returns\n" | 284 | "Returns\n" |
| 285 | "-------\n" | 285 | "-------\n" |
| 286 | "samples : np.ndarray([hop_size, channels], dtype=aubio.float_type)\n" | 286 | "samples : numpy.ndarray\n" |
| 287 | " NumPy array of shape `(hop_size, channels)` containing the new\n" | 287 | " NumPy array of shape `(hop_size, channels)` containing the new\n" |
| 288 | " audio samples.\n" | 288 | " audio samples.\n" |
| 289 | "read : int\n" | 289 | "read : int\n" |
| @@ -29,6 +29,7 @@ from ._aubio import * · 28 unmodified lines | |||
| 29 | from .midiconv import * | 29 | from .midiconv import * |
| 30 | from .slicing import * | 30 | from .slicing import * |
| 31 | 31 | ||
| 32 | |||
| 32 | class fvec(numpy.ndarray): | 33 | class fvec(numpy.ndarray): |
| 33 | """fvec(input_arg=1024) | 34 | """fvec(input_arg=1024) |
| 34 | A vector holding float samples. | 35 | A vector holding float samples. |
| @@ -11,6 +11,7 @@ readable code examples, check out the `python/demos` folder.""" · 10 unmodified lines | |||
| 11 | 11 | ||
| 12 | import sys | 12 | import sys |
| 13 | import argparse | 13 | import argparse |
| 14 | import warnings | ||
| 14 | import aubio | 15 | import aubio |
| 15 | 16 | ||
| 16 | def aubio_parser(): | 17 | def aubio_parser(): |
| @@ -168,10 +169,10 @@ class AubioArgumentParser(argparse.ArgumentParser): · 151 unmodified lines | |||
| 168 | help="samplerate at which the file should be represented") | 169 | help="samplerate at which the file should be represented") |
| 169 | 170 | ||
| 170 | def add_verbose_help(self): | 171 | def add_verbose_help(self): |
| 171 | self.add_argument("-v","--verbose", | 172 | self.add_argument("-v", "--verbose", |
| 172 | action="count", dest="verbose", default=1, | 173 | action="count", dest="verbose", default=1, |
| 173 | help="make lots of noise [default]") | 174 | help="make lots of noise [default]") |
| 174 | self.add_argument("-q","--quiet", | 175 | self.add_argument("-q", "--quiet", |
| 175 | action="store_const", dest="verbose", const=0, | 176 | action="store_const", dest="verbose", const=0, |
| 176 | help="be quiet") | 177 | help="be quiet") |
| 177 | 178 | ||
| @@ -180,25 +181,25 @@ class AubioArgumentParser(argparse.ArgumentParser): · 2 unmodified lines | |||
| 180 | self.add_hop_size(hop_size=hop_size) | 181 | self.add_hop_size(hop_size=hop_size) |
| 181 | 182 | ||
| 182 | def add_buf_size(self, buf_size=512): | 183 | def add_buf_size(self, buf_size=512): |
| 183 | self.add_argument("-B","--bufsize", | 184 | self.add_argument("-B", "--bufsize", |
| 184 | action="store", dest="buf_size", default=buf_size, | 185 | action="store", dest="buf_size", default=buf_size, |
| 185 | metavar = "<size>", type=int, | 186 | metavar = "<size>", type=int, |
| 186 | help="buffer size [default=%d]" % buf_size) | 187 | help="buffer size [default=%d]" % buf_size) |
| 187 | 188 | ||
| 188 | def add_hop_size(self, hop_size=256): | 189 | def add_hop_size(self, hop_size=256): |
| 189 | self.add_argument("-H","--hopsize", | 190 | self.add_argument("-H", "--hopsize", |
| 190 | metavar = "<size>", type=int, | 191 | metavar = "<size>", type=int, |
| 191 | action="store", dest="hop_size", default=hop_size, | 192 | action="store", dest="hop_size", default=hop_size, |
| 192 | help="overlap size [default=%d]" % hop_size) | 193 | help="overlap size [default=%d]" % hop_size) |
| 193 | 194 | ||
| 194 | def add_method(self, method='default', helpstr='method'): | 195 | def add_method(self, method='default', helpstr='method'): |
| 195 | self.add_argument("-m","--method", | 196 | self.add_argument("-m", "--method", |
| 196 | metavar = "<method>", type=str, | 197 | metavar = "<method>", type=str, |
| 197 | action="store", dest="method", default=method, | 198 | action="store", dest="method", default=method, |
| 198 | help="%s [default=%s]" % (helpstr, method)) | 199 | help="%s [default=%s]" % (helpstr, method)) |
| 199 | 200 | ||
| 200 | def add_threshold(self, default=None): | 201 | def add_threshold(self, default=None): |
| 201 | self.add_argument("-t","--threshold", | 202 | self.add_argument("-t", "--threshold", |
| 202 | metavar = "<threshold>", type=float, | 203 | metavar = "<threshold>", type=float, |
| 203 | action="store", dest="threshold", default=default, | 204 | action="store", dest="threshold", default=default, |
| 204 | help="threshold [default=%s]" % default) | 205 | help="threshold [default=%s]" % default) |
| @@ -239,14 +240,16 @@ class AubioArgumentParser(argparse.ArgumentParser): · 34 unmodified lines | |||
| 239 | help=helpstr) | 240 | help=helpstr) |
| 240 | 241 | ||
| 241 | def add_slicer_options(self): | 242 | def add_slicer_options(self): |
| 242 | self.add_argument("-o","--output", type = str, | 243 | self.add_argument("-o", "--output", type = str, |
| 243 | metavar = "<outputdir>", | 244 | metavar = "<outputdir>", |
| 244 | action="store", dest="output_directory", default=None, | 245 | action="store", dest="output_directory", default=None, |
| 245 | help="specify path where slices of the original file should be created") | 246 | help="specify path where slices of the original file should" |
| 247 | " be created") | ||
| 246 | self.add_argument("--cut-until-nsamples", type = int, | 248 | self.add_argument("--cut-until-nsamples", type = int, |
| 247 | metavar = "<samples>", | 249 | metavar = "<samples>", |
| 248 | action = "store", dest = "cut_until_nsamples", default = None, | 250 | action = "store", dest = "cut_until_nsamples", default = None, |
| 249 | help="how many extra samples should be added at the end of each slice") | 251 | help="how many extra samples should be added at the end of" |
| 252 | " each slice") | ||
| 250 | self.add_argument("--cut-every-nslices", type = int, | 253 | self.add_argument("--cut-every-nslices", type = int, |
| 251 | metavar = "<samples>", | 254 | metavar = "<samples>", |
| 252 | action = "store", dest = "cut_every_nslices", default = None, | 255 | action = "store", dest = "cut_every_nslices", default = None, |
| @@ -254,7 +257,8 @@ class AubioArgumentParser(argparse.ArgumentParser): · 1 unmodified line | |||
| 254 | self.add_argument("--cut-until-nslices", type = int, | 257 | self.add_argument("--cut-until-nslices", type = int, |
| 255 | metavar = "<slices>", | 258 | metavar = "<slices>", |
| 256 | action = "store", dest = "cut_until_nslices", default = None, | 259 | action = "store", dest = "cut_until_nslices", default = None, |
| 257 | help="how many extra slices should be added at the end of each slice") | 260 | help="how many extra slices should be added at the end of" |
| 261 | " each slice") | ||
| 258 | self.add_argument("--create-first", | 262 | self.add_argument("--create-first", |
| 259 | action = "store_true", dest = "create_first", default = False, | 263 | action = "store_true", dest = "create_first", default = False, |
| 260 | help="always include first slice") | 264 | help="always include first slice") |
| @@ -288,7 +292,8 @@ class default_process(object): · 27 unmodified lines | |||
| 288 | self.time2string = timefunc(args.time_format) | 292 | self.time2string = timefunc(args.time_format) |
| 289 | if args.verbose > 2 and hasattr(self, 'options'): | 293 | if args.verbose > 2 and hasattr(self, 'options'): |
| 290 | name = type(self).__name__.split('_')[1] | 294 | name = type(self).__name__.split('_')[1] |
| 291 | optstr = ' '.join(['running', name, 'with options', repr(self.options), '\n']) | 295 | optstr = ' '.join(['running', name, 'with options', |
| 296 | repr(self.options), '\n']) | ||
| 292 | sys.stderr.write(optstr) | 297 | sys.stderr.write(optstr) |
| 293 | def flush(self, frames_read, samplerate): | 298 | def flush(self, frames_read, samplerate): |
| 294 | # optionally called at the end of process | 299 | # optionally called at the end of process |
| @@ -296,7 +301,7 @@ class default_process(object): · 1 unmodified line | |||
| 296 | 301 | ||
| 297 | def parse_options(self, args, valid_opts): | 302 | def parse_options(self, args, valid_opts): |
| 298 | # get any valid options found in a dictionnary of arguments | 303 | # get any valid options found in a dictionnary of arguments |
| 299 | options = {k :v for k,v in vars(args).items() if k in valid_opts} | 304 | options = {k: v for k, v in vars(args).items() if k in valid_opts} |
| 300 | self.options = options | 305 | self.options = options |
| 301 | 306 | ||
| 302 | def remap_pvoc_options(self, options): | 307 | def remap_pvoc_options(self, options): |
| @@ -377,7 +382,7 @@ class process_tempo(process_beat): · 74 unmodified lines | |||
| 377 | if len(self.beat_locations) < 2: | 382 | if len(self.beat_locations) < 2: |
| 378 | outstr = "unknown bpm" | 383 | outstr = "unknown bpm" |
| 379 | else: | 384 | else: |
| 380 | bpms = 60./ np.diff(self.beat_locations) | 385 | bpms = 60. / np.diff(self.beat_locations) |
| 381 | median_bpm = np.mean(bpms) | 386 | median_bpm = np.mean(bpms) |
| 382 | if len(self.beat_locations) < 10: | 387 | if len(self.beat_locations) < 10: |
| 383 | outstr = "%.2f bpm (uncertain)" % median_bpm | 388 | outstr = "%.2f bpm (uncertain)" % median_bpm |
| @@ -398,14 +403,14 @@ class process_notes(default_process): · 14 unmodified lines | |||
| 398 | def __call__(self, block): | 403 | def __call__(self, block): |
| 399 | return self.notes(block) | 404 | return self.notes(block) |
| 400 | def repr_res(self, res, frames_read, samplerate): | 405 | def repr_res(self, res, frames_read, samplerate): |
| 401 | if res[2] != 0: # note off | 406 | if res[2] != 0: # note off |
| 402 | fmt_out = self.time2string(frames_read, samplerate) | 407 | fmt_out = self.time2string(frames_read, samplerate) |
| 403 | sys.stdout.write(fmt_out + '\n') | 408 | sys.stdout.write(fmt_out + '\n') |
| 404 | if res[0] != 0: # note on | 409 | if res[0] != 0: # note on |
| 405 | lastmidi = res[0] | 410 | lastmidi = res[0] |
| 406 | fmt_out = "%f\t" % lastmidi | 411 | fmt_out = "%f\t" % lastmidi |
| 407 | fmt_out += self.time2string(frames_read, samplerate) | 412 | fmt_out += self.time2string(frames_read, samplerate) |
| 408 | sys.stdout.write(fmt_out) # + '\t') | 413 | sys.stdout.write(fmt_out) # + '\t') |
| 409 | def flush(self, frames_read, samplerate): | 414 | def flush(self, frames_read, samplerate): |
| 410 | eof = self.time2string(frames_read, samplerate) | 415 | eof = self.time2string(frames_read, samplerate) |
| 411 | sys.stdout.write(eof + '\n') | 416 | sys.stdout.write(eof + '\n') |
| @@ -472,13 +477,13 @@ class process_quiet(default_process): · 60 unmodified lines | |||
| 472 | if aubio.silence_detection(block, self.silence) == 1: | 477 | if aubio.silence_detection(block, self.silence) == 1: |
| 473 | if self.wassilence != 1: | 478 | if self.wassilence != 1: |
| 474 | self.wassilence = 1 | 479 | self.wassilence = 1 |
| 475 | return 2 # newly found silence | 480 | return 2 # newly found silence |
| 476 | return 1 # silence again | 481 | return 1 # silence again |
| 477 | else: | 482 | else: |
| 478 | if self.wassilence != 0: | 483 | if self.wassilence != 0: |
| 479 | self.wassilence = 0 | 484 | self.wassilence = 0 |
| 480 | return -1 # newly found noise | 485 | return -1 # newly found noise |
| 481 | return 0 # noise again | 486 | return 0 # noise again |
| 482 | 487 | ||
| 483 | def repr_res(self, res, frames_read, samplerate): | 488 | def repr_res(self, res, frames_read, samplerate): |
| 484 | fmt_out = None | 489 | fmt_out = None |
| @@ -498,20 +503,47 @@ class process_cut(process_onset): · 13 unmodified lines | |||
| 498 | 503 | ||
| 499 | def __call__(self, block): | 504 | def __call__(self, block): |
| 500 | ret = super(process_cut, self).__call__(block) | 505 | ret = super(process_cut, self).__call__(block) |
| 501 | if ret: self.slices.append(self.onset.get_last()) | 506 | if ret: |
| 507 | self.slices.append(self.onset.get_last()) | ||
| 502 | return ret | 508 | return ret |
| 503 | 509 | ||
| 504 | def flush(self, frames_read, samplerate): | 510 | def flush(self, frames_read, samplerate): |
| 505 | from aubio.cut import _cut_slice | ||
| 506 | _cut_slice(self.options, self.slices) | 511 | _cut_slice(self.options, self.slices) |
| 507 | duration = float (frames_read) / float(samplerate) | 512 | duration = float(frames_read) / float(samplerate) |
| 508 | base_info = '%(source_file)s' % {'source_file': self.options.source_uri} | 513 | base_info = '%(source_file)s' % \ |
| 514 | {'source_file': self.options.source_uri} | ||
| 509 | base_info += ' (total %(duration).2fs at %(samplerate)dHz)\n' % \ | 515 | base_info += ' (total %(duration).2fs at %(samplerate)dHz)\n' % \ |
| 510 | {'duration': duration, 'samplerate': samplerate} | 516 | {'duration': duration, 'samplerate': samplerate} |
| 511 | info = "created %d slices from " % len(self.slices) | 517 | info = "created %d slices from " % len(self.slices) |
| 512 | info += base_info | 518 | info += base_info |
| 513 | sys.stderr.write(info) | 519 | sys.stderr.write(info) |
| 514 | 520 | ||
| 521 | def _cut_slice(options, timestamps): | ||
| 522 | # cutting pass | ||
| 523 | nstamps = len(timestamps) | ||
| 524 | if nstamps > 0: | ||
| 525 | # generate output files | ||
| 526 | timestamps_end = None | ||
| 527 | if options.cut_every_nslices: | ||
| 528 | timestamps = timestamps[::options.cut_every_nslices] | ||
| 529 | nstamps = len(timestamps) | ||
| 530 | if options.cut_until_nslices and options.cut_until_nsamples: | ||
| 531 | msg = "using cut_until_nslices, but cut_until_nsamples is set" | ||
| 532 | warnings.warn(msg) | ||
| 533 | if options.cut_until_nsamples: | ||
| 534 | lag = options.cut_until_nsamples | ||
| 535 | timestamps_end = [t + lag for t in timestamps[1:]] | ||
| 536 | timestamps_end += [1e120] | ||
| 537 | if options.cut_until_nslices: | ||
| 538 | slice_lag = options.cut_until_nslices | ||
| 539 | timestamps_end = [t for t in timestamps[1 + slice_lag:]] | ||
| 540 | timestamps_end += [1e120] * (options.cut_until_nslices + 1) | ||
| 541 | aubio.slice_source_at_stamps(options.source_uri, | ||
| 542 | timestamps, timestamps_end = timestamps_end, | ||
| 543 | output_dir = options.output_directory, | ||
| 544 | samplerate = options.samplerate, | ||
| 545 | create_first = options.create_first) | ||
| 546 | |||
| 515 | def main(): | 547 | def main(): |
| 516 | parser = aubio_parser() | 548 | parser = aubio_parser() |
| 517 | if sys.version_info[0] != 3: | 549 | if sys.version_info[0] != 3: |
| @@ -525,19 +557,20 @@ def main(): · 7 unmodified lines | |||
| 525 | parser_root.add_argument('-V', '--version', help="show version", | 557 | parser_root.add_argument('-V', '--version', help="show version", |
| 526 | action="store_true", dest="show_version") | 558 | action="store_true", dest="show_version") |
| 527 | args, extras = parser_root.parse_known_args() | 559 | args, extras = parser_root.parse_known_args() |
| 528 | if args.show_version == False: # no -V, forward to parser | 560 | if not args.show_version: # no -V, forward to parser |
| 529 | args = parser.parse_args(extras, namespace=args) | 561 | args = parser.parse_args(extras, namespace=args) |
| 530 | elif len(extras) != 0: # -V with other arguments, print help | 562 | elif len(extras) != 0: # -V with other arguments, print help |
| 531 | parser.print_help() | 563 | parser.print_help() |
| 532 | sys.exit(1) | 564 | sys.exit(1) |
| 533 | else: # in py3, we can simply use parser directly | 565 | else: # in py3, we can simply use parser directly |
| 534 | args = parser.parse_args() | 566 | args = parser.parse_args() |
| 535 | if 'show_version' in args and args.show_version: | 567 | if 'show_version' in args and args.show_version: |
| 536 | sys.stdout.write('aubio version ' + aubio.version + '\n') | 568 | sys.stdout.write('aubio version ' + aubio.version + '\n') |
| 537 | sys.exit(0) | 569 | sys.exit(0) |
| 538 | elif 'verbose' in args and args.verbose > 3: | 570 | elif 'verbose' in args and args.verbose > 3: |
| 539 | sys.stderr.write('aubio version ' + aubio.version + '\n') | 571 | sys.stderr.write('aubio version ' + aubio.version + '\n') |
| 540 | if 'command' not in args or args.command is None or args.command in ['help']: | 572 | if 'command' not in args or args.command is None \ |
| 573 | or args.command in ['help']: | ||
| 541 | # no command given, print help and return 1 | 574 | # no command given, print help and return 1 |
| 542 | parser.print_help() | 575 | parser.print_help() |
| 543 | if args.command and args.command in ['help']: | 576 | if args.command and args.command in ['help']: |
| @@ -571,7 +604,8 @@ def main(): · 27 unmodified lines | |||
| 571 | # increment total number of frames read | 604 | # increment total number of frames read |
| 572 | frames_read += read | 605 | frames_read += read |
| 573 | # exit loop at end of file | 606 | # exit loop at end of file |
| 574 | if read < a_source.hop_size: break | 607 | if read < a_source.hop_size: |
| 608 | break | ||
| 575 | # flush the processor if needed | 609 | # flush the processor if needed |
| 576 | processor.flush(frames_read, a_source.samplerate) | 610 | processor.flush(frames_read, a_source.samplerate) |
| 577 | if args.verbose > 1: | 611 | if args.verbose > 1: |
| @@ -579,7 +613,7 @@ def main(): · 1 unmodified line | |||
| 579 | fmt_string += " ({:d} samples in {:d} blocks of {:d})" | 613 | fmt_string += " ({:d} samples in {:d} blocks of {:d})" |
| 580 | fmt_string += " from {:s} at {:d}Hz\n" | 614 | fmt_string += " from {:s} at {:d}Hz\n" |
| 581 | sys.stderr.write(fmt_string.format( | 615 | sys.stderr.write(fmt_string.format( |
| 582 | frames_read/float(a_source.samplerate), | 616 | frames_read / float(a_source.samplerate), |
| 583 | frames_read, | 617 | frames_read, |
| 584 | frames_read // a_source.hop_size + 1, | 618 | frames_read // a_source.hop_size + 1, |
| 585 | a_source.hop_size, | 619 | a_source.hop_size, |
| @@ -5,83 +5,83 @@ · 4 unmodified lines | |||
| 5 | """ | 5 | """ |
| 6 | 6 | ||
| 7 | import sys | 7 | import sys |
| 8 | from aubio.cmd import AubioArgumentParser | 8 | from aubio.cmd import AubioArgumentParser, _cut_slice |
| 9 | 9 | ||
| 10 | def aubio_cut_parser(): | 10 | def aubio_cut_parser(): |
| 11 | parser = AubioArgumentParser() | 11 | parser = AubioArgumentParser() |
| 12 | parser.add_input() | 12 | parser.add_input() |
| 13 | parser.add_argument("-O","--onset-method", | 13 | parser.add_argument("-O", "--onset-method", |
| 14 | action="store", dest="onset_method", default='default', | 14 | action="store", dest="onset_method", default='default', |
| 15 | metavar = "<onset_method>", | 15 | metavar = "<onset_method>", |
| 16 | help="onset detection method [default=default] \ | 16 | help="onset detection method [default=default] \ |
| 17 | complexdomain|hfc|phase|specdiff|energy|kl|mkl") | 17 | complexdomain|hfc|phase|specdiff|energy|kl|mkl") |
| 18 | # cutting methods | 18 | # cutting methods |
| 19 | parser.add_argument("-b","--beat", | 19 | parser.add_argument("-b", "--beat", |
| 20 | action="store_true", dest="beat", default=False, | 20 | action="store_true", dest="beat", default=False, |
| 21 | help="slice at beat locations") | 21 | help="slice at beat locations") |
| 22 | """ | 22 | """ |
| 23 | parser.add_argument("-S","--silencecut", | 23 | parser.add_argument("-S", "--silencecut", |
| 24 | action="store_true", dest="silencecut", default=False, | 24 | action="store_true", dest="silencecut", default=False, |
| 25 | help="use silence locations") | 25 | help="use silence locations") |
| 26 | parser.add_argument("-s","--silence", | 26 | parser.add_argument("-s", "--silence", |
| 27 | metavar = "<value>", | 27 | metavar = "<value>", |
| 28 | action="store", dest="silence", default=-70, | 28 | action="store", dest="silence", default=-70, |
| 29 | help="silence threshold [default=-70]") | 29 | help="silence threshold [default=-70]") |
| 30 | """ | 30 | """ |
| 31 | # algorithm parameters | 31 | # algorithm parameters |
| 32 | parser.add_buf_hop_size() | 32 | parser.add_buf_hop_size() |
| 33 | parser.add_argument("-t","--threshold", "--onset-threshold", | 33 | parser.add_argument("-t", "--threshold", "--onset-threshold", |
| 34 | metavar = "<threshold>", type=float, | 34 | metavar = "<threshold>", type=float, |
| 35 | action="store", dest="threshold", default=0.3, | 35 | action="store", dest="threshold", default=0.3, |
| 36 | help="onset peak picking threshold [default=0.3]") | 36 | help="onset peak picking threshold [default=0.3]") |
| 37 | parser.add_argument("-c","--cut", | 37 | parser.add_argument("-c", "--cut", |
| 38 | action="store_true", dest="cut", default=False, | 38 | action="store_true", dest="cut", default=False, |
| 39 | help="cut input sound file at detected labels") | 39 | help="cut input sound file at detected labels") |
| 40 | parser.add_minioi() | 40 | parser.add_minioi() |
| 41 | 41 | ||
| 42 | """ | 42 | """ |
| 43 | parser.add_argument("-D","--delay", | 43 | parser.add_argument("-D", "--delay", |
| 44 | action = "store", dest = "delay", type = float, | 44 | action = "store", dest = "delay", type = float, |
| 45 | metavar = "<seconds>", default=0, | 45 | metavar = "<seconds>", default=0, |
| 46 | help="number of seconds to take back [default=system]\ | 46 | help="number of seconds to take back [default=system]\ |
| 47 | default system delay is 3*hopsize/samplerate") | 47 | default system delay is 3*hopsize/samplerate") |
| 48 | parser.add_argument("-C","--dcthreshold", | 48 | parser.add_argument("-C", "--dcthreshold", |
| 49 | metavar = "<value>", | 49 | metavar = "<value>", |
| 50 | action="store", dest="dcthreshold", default=1., | 50 | action="store", dest="dcthreshold", default=1., |
| 51 | help="onset peak picking DC component [default=1.]") | 51 | help="onset peak picking DC component [default=1.]") |
| 52 | parser.add_argument("-L","--localmin", | 52 | parser.add_argument("-L", "--localmin", |
| 53 | action="store_true", dest="localmin", default=False, | 53 | action="store_true", dest="localmin", default=False, |
| 54 | help="use local minima after peak detection") | 54 | help="use local minima after peak detection") |
| 55 | parser.add_argument("-d","--derivate", | 55 | parser.add_argument("-d", "--derivate", |
| 56 | action="store_true", dest="derivate", default=False, | 56 | action="store_true", dest="derivate", default=False, |
| 57 | help="derivate onset detection function") | 57 | help="derivate onset detection function") |
| 58 | parser.add_argument("-z","--zerocross", | 58 | parser.add_argument("-z", "--zerocross", |
| 59 | metavar = "<value>", | 59 | metavar = "<value>", |
| 60 | action="store", dest="zerothres", default=0.008, | 60 | action="store", dest="zerothres", default=0.008, |
| 61 | help="zero-crossing threshold for slicing [default=0.00008]") | 61 | help="zero-crossing threshold for slicing [default=0.00008]") |
| 62 | # plotting functions | 62 | # plotting functions |
| 63 | parser.add_argument("-p","--plot", | 63 | parser.add_argument("-p", "--plot", |
| 64 | action="store_true", dest="plot", default=False, | 64 | action="store_true", dest="plot", default=False, |
| 65 | help="draw plot") | 65 | help="draw plot") |
| 66 | parser.add_argument("-x","--xsize", | 66 | parser.add_argument("-x", "--xsize", |
| 67 | metavar = "<size>", | 67 | metavar = "<size>", |
| 68 | action="store", dest="xsize", default=1., | 68 | action="store", dest="xsize", default=1., |
| 69 | type=float, help="define xsize for plot") | 69 | type=float, help="define xsize for plot") |
| 70 | parser.add_argument("-y","--ysize", | 70 | parser.add_argument("-y", "--ysize", |
| 71 | metavar = "<size>", | 71 | metavar = "<size>", |
| 72 | action="store", dest="ysize", default=1., | 72 | action="store", dest="ysize", default=1., |
| 73 | type=float, help="define ysize for plot") | 73 | type=float, help="define ysize for plot") |
| 74 | parser.add_argument("-f","--function", | 74 | parser.add_argument("-f", "--function", |
| 75 | action="store_true", dest="func", default=False, | 75 | action="store_true", dest="func", default=False, |
| 76 | help="print detection function") | 76 | help="print detection function") |
| 77 | parser.add_argument("-n","--no-onsets", | 77 | parser.add_argument("-n", "--no-onsets", |
| 78 | action="store_true", dest="nplot", default=False, | 78 | action="store_true", dest="nplot", default=False, |
| 79 | help="do not plot detected onsets") | 79 | help="do not plot detected onsets") |
| 80 | parser.add_argument("-O","--outplot", | 80 | parser.add_argument("-O", "--outplot", |
| 81 | metavar = "<output_image>", | 81 | metavar = "<output_image>", |
| 82 | action="store", dest="outplot", default=None, | 82 | action="store", dest="outplot", default=None, |
| 83 | help="save plot to output.{ps,png}") | 83 | help="save plot to output.{ps,png}") |
| 84 | parser.add_argument("-F","--spectrogram", | 84 | parser.add_argument("-F", "--spectrogram", |
| 85 | action="store_true", dest="spectro", default=False, | 85 | action="store_true", dest="spectro", default=False, |
| 86 | help="add spectrogram to the plot") | 86 | help="add spectrogram to the plot") |
| 87 | """ | 87 | """ |
| @@ -105,9 +105,11 @@ def _cut_analyze(options): · 17 unmodified lines | |||
| 105 | options.samplerate = samplerate | 105 | options.samplerate = samplerate |
| 106 | 106 | ||
| 107 | if options.beat: | 107 | if options.beat: |
| 108 | o = tempo(options.onset_method, bufsize, hopsize, samplerate=samplerate) | 108 | o = tempo(options.onset_method, bufsize, hopsize, |
| 109 | samplerate=samplerate) | ||
| 109 | else: | 110 | else: |
| 110 | o = onset(options.onset_method, bufsize, hopsize, samplerate=samplerate) | 111 | o = onset(options.onset_method, bufsize, hopsize, |
| 112 | samplerate=samplerate) | ||
| 111 | if options.minioi: | 113 | if options.minioi: |
| 112 | if options.minioi.endswith('ms'): | 114 | if options.minioi.endswith('ms'): |
| 113 | o.set_minioi_ms(int(options.minioi[:-2])) | 115 | o.set_minioi_ms(int(options.minioi[:-2])) |
| @@ -122,37 +124,15 @@ def _cut_analyze(options): · 8 unmodified lines | |||
| 122 | while True: | 124 | while True: |
| 123 | samples, read = s() | 125 | samples, read = s() |
| 124 | if o(samples): | 126 | if o(samples): |
| 125 | timestamps.append (o.get_last()) | 127 | timestamps.append(o.get_last()) |
| 126 | if options.verbose: print ("%.4f" % o.get_last_s()) | 128 | if options.verbose: |
| 129 | print("%.4f" % o.get_last_s()) | ||
| 127 | total_frames += read | 130 | total_frames += read |
| 128 | if read < hopsize: break | 131 | if read < hopsize: |
| 132 | break | ||
| 129 | del s | 133 | del s |
| 130 | return timestamps, total_frames | 134 | return timestamps, total_frames |
| 131 | 135 | ||
| 132 | def _cut_slice(options, timestamps): | ||
| 133 | # cutting pass | ||
| 134 | nstamps = len(timestamps) | ||
| 135 | if nstamps > 0: | ||
| 136 | # generate output files | ||
| 137 | from aubio.slicing import slice_source_at_stamps | ||
| 138 | timestamps_end = None | ||
| 139 | if options.cut_every_nslices: | ||
| 140 | timestamps = timestamps[::options.cut_every_nslices] | ||
| 141 | nstamps = len(timestamps) | ||
| 142 | if options.cut_until_nslices and options.cut_until_nsamples: | ||
| 143 | print ("warning: using cut_until_nslices, but cut_until_nsamples is set") | ||
| 144 | if options.cut_until_nsamples: | ||
| 145 | timestamps_end = [t + options.cut_until_nsamples for t in timestamps[1:]] | ||
| 146 | timestamps_end += [ 1e120 ] | ||
| 147 | if options.cut_until_nslices: | ||
| 148 | timestamps_end = [t for t in timestamps[1 + options.cut_until_nslices:]] | ||
| 149 | timestamps_end += [ 1e120 ] * (options.cut_until_nslices + 1) | ||
| 150 | slice_source_at_stamps(options.source_uri, | ||
| 151 | timestamps, timestamps_end = timestamps_end, | ||
| 152 | output_dir = options.output_directory, | ||
| 153 | samplerate = options.samplerate, | ||
| 154 | create_first = options.create_first) | ||
| 155 | |||
| 156 | def main(): | 136 | def main(): |
| 157 | parser = aubio_cut_parser() | 137 | parser = aubio_cut_parser() |
| 158 | options = parser.parse_args() | 138 | options = parser.parse_args() |
| @@ -167,7 +147,7 @@ def main(): · 8 unmodified lines | |||
| 167 | timestamps, total_frames = _cut_analyze(options) | 147 | timestamps, total_frames = _cut_analyze(options) |
| 168 | 148 | ||
| 169 | # print some info | 149 | # print some info |
| 170 | duration = float (total_frames) / float(options.samplerate) | 150 | duration = float(total_frames) / float(options.samplerate) |
| 171 | base_info = '%(source_uri)s' % {'source_uri': options.source_uri} | 151 | base_info = '%(source_uri)s' % {'source_uri': options.source_uri} |
| 172 | base_info += ' (total %(duration).2fs at %(samplerate)dHz)\n' % \ | 152 | base_info += ' (total %(duration).2fs at %(samplerate)dHz)\n' % \ |
| 173 | {'duration': duration, 'samplerate': options.samplerate} | 153 | {'duration': duration, 'samplerate': options.samplerate} |
| @@ -1,11 +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', 'note2freq'] | ||
| 5 | |||
| 6 | import sys | 4 | import sys |
| 7 | from ._aubio import freqtomidi, miditofreq | 5 | from ._aubio import freqtomidi, miditofreq |
| 8 | 6 | ||
| 7 | __all__ = ['note2midi', 'midi2note', 'freq2note', 'note2freq'] | ||
| 8 | |||
| 9 | py3 = sys.version_info[0] == 3 | 9 | py3 = sys.version_info[0] == 3 |
| 10 | if py3: | 10 | if py3: |
| 11 | str_instances = str | 11 | str_instances = str |
| @@ -14,6 +14,7 @@ else: · 2 unmodified lines | |||
| 14 | str_instances = (str, unicode) | 14 | str_instances = (str, unicode) |
| 15 | int_instances = (int, long) | 15 | int_instances = (int, long) |
| 16 | 16 | ||
| 17 | |||
| 17 | def note2midi(note): | 18 | def note2midi(note): |
| 18 | """Convert note name to midi note number. | 19 | """Convert note name to midi note number. |
| 19 | 20 | ||
| @@ -55,13 +56,14 @@ def note2midi(note): · 35 unmodified lines | |||
| 55 | -------- | 56 | -------- |
| 56 | midi2note, freqtomidi, miditofreq | 57 | midi2note, freqtomidi, miditofreq |
| 57 | """ | 58 | """ |
| 58 | _valid_notenames = {'C': 0, 'D': 2, 'E': 4, 'F': 5, 'G': 7, 'A': 9, 'B': 11} | 59 | _valid_notenames = {'C': 0, 'D': 2, 'E': 4, 'F': 5, 'G': 7, |
| 60 | 'A': 9, 'B': 11} | ||
| 59 | _valid_modifiers = { | 61 | _valid_modifiers = { |
| 60 | u'𝄫': -2, # double flat | 62 | u'𝄫': -2, # double flat |
| 61 | u'♭': -1, 'b': -1, '\u266d': -1, # simple flat | 63 | u'♭': -1, 'b': -1, '\u266d': -1, # simple flat |
| 62 | u'♮': 0, '\u266e': 0, None: 0, # natural | 64 | u'♮': 0, '\u266e': 0, None: 0, # natural |
| 63 | '#': +1, u'♯': +1, '\u266f': +1, # sharp | 65 | '#': +1, u'♯': +1, '\u266f': +1, # sharp |
| 64 | u'𝄪': +2, # double sharp | 66 | u'𝄪': +2, # double sharp |
| 65 | } | 67 | } |
| 66 | _valid_octaves = range(-1, 10) | 68 | _valid_octaves = range(-1, 10) |
| 67 | if not isinstance(note, str_instances): | 69 | if not isinstance(note, str_instances): |
| @@ -70,7 +72,7 @@ def note2midi(note): · 2 unmodified lines | |||
| 70 | if len(note) not in range(2, 5): | 72 | if len(note) not in range(2, 5): |
| 71 | msg = "string of 2 to 4 characters expected, got {:d} ({:s})" | 73 | msg = "string of 2 to 4 characters expected, got {:d} ({:s})" |
| 72 | raise ValueError(msg.format(len(note), note)) | 74 | raise ValueError(msg.format(len(note), note)) |
| 73 | notename, modifier, octave = [None]*3 | 75 | notename, modifier, octave = [None] * 3 |
| 74 | 76 | ||
| 75 | if len(note) == 4: | 77 | if len(note) == 4: |
| 76 | notename, modifier, octave_sign, octave = note | 78 | notename, modifier, octave_sign, octave = note |
| @@ -93,12 +95,13 @@ def note2midi(note): · 16 unmodified lines | |||
| 93 | if octave not in _valid_octaves: | 95 | if octave not in _valid_octaves: |
| 94 | raise ValueError("%s is not a valid octave" % octave) | 96 | raise ValueError("%s is not a valid octave" % octave) |
| 95 | 97 | ||
| 96 | midi = 12 + octave * 12 + _valid_notenames[notename] \ | 98 | midi = (octave + 1) * 12 + _valid_notenames[notename] \ |
| 97 | + _valid_modifiers[modifier] | 99 | + _valid_modifiers[modifier] |
| 98 | if midi > 127: | 100 | if midi > 127: |
| 99 | raise ValueError("%s is outside of the range C-2 to G8" % note) | 101 | raise ValueError("%s is outside of the range C-2 to G8" % note) |
| 100 | return midi | 102 | return midi |
| 101 | 103 | ||
| 104 | |||
| 102 | def midi2note(midi): | 105 | def midi2note(midi): |
| 103 | """Convert midi note number to note name. | 106 | """Convert midi note number to note name. |
| 104 | 107 | ||
| @@ -136,9 +139,10 @@ def midi2note(midi): · 31 unmodified lines | |||
| 136 | msg = "an integer between 0 and 127 is excepted, got {:d}" | 139 | msg = "an integer between 0 and 127 is excepted, got {:d}" |
| 137 | raise ValueError(msg.format(midi)) | 140 | raise ValueError(msg.format(midi)) |
| 138 | _valid_notenames = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', | 141 | _valid_notenames = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', |
| 139 | 'A', 'A#', 'B'] | 142 | 'A', 'A#', 'B'] |
| 140 | return _valid_notenames[midi % 12] + str(int(midi / 12) - 1) | 143 | return _valid_notenames[midi % 12] + str(int(midi / 12) - 1) |
| 141 | 144 | ||
| 145 | |||
| 142 | def freq2note(freq): | 146 | def freq2note(freq): |
| 143 | """Convert frequency in Hz to nearest note name. | 147 | """Convert frequency in Hz to nearest note name. |
| 144 | 148 | ||
| @@ -162,6 +166,7 @@ def freq2note(freq): · 17 unmodified lines | |||
| 162 | nearest_note = int(freqtomidi(freq) + .5) | 166 | nearest_note = int(freqtomidi(freq) + .5) |
| 163 | return midi2note(nearest_note) | 167 | return midi2note(nearest_note) |
| 164 | 168 | ||
| 169 | |||
| 165 | def note2freq(note): | 170 | def note2freq(note): |
| 166 | """Convert note name to corresponding frequency, in Hz. | 171 | """Convert note name to corresponding frequency, in Hz. |
| 167 | 172 | ||
| @@ -5,6 +5,7 @@ from aubio import source, sink · 4 unmodified lines | |||
| 5 | 5 | ||
| 6 | _max_timestamp = 1e120 | 6 | _max_timestamp = 1e120 |
| 7 | 7 | ||
| 8 | |||
| 8 | def slice_source_at_stamps(source_file, timestamps, timestamps_end=None, | 9 | def slice_source_at_stamps(source_file, timestamps, timestamps_end=None, |
| 9 | output_dir=None, samplerate=0, hopsize=256, | 10 | output_dir=None, samplerate=0, hopsize=256, |
| 10 | create_first=False): | 11 | create_first=False): |
| @@ -72,7 +73,7 @@ def slice_source_at_stamps(source_file, timestamps, timestamps_end=None, · 61 unmodified lines | |||
| 72 | the file. | 73 | the file. |
| 73 | """ | 74 | """ |
| 74 | 75 | ||
| 75 | if timestamps is None or len(timestamps) == 0: | 76 | if not timestamps: |
| 76 | raise ValueError("no timestamps given") | 77 | raise ValueError("no timestamps given") |
| 77 | 78 | ||
| 78 | if timestamps[0] != 0 and create_first: | 79 | if timestamps[0] != 0 and create_first: |
| @@ -89,7 +90,6 @@ def slice_source_at_stamps(source_file, timestamps, timestamps_end=None, · 10 unmodified lines | |||
| 89 | timestamps_end = [t - 1 for t in timestamps[1:]] + [_max_timestamp] | 90 | timestamps_end = [t - 1 for t in timestamps[1:]] + [_max_timestamp] |
| 90 | 91 | ||
| 91 | regions = list(zip(timestamps, timestamps_end)) | 92 | regions = list(zip(timestamps, timestamps_end)) |
| 92 | #print regions | ||
| 93 | 93 | ||
| 94 | source_base_name, _ = os.path.splitext(os.path.basename(source_file)) | 94 | source_base_name, _ = os.path.splitext(os.path.basename(source_file)) |
| 95 | if output_dir is not None: | 95 | if output_dir is not None: |
| @@ -97,8 +97,8 @@ def slice_source_at_stamps(source_file, timestamps, timestamps_end=None, · 1 unmodified line | |||
| 97 | os.makedirs(output_dir) | 97 | os.makedirs(output_dir) |
| 98 | source_base_name = os.path.join(output_dir, source_base_name) | 98 | source_base_name = os.path.join(output_dir, source_base_name) |
| 99 | 99 | ||
| 100 | def new_sink_name(source_base_name, timestamp, samplerate): | 100 | def _new_sink_name(source_base_name, timestamp, samplerate): |
| 101 | """ create a sink based on a timestamp in samples, converted in seconds """ | 101 | # create name based on a timestamp in samples, converted in seconds |
| 102 | timestamp_seconds = timestamp / float(samplerate) | 102 | timestamp_seconds = timestamp / float(samplerate) |
| 103 | return source_base_name + "_%011.6f" % timestamp_seconds + '.wav' | 103 | return source_base_name + "_%011.6f" % timestamp_seconds + '.wav' |
| 104 | 104 | ||
| @@ -113,16 +113,17 @@ def slice_source_at_stamps(source_file, timestamps, timestamps_end=None, · 8 unmodified lines | |||
| 113 | # get hopsize new samples from source | 113 | # get hopsize new samples from source |
| 114 | vec, read = _source.do_multi() | 114 | vec, read = _source.do_multi() |
| 115 | # if the total number of frames read will exceed the next region start | 115 | # if the total number of frames read will exceed the next region start |
| 116 | while len(regions) and total_frames + read >= regions[0][0]: | 116 | while regions and total_frames + read >= regions[0][0]: |
| 117 | #print "getting", regions[0], "at", total_frames | ||
| 118 | # get next region | 117 | # get next region |
| 119 | start_stamp, end_stamp = regions.pop(0) | 118 | start_stamp, end_stamp = regions.pop(0) |
| 120 | # create a name for the sink | 119 | # create a name for the sink |
| 121 | new_sink_path = new_sink_name(source_base_name, start_stamp, samplerate) | 120 | new_sink_path = _new_sink_name(source_base_name, start_stamp, |
| 121 | samplerate) | ||
| 122 | # create its sink | 122 | # create its sink |
| 123 | _sink = sink(new_sink_path, samplerate, _source.channels) | 123 | _sink = sink(new_sink_path, samplerate, _source.channels) |
| 124 | # create a dictionary containing all this | 124 | # create a dictionary containing all this |
| 125 | new_slice = {'start_stamp': start_stamp, 'end_stamp': end_stamp, 'sink': _sink} | 125 | new_slice = {'start_stamp': start_stamp, 'end_stamp': end_stamp, |
| 126 | 'sink': _sink} | ||
| 126 | # append the dictionary to the current list of slices | 127 | # append the dictionary to the current list of slices |
| 127 | slices.append(new_slice) | 128 | slices.append(new_slice) |
| 128 | 129 | ||
| @@ -134,13 +135,11 @@ def slice_source_at_stamps(source_file, timestamps, timestamps_end=None, · 5 unmodified lines | |||
| 134 | start = max(start_stamp - total_frames, 0) | 135 | start = max(start_stamp - total_frames, 0) |
| 135 | # number of samples yet to written be until end of region | 136 | # number of samples yet to written be until end of region |
| 136 | remaining = end_stamp - total_frames + 1 | 137 | remaining = end_stamp - total_frames + 1 |
| 137 | #print current_slice, remaining, start | ||
| 138 | # not enough frames remaining, time to split | 138 | # not enough frames remaining, time to split |
| 139 | if remaining < read: | 139 | if remaining < read: |
| 140 | if remaining > start: | 140 | if remaining > start: |
| 141 | # write remaining samples from current region | 141 | # write remaining samples from current region |
| 142 | _sink.do_multi(vec[:, start:remaining], remaining - start) | 142 | _sink.do_multi(vec[:, start:remaining], remaining - start) |
| 143 | #print("closing region", "remaining", remaining) | ||
| 144 | # close this file | 143 | # close this file |
| 145 | _sink.close() | 144 | _sink.close() |
| 146 | elif read > start: | 145 | elif read > start: |
| @@ -149,6 +148,6 @@ def slice_source_at_stamps(source_file, timestamps, timestamps_end=None, · 2 unmodified lines | |||
| 149 | total_frames += read | 148 | total_frames += read |
| 150 | # remove old slices | 149 | # remove old slices |
| 151 | slices = list(filter(lambda s: s['end_stamp'] > total_frames, | 150 | slices = list(filter(lambda s: s['end_stamp'] > total_frames, |
| 152 | slices)) | 151 | slices)) |
| 153 | if read < hopsize: | 152 | if read < hopsize: |
| 154 | break | 153 | break |