ref: 9bec8fe9033cefc8f81e593defd4a00b908684fc
parent: 4798fdf068bb6b3c8d6eb5529c5628a6505fa564
author: Paul Brossier <[email protected]>
date: Thu Apr 20 08:47:39 EDT 2006
first draft for beat evaluation first draft for beat evaluation
--- a/python/aubio/task/beat.py
+++ b/python/aubio/task/beat.py
@@ -13,6 +13,7 @@
self.dfframe = fvec(self.btwinlen,self.channels)
self.bt = beattracking(self.btwinlen,self.channels)
self.pos2 = 0
+ self.old = -1000
def __call__(self):
taskonset.__call__(self)
@@ -32,8 +33,170 @@
if self.pos2 == self.btoutput.get(i,0) and \
aubio_silence_detection(self.myvec(),
self.params.silence)!=1:
- return self.frameread, 0
+ now = self.frameread-0
+ period = (60 * self.params.samplerate) / ((now - self.old) * self.params.hopsize)
+ self.old = now
+ return now*self.params.step,period
- def eval(self,results):
- pass
+ def eval(self,results,tol=0.20,tolcontext=0.25):
+ obeats = self.gettruth()
+ etime = [result[0] for result in results]
+ otime = [obeat[0] for obeat in obeats]
+ CML_tot, CML_max, CML_start, CML_end = 0,0,0,0
+ AML_tot, AML_max, AML_start, AML_end = 0,0,0,0
+ AMLd_tot, AMLd_max, AMLd_start, AMLd_end = 0,0,0,0
+ AMLh_tot, AMLh_max, AMLh_start, AMLh_end = 0,0,0,0
+ AMLo_tot, AMLo_max, AMLo_start, AMLo_end = 0,0,0,0
+ # results iteration
+ j = 1
+ # for each annotation
+ for i in range(2,len(otime)-2):
+ if j+1 >= len(etime): break
+ count = 0
+ # look for next matching beat
+ while otime[i] > etime[j] - (otime[i] - otime[i+1])*tol:
+ if count > 0:
+ #print "spurious etime"
+ if CML_end - CML_start > CML_max:
+ CML_max = CML_end - CML_start
+ CML_start, CML_end = j, j
+ if AMLh_end - AMLh_start > AMLh_max:
+ AMLh_max = AMLh_end - AMLh_start
+ AMLh_start, AMLh_end = j, j
+ if AMLd_end - AMLd_start > AMLd_max:
+ AMLd_max = AMLd_end - AMLd_start
+ AMLd_start, AMLd_end = j, j
+ if AMLo_end - AMLo_start > AMLo_max:
+ AMLo_max = AMLo_end - AMLo_start
+ AMLo_start, AMLo_end = j, j
+ j += 1
+ count += 1
+ if j+1 >= len(etime): break
+ #print otime[i-1],etime[j-1]," ",otime[i],etime[j]," ",otime[i+1],etime[j+1]
+ prevtempo = (otime[i] - otime[i-1])
+ nexttempo = (otime[i+1] - otime[i])
+ current0 = (etime[j] > otime[i] - prevtempo*tol)
+ current1 = (etime[j] < otime[i] + prevtempo*tol)
+
+ # check correct tempo
+ prev0 = (etime[j-1] > otime[i-1] - prevtempo*tolcontext)
+ prev1 = (etime[j-1] < otime[i-1] + prevtempo*tolcontext)
+ next0 = (etime[j+1] > otime[i+1] - nexttempo*tolcontext)
+ next1 = (etime[j+1] < otime[i+1] + nexttempo*tolcontext)
+
+ # check for off beat
+ prevoffb0 = (etime[j-1] > otime[i-1] - prevtempo/2 - prevtempo*tolcontext)
+ prevoffb1 = (etime[j-1] < otime[i-1] - prevtempo/2 + prevtempo*tolcontext)
+ nextoffb0 = (etime[j+1] > otime[i+1] - nexttempo/2 - nexttempo*tolcontext)
+ nextoffb1 = (etime[j+1] < otime[i+1] - nexttempo/2 + nexttempo*tolcontext)
+
+ # check half tempo
+ prevhalf0 = (etime[j-1] > otime[i-1] + prevtempo - prevtempo/2*tolcontext)
+ prevhalf1 = (etime[j-1] < otime[i-1] + prevtempo + prevtempo/2*tolcontext)
+ nexthalf0 = (etime[j+1] > otime[i+1] - nexttempo - nexttempo/2*tolcontext)
+ nexthalf1 = (etime[j+1] < otime[i+1] - nexttempo + nexttempo/2*tolcontext)
+
+ # check double tempo
+ prevdoub0 = (etime[j-1] > otime[i-1] - prevtempo - prevtempo*2*tolcontext)
+ prevdoub1 = (etime[j-1] < otime[i-1] - prevtempo + prevtempo*2*tolcontext)
+ nextdoub0 = (etime[j+1] > otime[i+1] + nexttempo - nexttempo*2*tolcontext)
+ nextdoub1 = (etime[j+1] < otime[i+1] + nexttempo + nexttempo*2*tolcontext)
+
+ if current0 and current1 and prev0 and prev1 and next0 and next1:
+ #print "YES!"
+ CML_end = j
+ CML_tot += 1
+ else:
+ if CML_end - CML_start > CML_max:
+ CML_max = CML_end - CML_start
+ CML_start, CML_end = j, j
+ if current0 and current1 and prevhalf0 and prevhalf1 and nexthalf0 and nexthalf1:
+ AMLh_end = j
+ AMLh_tot += 1
+ else:
+ if AMLh_end - AMLh_start > AMLh_max:
+ AMLh_max = AMLh_end - AMLh_start
+ AMLh_start, AMLh_end = j, j
+ if current0 and current1 and prevdoub0 and prevdoub1 and nextdoub0 and nextdoub1:
+ AMLd_end = j
+ AMLd_tot += 1
+ else:
+ if AMLd_end - AMLd_start > AMLd_max:
+ AMLd_max = AMLd_end - AMLd_start
+ AMLd_start, AMLd_end = j, j
+ if current0 and current1 and prevoffb0 and prevoffb1 and nextoffb0 and nextoffb1:
+ AMLo_end = j
+ AMLo_tot += 1
+ else:
+ if AMLo_end - AMLo_start > AMLo_max:
+ AMLo_max = AMLo_end - AMLo_start
+ AMLo_start, AMLo_end = j, j
+ # look for next matching beat
+ count = 0
+ while otime[i] > etime[j] - (otime[i] - otime[i+1])*tolcontext:
+ j += 1
+ if count > 0:
+ #print "spurious etime"
+ start = j
+ count += 1
+ total = float(len(otime))
+ CML_tot /= total
+ AMLh_tot /= total
+ AMLd_tot /= total
+ AMLo_tot /= total
+ CML_cont = CML_max/total
+ AMLh_cont = AMLh_max/total
+ AMLd_cont = AMLd_max/total
+ AMLo_cont = AMLo_max/total
+ return CML_cont, CML_tot, AMLh_cont, AMLh_tot, AMLd_cont, AMLd_tot, AMLo_cont, AMLo_tot
+
+# for i in allfreq:
+# freq.append(float(i) / 2. / N * samplerate )
+# while freq[i]>freqs[j]:
+# j += 1
+# a0 = weight[j-1]
+# a1 = weight[j]
+# f0 = freqs[j-1]
+# f1 = freqs[j]
+# if f0!=0:
+# iweight.append((a1-a0)/(f1-f0)*freq[i] + (a0 - (a1 - a0)/(f1/f0 -1.)))
+# else:
+# iweight.append((a1-a0)/(f1-f0)*freq[i] + a0)
+# while freq[i]>freqs[j]:
+# j += 1
+
+
+ def gettruth(self):
+ import os.path
+ from aubio.txtfile import read_datafile
+ datafile = self.input.replace('.wav','.txt')
+ if not os.path.isfile(datafile):
+ print "no ground truth "
+ return False,False
+ else:
+ values = read_datafile(datafile,depth=0)
+ old = -1000
+ for i in range(len(values)):
+ now = values[i]
+ period = 60 / (now - old)
+ old = now
+ values[i] = [now,period]
+ return values
+
+
+ def plot(self,oplots,results):
+ import Gnuplot
+ oplots.append(Gnuplot.Data(results,with='linespoints',title="auto"))
+
+ def plotplot(self,oplots,outplot=None):
+ import Gnuplot
+ from aubio.gnuplot import gnuplot_init, audio_to_array, make_audio_plot
+ import re
+ # audio data
+ #time,data = audio_to_array(self.input)
+ #f = make_audio_plot(time,data)
+
+ g = gnuplot_init(outplot)
+ oplots = [Gnuplot.Data(self.gettruth(),with='linespoints',title="orig")] + oplots
+ g.plot(*oplots)