1 from aubio.task.task import task
2 from aubio.task.silence import tasksilence
3 from aubio.task.utils import *
4 from aubio.aubioclass import *
7 def __init__(self,input,params=None):
8 task.__init__(self,input,params=params)
9 self.shortlist = [0. for i in range(self.params.pitchsmooth)]
10 if self.params.pitchmode == 'yinfft':
11 yinthresh = self.params.yinfftthresh
12 elif self.params.pitchmode == 'yin':
13 yinthresh = self.params.yinthresh
16 self.pitchdet = pitchdetection(mode=get_pitch_mode(self.params.pitchmode),
17 bufsize=self.params.bufsize,
18 hopsize=self.params.hopsize,
19 channels=self.channels,
20 samplerate=self.srate,
21 omode=self.params.omode,
25 from aubio.median import short_find
27 if (aubio_silence_detection(self.myvec(),self.params.silence)==1):
30 freq = self.pitchdet(self.myvec)
31 minpitch = self.params.pitchmin
32 maxpitch = self.params.pitchmax
33 if maxpitch and freq > maxpitch :
35 elif minpitch and freq < minpitch :
37 if self.params.pitchsmooth:
38 self.shortlist.append(freq)
40 smoothfreq = short_find(self.shortlist,
41 len(self.shortlist)/2)
46 def compute_all(self):
49 while(self.readsize==self.params.hopsize):
52 if self.params.verbose:
53 self.fprint("%s\t%s" % (self.frameread*self.params.step,freq))
57 """ extract ground truth array in frequency """
59 """ from wavfile.txt """
60 datafile = self.input.replace('.wav','.txt')
61 if datafile == self.input: datafile = ""
62 """ from file.<midinote>.wav """
63 # FIXME very weak check
64 floatpit = self.input.split('.')[-2]
65 if not os.path.isfile(datafile) and len(self.input.split('.')) < 3:
66 print "no ground truth "
70 self.truth = float(floatpit)
71 #print "ground truth found in filename:", self.truth
72 tasksil = tasksilence(self.input,params=self.params)
74 while(tasksil.readsize==tasksil.params.hopsize):
76 time.append(tasksil.params.step*(tasksil.frameread))
77 if not tasksil.issilence:
78 pitch.append(self.truth)
83 # FIXME very weak check
84 if not os.path.isfile(datafile):
85 print "no ground truth found"
88 from aubio.txtfile import read_datafile
89 values = read_datafile(datafile)
91 for i in range(len(values)):
92 time.append(values[i][0])
93 if values[i][1] == 0.0:
96 pitch.append(aubio_freqtomidi(values[i][1]))
99 def oldeval(self,results):
101 return sum(l)/max(float(len(l)),1)
103 from aubio.median import percental
104 timet,pitcht = self.gettruth()
109 else: res.append(self.truth-i)
110 if not res or len(res) < 3:
111 avg = self.truth; med = self.truth
114 med = percental(res,len(res)/2)
115 return self.truth, self.truth-med, self.truth-avg
117 def eval(self,pitch,tol=0.5):
118 timet,pitcht = self.gettruth()
119 pitch = [aubio_freqtomidi(i) for i in pitch]
120 for i in range(len(pitch)):
121 if pitch[i] == "nan" or pitch[i] == -1:
123 time = [ (i+self.params.pitchdelay)*self.params.step for i in range(len(pitch)) ]
124 #print len(timet),len(pitcht)
125 #print len(time),len(pitch)
126 if len(timet) != len(time):
127 time = time[1:len(timet)+1]
128 pitch = pitch[1:len(pitcht)+1]
129 #pitcht = [aubio_freqtomidi(i) for i in pitcht]
130 for i in range(len(pitcht)):
131 if pitcht[i] == "nan" or pitcht[i] == "-inf" or pitcht[i] == -1:
133 assert len(timet) == len(time)
134 assert len(pitcht) == len(pitch)
135 osil, esil, opit, epit, echr = 0, 0, 0, 0, 0
136 for i in range(len(pitcht)):
137 if pitcht[i] == -1: # currently silent
138 osil += 1 # count a silence
139 if pitch[i] <= 0. or pitch[i] == "nan":
140 esil += 1 # found a silence
143 if abs(pitcht[i] - pitch[i]) < tol:
146 elif abs(pitcht[i] - pitch[i]) % 12. < tol:
149 # print timet[i], pitcht[i], time[i], pitch[i]
150 #print "origsilence", "foundsilence", "origpitch", "foundpitch", "orig pitchroma", "found pitchchroma"
151 #print 100.*esil/float(osil), 100.*epit/float(opit), 100.*echr/float(opit)
152 return osil, esil, opit, epit, echr
154 def plot(self,pitch,wplot,oplots,titles,outplot=None):
157 time = [ (i+self.params.pitchdelay)*self.params.step for i in range(len(pitch)) ]
158 pitch = [aubio_freqtomidi(i) for i in pitch]
159 oplots.append(Gnuplot.Data(time,pitch,with='lines',
160 title=self.params.pitchmode))
161 titles.append(self.params.pitchmode)
164 def plotplot(self,wplot,oplots,titles,outplot=None,extension=None,xsize=1.,ysize=1.,multiplot = 1, midi = 1, truth = 1):
165 from aubio.gnuplot import gnuplot_create , audio_to_array, make_audio_plot
169 # check if ground truth exists
171 timet,pitcht = self.gettruth()
173 oplots = [Gnuplot.Data(timet,pitcht,with='lines',
174 title='ground truth')] + oplots
176 g = gnuplot_create(outplot=outplot, extension=extension)
177 g('set title \'%s\'' % (re.sub('.*/','',self.input)))
178 g('set size %f,%f' % (xsize,ysize) )
180 # hack to align left axis
184 time,data = audio_to_array(self.input)
185 wplot = [make_audio_plot(time,data)]
186 g('set origin 0,%f' % (0.7*ysize) )
187 g('set size %f,%f' % (xsize,0.3*ysize))
188 #g('set format y "%1f"')
189 g('set xrange [0:%f]' % max(time))
190 g('set yrange [-1:1]')
193 g.xlabel('time (s)',offset=(0,0.7))
194 g.ylabel('amplitude')
197 # default settings for next plots
200 g('set format y "%3e"')
207 #g.xlabel('time (s)')
209 g('set yrange [100:%f]' % self.params.pitchmax)
212 g('set yrange [%f:%f]' % (aubio_freqtomidi(self.params.pitchmin), aubio_freqtomidi(self.params.pitchmax)))
213 g('set y2tics %f,%f' % (round(aubio_freqtomidi(self.params.pitchmin)+.5),12))
217 y = 0.7*ysize # the vertical proportion of the plot taken by onset functions
218 delta = 0.035 # the constant part of y taken by last plot label and data
220 # plot pitch detection functions
221 g('set size %f,%f' % ( xsize, (y-delta)/N))
222 g('set origin 0,%f' % ((N-i-1)*(y-delta)/N + delta ))
224 g('set xrange [0:%f]' % max(time))
227 g('set size %f,%f' % (xsize, (y-delta)/N + delta ) )
229 g.xlabel('time (s)', offset=(0,0.7))
233 g('set key right top')