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

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

rename aubio_pitchdetection to aubio_pitch

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