source: python/aubio/task/pitch.py @ 8d1323b

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

python/aubio: more changes for mono

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