1 """Copyright (C) 2004 Paul Brossier <piem@altern.org>
2 print aubio.__LICENSE__ for the terms of use
6 Copyright (C) 2004 Paul Brossier <piem@altern.org>
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 from numarray import *
26 import Gnuplot, Gnuplot.funcutils
28 def plotnote(la,title=None) :
29 if la[0,:].size() == 3:
30 d = plotnote_withends(la, plot_title=title)
32 # scale data if in freq (for REF.txt files)
33 if max(la[:,1] > 128 ):
34 print "scaling frequency data to midi range"
36 la[:,1] = log(la[:,1])/0.6931
39 d = plotnote_withoutends(la, plot_title=title)
42 def plotnote_multi(lalist,title=None,fileout=None) :
44 for i in range(len(lalist)):
45 d.append(plotnote(lalist[i], title=title))
49 def plotnote_withends(la,plot_title=None) :
51 x_widths = array(la[:,1]-la[:,0])/2.
52 d.append(Gnuplot.Data(
53 la[:,0]+x_widths, # x centers
56 __notesheight*ones(len(la)), # y errors
57 title=plot_title,with=('boxxyerrorbars fs 3')))
61 def plotnote_withoutends(la,plot_title=None) :
62 """ bug: fails drawing last note """
64 x_widths = array(la[1:,0]-la[:-1,0])/2;
65 d.append(Gnuplot.Data(
66 la[:-1,0]+x_widths, # x centers
67 la[:-1,1], # y centers
69 __notesheight*ones(len(la)-1), # y errors
70 title=plot_title,with=('boxxyerrorbars fs 3')))
73 def plotnote_do(d,fileout=None):
74 g = Gnuplot.Gnuplot(debug=1, persist=1)
75 g.gnuplot('set style fill solid border 1; \
77 set boxwidth 0.9 relative; \
82 set grid xtics ytics mxtics mytics')
85 g.ylabel('Midi pitch')
87 #g.gnuplot('set multiplot')
90 #g.gnuplot('set nomultiplot')
92 g.hardcopy(fileout, enhanced=1, color=0)
94 def audio_to_array(filename):
95 import aubio.aubioclass
97 filei = aubio.aubioclass.sndfile(filename)
98 framestep = 1/(filei.samplerate()+0.)
99 channels = filei.channels()
100 myvec = aubio.aubioclass.fvec(hopsize,channels)
103 while (readsize==hopsize):
104 readsize = filei.read(hopsize,myvec)
105 #for i in range(channels):
108 while (curpos < readsize):
109 data.append(myvec.get(curpos,i))
111 time = arange(len(data))*framestep
114 def plot_audio(filenames, fileout=None, start=0, end=None, noaxis=None):
115 g = Gnuplot.Gnuplot(debug=1, persist=1)
117 todraw = len(filenames)
120 g.gnuplot('set multiplot;')
121 while (len(filenames)):
122 d.append(plot_audio_make(filenames.pop(0)))
123 if not noaxis and todraw==1:
125 g.ylabel('Amplitude')
126 g.gnuplot('set size %f,1.;' % (xsize) )
127 g.gnuplot('set origin %f,0.;' % (xorig) )
128 g.gnuplot('set style data lines; \
129 set yrange [-1.:1.]; \
130 set xrange [0:%f]' % b[-1])
133 g.gnuplot('unset multiplot;')
135 g.hardcopy(fileout, enhanced=1, color=0)
137 def make_audio_plot(time,data,maxpoints=10000):
138 """ create gnuplot plot from an audio file """
140 downsample = length/maxpoints
141 if downsample == 0: downsample = 1
142 x = array(time).resize(length)[0:-1:downsample]
143 y = array(data).resize(length)[0:-1:downsample]
144 return Gnuplot.Data(x,y,with='lines')
147 def plot_onsets(filename, onsets, ofunc, samplerate=44100., hopsize=512, outplot=None):
151 from aubio.onsetcompare import onset_roc
153 if len(onsets) == 0: onsets = [0.];
155 # onset detection function
156 downtime = (hopsize/samplerate)*numarray.arange(len(ofunc))
157 d = Gnuplot.Data(downtime,ofunc,with='lines')
160 x1 = (hopsize/samplerate)*numarray.array(onsets)
161 y1 = max(ofunc)*numarray.ones(len(onsets))
162 e = Gnuplot.Data(x1,-y1,with='impulses')
163 e2= Gnuplot.Data(x1,y1,with='impulses')
165 # check if datafile exists truth
166 datafile = filename.replace('.wav','.txt')
167 if not os.path.isfile(datafile):
168 title = "truth file not found"
169 t = Gnuplot.Data(0,0,with='impulses')
171 t_onsets = aubio.txtfile.read_datafile(datafile)
172 y2 = max(ofunc)*numarray.ones(len(t_onsets))
173 x2 = numarray.array(t_onsets).resize(len(t_onsets))
174 t = Gnuplot.Data(x2,y2,with='impulses')
178 orig, missed, merged, expc, bad, doubled = \
180 title = "GD %2.3f%% FP %2.3f%%" % \
181 ((100*float(orig-missed-merged)/(orig)),
182 (100*float(bad+doubled)/(orig)))
183 #print orig, missed, merged, expc, bad, doubled
184 #print "GD %2.8f\t" % (100*float(orig-missed-merged)/(orig)),
185 #print "FP %2.8f\t" % (100*float(bad+doubled)/(orig)) ,
186 #print "GD-merged %2.8f\t" % (100*float(orig-missed)/(orig)) ,
187 #print "FP-pruned %2.8f\t" % (100*float(bad)/(orig))
190 time,data = audio_to_array(filename)
191 f = make_audio_plot(time,data)
194 g = Gnuplot.Gnuplot(debug=1, persist=1)
196 extension = outplot.split('.')[-1]
197 if extension == 'ps': extension = 'postscript'
198 g('set terminal %s' % extension)
199 g('set output \'%s\'' % outplot)
201 g('set title \'%s %s\'' % (filename,title))
205 # hack to align left axis
208 # plot waveform and onsets
210 g('set origin 0,0.7')
211 g('set xrange [0:%f]' % max(time))
212 g('set yrange [-1:1]')
213 g.ylabel('amplitude')
218 # plot onset detection function
221 g('set xrange [0:%f]' % (hopsize/samplerate*len(ofunc)))
222 g('set yrange [0:%f]' % (max(ofunc)*1.01))
224 g.ylabel('onset detection value')
230 def plot_pitch(filename, pitch, samplerate=44100., hopsize=512, outplot=None):
235 # onset detection function
236 downtime = (hopsize/samplerate)*numarray.arange(len(pitch))
237 d = Gnuplot.Data(downtime,pitch,with='lines')
239 # check if datafile exists truth
240 datafile = filename.replace('.wav','.txt')
241 if not os.path.isfile(datafile):
242 title = "truth file not found"
243 t = Gnuplot.Data(0,0,with='impulses')
245 title = "truth file plotting not implemented yet"
246 t = Gnuplot.Data(0,0,with='impulses')
247 #times,pitch = aubio.txtfile.read_datafile(datafile)
248 #t = Gnuplot.Data(times,pitch,with='lines')
250 #orig, missed, merged, expc, bad, doubled = \
251 # onset_roc(x2,x1,tol)
252 #title = "GD %2.3f%% FP %2.3f%%" % \
253 # ((100*float(orig-missed-merged)/(orig)),
254 # (100*float(bad+doubled)/(orig)))
255 #print orig, missed, merged, expc, bad, doubled
256 #print "GD %2.8f\t" % (100*float(orig-missed-merged)/(orig)),
257 #print "FP %2.8f\t" % (100*float(bad+doubled)/(orig)) ,
258 #print "GD-merged %2.8f\t" % (100*float(orig-missed)/(orig)) ,
259 #print "FP-pruned %2.8f\t" % (100*float(bad)/(orig))
262 time,data = audio_to_array(filename)
263 f = make_audio_plot(time,data)
266 g = Gnuplot.Gnuplot(debug=1, persist=1)
268 extension = outplot.split('.')[-1]
269 if extension == 'ps': extension = 'postscript'
270 g('set terminal %s' % extension)
271 g('set output \'%s\'' % outplot)
273 g('set title \'%s %s\'' % (filename,title))
277 # hack to align left axis
280 # plot waveform and onsets
282 g('set origin 0,0.7')
283 g('set xrange [0:%f]' % max(time))
284 g('set yrange [-1:1]')
285 g.ylabel('amplitude')
290 # plot onset detection function
293 g('set xrange [0:%f]' % (hopsize/samplerate*len(pitch)))
294 g('set yrange [0:%f]' % (max(pitch)*1.01))
296 g.ylabel('frequency (Hz)')