source: python/aubio/task/beat.py @ 9bec8fe

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

first draft for beat evaluation
first draft for beat evaluation

  • Property mode set to 100644
File size: 6.8 KB
Line 
1from aubio.aubioclass import *
2from onset import taskonset
3
4class taskbeat(taskonset):
5        def __init__(self,input,params=None,output=None):
6                """ open the input file and initialize arguments
7                parameters should be set *before* calling this method.
8                """
9                taskonset.__init__(self,input,output=None,params=params)
10                self.btwinlen  = 512**2/self.params.hopsize
11                self.btstep    = self.btwinlen/4
12                self.btoutput  = fvec(self.btstep,self.channels)
13                self.dfframe   = fvec(self.btwinlen,self.channels)
14                self.bt        = beattracking(self.btwinlen,self.channels)
15                self.pos2      = 0
16                self.old       = -1000
17
18        def __call__(self):
19                taskonset.__call__(self)
20                # write to current file
21                if self.pos2 == self.btstep - 1 : 
22                        self.bt.do(self.dfframe,self.btoutput)
23                        for i in range (self.btwinlen - self.btstep):
24                                self.dfframe.set(self.dfframe.get(i+self.btstep,0),i,0) 
25                        for i in range(self.btwinlen - self.btstep, self.btwinlen): 
26                                self.dfframe.set(0,i,0)
27                        self.pos2 = -1;
28                self.pos2 += 1
29                val = self.opick.pp.getval()
30                self.dfframe.set(val,self.btwinlen - self.btstep + self.pos2,0)
31                i=0
32                for i in range(1,int( self.btoutput.get(0,0) ) ):
33                        if self.pos2 == self.btoutput.get(i,0) and \
34                                aubio_silence_detection(self.myvec(),
35                                        self.params.silence)!=1: 
36                                now = self.frameread-0
37                                period = (60 * self.params.samplerate) / ((now - self.old) * self.params.hopsize)
38                                self.old = now
39                                return now*self.params.step,period
40       
41        def eval(self,results,tol=0.20,tolcontext=0.25):
42                obeats = self.gettruth()
43                etime = [result[0] for result in results]
44                otime = [obeat[0] for obeat in obeats]
45                CML_tot, CML_max, CML_start, CML_end = 0,0,0,0
46                AML_tot, AML_max, AML_start, AML_end = 0,0,0,0
47                AMLd_tot, AMLd_max, AMLd_start, AMLd_end = 0,0,0,0
48                AMLh_tot, AMLh_max, AMLh_start, AMLh_end = 0,0,0,0
49                AMLo_tot, AMLo_max, AMLo_start, AMLo_end = 0,0,0,0
50                # results iteration
51                j = 1
52                # for each annotation
53                for i in range(2,len(otime)-2):
54                        if j+1 >= len(etime): break
55                        count = 0
56                        # look for next matching beat
57                        while otime[i] > etime[j] - (otime[i] - otime[i+1])*tol:
58                                if count > 0: 
59                                        #print "spurious etime"
60                                        if CML_end - CML_start > CML_max:
61                                                CML_max = CML_end - CML_start
62                                        CML_start, CML_end = j, j
63                                        if AMLh_end - AMLh_start > AMLh_max:
64                                                AMLh_max = AMLh_end - AMLh_start
65                                        AMLh_start, AMLh_end = j, j
66                                        if AMLd_end - AMLd_start > AMLd_max:
67                                                AMLd_max = AMLd_end - AMLd_start
68                                        AMLd_start, AMLd_end = j, j
69                                        if AMLo_end - AMLo_start > AMLo_max:
70                                                AMLo_max = AMLo_end - AMLo_start
71                                        AMLo_start, AMLo_end = j, j
72                                j += 1
73                                count += 1
74                        if j+1 >= len(etime): break
75                        #print otime[i-1],etime[j-1]," ",otime[i],etime[j]," ",otime[i+1],etime[j+1]
76                        prevtempo = (otime[i] - otime[i-1])
77                        nexttempo = (otime[i+1] - otime[i])
78
79                        current0  = (etime[j] > otime[i] - prevtempo*tol)
80                        current1  = (etime[j] < otime[i] + prevtempo*tol)
81
82                        # check correct tempo
83                        prev0 = (etime[j-1] > otime[i-1] - prevtempo*tolcontext)
84                        prev1 = (etime[j-1] < otime[i-1] + prevtempo*tolcontext)
85                        next0 = (etime[j+1] > otime[i+1] - nexttempo*tolcontext)
86                        next1 = (etime[j+1] < otime[i+1] + nexttempo*tolcontext)
87
88                        # check for off beat
89                        prevoffb0 = (etime[j-1] > otime[i-1] - prevtempo/2 - prevtempo*tolcontext)
90                        prevoffb1 = (etime[j-1] < otime[i-1] - prevtempo/2 + prevtempo*tolcontext)
91                        nextoffb0 = (etime[j+1] > otime[i+1] - nexttempo/2 - nexttempo*tolcontext)
92                        nextoffb1 = (etime[j+1] < otime[i+1] - nexttempo/2 + nexttempo*tolcontext)
93
94                        # check half tempo
95                        prevhalf0 = (etime[j-1] > otime[i-1] + prevtempo - prevtempo/2*tolcontext)
96                        prevhalf1 = (etime[j-1] < otime[i-1] + prevtempo + prevtempo/2*tolcontext)
97                        nexthalf0 = (etime[j+1] > otime[i+1] - nexttempo - nexttempo/2*tolcontext)
98                        nexthalf1 = (etime[j+1] < otime[i+1] - nexttempo + nexttempo/2*tolcontext)
99
100                        # check double tempo
101                        prevdoub0 = (etime[j-1] > otime[i-1] - prevtempo - prevtempo*2*tolcontext)
102                        prevdoub1 = (etime[j-1] < otime[i-1] - prevtempo + prevtempo*2*tolcontext)
103                        nextdoub0 = (etime[j+1] > otime[i+1] + nexttempo - nexttempo*2*tolcontext)
104                        nextdoub1 = (etime[j+1] < otime[i+1] + nexttempo + nexttempo*2*tolcontext)
105
106                        if current0 and current1 and prev0 and prev1 and next0 and next1: 
107                                #print "YES!"
108                                CML_end = j     
109                                CML_tot += 1
110                        else:
111                                if CML_end - CML_start > CML_max:
112                                        CML_max = CML_end - CML_start
113                                CML_start, CML_end = j, j
114                        if current0 and current1 and prevhalf0 and prevhalf1 and nexthalf0 and nexthalf1: 
115                                AMLh_end = j
116                                AMLh_tot += 1
117                        else:
118                                if AMLh_end - AMLh_start > AMLh_max:
119                                        AMLh_max = AMLh_end - AMLh_start
120                                AMLh_start, AMLh_end = j, j
121                        if current0 and current1 and prevdoub0 and prevdoub1 and nextdoub0 and nextdoub1: 
122                                AMLd_end = j
123                                AMLd_tot += 1
124                        else:
125                                if AMLd_end - AMLd_start > AMLd_max:
126                                        AMLd_max = AMLd_end - AMLd_start
127                                AMLd_start, AMLd_end = j, j
128                        if current0 and current1 and prevoffb0 and prevoffb1 and nextoffb0 and nextoffb1: 
129                                AMLo_end = j
130                                AMLo_tot += 1
131                        else:
132                                if AMLo_end - AMLo_start > AMLo_max:
133                                        AMLo_max = AMLo_end - AMLo_start
134                                AMLo_start, AMLo_end = j, j
135                        # look for next matching beat
136                        count = 0 
137                        while otime[i] > etime[j] - (otime[i] - otime[i+1])*tolcontext:
138                                j += 1
139                                if count > 0: 
140                                        #print "spurious etime"
141                                        start = j
142                                count += 1
143                total = float(len(otime))
144                CML_tot  /= total
145                AMLh_tot /= total
146                AMLd_tot /= total
147                AMLo_tot /= total
148                CML_cont  = CML_max/total
149                AMLh_cont = AMLh_max/total
150                AMLd_cont = AMLd_max/total
151                AMLo_cont = AMLo_max/total
152                return CML_cont, CML_tot, AMLh_cont, AMLh_tot, AMLd_cont, AMLd_tot, AMLo_cont, AMLo_tot
153
154#               for i in allfreq:
155#                       freq.append(float(i) / 2. / N  * samplerate )
156#                       while freq[i]>freqs[j]:
157#                               j += 1
158#                       a0 = weight[j-1]
159#                       a1 = weight[j]
160#                       f0 = freqs[j-1]
161#                       f1 = freqs[j]
162#                       if f0!=0:
163#                               iweight.append((a1-a0)/(f1-f0)*freq[i] + (a0 - (a1 - a0)/(f1/f0 -1.)))
164#                       else:
165#                               iweight.append((a1-a0)/(f1-f0)*freq[i] + a0)
166#                       while freq[i]>freqs[j]:
167#                               j += 1
168                       
169       
170        def gettruth(self):
171                import os.path
172                from aubio.txtfile import read_datafile
173                datafile = self.input.replace('.wav','.txt')
174                if not os.path.isfile(datafile):
175                        print "no ground truth "
176                        return False,False
177                else:
178                        values = read_datafile(datafile,depth=0)
179                        old = -1000
180                        for i in range(len(values)):
181                                now = values[i]
182                                period = 60 / (now - old)
183                                old = now
184                                values[i] = [now,period]
185                return values
186       
187
188        def plot(self,oplots,results):
189                import Gnuplot
190                oplots.append(Gnuplot.Data(results,with='linespoints',title="auto"))
191
192        def plotplot(self,oplots,outplot=None):
193                import Gnuplot
194                from aubio.gnuplot import gnuplot_init, audio_to_array, make_audio_plot
195                import re
196                # audio data
197                #time,data = audio_to_array(self.input)
198                #f = make_audio_plot(time,data)
199
200                g = gnuplot_init(outplot)
201                oplots = [Gnuplot.Data(self.gettruth(),with='linespoints',title="orig")] + oplots
202                g.plot(*oplots)
Note: See TracBrowser for help on using the repository browser.