1 | #! /usr/bin/python |
---|
2 | |
---|
3 | from aubio.bench.config import * |
---|
4 | from aubio.bench.node import * |
---|
5 | |
---|
6 | class onset_parameters: |
---|
7 | def __init__(self): |
---|
8 | """ set default parameters """ |
---|
9 | self.silence = -70 |
---|
10 | self.derivate = False |
---|
11 | self.localmin = False |
---|
12 | self.bufsize = 512 |
---|
13 | self.hopsize = 256 |
---|
14 | self.samplerate = 44100 |
---|
15 | self.tol = 0.05 |
---|
16 | self.step = float(self.hopsize)/float(self.samplerate) |
---|
17 | self.threshold = 0.1 |
---|
18 | self.mode = 'dual' |
---|
19 | |
---|
20 | class benchonset(bench): |
---|
21 | |
---|
22 | def compute_results(self): |
---|
23 | self.P = 100*float(self.expc-self.missed-self.merged)/(self.expc-self.missed-self.merged + self.bad+self.doubled) |
---|
24 | self.R = 100*float(self.expc-self.missed-self.merged)/(self.expc-self.missed-self.merged + self.missed+self.merged) |
---|
25 | if self.R < 0: self.R = 0 |
---|
26 | self.F = 2* self.P*self.R / (self.P+self.R) |
---|
27 | |
---|
28 | self.values = [self.params.mode, |
---|
29 | "%2.3f" % self.params.threshold, |
---|
30 | self.orig, |
---|
31 | self.expc, |
---|
32 | self.missed, |
---|
33 | self.merged, |
---|
34 | self.bad, |
---|
35 | self.doubled, |
---|
36 | (self.orig-self.missed-self.merged), |
---|
37 | "%2.3f" % (100*float(self.orig-self.missed-self.merged)/(self.orig)), |
---|
38 | "%2.3f" % (100*float(self.bad+self.doubled)/(self.orig)), |
---|
39 | "%2.3f" % (100*float(self.orig-self.missed)/(self.orig)), |
---|
40 | "%2.3f" % (100*float(self.bad)/(self.orig)), |
---|
41 | "%2.3f" % self.P, |
---|
42 | "%2.3f" % self.R, |
---|
43 | "%2.3f" % self.F ] |
---|
44 | |
---|
45 | def compute_onset(self,input,output): |
---|
46 | from aubio.tasks import getonsets, get_onset_mode |
---|
47 | from aubio.onsetcompare import onset_roc, onset_diffs |
---|
48 | from aubio.txtfile import read_datafile |
---|
49 | amode = 'roc' |
---|
50 | vmode = 'verbose' |
---|
51 | vmode = '' |
---|
52 | lres, ofunc = getonsets(input, |
---|
53 | self.params.threshold, |
---|
54 | self.params.silence, |
---|
55 | mode=get_onset_mode(self.params.mode), |
---|
56 | localmin=self.params.localmin, |
---|
57 | derivate=self.params.derivate, |
---|
58 | bufsize=self.params.bufsize, |
---|
59 | hopsize=self.params.hopsize, |
---|
60 | storefunc=False) |
---|
61 | |
---|
62 | for i in range(len(lres)): lres[i] = lres[i]*self.params.step |
---|
63 | ltru = read_datafile(input.replace('.wav','.txt'),depth=0) |
---|
64 | if vmode=='verbose': |
---|
65 | print "Running with mode %s" % self.params.mode, |
---|
66 | print " and threshold %f" % self.params.threshold, |
---|
67 | print " on file", input |
---|
68 | #print ltru; print lres |
---|
69 | if amode == 'localisation': |
---|
70 | l = onset_diffs(ltru,lres,self.params.tol) |
---|
71 | mean = 0 |
---|
72 | for i in l: mean += i |
---|
73 | if len(l): print "%.3f" % (mean/len(l)) |
---|
74 | else: print "?0" |
---|
75 | elif amode == 'roc': |
---|
76 | orig, missed, merged, expc, bad, doubled = onset_roc(ltru,lres,self.params.tol) |
---|
77 | self.orig += orig |
---|
78 | self.missed += missed |
---|
79 | self.merged += merged |
---|
80 | self.expc += expc |
---|
81 | self.bad += bad |
---|
82 | self.doubled += doubled |
---|
83 | self.compute_results() |
---|
84 | |
---|
85 | def compute_data(self): |
---|
86 | self.orig, self.missed, self.merged, self.expc, \ |
---|
87 | self.bad, self.doubled = 0, 0, 0, 0, 0, 0 |
---|
88 | act_on_data(self.compute_onset,self.datadir,self.resdir, \ |
---|
89 | suffix='',filter='f -name \'*.wav\'') |
---|
90 | |
---|
91 | def run_bench(self,modes=['dual'],thresholds=[0.5]): |
---|
92 | self.modes = modes |
---|
93 | self.thresholds = thresholds |
---|
94 | |
---|
95 | self.pretty_print(self.titles) |
---|
96 | for mode in self.modes: |
---|
97 | self.params.mode = mode |
---|
98 | for threshold in self.thresholds: |
---|
99 | self.params.threshold = threshold |
---|
100 | self.compute_data() |
---|
101 | self.compute_results() |
---|
102 | self.pretty_print(self.values) |
---|
103 | |
---|
104 | def auto_learn(self,modes=['dual'],thresholds=[0.1,1.5]): |
---|
105 | """ simple dichotomia like algorithm to optimise threshold """ |
---|
106 | self.modes = modes |
---|
107 | self.pretty_print(self.titles) |
---|
108 | for mode in self.modes: |
---|
109 | steps = 10 |
---|
110 | lesst = thresholds[0] |
---|
111 | topt = thresholds[1] |
---|
112 | self.params.mode = mode |
---|
113 | |
---|
114 | self.params.threshold = topt |
---|
115 | self.compute_data() |
---|
116 | self.pretty_print(self.values) |
---|
117 | topF = self.F |
---|
118 | |
---|
119 | self.params.threshold = lesst |
---|
120 | self.compute_data() |
---|
121 | self.pretty_print(self.values) |
---|
122 | lessF = self.F |
---|
123 | |
---|
124 | for i in range(steps): |
---|
125 | self.params.threshold = ( lesst + topt ) * .5 |
---|
126 | self.compute_data() |
---|
127 | self.pretty_print(self.values) |
---|
128 | if self.F == 100.0 or self.F == topF: |
---|
129 | print "assuming we converged, stopping" |
---|
130 | break |
---|
131 | #elif abs(self.F - topF) < 0.01 : |
---|
132 | # print "done converging" |
---|
133 | # break |
---|
134 | if topF < self.F: |
---|
135 | #lessF = topF |
---|
136 | #lesst = topt |
---|
137 | topF = self.F |
---|
138 | topt = self.params.threshold |
---|
139 | elif lessF < self.F: |
---|
140 | lessF = self.F |
---|
141 | lesst = self.params.threshold |
---|
142 | if topt == lesst: |
---|
143 | lesst /= 2. |
---|
144 | |
---|
145 | |
---|
146 | #modes = [ 'complex' ] |
---|
147 | modes = ['complex', 'energy', 'phase', 'specdiff', 'kl', 'mkl', 'dual'] |
---|
148 | #thresholds = [1.5] |
---|
149 | thresholds = [ 0.01, 0.05, 0.1, 0.2, 0.3, 0.4, 0.5] |
---|
150 | |
---|
151 | #datapath = "%s%s" % (DATADIR,'/onset/DB/*/') |
---|
152 | datapath = "%s%s" % (DATADIR,'/onset/DB/PercussivePhrases/RobertRich') |
---|
153 | respath = '/var/tmp/DB-testings' |
---|
154 | |
---|
155 | benchonset = benchonset(datapath,respath,checkres=True,checkanno=True) |
---|
156 | |
---|
157 | benchonset.params = onset_parameters() |
---|
158 | |
---|
159 | benchonset.titles = [ 'mode', 'thres', 'orig', 'expc', 'missd', 'mergd', |
---|
160 | 'bad', 'doubl', 'corrt', 'GD', 'FP', 'GD-merged', 'FP-pruned', |
---|
161 | 'prec', 'recl', 'dist' ] |
---|
162 | benchonset.formats = ["%12s" , "| %6s", "| %6s", "| %6s", "| %6s", "| %6s", |
---|
163 | "| %6s", "| %6s", "| %6s", "| %8s", "| %8s", "| %8s", "| %8s", |
---|
164 | "| %6s", "| %6s", "| %6s"] |
---|
165 | |
---|
166 | #benchonset.run_bench(modes=modes,thresholds=thresholds) |
---|
167 | benchonset.auto_learn(modes=modes) |
---|
168 | |
---|
169 | # gatherdata |
---|
170 | #act_on_data(my_print,datapath,respath,suffix='.txt',filter='f -name \'*.wav\'') |
---|
171 | # gatherthreshold |
---|
172 | # gathermodes |
---|
173 | # comparediffs |
---|
174 | # gatherdiffs |
---|
175 | |
---|
176 | |
---|