History

merged aubioplot-onsets into aubiocut, added some more options

Paul Brossier committed 21 years ago

Commit 80c04171 parent 588a09f5 files · +137 −155Browse files

Showing the changes to python (5 of 5 files). Show all

Unified · Split

5 files
  1. python/README +3 −2
  2. python/aubio/aubioclass.py +23 −12
  3. python/aubio/gnuplot.py +83 −3
  4. python/aubiocut +28 −14
  5. python/aubioplot-onset +0 −124
python/README+3−2
@@ -1,5 +1,6 @@
1Here you will find some examples of python scripts and some evaluation1Here you will find some examples of python scripts and some evaluation
2routines. The python interface for libaubio is generated using Swig.2routines. The python interface for libaubio is generated using Swig.
3 3
4To have it working before installation, set LD_LIBRARY_PATH as:4To have it working before installation, you will need to set LD_LIBRARY_PATH
5LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib:../src/.libs5# export LD_LIBRARY_PATH=../src/.libs:../ext/.libs
6for instance, to run the python script from within aubio/python/.
python/aubio/aubioclass.py+23−12
@@ -73,7 +73,7 @@ class peakpick: · 72 unmodified lines
73 73
74class onsetpick:74class onsetpick:
75 """ superclass for aubio_pvoc + aubio_onsetdetection + aubio_peakpicker """75 """ superclass for aubio_pvoc + aubio_onsetdetection + aubio_peakpicker """
76 def __init__(self,bufsize,hopsize,channels,myvec,threshold,mode='dual'):76 def __init__(self,bufsize,hopsize,channels,myvec,threshold,mode='dual',derivate=False):
77 self.myfft = cvec(bufsize,channels)77 self.myfft = cvec(bufsize,channels)
78 self.pv = pvoc(bufsize,hopsize,channels)78 self.pv = pvoc(bufsize,hopsize,channels)
79 if mode in [complexdomain,hfc,phase,energy,specdiff] :79 if mode in [complexdomain,hfc,phase,energy,specdiff] :
@@ -86,6 +86,8 @@ class onsetpick: · 6 unmodified lines
86 self.myonset2 = fvec(1,channels)86 self.myonset2 = fvec(1,channels)
87 self.mode = mode87 self.mode = mode
88 self.pp = peakpick(float(threshold))88 self.pp = peakpick(float(threshold))
89 self.derivate = derivate
90 self.oldval = 0.
89 91
90 def do(self,myvec): 92 def do(self,myvec):
91 self.pv.do(myvec,self.myfft)93 self.pv.do(myvec,self.myfft)
@@ -93,15 +95,23 @@ class onsetpick: · 1 unmodified line
93 if self.mode == 'dual':95 if self.mode == 'dual':
94 self.myod2.do(self.myfft,self.myonset2)96 self.myod2.do(self.myfft,self.myonset2)
95 self.myonset.set(self.myonset.get(0,0)*self.myonset2.get(0,0),0,0)97 self.myonset.set(self.myonset.get(0,0)*self.myonset2.get(0,0),0,0)
98 if self.derivate:
99 val = self.myonset.get(0,0)
100 dval = val - self.oldval
101 self.oldval = val
102 if dval > 0: self.myonset.set(dval,0,0)
103 else: self.myonset.set(0.,0,0)
96 return self.pp.do(self.myonset),self.myonset.get(0,0)104 return self.pp.do(self.myonset),self.myonset.get(0,0)
97 105
98def getonsets(filein,threshold=0.2,silence=-70.,bufsize=1024,hopsize=512,mode='dual',localmin=False,storefunc=False):106def getonsets(filein,threshold=0.2,silence=-70.,bufsize=1024,hopsize=512,
107 mode='dual',localmin=False,storefunc=False,derivate=False):
99 frameread = 0108 frameread = 0
100 filei = sndfile(filein)109 filei = sndfile(filein)
101 channels = filei.channels()110 channels = filei.channels()
102 myvec = fvec(hopsize,channels)111 myvec = fvec(hopsize,channels)
103 readsize = filei.read(hopsize,myvec)112 readsize = filei.read(hopsize,myvec)
104 opick = onsetpick(bufsize,hopsize,channels,myvec,threshold,mode=mode)113 opick = onsetpick(bufsize,hopsize,channels,myvec,threshold,
114 mode=mode,derivate=derivate)
105 mylist = list()115 mylist = list()
106 if localmin:116 if localmin:
107 ovalist = [0., 0., 0., 0., 0.]117 ovalist = [0., 0., 0., 0., 0.]
@@ -113,7 +123,8 @@ def getonsets(filein,threshold=0.2,silence=-70.,bufsize=1024,hopsize=512,mode='d · 5 unmodified lines
113 if (aubio_silence_detection(myvec(),silence)):123 if (aubio_silence_detection(myvec(),silence)):
114 isonset=0124 isonset=0
115 if localmin:125 if localmin:
116 ovalist.append(val)126 if val > 0: ovalist.append(val)
127 else: ovalist.append(0)
117 ovalist.pop(0)128 ovalist.pop(0)
118 if storefunc:129 if storefunc:
119 ofunclist.append(val)130 ofunclist.append(val)
@@ -135,7 +146,7 @@ def getonsets(filein,threshold=0.2,silence=-70.,bufsize=1024,hopsize=512,mode='d · 15 unmodified lines
135 if storefunc: return mylist, ofunclist146 if storefunc: return mylist, ofunclist
136 else: return mylist147 else: return mylist
137 148
138def cutfile(filein,slicetimes,zerothres=0.002,bufsize=1024,hopsize=512):149def cutfile(filein,slicetimes,zerothres=0.008,bufsize=1024,hopsize=512):
139 frameread = 0150 frameread = 0
140 readsize = hopsize 151 readsize = hopsize
141 filei = sndfile(filein)152 filei = sndfile(filein)
@@ -153,18 +164,18 @@ def cutfile(filein,slicetimes,zerothres=0.002,bufsize=1024,hopsize=512): · 11 unmodified lines
153 # write up to 1st zero crossing164 # write up to 1st zero crossing
154 zerocross = 0165 zerocross = 0
155 while ( abs( myvec.get(zerocross,0) ) > zerothres ):166 while ( abs( myvec.get(zerocross,0) ) > zerothres ):
156 zerocross += 1167 zerocross += 1
157 writesize = fileo.write(zerocross,myvec)168 writesize = fileo.write(zerocross,myvec)
158 fromcross = 0169 fromcross = 0
159 while (zerocross < readsize):170 while (zerocross < readsize):
160 for i in range(channels):171 for i in range(channels):
161 mycopy.set(myvec.get(zerocross,i),fromcross,i)172 mycopy.set(myvec.get(zerocross,i),fromcross,i)
162 fromcross += 1173 fromcross += 1
163 zerocross += 1174 zerocross += 1
164 del fileo175 del fileo
165 fileo = sndfile("%s%s%f%s%s" % 176 fileo = sndfile("%s%s%f%s%s" %
166 (filein.split(".")[0].split("/")[-1],".",177 (filein.split(".")[0].split("/")[-1],".",
167 frameread*framestep,".",filein.split(".")[-1]),model=filei)178 frameread*framestep,".",filein.split(".")[-1]),model=filei)
168 writesize = fileo.write(fromcross,mycopy)179 writesize = fileo.write(fromcross,mycopy)
169 else:180 else:
170 writesize = fileo.write(readsize,myvec)181 writesize = fileo.write(readsize,myvec)
python/aubio/gnuplot.py+83−3
@@ -136,10 +136,90 @@ def plot_audio(filenames, fileout=None, start=0, end=None, noaxis=None): · 135 unmodified lines
136 136
137def make_audio_plot(time,data,maxpoints=10000):137def make_audio_plot(time,data,maxpoints=10000):
138 """ create gnuplot plot from an audio file """138 """ create gnuplot plot from an audio file """
139 import numarray
140 length = len(time)139 length = len(time)
141 downsample = length/maxpoints140 downsample = length/maxpoints
142 if downsample == 0: downsample = 1141 if downsample == 0: downsample = 1
143 x = numarray.array(time).resize(length)[0:-1:downsample]142 x = array(time).resize(length)[0:-1:downsample]
144 y = numarray.array(data).resize(length)[0:-1:downsample]143 y = array(data).resize(length)[0:-1:downsample]
145 return Gnuplot.Data(x,y,with='lines')144 return Gnuplot.Data(x,y,with='lines')
145
146
147def plot_onsets(filename, onsets, ofunc, samplerate=44100., hopsize=512, outplot=None):
148 import aubio.txtfile
149 import os.path
150 import numarray
151 from aubio.onsetcompare import onset_roc
152
153 # onset detection function
154 downtime = (hopsize/samplerate)*numarray.arange(len(ofunc))
155 d = Gnuplot.Data(downtime,ofunc,with='lines')
156
157 # detected onsets
158 x1 = (hopsize/samplerate)*numarray.array(onsets)
159 y1 = max(ofunc)*numarray.ones(len(onsets))
160 e = Gnuplot.Data(x1,-y1,with='impulses')
161 e2= Gnuplot.Data(x1,y1,with='impulses')
162
163 # check if datafile exists truth
164 datafile = filename.replace('.wav','.txt')
165 if not os.path.isfile(datafile):
166 title = "truth file not found"
167 t = Gnuplot.Data(0,0,with='impulses')
168 else:
169 t_onsets = aubio.txtfile.read_datafile(datafile)
170 y2 = max(ofunc)*numarray.ones(len(t_onsets))
171 x2 = numarray.array(t_onsets).resize(len(t_onsets))
172 t = Gnuplot.Data(x2,y2,with='impulses')
173
174 tol = 0.050
175
176 orig, missed, merged, expc, bad, doubled = \
177 onset_roc(x2,x1,tol)
178 title = "GD %2.3f%% FP %2.3f%%" % \
179 ((100*float(orig-missed-merged)/(orig)),
180 (100*float(bad+doubled)/(orig)))
181 #print orig, missed, merged, expc, bad, doubled
182 #print "GD %2.8f\t" % (100*float(orig-missed-merged)/(orig)),
183 #print "FP %2.8f\t" % (100*float(bad+doubled)/(orig)) ,
184 #print "GD-merged %2.8f\t" % (100*float(orig-missed)/(orig)) ,
185 #print "FP-pruned %2.8f\t" % (100*float(bad)/(orig))
186
187 # audio data
188 time,data = audio_to_array(filename)
189 f = make_audio_plot(time,data)
190
191 # prepare the plot
192 g = Gnuplot.Gnuplot(debug=1, persist=1)
193 if outplot:
194 extension = outplot.split('.')[-1]
195 if extension == 'ps': extension = 'postscript'
196 g('set terminal %s' % extension)
197 g('set output \'%s\'' % outplot)
198
199 g('set title \'%s %s\'' % (filename,title))
200
201 g('set multiplot')
202
203 # hack to align left axis
204 g('set lmargin 15')
205
206 # plot waveform and onsets
207 g('set size 1,0.3')
208 g('set origin 0,0.7')
209 g('set xrange [0:%f]' % max(time))
210 g('set yrange [-1:1]')
211 g.ylabel('amplitude')
212 g.plot(f,e,t)
213
214 g('unset title')
215
216 # plot onset detection function
217 g('set size 1,0.7')
218 g('set origin 0,0')
219 g('set xrange [0:%f]' % (hopsize/samplerate*len(ofunc)))
220 g('set yrange [0:%f]' % (max(ofunc)*1.01))
221 g.xlabel('time')
222 g.ylabel('onset detection value')
223 g.plot(d,e2)
224
225 g('unset multiplot')
python/aubiocut+28−14
@@ -33,7 +33,7 @@ def parse_args(): · 32 unmodified lines
33 help="input sound file")33 help="input sound file")
34 parser.add_option("-m","--mode", action="callback", 34 parser.add_option("-m","--mode", action="callback",
35 callback=check_mode, dest="mode", default='dual', 35 callback=check_mode, dest="mode", default='dual',
36 help="onsetdetection mode [default=dual] \36 help="onset detection mode [default=dual] \
37 complexdomain|hfc|phase|specdiff|energy|dual")37 complexdomain|hfc|phase|specdiff|energy|dual")
38 parser.add_option("-B","--bufsize",38 parser.add_option("-B","--bufsize",
39 action="store", dest="bufsize", default=1024, 39 action="store", dest="bufsize", default=1024,
@@ -51,8 +51,9 @@ def parse_args(): · 11 unmodified lines
51 action="store", dest="mintol", default=0.048, 51 action="store", dest="mintol", default=0.048,
52 help="minimum inter onset interval [default=0.048]")52 help="minimum inter onset interval [default=0.048]")
53 parser.add_option("-D","--delay",53 parser.add_option("-D","--delay",
54 action="store", dest="delay", default=0.022, 54 action="store", dest="delay",
55 help="number of seconds to take back [default=0.022]")55 help="number of seconds to take back [default=system]\
56 default system delay is 2*hopsize/samplerate")
56 parser.add_option("-L","--localmin",57 parser.add_option("-L","--localmin",
57 action="store_true", dest="localmin", default=False, 58 action="store_true", dest="localmin", default=False,
58 help="use local minima after peak detection")59 help="use local minima after peak detection")
@@ -60,23 +61,23 @@ def parse_args(): · 1 unmodified line
60 action="store_true", dest="cut", default=False,61 action="store_true", dest="cut", default=False,
61 help="cut input sound file at detected labels \62 help="cut input sound file at detected labels \
62 best used with option -L")63 best used with option -L")
64 parser.add_option("-d","--derivate",
65 action="store_true", dest="derivate", default=False,
66 help="derivate onset detection function")
63 # to be implemented67 # to be implemented
64 # plotting functions
65 parser.add_option("-d","--derivative",
66 action="store_true", dest="derivative", default=False,
67 help="NOT IMPLEMENTED derivate onset detection function")
68 parser.add_option("-p","--plot",
69 action="store_true", dest="doplot", default=False,
70 help="NOT IMPLEMENTED draw plot")
71 parser.add_option("-O","--outplot",
72 action="store", dest="output-plot", default=None,
73 help="NOT IMPLEMENTED save plot to output.{ps,png}")
74 parser.add_option("-z","--zerocross",68 parser.add_option("-z","--zerocross",
75 action="store_true", dest="zerocross", default=False, 69 action="store_true", dest="zerocross", default=False,
76 help="NOT IMPLEMENTED zero crossing matching")70 help="NOT IMPLEMENTED zero crossing matching")
77 parser.add_option("-b","--beat",71 parser.add_option("-b","--beat",
78 action="store_true", dest="beat", default=False,72 action="store_true", dest="beat", default=False,
79 help="NOT IMPLEMENTED output beat locations")73 help="NOT IMPLEMENTED output beat locations")
74 # plotting functions
75 parser.add_option("-p","--plot",
76 action="store_true", dest="plot", default=False,
77 help="draw plot")
78 parser.add_option("-O","--outplot",
79 action="store", dest="outplot", default=None,
80 help="save plot to output.{ps,png}")
80 parser.add_option("-v","--verbose",81 parser.add_option("-v","--verbose",
81 action="store_true", dest="verbose", default=False,82 action="store_true", dest="verbose", default=False,
82 help="make lots of noise [default]")83 help="make lots of noise [default]")
@@ -99,14 +100,22 @@ step = float(samplerate)/float(hopsize) · 16 unmodified lines
99threshold = float(options.threshold)100threshold = float(options.threshold)
100silence = float(options.silence)101silence = float(options.silence)
101mintol = float(options.mintol)*step102mintol = float(options.mintol)*step
102delay = float(options.delay)103# default take back system delay
104if options.delay: delay = float(options.delay)
105else: delay = 2./step
103 106
104if options.beat:107if options.beat:
105 #onsets = getbeats(filename,threshold,silence,mode=options.mode)108 #onsets = getbeats(filename,threshold,silence,mode=options.mode)
106 exit("not implemented yet")109 exit("not implemented yet")
110elif options.plot:
111 onsets, ofunc = getonsets(filename,threshold,silence,
112 mode=options.mode,localmin=options.localmin,
113 derivate=options.derivate,
114 bufsize=bufsize,hopsize=hopsize,storefunc=True)
107else:115else:
108 onsets = getonsets(filename,threshold,silence,116 onsets = getonsets(filename,threshold,silence,
109 mode=options.mode,localmin=options.localmin,117 mode=options.mode,localmin=options.localmin,
118 derivate=options.derivate,
110 bufsize=bufsize,hopsize=hopsize)119 bufsize=bufsize,hopsize=hopsize)
111 120
112# take back system delay121# take back system delay
@@ -128,5 +137,10 @@ if mintol > 0: · 15 unmodified lines
128if options.verbose:137if options.verbose:
129 for i in onsets: print "%f" % (i/step)138 for i in onsets: print "%f" % (i/step)
130 139
140if options.plot:
141 from aubio.gnuplot import plot_onsets
142 plot_onsets(filename, onsets, ofunc,
143 samplerate=samplerate, hopsize=hopsize, outplot=options.outplot)
144
131if options.cut:145if options.cut:
132 cutfile(filename,onsets,bufsize=bufsize,hopsize=hopsize)146 cutfile(filename,onsets,bufsize=bufsize,hopsize=hopsize)
python/aubioplot-onset+0−124
@@ -1,124 +0,0 @@
1#! /usr/bin/python
2
3import sys
4import numarray
5import Gnuplot, Gnuplot.funcutils
6from aubio.aubioclass import *
7import aubio.gnuplot
8import aubio.txtfile
9from aubio.onsetcompare import onset_roc
10
11
12usage = "usage: %s [options] soundfile" % sys.argv[0]
13
14def parse_args():
15 from optparse import OptionParser
16 parser = OptionParser(usage=usage)
17 parser.add_option("-v","--verbose",
18 action="store_true", dest="verbose", default=False,
19 help="make lots of noise")
20 parser.add_option("-q","--quiet",
21 action="store_false", dest="verbose", default=True,
22 help="be quiet [default]")
23 parser.add_option("-t","--threshold",
24 action="store", dest="threshold", default=0.3,
25 help="onset detection threshold [default=0.3]")
26 parser.add_option("-s","--silence",
27 action="store", dest="silence", default=-70,
28 help="silence [default=-70]")
29 def check_mode(option, opt, value, parser):
30 nvalue = parser.rargs[0]
31 if nvalue == 'complexdomain' : setattr(parser.values, option.dest, complexdomain)
32 elif nvalue == 'hfc' : setattr(parser.values, option.dest, hfc)
33 elif nvalue == 'phase' : setattr(parser.values, option.dest, phase)
34 elif nvalue == 'specdiff' : setattr(parser.values, option.dest, specdiff)
35 elif nvalue == 'energy' : setattr(parser.values, option.dest, energy)
36 elif nvalue == 'dual' : setattr(parser.values, option.dest, 'dual')
37 parser.add_option("-m","--mode",
38 action="callback", callback=check_mode, dest="mode", default='dual',
39 help="onsetdetection mode [default=dual]")
40 parser.add_option("-o","--outplot",
41 action="store", dest="outplot", default=None,
42 help="be quiet [default=None]")
43 (options, args) = parser.parse_args()
44 if not len(args):
45 print "no file name given\n", usage
46 sys.exit(1)
47 return options, args
48
49options, args = parse_args()
50
51filename = args[0] #FIXME should move to optparse
52threshold = float(options.threshold)
53silence = float(options.silence)
54
55print options.mode
56onsets, ofunc = getonsetsfunc(filename,threshold,silence,mode=options.mode)
57
58g = Gnuplot.Gnuplot(debug=1, persist=1)
59
60if options.outplot:
61 extension = options.outplot.split('.')[-1]
62 if extension == 'ps': extension = 'postscript'
63 g('set terminal %s' % extension)
64 g('set output \'%s\'' % options.outplot)
65
66g('set multiplot')
67
68# onset detection function
69downtime = (512./44100.)*numarray.arange(len(ofunc))
70d = Gnuplot.Data(downtime,ofunc,with='lines')
71
72# detected onsets
73x1 = (512./44100.)*numarray.array(onsets)
74y1 = max(ofunc)*numarray.ones(len(onsets))
75e = Gnuplot.Data(x1,-y1,with='impulses')
76e2= Gnuplot.Data(x1,y1,with='impulses')
77
78# truth
79import os.path
80datafile = filename.replace('.wav','.txt')
81if not os.path.isfile(datafile):
82 print "truth file not found"
83 t = Gnuplot.Data(0,0,with='impulses')
84else:
85 t_onsets = aubio.txtfile.read_datafile(datafile)
86 y2 = max(ofunc)*numarray.ones(len(t_onsets))
87 x2 = numarray.array(t_onsets).resize(len(t_onsets))
88 t = Gnuplot.Data(x2,y2,with='impulses')
89
90 eps = 4*0.012
91
92 orig, missed, merged, expc, bad, doubled = \
93 onset_roc(x2,x1,eps)
94 print orig, missed, merged, expc, bad, doubled
95 print "GD %2.8f\t" % (100*float(orig-missed-merged)/(orig)),
96 print "FP %2.8f\t" % (100*float(bad+doubled)/(orig)) ,
97 print "GD-merged %2.8f\t" % (100*float(orig-missed)/(orig)) ,
98 print "FP-pruned %2.8f\t" % (100*float(bad)/(orig))
99
100# audio data
101time,data = aubio.gnuplot.audio_to_array(filename)
102f = aubio.gnuplot.make_audio_plot(time,data)
103
104# hack to align left axis
105g('set lmargin 15')
106
107g('set size 1,0.3')
108g('set origin 0,0.7')
109g('set xrange [0:%f]' % max(time))
110g('set yrange [-1:1]')
111g.ylabel('amplitude')
112g.plot(f,e,t)
113
114g('set size 1,0.7')
115g('set origin 0,0')
116g('set xrange [0:%f]' % (512./44100.*len(ofunc)))
117g('set yrange [0:%f]' % (max(ofunc)*1.01))
118g.xlabel('time')
119g.ylabel('onset detection value')
120
121g.plot(d,e2)
122
123g('unset multiplot')
124

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