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 @@
11 Here you will find some examples of python scripts and some evaluation
22 routines. The python interface for libaubio is generated using Swig.
33
4−To have it working before installation, set LD_LIBRARY_PATH as:
5−LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib:../src/.libs
4+To have it working before installation, you will need to set LD_LIBRARY_PATH
5+# export LD_LIBRARY_PATH=../src/.libs:../ext/.libs
6+for 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
7373
7474 class onsetpick:
7575 """ 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):
7777 self.myfft = cvec(bufsize,channels)
7878 self.pv = pvoc(bufsize,hopsize,channels)
7979 if mode in [complexdomain,hfc,phase,energy,specdiff] :
@@ -86,6 +86,8 @@ class onsetpick: · 6 unmodified lines
8686 self.myonset2 = fvec(1,channels)
8787 self.mode = mode
8888 self.pp = peakpick(float(threshold))
89+ self.derivate = derivate
90+ self.oldval = 0.
8991
9092 def do(self,myvec):
9193 self.pv.do(myvec,self.myfft)
@@ -93,15 +95,23 @@ class onsetpick: · 1 unmodified line
9395 if self.mode == 'dual':
9496 self.myod2.do(self.myfft,self.myonset2)
9597 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)
96104 return self.pp.do(self.myonset),self.myonset.get(0,0)
97105
98−def getonsets(filein,threshold=0.2,silence=-70.,bufsize=1024,hopsize=512,mode='dual',localmin=False,storefunc=False):
106+def getonsets(filein,threshold=0.2,silence=-70.,bufsize=1024,hopsize=512,
107+ mode='dual',localmin=False,storefunc=False,derivate=False):
99108 frameread = 0
100109 filei = sndfile(filein)
101110 channels = filei.channels()
102111 myvec = fvec(hopsize,channels)
103112 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)
105115 mylist = list()
106116 if localmin:
107117 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
113123 if (aubio_silence_detection(myvec(),silence)):
114124 isonset=0
115125 if localmin:
116− ovalist.append(val)
126+ if val > 0: ovalist.append(val)
127+ else: ovalist.append(0)
117128 ovalist.pop(0)
118129 if storefunc:
119130 ofunclist.append(val)
@@ -135,7 +146,7 @@ def getonsets(filein,threshold=0.2,silence=-70.,bufsize=1024,hopsize=512,mode='d · 15 unmodified lines
135146 if storefunc: return mylist, ofunclist
136147 else: return mylist
137148
138−def cutfile(filein,slicetimes,zerothres=0.002,bufsize=1024,hopsize=512):
149+def cutfile(filein,slicetimes,zerothres=0.008,bufsize=1024,hopsize=512):
139150 frameread = 0
140151 readsize = hopsize
141152 filei = sndfile(filein)
@@ -153,18 +164,18 @@ def cutfile(filein,slicetimes,zerothres=0.002,bufsize=1024,hopsize=512): · 11 unmodified lines
153164 # write up to 1st zero crossing
154165 zerocross = 0
155166 while ( abs( myvec.get(zerocross,0) ) > zerothres ):
156− zerocross += 1
167+ zerocross += 1
157168 writesize = fileo.write(zerocross,myvec)
158169 fromcross = 0
159170 while (zerocross < readsize):
160− for i in range(channels):
161− mycopy.set(myvec.get(zerocross,i),fromcross,i)
162− fromcross += 1
163− zerocross += 1
171+ for i in range(channels):
172+ mycopy.set(myvec.get(zerocross,i),fromcross,i)
173+ fromcross += 1
174+ zerocross += 1
164175 del fileo
165176 fileo = sndfile("%s%s%f%s%s" %
166− (filein.split(".")[0].split("/")[-1],".",
167− frameread*framestep,".",filein.split(".")[-1]),model=filei)
177+ (filein.split(".")[0].split("/")[-1],".",
178+ frameread*framestep,".",filein.split(".")[-1]),model=filei)
168179 writesize = fileo.write(fromcross,mycopy)
169180 else:
170181 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
136136
137137 def make_audio_plot(time,data,maxpoints=10000):
138138 """ create gnuplot plot from an audio file """
139− import numarray
140139 length = len(time)
141140 downsample = length/maxpoints
142141 if downsample == 0: downsample = 1
143− x = numarray.array(time).resize(length)[0:-1:downsample]
144− y = numarray.array(data).resize(length)[0:-1:downsample]
142+ x = array(time).resize(length)[0:-1:downsample]
143+ y = array(data).resize(length)[0:-1:downsample]
145144 return Gnuplot.Data(x,y,with='lines')
145+
146+
147+def 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
3333 help="input sound file")
3434 parser.add_option("-m","--mode", action="callback",
3535 callback=check_mode, dest="mode", default='dual',
36− help="onsetdetection mode [default=dual] \
36+ help="onset detection mode [default=dual] \
3737 complexdomain|hfc|phase|specdiff|energy|dual")
3838 parser.add_option("-B","--bufsize",
3939 action="store", dest="bufsize", default=1024,
@@ -51,8 +51,9 @@ def parse_args(): · 11 unmodified lines
5151 action="store", dest="mintol", default=0.048,
5252 help="minimum inter onset interval [default=0.048]")
5353 parser.add_option("-D","--delay",
54− action="store", dest="delay", default=0.022,
55− help="number of seconds to take back [default=0.022]")
54+ action="store", dest="delay",
55+ help="number of seconds to take back [default=system]\
56+ default system delay is 2*hopsize/samplerate")
5657 parser.add_option("-L","--localmin",
5758 action="store_true", dest="localmin", default=False,
5859 help="use local minima after peak detection")
@@ -60,23 +61,23 @@ def parse_args(): · 1 unmodified line
6061 action="store_true", dest="cut", default=False,
6162 help="cut input sound file at detected labels \
6263 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")
6367 # 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}")
7468 parser.add_option("-z","--zerocross",
7569 action="store_true", dest="zerocross", default=False,
7670 help="NOT IMPLEMENTED zero crossing matching")
7771 parser.add_option("-b","--beat",
7872 action="store_true", dest="beat", default=False,
7973 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}")
8081 parser.add_option("-v","--verbose",
8182 action="store_true", dest="verbose", default=False,
8283 help="make lots of noise [default]")
@@ -99,14 +100,22 @@ step = float(samplerate)/float(hopsize) · 16 unmodified lines
99100 threshold = float(options.threshold)
100101 silence = float(options.silence)
101102 mintol = float(options.mintol)*step
102−delay = float(options.delay)
103+# default take back system delay
104+if options.delay: delay = float(options.delay)
105+else: delay = 2./step
103106
104107 if options.beat:
105108 #onsets = getbeats(filename,threshold,silence,mode=options.mode)
106109 exit("not implemented yet")
110+elif 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)
107115 else:
108116 onsets = getonsets(filename,threshold,silence,
109117 mode=options.mode,localmin=options.localmin,
118+ derivate=options.derivate,
110119 bufsize=bufsize,hopsize=hopsize)
111120
112121 # take back system delay
@@ -128,5 +137,10 @@ if mintol > 0: · 15 unmodified lines
128137 if options.verbose:
129138 for i in onsets: print "%f" % (i/step)
130139
140+if options.plot:
141+ from aubio.gnuplot import plot_onsets
142+ plot_onsets(filename, onsets, ofunc,
143+ samplerate=samplerate, hopsize=hopsize, outplot=options.outplot)
144+
131145 if options.cut:
132146 cutfile(filename,onsets,bufsize=bufsize,hopsize=hopsize)
python/aubioplot-onset+0−124
@@ -1,124 +0,0 @@
1−#! /usr/bin/python
2−
3−import sys
4−import numarray
5−import Gnuplot, Gnuplot.funcutils
6−from aubio.aubioclass import *
7−import aubio.gnuplot
8−import aubio.txtfile
9−from aubio.onsetcompare import onset_roc
10−
11−
12−usage = "usage: %s [options] soundfile" % sys.argv[0]
13−
14−def 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−
49−options, args = parse_args()
50−
51−filename = args[0] #FIXME should move to optparse
52−threshold = float(options.threshold)
53−silence = float(options.silence)
54−
55−print options.mode
56−onsets, ofunc = getonsetsfunc(filename,threshold,silence,mode=options.mode)
57−
58−g = Gnuplot.Gnuplot(debug=1, persist=1)
59−
60−if 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−
66−g('set multiplot')
67−
68−# onset detection function
69−downtime = (512./44100.)*numarray.arange(len(ofunc))
70−d = Gnuplot.Data(downtime,ofunc,with='lines')
71−
72−# detected onsets
73−x1 = (512./44100.)*numarray.array(onsets)
74−y1 = max(ofunc)*numarray.ones(len(onsets))
75−e = Gnuplot.Data(x1,-y1,with='impulses')
76−e2= Gnuplot.Data(x1,y1,with='impulses')
77−
78−# truth
79−import os.path
80−datafile = filename.replace('.wav','.txt')
81−if not os.path.isfile(datafile):
82− print "truth file not found"
83− t = Gnuplot.Data(0,0,with='impulses')
84−else:
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
101−time,data = aubio.gnuplot.audio_to_array(filename)
102−f = aubio.gnuplot.make_audio_plot(time,data)
103−
104−# hack to align left axis
105−g('set lmargin 15')
106−
107−g('set size 1,0.3')
108−g('set origin 0,0.7')
109−g('set xrange [0:%f]' % max(time))
110−g('set yrange [-1:1]')
111−g.ylabel('amplitude')
112−g.plot(f,e,t)
113−
114−g('set size 1,0.7')
115−g('set origin 0,0')
116−g('set xrange [0:%f]' % (512./44100.*len(ofunc)))
117−g('set yrange [0:%f]' % (max(ofunc)*1.01))
118−g.xlabel('time')
119−g.ylabel('onset detection value')
120−
121−g.plot(d,e2)
122−
123−g('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