source: python/aubio/task/pitch.py @ 5d1c070

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

updated to new bench-pitch, fixed gettruth
updated to new bench-pitch, fixed gettruth

  • Property mode set to 100644
File size: 5.7 KB
Line 
1from aubio.task.task import task
2from aubio.task.silence import tasksilence
3from aubio.task.utils import * 
4from aubio.aubioclass import *
5
6class taskpitch(task):
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                self.pitchdet  = pitchdetection(mode=get_pitch_mode(self.params.pitchmode),
11                        bufsize=self.params.bufsize,
12                        hopsize=self.params.hopsize,
13                        channels=self.channels,
14                        samplerate=self.srate,
15                        omode=self.params.omode)
16
17        def __call__(self):
18                from aubio.median import short_find
19                task.__call__(self)
20                if (aubio_silence_detection(self.myvec(),self.params.silence)==1):
21                        freq = -1.
22                else:
23                        freq = self.pitchdet(self.myvec)
24                minpitch = self.params.pitchmin
25                maxpitch = self.params.pitchmax
26                if maxpitch and freq > maxpitch : 
27                        freq = -1.
28                elif minpitch and freq < minpitch :
29                        freq = -1.
30                if self.params.pitchsmooth:
31                        self.shortlist.append(freq)
32                        self.shortlist.pop(0)
33                        smoothfreq = short_find(self.shortlist,
34                                len(self.shortlist)/2)
35                        return smoothfreq
36                else:
37                        return freq
38
39        def compute_all(self):
40                """ Compute data """
41                mylist    = []
42                while(self.readsize==self.params.hopsize):
43                        freq = self()
44                        mylist.append(freq)
45                        if self.params.verbose:
46                                self.fprint("%s\t%s" % (self.frameread*self.params.step,freq))
47                return mylist
48
49        def gettruth(self):
50                """ extract ground truth array in frequency """
51                import os.path
52                """ from wavfile.txt """
53                datafile = self.input.replace('.wav','.txt')
54                if datafile == self.input: datafile = ""
55                """ from file.<midinote>.wav """
56                # FIXME very weak check
57                floatpit = self.input.split('.')[-2]
58                if not os.path.isfile(datafile) and len(self.input.split('.')) < 3:
59                        print "no ground truth "
60                        return False,False
61                elif floatpit:
62                        try:
63                                self.truth = float(floatpit)
64                                #print "ground truth found in filename:", self.truth
65                                tasksil = tasksilence(self.input,params=self.params)
66                                time,pitch =[],[]
67                                while(tasksil.readsize==tasksil.params.hopsize):
68                                        tasksil()
69                                        time.append(tasksil.params.step*tasksil.frameread)
70                                        if not tasksil.issilence:
71                                                pitch.append(self.truth)
72                                        else:
73                                                pitch.append(-1.)
74                                return time,pitch #0,aubio_miditofreq(float(floatpit))
75                        except ValueError:
76                                # FIXME very weak check
77                                if not os.path.isfile(datafile):
78                                        print "no ground truth found"
79                                        return 0,0
80                                else:
81                                        from aubio.txtfile import read_datafile
82                                        values = read_datafile(datafile)
83                                        time, pitch = [], []
84                                        for i in range(len(values)):
85                                                time.append(values[i][0])
86                                                pitch.append(aubio_freqtomidi(values[i][1]))
87                                        return time,pitch
88
89        def oldeval(self,results):
90                def mmean(l):
91                        return sum(l)/max(float(len(l)),1)
92
93                from aubio.median import percental
94                timet,pitcht = self.gettruth()
95                res = []
96                for i in results:
97                        #print i,self.truth
98                        if i <= 0: pass
99                        else: res.append(self.truth-i)
100                if not res or len(res) < 3: 
101                        avg = self.truth; med = self.truth
102                else:
103                        avg = mmean(res) 
104                        med = percental(res,len(res)/2) 
105                return self.truth, self.truth-med, self.truth-avg
106
107        def eval(self,pitch,tol=0.9):
108                timet,pitcht = self.gettruth()
109                pitch = [aubio_freqtomidi(i) for i in pitch]
110                for i in range(len(pitch)):
111                        if pitch[i] == "nan" or pitch[i] == -1:
112                                pitch[i] = -1
113                time = [ i*self.params.step for i in range(len(pitch)) ]
114                assert len(timet) == len(time) 
115                assert len(pitcht) == len(pitch)
116                osil, esil, opit, epit, echr = 0, 0, 0, 0, 0
117                for i in range(len(pitcht)):
118                        if pitcht[i] == -1: # currently silent
119                                osil += 1 # count a silence
120                                if pitch[i] == -1. or pitch[i] == "nan": 
121                                        esil += 1 # found a silence
122                        else:
123                                opit +=1
124                                if abs(pitcht[i] - pitch[i]) < tol:
125                                        epit += 1
126                                        echr += 1
127                                elif abs(pitcht[i] - pitch[i]) % 12. < tol:
128                                        echr += 1
129                                #else:
130                                #       print timet[i], pitcht[i], time[i], pitch[i]
131                #print "origsilence", "foundsilence", "origpitch", "foundpitch", "orig pitchroma", "found pitchchroma"
132                #print 100.*esil/float(osil), 100.*epit/float(opit), 100.*echr/float(opit)
133                return osil, esil, opit, epit, echr
134
135        def plot(self,pitch,wplot,oplots,outplot=None):
136                import numarray
137                import Gnuplot
138
139                downtime = self.params.step*numarray.arange(len(pitch))
140                oplots.append(Gnuplot.Data(downtime,pitch,with='linespoints',
141                        title=self.params.pitchmode))
142
143                       
144        def plotplot(self,wplot,oplots,outplot=None,multiplot = 0):
145                from aubio.gnuplot import gnuplot_init, audio_to_array, make_audio_plot
146                import re
147                import Gnuplot
148                # audio data
149                time,data = audio_to_array(self.input)
150                f = make_audio_plot(time,data)
151
152                # check if ground truth exists
153                timet,pitcht = self.gettruth()
154                if timet and pitcht:
155                        pitcht = [aubio_miditofreq(i) for i in pitcht]
156                        oplots = [Gnuplot.Data(timet,pitcht,with='lines',
157                                title='ground truth')] + oplots
158
159                t = Gnuplot.Data(0,0,with='impulses') 
160
161                g = gnuplot_init(outplot)
162                g('set title \'%s\'' % (re.sub('.*/','',self.input)))
163                g('set multiplot')
164                # hack to align left axis
165                g('set lmargin 15')
166                # plot waveform and onsets
167                g('set size 1,0.3')
168                g('set origin 0,0.7')
169                g('set xrange [0:%f]' % max(time)) 
170                g('set yrange [-1:1]') 
171                g.ylabel('amplitude')
172                g.plot(f)
173                g('unset title')
174                # plot onset detection function
175
176
177                g('set size 1,0.7')
178                g('set origin 0,0')
179                g('set xrange [0:%f]' % max(time))
180                g('set yrange [100:%f]' % self.params.pitchmax) 
181                g('set key right top')
182                g('set noclip one') 
183                g('set format x ""')
184                g('set log y')
185                #g.xlabel('time (s)')
186                g.ylabel('f0 (Hz)')
187                if multiplot:
188                        for i in range(len(oplots)):
189                                # plot onset detection functions
190                                g('set size 1,%f' % (0.7/(len(oplots))))
191                                g('set origin 0,%f' % (float(i)*0.7/(len(oplots))))
192                                g('set xrange [0:%f]' % max(time))
193                                g.plot(oplots[i])
194                else:
195                        g.plot(*oplots)
196                g('unset multiplot')
197
Note: See TracBrowser for help on using the repository browser.