ref: 75139a99ef6ddaba3713d9a1181659c8026d02a3
parent: 257debc559c5e912337cbd755fbcea37f09dccff
author: Paul Brossier <piem@altern.org>
date: Thu Dec 15 20:26:25 EST 2005
complete rewrite of bench onset, no more command line call complete rewrite of bench onset, no more command line call
--- a/python/bench-onset
+++ b/python/bench-onset
@@ -3,27 +3,173 @@
from aubio.bench.config import *
from aubio.bench.node import *
-datapath = "%s%s" % (DATADIR,'/onset/DB')
-respath = '/var/tmp/DB-testings'
+class onset_parameters:
+ def __init__(self):
+ """ set default parameters """
+ self.silence = -70
+ self.derivate = False
+ self.localmin = False
+ self.bufsize = 512
+ self.hopsize = 256
+ self.samplerate = 44100
+ self.tol = 0.05
+ self.step = float(self.hopsize)/float(self.samplerate)
+ self.threshold = 0.1
+ self.mode = 'dual'
-MODES = 'hfc', 'complexdomain', 'energy', 'phase', 'specdiff', 'kl', 'mkl'
-THRESHOLD = range(1,14,1)
+class taskonset(task):
+
+ def pretty_print(self,values):
+ for i in range(len(values)):
+ print self.formats[i] % values[i],
-# prepareresultpath
-act_on_results(mkdir,datapath,respath,filter='d')
+ def compute_results(self):
+ self.P = 100*float(self.expc-self.missed-self.merged)/(self.expc-self.missed-self.merged + self.bad+self.doubled)
+ self.R = 100*float(self.expc-self.missed-self.merged)/(self.expc-self.missed-self.merged + self.missed+self.merged)
+ if self.R < 0: self.R = 0
+ self.F = 2* self.P*self.R / (self.P+self.R)
-def compute_data(input,output):
- aubiocmd = "%s%s %s%s" % \
- ("LD_LIBRARY_PATH=",LD_LIBRARY_PATH,AUBIOHOME,"/examples/aubioonset")
- for m in MODES:
- for k in THRESHOLD:
- cmd = "%s --input \"%s\" --onset %s --threshold %s > \"%s--%s--%s.txt\"" \
- % (aubiocmd,input,m,k/10.,output,m,k/10.)
- runcommand(cmd,debug=1)
+ self.values = [self.params.mode,
+ "%2.3f" % self.params.threshold,
+ self.orig,
+ self.expc,
+ self.missed,
+ self.merged,
+ self.bad,
+ self.doubled,
+ (self.orig-self.missed-self.merged),
+ "%2.3f" % (100*float(self.orig-self.missed-self.merged)/(self.orig)),
+ "%2.3f" % (100*float(self.bad+self.doubled)/(self.orig)),
+ "%2.3f" % (100*float(self.orig-self.missed)/(self.orig)),
+ "%2.3f" % (100*float(self.bad)/(self.orig)),
+ "%2.3f" % self.P,
+ "%2.3f" % self.R,
+ "%2.3f" % self.F ]
+ def compute_onset(self,input,output):
+ from aubio.tasks import getonsets, get_onset_mode
+ from aubio.onsetcompare import onset_roc, onset_diffs
+ from aubio.txtfile import read_datafile
+ amode = 'roc'
+ vmode = 'verbose'
+ vmode = ''
+ lres, ofunc = getonsets(input,
+ self.params.threshold,
+ self.params.silence,
+ mode=get_onset_mode(self.params.mode),
+ localmin=self.params.localmin,
+ derivate=self.params.derivate,
+ bufsize=self.params.bufsize,
+ hopsize=self.params.hopsize,
+ storefunc=False)
-# computedata
-act_on_data(compute_data,datapath,respath,suffix='',filter='f -name \'*.wav\'')
+ for i in range(len(lres)): lres[i] = lres[i]*self.params.step
+ ltru = read_datafile(input.replace('.wav','.txt'),depth=0)
+ if vmode=='verbose':
+ print "Running with mode %s" % self.params.mode,
+ print " and threshold %f" % self.params.threshold,
+ print " on file", input
+ #print ltru; print lres
+ if amode == 'localisation':
+ l = onset_diffs(ltru,lres,self.params.tol)
+ mean = 0
+ for i in l: mean += i
+ if len(l): print "%.3f" % (mean/len(l))
+ else: print "?0"
+ elif amode == 'roc':
+ orig, missed, merged, expc, bad, doubled = onset_roc(ltru,lres,self.params.tol)
+ self.orig += orig
+ self.missed += missed
+ self.merged += merged
+ self.expc += expc
+ self.bad += bad
+ self.doubled += doubled
+ self.compute_results()
+
+ def compute_data(self):
+ self.orig, self.missed, self.merged, self.expc, \
+ self.bad, self.doubled = 0, 0, 0, 0, 0, 0
+ act_on_data(self.compute_onset,self.datadir,self.resdir, \
+ suffix='',filter='f -name \'*.wav\'')
+
+ def run_bench(self,modes=['dual'],thresholds=[0.5]):
+ self.modes = modes
+ self.thresholds = thresholds
+
+ self.pretty_print(self.titles)
+ for mode in self.modes:
+ self.params.mode = mode
+ for threshold in self.thresholds:
+ self.params.threshold = threshold
+ self.compute_data()
+ self.compute_results()
+ self.pretty_print(self.values)
+
+ def auto_learn(self,modes=['dual'],thresholds=[0.1,1.5]):
+ """ simple dichotomia like algorithm to optimise threshold """
+ self.modes = modes
+ self.pretty_print(self.titles)
+ for mode in self.modes:
+ steps = 10
+ lesst = thresholds[0]
+ topt = thresholds[1]
+ self.params.mode = mode
+
+ self.params.threshold = topt
+ self.compute_data()
+ self.pretty_print(self.values)
+ topF = self.F
+
+ self.params.threshold = lesst
+ self.compute_data()
+ self.pretty_print(self.values)
+ lessF = self.F
+
+ for i in range(steps):
+ self.params.threshold = ( lesst + topt ) * .5
+ self.compute_data()
+ self.pretty_print(self.values)
+ if self.F == 100.0 or self.F == topF:
+ print "assuming we converged, stopping"
+ break
+ #elif abs(self.F - topF) < 0.01 :
+ # print "done converging"
+ # break
+ if topF < self.F:
+ #lessF = topF
+ #lesst = topt
+ topF = self.F
+ topt = self.params.threshold
+ elif lessF < self.F:
+ lessF = self.F
+ lesst = self.params.threshold
+ if topt == lesst:
+ lesst /= 2.
+
+
+#modes = [ 'complex' ]
+modes = ['complex', 'energy', 'phase', 'specdiff', 'kl', 'mkl', 'dual']
+#thresholds = [1.5]
+thresholds = [ 0.01, 0.05, 0.1, 0.2, 0.3, 0.4, 0.5]
+
+#datapath = "%s%s" % (DATADIR,'/onset/DB/*/')
+datapath = "%s%s" % (DATADIR,'/onset/DB/PercussivePhrases/RobertRich')
+respath = '/var/tmp/DB-testings'
+
+taskonset = taskonset(datapath,respath)
+
+taskonset.params = onset_parameters()
+
+taskonset.titles = [ 'mode', 'thres', 'orig', 'expc', 'missd', 'mergd',
+'bad', 'doubl', 'corrt', 'GD', 'FP', 'GD-merged', 'FP-pruned',
+'prec', 'recl', 'dist' ]
+taskonset.formats = ["%12s" , "| %6s", "| %6s", "| %6s", "| %6s", "| %6s",
+"| %6s", "| %6s", "| %6s", "| %8s", "| %8s", "| %8s", "| %8s",
+"| %6s", "| %6s", "| %6s"]
+
+#taskonset.run_bench(modes=modes,thresholds=thresholds)
+taskonset.auto_learn(modes=modes)
# gatherdata
#act_on_data(my_print,datapath,respath,suffix='.txt',filter='f -name \'*.wav\'')