source: python/aubio/gnuplot.py @ 6efdc83

feature/autosinkfeature/cnnfeature/cnn_orgfeature/constantqfeature/crepefeature/crepe_orgfeature/pitchshiftfeature/pydocstringsfeature/timestretchfix/ffmpeg5pitchshiftsamplertimestretchyinfft+
Last change on this file since 6efdc83 was 77671b4, checked in by Paul Brossier <piem@altern.org>, 19 years ago

add plotting of truth file for pitch

  • Property mode set to 100644
File size: 10.6 KB
Line 
1"""Copyright (C) 2004 Paul Brossier <piem@altern.org>
2print aubio.__LICENSE__ for the terms of use
3"""
4
5__LICENSE__ = """\
6         Copyright (C) 2004 Paul Brossier <piem@altern.org>
7
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.
12
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.
17
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.
21"""
22
23__notesheight = 0.25
24
25from numarray import *
26import Gnuplot, Gnuplot.funcutils
27
28def plotnote(la,title=None) :
29        if la[0,:].size() == 3:
30                d = plotnote_withends(la, plot_title=title)
31        else: 
32            # scale data if in freq (for REF.txt files)
33            if max(la[:,1] > 128 ):
34                print "scaling frequency data to midi range"
35                la[:,1] /= 6.875
36                la[:,1] = log(la[:,1])/0.6931
37                la[:,1] *= 12
38                la[:,1] -= 3
39            d = plotnote_withoutends(la, plot_title=title)
40        return d
41
42def plotnote_multi(lalist,title=None,fileout=None) :
43        d=list()
44        for i in range(len(lalist)):
45            d.append(plotnote(lalist[i], title=title))
46        return d
47       
48
49def plotnote_withends(la,plot_title=None) :
50        d=[]
51        x_widths = array(la[:,1]-la[:,0])/2.
52        d.append(Gnuplot.Data(
53                la[:,0]+x_widths,               # x centers
54                la[:,2],                        # y centers
55                x_widths,                       # x errors
56                __notesheight*ones(len(la)),    # y errors
57                title=plot_title,with=('boxxyerrorbars fs 3')))
58        return d
59
60
61def plotnote_withoutends(la,plot_title=None) :
62        """ bug: fails drawing last note """
63        d=[]
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
68                x_widths,                       # x errors
69                __notesheight*ones(len(la)-1),  # y errors
70                title=plot_title,with=('boxxyerrorbars fs 3')))
71        return d
72
73def plotnote_do(d,fileout=None):
74    g = Gnuplot.Gnuplot(debug=1, persist=1)
75    g.gnuplot('set style fill solid border 1; \
76    set size ratio 1/6; \
77    set boxwidth 0.9 relative; \
78    set mxtics 2.5; \
79    set mytics 2.5; \
80    set xtics 5; \
81    set ytics 1; \
82    set grid xtics ytics mxtics mytics')
83
84    g.xlabel('Time (s)')
85    g.ylabel('Midi pitch')
86    # do the plot
87    #g.gnuplot('set multiplot')
88    #for i in d:
89    g.plot(d[0])
90    #g.gnuplot('set nomultiplot')
91    if fileout != None:
92        g.hardcopy(fileout, enhanced=1, color=0)
93
94def audio_to_array(filename):
95        import aubio.aubioclass
96        hopsize  = 2048
97        filei    = aubio.aubioclass.sndfile(filename)
98        framestep = 1/(filei.samplerate()+0.)
99        channels = filei.channels()
100        myvec    = aubio.aubioclass.fvec(hopsize,channels)
101        data = []
102        readsize = hopsize
103        while (readsize==hopsize):
104                readsize = filei.read(hopsize,myvec)
105                #for i in range(channels):
106                i = 0
107                curpos = 0
108                while (curpos < readsize):
109                        data.append(myvec.get(curpos,i))
110                        curpos+=1
111        time = arange(len(data))*framestep
112        return time,data
113
114def plot_audio(filenames, fileout=None, start=0, end=None, noaxis=None):
115        g = Gnuplot.Gnuplot(debug=1, persist=1)
116        d = []
117        todraw = len(filenames)
118        xorig = 0.
119        xsize = 1./todraw
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:
124                        g.xlabel('Time (s)')
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]) 
131                g.plot(d.pop(0))
132                xorig += 1./todraw
133        g.gnuplot('unset multiplot;')
134        if fileout != None:
135                g.hardcopy(fileout, enhanced=1, color=0)
136
137def make_audio_plot(time,data,maxpoints=10000):
138        """ create gnuplot plot from an audio file """
139        length = len(time)
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')
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        d,d2 = [],[]
154        maxofunc = 0
155        for i in range(len(onsets)):
156                if len(onsets[i]) == 0: onsets[i] = [0.];
157
158                # onset detection function
159                downtime = (hopsize/samplerate)*numarray.arange(len(ofunc[i]))
160                d.append(Gnuplot.Data(downtime,ofunc[i],with='lines'))
161                maxofunc = max(max(ofunc[i]), maxofunc)
162
163        for i in range(len(onsets)):
164                # detected onsets
165                x1 = (hopsize/samplerate)*numarray.array(onsets[i])
166                y1 = maxofunc*numarray.ones(len(onsets[i]))
167                d.append(Gnuplot.Data(x1,y1,with='impulses'))
168                d2.append(Gnuplot.Data(x1,-y1,with='impulses'))
169
170        # check if datafile exists truth
171        datafile = filename.replace('.wav','.txt')
172        if not os.path.isfile(datafile):
173                title = "truth file not found"
174                t = Gnuplot.Data(0,0,with='impulses') 
175        else:
176                t_onsets = aubio.txtfile.read_datafile(datafile)
177                y2 = maxofunc*numarray.ones(len(t_onsets))
178                x2 = numarray.array(t_onsets).resize(len(t_onsets))
179                d2.append(Gnuplot.Data(x2,y2,with='impulses'))
180               
181                tol = 0.050 
182
183                orig, missed, merged, expc, bad, doubled = \
184                        onset_roc(x2,x1,tol)
185                title = "GD %2.3f%% FP %2.3f%%" % \
186                        ((100*float(orig-missed-merged)/(orig)),
187                         (100*float(bad+doubled)/(orig)))
188                #print  orig, missed, merged, expc, bad, doubled
189                #print "GD %2.8f\t"        % (100*float(orig-missed-merged)/(orig)),
190                #print "FP %2.8f\t"        % (100*float(bad+doubled)/(orig))       ,
191                #print "GD-merged %2.8f\t" % (100*float(orig-missed)/(orig))       ,
192                #print "FP-pruned %2.8f\t" % (100*float(bad)/(orig))               
193
194        # audio data
195        time,data = audio_to_array(filename)
196        d2.append(make_audio_plot(time,data))
197
198        # prepare the plot
199        g = Gnuplot.Gnuplot(debug=1, persist=1)
200        if outplot:
201                extension = outplot.split('.')[-1]
202                if extension == 'ps': extension = 'postscript'
203                g('set terminal %s' % extension)
204                g('set output \'%s\'' % outplot)
205
206        g('set title \'%s %s\'' % (filename,title))
207
208        g('set multiplot')
209
210        # hack to align left axis
211        g('set lmargin 15')
212
213        # plot waveform and onsets
214        g('set size 1,0.3')
215        g('set origin 0,0.7')
216        g('set xrange [0:%f]' % max(time)) 
217        g('set yrange [-1:1]') 
218        g.ylabel('amplitude')
219        g.plot(*d2)
220       
221        g('unset title')
222
223        # plot onset detection function
224        g('set size 1,0.7')
225        g('set origin 0,0')
226        g('set xrange [0:%f]' % (hopsize/samplerate*len(ofunc[0])))
227        g('set yrange [0:%f]' % (maxofunc*1.01))
228        g.xlabel('time')
229        g.ylabel('onset detection value')
230        g.plot(*d)
231
232        g('unset multiplot')
233
234
235def plot_pitch(filename, pitch, samplerate=44100., hopsize=512, outplot=None):
236        import aubio.txtfile
237        import os.path
238        import numarray
239
240        d = []
241        maxpitch = 100
242        for i in range(len(pitch)):
243                downtime = (hopsize/samplerate)*numarray.arange(len(pitch[i]))
244                d.append(Gnuplot.Data(downtime,pitch[i],with='lines',
245                        title=('%d' % i)))
246                maxpitch = max(maxpitch,max(pitch[i][:])*1.1)
247
248        # check if datafile exists truth
249        datafile = filename.replace('.wav','.txt')
250        if not os.path.isfile(datafile):
251                title = "truth file not found"
252                t = Gnuplot.Data(0,0,with='impulses') 
253        else:
254                title = "truth file plotting not implemented yet"
255                values = aubio.txtfile.read_datafile(datafile)
256                time, pitch = [], []
257                for i in range(len(values)):
258                        time.append(values[i][0])
259                        pitch.append(values[i][1])
260                d.append(Gnuplot.Data(time,pitch,with='lines',title='ground truth'))
261               
262                #orig, missed, merged, expc, bad, doubled = \
263                #        onset_roc(x2,x1,tol)
264                #title = "GD %2.3f%% FP %2.3f%%" % \
265                #        ((100*float(orig-missed-merged)/(orig)),
266                #         (100*float(bad+doubled)/(orig)))
267                #print  orig, missed, merged, expc, bad, doubled
268                #print "GD %2.8f\t"        % (100*float(orig-missed-merged)/(orig)),
269                #print "FP %2.8f\t"        % (100*float(bad+doubled)/(orig))       ,
270                #print "GD-merged %2.8f\t" % (100*float(orig-missed)/(orig))       ,
271                #print "FP-pruned %2.8f\t" % (100*float(bad)/(orig))               
272
273        # audio data
274        time,data = audio_to_array(filename)
275        f = make_audio_plot(time,data)
276
277        # prepare the plot
278        g = Gnuplot.Gnuplot(debug=1, persist=1)
279        if outplot:
280                extension = outplot.split('.')[-1]
281                if extension == 'ps': extension = 'postscript'
282                g('set terminal %s' % extension)
283                g('set output \'%s\'' % outplot)
284
285        g('set title \'%s %s\'' % (filename,title))
286
287        g('set multiplot')
288
289        # hack to align left axis
290        g('set lmargin 15')
291
292        # plot waveform and onsets
293        g('set size 1,0.3')
294        g('set origin 0,0.7')
295        g('set xrange [0:%f]' % max(time)) 
296        g('set yrange [-1:1]') 
297        g.ylabel('amplitude')
298        g.plot(f)
299       
300        g('unset title')
301
302        # plot onset detection function
303        g('set size 1,0.7')
304        g('set origin 0,0')
305        g('set xrange [0:%f]' % max(time))
306        g('set yrange [40:%f]' % maxpitch) 
307        g('set key right top')
308        g.xlabel('time')
309        g.ylabel('frequency (Hz)')
310        g.plot(*d)
311
312        g('unset multiplot')
Note: See TracBrowser for help on using the repository browser.