Showing the changes to python (6 of 6 files). Show all
Unified · Split
| @@ -1,155 +0,0 @@ | |||
| 1 | #! /usr/bin/env python | ||
| 2 | |||
| 3 | """ this file was written by Paul Brossier | ||
| 4 | it is released under the GNU/GPL license. | ||
| 5 | """ | ||
| 6 | |||
| 7 | import sys | ||
| 8 | #from aubio.task import * | ||
| 9 | |||
| 10 | usage = "usage: %s [options] -i soundfile" % sys.argv[0] | ||
| 11 | |||
| 12 | def parse_args(): | ||
| 13 | from optparse import OptionParser | ||
| 14 | parser = OptionParser(usage=usage) | ||
| 15 | parser.add_option("-i", "--input", action = "store", dest = "source_file", | ||
| 16 | help="input sound file to analyse", metavar = "<source_file>") | ||
| 17 | parser.add_option("-m","--method", | ||
| 18 | action="store", dest="onset_method", default='default', | ||
| 19 | metavar = "<onset_method>", | ||
| 20 | help="onset detection method [default=default] \ | ||
| 21 | complexdomain|hfc|phase|specdiff|energy|kl|mkl") | ||
| 22 | # cutting methods | ||
| 23 | """ | ||
| 24 | parser.add_option("-b","--beat", | ||
| 25 | action="store_true", dest="beat", default=False, | ||
| 26 | help="use beat locations") | ||
| 27 | parser.add_option("-S","--silencecut", | ||
| 28 | action="store_true", dest="silencecut", default=False, | ||
| 29 | help="use silence locations") | ||
| 30 | parser.add_option("-s","--silence", | ||
| 31 | metavar = "<value>", | ||
| 32 | action="store", dest="silence", default=-70, | ||
| 33 | help="silence threshold [default=-70]") | ||
| 34 | """ | ||
| 35 | # algorithm parameters | ||
| 36 | parser.add_option("--samplerate", | ||
| 37 | metavar = "<freq>", type='int', | ||
| 38 | action="store", dest="samplerate", default=0, | ||
| 39 | help="samplerate at which the file should be represented") | ||
| 40 | parser.add_option("-B","--bufsize", | ||
| 41 | action="store", dest="bufsize", default=512, | ||
| 42 | metavar = "<size>", | ||
| 43 | help="buffer size [default=512]") | ||
| 44 | parser.add_option("-H","--hopsize", | ||
| 45 | metavar = "<size>", | ||
| 46 | action="store", dest="hopsize", default=256, | ||
| 47 | help="overlap size [default=256]") | ||
| 48 | parser.add_option("-t","--threshold", | ||
| 49 | metavar = "<value>", type="float", | ||
| 50 | action="store", dest="threshold", default=0.3, | ||
| 51 | help="onset peak picking threshold [default=0.3]") | ||
| 52 | """ | ||
| 53 | parser.add_option("-c","--cut", | ||
| 54 | action="store_true", dest="cut", default=False, | ||
| 55 | help="cut input sound file at detected labels \ | ||
| 56 | best used with option -L") | ||
| 57 | parser.add_option("-D","--delay", | ||
| 58 | action = "store", dest = "delay", type = "float", | ||
| 59 | metavar = "<seconds>", default=0, | ||
| 60 | help="number of seconds to take back [default=system]\ | ||
| 61 | default system delay is 3*hopsize/samplerate") | ||
| 62 | parser.add_option("-C","--dcthreshold", | ||
| 63 | metavar = "<value>", | ||
| 64 | action="store", dest="dcthreshold", default=1., | ||
| 65 | help="onset peak picking DC component [default=1.]") | ||
| 66 | parser.add_option("-M","--mintol", | ||
| 67 | metavar = "<value>", | ||
| 68 | action="store", dest="mintol", default=0.048, | ||
| 69 | help="minimum inter onset interval [default=0.048]") | ||
| 70 | parser.add_option("-L","--localmin", | ||
| 71 | action="store_true", dest="localmin", default=False, | ||
| 72 | help="use local minima after peak detection") | ||
| 73 | parser.add_option("-d","--derivate", | ||
| 74 | action="store_true", dest="derivate", default=False, | ||
| 75 | help="derivate onset detection function") | ||
| 76 | parser.add_option("-z","--zerocross", | ||
| 77 | metavar = "<value>", | ||
| 78 | action="store", dest="zerothres", default=0.008, | ||
| 79 | help="zero-crossing threshold for slicing [default=0.00008]") | ||
| 80 | """ | ||
| 81 | # plotting functions | ||
| 82 | """ | ||
| 83 | parser.add_option("-p","--plot", | ||
| 84 | action="store_true", dest="plot", default=False, | ||
| 85 | help="draw plot") | ||
| 86 | parser.add_option("-x","--xsize", | ||
| 87 | metavar = "<size>", | ||
| 88 | action="store", dest="xsize", default=1., | ||
| 89 | type='float', help="define xsize for plot") | ||
| 90 | parser.add_option("-y","--ysize", | ||
| 91 | metavar = "<size>", | ||
| 92 | action="store", dest="ysize", default=1., | ||
| 93 | type='float', help="define ysize for plot") | ||
| 94 | parser.add_option("-f","--function", | ||
| 95 | action="store_true", dest="func", default=False, | ||
| 96 | help="print detection function") | ||
| 97 | parser.add_option("-n","--no-onsets", | ||
| 98 | action="store_true", dest="nplot", default=False, | ||
| 99 | help="do not plot detected onsets") | ||
| 100 | parser.add_option("-O","--outplot", | ||
| 101 | metavar = "<output_image>", | ||
| 102 | action="store", dest="outplot", default=None, | ||
| 103 | help="save plot to output.{ps,png}") | ||
| 104 | parser.add_option("-F","--spectrogram", | ||
| 105 | action="store_true", dest="spectro", default=False, | ||
| 106 | help="add spectrogram to the plot") | ||
| 107 | """ | ||
| 108 | parser.add_option("-v","--verbose", | ||
| 109 | action="store_true", dest="verbose", default=True, | ||
| 110 | help="make lots of noise [default]") | ||
| 111 | parser.add_option("-q","--quiet", | ||
| 112 | action="store_false", dest="verbose", default=True, | ||
| 113 | help="be quiet") | ||
| 114 | (options, args) = parser.parse_args() | ||
| 115 | if not options.source_file: | ||
| 116 | print "no file name given\n", usage | ||
| 117 | sys.exit(1) | ||
| 118 | return options, args | ||
| 119 | |||
| 120 | if __name__ == '__main__': | ||
| 121 | options, args = parse_args() | ||
| 122 | |||
| 123 | hopsize = options.hopsize | ||
| 124 | bufsize = options.bufsize | ||
| 125 | samplerate = options.samplerate | ||
| 126 | source_file = options.source_file | ||
| 127 | |||
| 128 | from aubio import onset, source | ||
| 129 | |||
| 130 | s = source(source_file, samplerate, hopsize) | ||
| 131 | if samplerate == 0: samplerate = s.get_samplerate() | ||
| 132 | |||
| 133 | o = onset(options.onset_method, bufsize, hopsize) | ||
| 134 | o.set_threshold(options.threshold) | ||
| 135 | |||
| 136 | |||
| 137 | timestamps = [] | ||
| 138 | block_read = 0 | ||
| 139 | while True: | ||
| 140 | samples, read = s() | ||
| 141 | is_onset = o(samples) | ||
| 142 | if is_onset: | ||
| 143 | this_onset = (block_read * hopsize - is_onset[0]) | ||
| 144 | if options.verbose: | ||
| 145 | print "%.4f" % ( this_onset / samplerate ) | ||
| 146 | timestamps.append (this_onset) | ||
| 147 | block_read += 1 | ||
| 148 | if read < hopsize: break | ||
| 149 | |||
| 150 | # print some info | ||
| 151 | duration = float ( block_read * hopsize + read ) / samplerate | ||
| 152 | nstamps = len(timestamps) | ||
| 153 | info = 'found %(nstamps)d timestamps in %(source_file)s' % locals() | ||
| 154 | info += ' (read %(duration).2fs at %(samplerate)dHz)\n' % locals() | ||
| 155 | sys.stderr.write(info) | ||
| @@ -1,41 +0,0 @@ | |||
| 1 | #! /usr/bin/env python | ||
| 2 | |||
| 3 | import sys | ||
| 4 | from aubio import tempo, source | ||
| 5 | |||
| 6 | win_s = 512 # fft size | ||
| 7 | hop_s = win_s / 2 # hop size | ||
| 8 | samplerate = 44100 | ||
| 9 | |||
| 10 | if len(sys.argv) < 2: | ||
| 11 | print "Usage: %s <filename>" % sys.argv[0] | ||
| 12 | sys.exit(1) | ||
| 13 | |||
| 14 | filename = sys.argv[1] | ||
| 15 | beats = [] | ||
| 16 | |||
| 17 | s = source(filename, samplerate, hop_s) | ||
| 18 | t = tempo("default", win_s, hop_s) | ||
| 19 | |||
| 20 | block_read = 0 | ||
| 21 | while True: | ||
| 22 | samples, read = s() | ||
| 23 | isbeat = t(samples) | ||
| 24 | if isbeat: | ||
| 25 | thisbeat = (block_read * hop_s + isbeat[0]) / samplerate | ||
| 26 | print "%.4f" % thisbeat | ||
| 27 | beats.append (thisbeat) | ||
| 28 | block_read += 1 | ||
| 29 | if read < hop_s: break | ||
| 30 | |||
| 31 | periods = [60./(b - a) for a,b in zip(beats[:-1],beats[1:])] | ||
| 32 | |||
| 33 | from numpy import mean, median | ||
| 34 | if len(periods): | ||
| 35 | print 'mean period:', "%.2f" % mean(periods), 'bpm', 'median', "%.2f" % median(periods), 'bpm' | ||
| 36 | if 0: | ||
| 37 | from pylab import plot, show | ||
| 38 | plot(beats[1:], periods) | ||
| 39 | show() | ||
| 40 | else: | ||
| 41 | print 'mean period:', "%.2f" % 0, 'bpm', 'median', "%.2f" % 0, 'bpm' | ||
| @@ -18,12 +18,16 @@ if len( sys.argv ) > 2: samplerate = int(sys.argv[2]) · 17 unmodified lines | |||
| 18 | 18 | ||
| 19 | s = source(filename, samplerate, hop_s) | 19 | s = source(filename, samplerate, hop_s) |
| 20 | samplerate = s.samplerate | 20 | samplerate = s.samplerate |
| 21 | o = onset("default", win_s, hop_s) | 21 | o = onset("default", win_s, hop_s, samplerate) |
| 22 | 22 | ||
| 23 | # onset detection delay, in blocks | 23 | # onset detection delay, in samples |
| 24 | # default to 4 blocks delay to catch up with | ||
| 24 | delay = 4. * hop_s | 25 | delay = 4. * hop_s |
| 25 | 26 | ||
| 27 | # list of onsets, in samples | ||
| 26 | onsets = [] | 28 | onsets = [] |
| 29 | |||
| 30 | # total number of frames read | ||
| 27 | total_frames = 0 | 31 | total_frames = 0 |
| 28 | while True: | 32 | while True: |
| 29 | samples, read = s() | 33 | samples, read = s() |
| @@ -18,11 +18,13 @@ if len( sys.argv ) > 2: samplerate = int(sys.argv[2]) · 17 unmodified lines | |||
| 18 | 18 | ||
| 19 | s = source(filename, samplerate, hop_s) | 19 | s = source(filename, samplerate, hop_s) |
| 20 | samplerate = s.samplerate | 20 | samplerate = s.samplerate |
| 21 | o = onset("default", win_s, hop_s) | 21 | o = onset("default", win_s, hop_s, samplerate) |
| 22 | 22 | ||
| 23 | # onset detection delay, in blocks | 23 | # onset detection delay, in samples |
| 24 | # default to 4 blocks delay to catch up with | ||
| 24 | delay = 4. * hop_s | 25 | delay = 4. * hop_s |
| 25 | 26 | ||
| 27 | # list of onsets, in samples | ||
| 26 | onsets = [] | 28 | onsets = [] |
| 27 | 29 | ||
| 28 | # storage for plotted data | 30 | # storage for plotted data |
| @@ -31,6 +33,7 @@ tdesc = [] · 2 unmodified lines | |||
| 31 | allsamples_max = zeros(0,) | 33 | allsamples_max = zeros(0,) |
| 32 | downsample = 2 # to plot n samples / hop_s | 34 | downsample = 2 # to plot n samples / hop_s |
| 33 | 35 | ||
| 36 | # total number of frames read | ||
| 34 | total_frames = 0 | 37 | total_frames = 0 |
| 35 | while True: | 38 | while True: |
| 36 | samples, read = s() | 39 | samples, read = s() |
| @@ -38,7 +41,7 @@ while True: · 1 unmodified line | |||
| 38 | if is_onset: | 41 | if is_onset: |
| 39 | this_onset = int(total_frames - delay + is_onset[0] * hop_s) | 42 | this_onset = int(total_frames - delay + is_onset[0] * hop_s) |
| 40 | print "%f" % (this_onset / float(samplerate)) | 43 | print "%f" % (this_onset / float(samplerate)) |
| 41 | onsets.append(this_onset / float(samplerate)) | 44 | onsets.append(this_onset) |
| 42 | # keep some data to plot it later | 45 | # keep some data to plot it later |
| 43 | new_maxes = (abs(samples.reshape(hop_s/downsample, downsample))).max(axis=0) | 46 | new_maxes = (abs(samples.reshape(hop_s/downsample, downsample))).max(axis=0) |
| 44 | allsamples_max = hstack([allsamples_max, new_maxes]) | 47 | allsamples_max = hstack([allsamples_max, new_maxes]) |
| @@ -58,7 +61,9 @@ if 1: · 13 unmodified lines | |||
| 58 | plt.rc('lines',linewidth='.8') | 61 | plt.rc('lines',linewidth='.8') |
| 59 | plt1.plot(allsamples_max_times, allsamples_max, '-b') | 62 | plt1.plot(allsamples_max_times, allsamples_max, '-b') |
| 60 | plt1.plot(allsamples_max_times, -allsamples_max, '-b') | 63 | plt1.plot(allsamples_max_times, -allsamples_max, '-b') |
| 61 | for stamp in onsets: plt1.plot([stamp, stamp], [-1., 1.], '-r') | 64 | for stamp in onsets: |
| 65 | stamp /= float(samplerate) | ||
| 66 | plt1.plot([stamp, stamp], [-1., 1.], '-r') | ||
| 62 | plt1.axis(xmin = 0., xmax = max(allsamples_max_times) ) | 67 | plt1.axis(xmin = 0., xmax = max(allsamples_max_times) ) |
| 63 | plt1.xaxis.set_visible(False) | 68 | plt1.xaxis.set_visible(False) |
| 64 | plt1.yaxis.set_visible(False) | 69 | plt1.yaxis.set_visible(False) |
| @@ -66,7 +71,9 @@ if 1: · 1 unmodified line | |||
| 66 | desc_plot = [d / max(desc) for d in desc] | 71 | desc_plot = [d / max(desc) for d in desc] |
| 67 | plt2.plot(desc_times, desc_plot, '-g') | 72 | plt2.plot(desc_times, desc_plot, '-g') |
| 68 | tdesc_plot = [d / max(desc) for d in tdesc] | 73 | tdesc_plot = [d / max(desc) for d in tdesc] |
| 69 | for stamp in onsets: plt2.plot([stamp, stamp], [min(tdesc_plot), max(desc_plot)], '-r') | 74 | for stamp in onsets: |
| 75 | stamp /= float(samplerate) | ||
| 76 | plt2.plot([stamp, stamp], [min(tdesc_plot), max(desc_plot)], '-r') | ||
| 70 | plt2.plot(desc_times, tdesc_plot, '-y') | 77 | plt2.plot(desc_times, tdesc_plot, '-y') |
| 71 | plt2.axis(ymin = min(tdesc_plot), ymax = max(desc_plot)) | 78 | plt2.axis(ymin = min(tdesc_plot), ymax = max(desc_plot)) |
| 72 | plt.xlabel('time (s)') | 79 | plt.xlabel('time (s)') |
| @@ -0,0 +1,40 @@ | |||
| 1 | #! /usr/bin/env python | ||
| 2 | |||
| 3 | import sys | ||
| 4 | from aubio import tempo, source | ||
| 5 | |||
| 6 | win_s = 512 # fft size | ||
| 7 | hop_s = win_s / 2 # hop size | ||
| 8 | |||
| 9 | if len(sys.argv) < 2: | ||
| 10 | print "Usage: %s <filename> [samplerate]" % sys.argv[0] | ||
| 11 | sys.exit(1) | ||
| 12 | |||
| 13 | filename = sys.argv[1] | ||
| 14 | |||
| 15 | samplerate = 0 | ||
| 16 | if len( sys.argv ) > 2: samplerate = int(sys.argv[2]) | ||
| 17 | |||
| 18 | s = source(filename, samplerate, hop_s) | ||
| 19 | samplerate = s.samplerate | ||
| 20 | o = tempo("default", win_s, hop_s, samplerate) | ||
| 21 | |||
| 22 | # tempo detection delay, in samples | ||
| 23 | # default to 4 blocks delay to catch up with | ||
| 24 | delay = 4. * hop_s | ||
| 25 | |||
| 26 | # list of beats, in samples | ||
| 27 | beats = [] | ||
| 28 | |||
| 29 | # total number of frames read | ||
| 30 | total_frames = 0 | ||
| 31 | while True: | ||
| 32 | samples, read = s() | ||
| 33 | is_beat = o(samples) | ||
| 34 | if is_beat: | ||
| 35 | this_beat = int(total_frames - delay + is_beat[0] * hop_s) | ||
| 36 | print "%f" % (this_beat / float(samplerate)) | ||
| 37 | beats.append(this_beat) | ||
| 38 | total_frames += read | ||
| 39 | if read < hop_s: break | ||
| 40 | #print len(beats) | ||
| @@ -0,0 +1,84 @@ | |||
| 1 | #! /usr/bin/env python | ||
| 2 | |||
| 3 | import sys | ||
| 4 | from aubio import tempo, source | ||
| 5 | |||
| 6 | win_s = 512 # fft size | ||
| 7 | hop_s = win_s / 2 # hop size | ||
| 8 | |||
| 9 | if len(sys.argv) < 2: | ||
| 10 | print "Usage: %s <filename> [samplerate]" % sys.argv[0] | ||
| 11 | sys.exit(1) | ||
| 12 | |||
| 13 | filename = sys.argv[1] | ||
| 14 | |||
| 15 | samplerate = 0 | ||
| 16 | if len( sys.argv ) > 2: samplerate = int(sys.argv[2]) | ||
| 17 | |||
| 18 | s = source(filename, samplerate, hop_s) | ||
| 19 | samplerate = s.samplerate | ||
| 20 | o = tempo("default", win_s, hop_s, samplerate) | ||
| 21 | |||
| 22 | # tempo detection delay, in samples | ||
| 23 | # default to 4 blocks delay to catch up with | ||
| 24 | delay = 4. * hop_s | ||
| 25 | |||
| 26 | # list of beats, in samples | ||
| 27 | beats = [] | ||
| 28 | |||
| 29 | # total number of frames read | ||
| 30 | total_frames = 0 | ||
| 31 | while True: | ||
| 32 | samples, read = s() | ||
| 33 | is_beat = o(samples) | ||
| 34 | if is_beat: | ||
| 35 | this_beat = int(total_frames - delay + is_beat[0] * hop_s) | ||
| 36 | #print "%f" % (this_beat / float(samplerate)) | ||
| 37 | beats.append(this_beat) | ||
| 38 | total_frames += read | ||
| 39 | if read < hop_s: break | ||
| 40 | |||
| 41 | #convert samples to seconds | ||
| 42 | beats = map( lambda x: x / float(samplerate), beats) | ||
| 43 | |||
| 44 | bpms = [60./(b - a) for a,b in zip(beats[:-1],beats[1:])] | ||
| 45 | |||
| 46 | if len(bpms): | ||
| 47 | print 'mean period:', "%.2f" % mean(bpms), 'bpm', 'median', "%.2f" % median(bpms), 'bpm' | ||
| 48 | print 'plotting', filename | ||
| 49 | # do plotting | ||
| 50 | from numpy import array, arange, mean, median | ||
| 51 | import matplotlib.pyplot as plt | ||
| 52 | plt1 = plt.axes([0.1, 0.75, 0.8, 0.19]) | ||
| 53 | plt2 = plt.axes([0.1, 0.1, 0.8, 0.65], sharex = plt1) | ||
| 54 | plt.rc('lines',linewidth='.8') | ||
| 55 | for stamp in beats: plt1.plot([stamp, stamp], [-1., 1.], '-r') | ||
| 56 | plt1.axis(xmin = 0., xmax = total_frames / float(samplerate) ) | ||
| 57 | plt1.xaxis.set_visible(False) | ||
| 58 | plt1.yaxis.set_visible(False) | ||
| 59 | |||
| 60 | # plot actual periods | ||
| 61 | plt2.plot(beats[1:], bpms, '-', label = 'raw') | ||
| 62 | |||
| 63 | # plot moving median of 5 last periods | ||
| 64 | median_win_s = 5 | ||
| 65 | bpms_median = [ median(bpms[i:i + median_win_s:1]) for i in range(len(bpms) - median_win_s ) ] | ||
| 66 | plt2.plot(beats[median_win_s+1:], bpms_median, '-', label = 'median of %d' % median_win_s) | ||
| 67 | # plot moving median of 10 last periods | ||
| 68 | median_win_s = 20 | ||
| 69 | bpms_median = [ median(bpms[i:i + median_win_s:1]) for i in range(len(bpms) - median_win_s ) ] | ||
| 70 | plt2.plot(beats[median_win_s+1:], bpms_median, '-', label = 'median of %d' % median_win_s) | ||
| 71 | |||
| 72 | plt2.axis(ymin = min(bpms), ymax = max(bpms)) | ||
| 73 | #plt2.axis(ymin = 40, ymax = 240) | ||
| 74 | plt.xlabel('time (mm:ss)') | ||
| 75 | plt.ylabel('beats per minute (bpm)') | ||
| 76 | plt2.set_xticklabels([ "%02d:%02d" % (t/60, t%60) for t in plt2.get_xticks()[:-1]], rotation = 50) | ||
| 77 | |||
| 78 | #plt.savefig('/tmp/t.png', dpi=200) | ||
| 79 | plt2.legend() | ||
| 80 | plt.show() | ||
| 81 | |||
| 82 | else: | ||
| 83 | print 'mean period:', "%.2f" % 0, 'bpm', 'median', "%.2f" % 0, 'bpm', | ||
| 84 | print 'nothing to plot, file too short?' | ||