source: python/aubio/task/pitch.py @ e2b1bda

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

update task.pitch.{eval,plot}
update task.pitch.{eval,plot}

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