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

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

update pitch plot
update pitch plot

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