History

splitting up tasks in many files splitting up tasks in many files

Paul Brossier committed 20 years ago

Commit 13c3fba1 parent c7713b211 files · +623 −589Browse files

Showing the changes to python (11 of 11 files). Show all

Unified · Split

11 files
  1. python/aubio/task/beat.py +39 −0
  2. python/aubio/task/cut.py +41 −0
  3. python/aubio/task/onset.py +184 −0
  4. python/aubio/task/params.py +26 −0
  5. python/aubio/task/pitch.py +175 −0
  6. python/aubio/task/silence.py +28 −0
  7. python/aubio/task/task.py +54 −0
  8. python/aubio/task/utils.py +74 −0
  9. python/aubio/tasks.py +0 −587
  10. python/aubiocut +1 −1
  11. python/aubiopitch +1 −1
python/aubio/task/beat.py+39−0
@@ -0,0 +1,39 @@
1from aubio.aubioclass import *
2from onset import taskonset
3
4class taskbeat(taskonset):
5 def __init__(self,input,params=None,output=None):
6 """ open the input file and initialize arguments
7 parameters should be set *before* calling this method.
8 """
9 taskonset.__init__(self,input,output=None,params=params)
10 self.btwinlen = 512**2/self.params.hopsize
11 self.btstep = self.btwinlen/4
12 self.btoutput = fvec(self.btstep,self.channels)
13 self.dfframe = fvec(self.btwinlen,self.channels)
14 self.bt = beattracking(self.btwinlen,self.channels)
15 self.pos2 = 0
16
17 def __call__(self):
18 taskonset.__call__(self)
19 # write to current file
20 if self.pos2 == self.btstep - 1 :
21 self.bt.do(self.dfframe,self.btoutput)
22 for i in range (self.btwinlen - self.btstep):
23 self.dfframe.set(self.dfframe.get(i+self.btstep,0),i,0)
24 for i in range(self.btwinlen - self.btstep, self.btwinlen):
25 self.dfframe.set(0,i,0)
26 self.pos2 = -1;
27 self.pos2 += 1
28 val = self.opick.pp.getval()
29 self.dfframe.set(val,self.btwinlen - self.btstep + self.pos2,0)
30 i=0
31 for i in range(1,int( self.btoutput.get(0,0) ) ):
32 if self.pos2 == self.btoutput.get(i,0) and \
33 aubio_silence_detection(self.myvec(),
34 self.params.silence)!=1:
35 return self.frameread, 0
36
37 def eval(self,results):
38 pass
39
python/aubio/task/cut.py+41−0
@@ -0,0 +1,41 @@
1from task import task
2from aubio.aubioclass import *
3
4class taskcut(task):
5 def __init__(self,input,slicetimes,params=None,output=None):
6 """ open the input file and initialize arguments
7 parameters should be set *before* calling this method.
8 """
9 task.__init__(self,input,output=None,params=params)
10 self.newname = "%s%s%09.5f%s%s" % (self.input.split(".")[0].split("/")[-1],".",
11 self.frameread*self.params.step,".",self.input.split(".")[-1])
12 self.fileo = sndfile(self.newname,model=self.filei)
13 self.myvec = fvec(self.params.hopsize,self.channels)
14 self.mycopy = fvec(self.params.hopsize,self.channels)
15 self.slicetimes = slicetimes
16
17 def __call__(self):
18 task.__call__(self)
19 # write to current file
20 if len(self.slicetimes) and self.frameread >= self.slicetimes[0][0]:
21 self.slicetimes.pop(0)
22 # write up to 1st zero crossing
23 zerocross = 0
24 while ( abs( self.myvec.get(zerocross,0) ) > self.params.zerothres ):
25 zerocross += 1
26 writesize = self.fileo.write(zerocross,self.myvec)
27 fromcross = 0
28 while (zerocross < self.readsize):
29 for i in range(self.channels):
30 self.mycopy.set(self.myvec.get(zerocross,i),fromcross,i)
31 fromcross += 1
32 zerocross += 1
33 del self.fileo
34 self.fileo = sndfile("%s%s%09.5f%s%s" %
35 (self.input.split(".")[0].split("/")[-1],".",
36 self.frameread*self.params.step,".",self.input.split(".")[-1]),model=self.filei)
37 writesize = self.fileo.write(fromcross,self.mycopy)
38 else:
39 writesize = self.fileo.write(self.readsize,self.myvec)
40
41
python/aubio/task/onset.py+184−0
@@ -0,0 +1,184 @@
1from aubio.task.task import task
2from aubio.task.utils import *
3from aubio.aubioclass import *
4
5class taskonset(task):
6 def __init__(self,input,output=None,params=None):
7 """ open the input file and initialize arguments
8 parameters should be set *before* calling this method.
9 """
10 task.__init__(self,input,params=params)
11 self.opick = onsetpick(self.params.bufsize,
12 self.params.hopsize,
13 self.channels,
14 self.myvec,
15 self.params.threshold,
16 mode=get_onset_mode(self.params.onsetmode),
17 dcthreshold=self.params.dcthreshold,
18 derivate=self.params.derivate)
19 self.olist = []
20 self.ofunc = []
21 self.maxofunc = 0
22 self.last = 0
23 if self.params.localmin:
24 self.ovalist = [0., 0., 0., 0., 0.]
25
26 def __call__(self):
27 task.__call__(self)
28 isonset,val = self.opick.do(self.myvec)
29 if (aubio_silence_detection(self.myvec(),self.params.silence)):
30 isonset=0
31 if self.params.storefunc:
32 self.ofunc.append(val)
33 if self.params.localmin:
34 if val > 0: self.ovalist.append(val)
35 else: self.ovalist.append(0)
36 self.ovalist.pop(0)
37 if (isonset == 1):
38 if self.params.localmin:
39 # find local minima before peak
40 i=len(self.ovalist)-1
41 while self.ovalist[i-1] < self.ovalist[i] and i > 0:
42 i -= 1
43 now = (self.frameread+1-i)
44 else:
45 now = self.frameread
46 # take back delay
47 if self.params.delay != 0.: now -= self.params.delay
48 if now < 0 :
49 now = 0
50 if self.params.mintol:
51 # prune doubled
52 if (now - self.last) > self.params.mintol:
53 self.last = now
54 return now, val
55 else:
56 return now, val
57
58
59 def fprint(self,foo):
60 print self.params.step*foo[0]
61
62 def eval(self,inputdata,ftru,mode='roc',vmode=''):
63 from txtfile import read_datafile
64 from onsetcompare import onset_roc, onset_diffs, onset_rocloc
65 ltru = read_datafile(ftru,depth=0)
66 lres = []
67 for i in range(len(inputdata)): lres.append(inputdata[i][0]*self.params.step)
68 if vmode=='verbose':
69 print "Running with mode %s" % self.params.onsetmode,
70 print " and threshold %f" % self.params.threshold,
71 print " on file", self.input
72 #print ltru; print lres
73 if mode == 'local':
74 l = onset_diffs(ltru,lres,self.params.tol)
75 mean = 0
76 for i in l: mean += i
77 if len(l): mean = "%.3f" % (mean/len(l))
78 else: mean = "?0"
79 return l, mean
80 elif mode == 'roc':
81 self.orig, self.missed, self.merged, \
82 self.expc, self.bad, self.doubled = \
83 onset_roc(ltru,lres,self.params.tol)
84 elif mode == 'rocloc':
85 self.v = {}
86 self.v['orig'], self.v['missed'], self.v['Tm'], \
87 self.v['expc'], self.v['bad'], self.v['Td'], \
88 self.v['l'], self.v['labs'] = \
89 onset_rocloc(ltru,lres,self.params.tol)
90
91 def plot(self,onsets,ofunc,wplot,oplots,nplot=False):
92 import Gnuplot, Gnuplot.funcutils
93 import aubio.txtfile
94 import os.path
95 import numarray
96 from aubio.onsetcompare import onset_roc
97
98 x1,y1,y1p = [],[],[]
99 oplot = []
100 if self.params.onsetmode in ('mkl','kl'): ofunc[0:10] = [0] * 10
101
102 self.lenofunc = len(ofunc)
103 self.maxofunc = max(ofunc)
104 # onset detection function
105 downtime = numarray.arange(len(ofunc))*self.params.step
106 oplot.append(Gnuplot.Data(downtime,ofunc,with='lines',title=self.params.onsetmode))
107
108 # detected onsets
109 if not nplot:
110 for i in onsets:
111 x1.append(i[0]*self.params.step)
112 y1.append(self.maxofunc)
113 y1p.append(-self.maxofunc)
114 #x1 = numarray.array(onsets)*self.params.step
115 #y1 = self.maxofunc*numarray.ones(len(onsets))
116 if x1:
117 oplot.append(Gnuplot.Data(x1,y1,with='impulses'))
118 wplot.append(Gnuplot.Data(x1,y1p,with='impulses'))
119
120 oplots.append(oplot)
121
122 # check if ground truth datafile exists
123 datafile = self.input.replace('.wav','.txt')
124 if datafile == self.input: datafile = ""
125 if not os.path.isfile(datafile):
126 self.title = "" #"(no ground truth)"
127 else:
128 t_onsets = aubio.txtfile.read_datafile(datafile)
129 x2 = numarray.array(t_onsets).resize(len(t_onsets))
130 y2 = self.maxofunc*numarray.ones(len(t_onsets))
131 wplot.append(Gnuplot.Data(x2,y2,with='impulses'))
132
133 tol = 0.050
134
135 orig, missed, merged, expc, bad, doubled = \
136 onset_roc(x2,x1,tol)
137 self.title = "GD %2.3f%% FP %2.3f%%" % \
138 ((100*float(orig-missed-merged)/(orig)),
139 (100*float(bad+doubled)/(orig)))
140
141
142 def plotplot(self,wplot,oplots,outplot=None):
143 from aubio.gnuplot import gnuplot_init, audio_to_array, make_audio_plot
144 import re
145 # audio data
146 time,data = audio_to_array(self.input)
147 wplot = [make_audio_plot(time,data)] + wplot
148 self.title = self.input
149 # prepare the plot
150 g = gnuplot_init(outplot)
151
152 g('set multiplot')
153
154 # hack to align left axis
155 g('set lmargin 6')
156 g('set tmargin 0')
157 g('set format x ""')
158 g('set format y ""')
159 g('set noytics')
160
161 for i in range(len(oplots)):
162 # plot onset detection functions
163 g('set size 1,%f' % (0.7/(len(oplots))))
164 g('set origin 0,%f' % (float(i)*0.7/(len(oplots))))
165 g('set xrange [0:%f]' % (self.lenofunc*self.params.step))
166 g.plot(*oplots[i])
167
168 g('set tmargin 3.0')
169 g('set xlabel "time (s)" 1,0')
170 g('set format x "%1.1f"')
171
172 g('set title \'%s %s\'' % (re.sub('.*/','',self.input),self.title))
173
174 # plot waveform and onsets
175 g('set size 1,0.3')
176 g('set origin 0,0.7')
177 g('set xrange [0:%f]' % max(time))
178 g('set yrange [-1:1]')
179 g.ylabel('amplitude')
180 g.plot(*wplot)
181
182 g('unset multiplot')
183
184
python/aubio/task/params.py+26−0
@@ -0,0 +1,26 @@
1from aubio.aubioclass import aubio_pitchm_freq
2
3class taskparams(object):
4 """ default parameters for task classes """
5 def __init__(self,input=None,output=None):
6 self.silence = -70
7 self.derivate = False
8 self.localmin = False
9 self.delay = 4.
10 self.storefunc = False
11 self.bufsize = 512
12 self.hopsize = 256
13 self.samplerate = 44100
14 self.tol = 0.05
15 self.mintol = 0.0
16 self.step = float(self.hopsize)/float(self.samplerate)
17 self.threshold = 0.1
18 self.onsetmode = 'dual'
19 self.pitchmode = 'yin'
20 self.pitchsmooth = 7
21 self.pitchmin=100.
22 self.pitchmax=1000.
23 self.dcthreshold = -1.
24 self.omode = aubio_pitchm_freq
25 self.verbose = False
26
python/aubio/task/pitch.py+175−0
@@ -0,0 +1,175 @@
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 = aubio_miditofreq(float(floatpit))
64 print "ground truth found in filename:", self.truth
65 tasksil = tasksilence(self.input)
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(values[i][1])
87 return time,pitch
88
89 def eval(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 neweval(self,results):
108 timet,pitcht = self.gettruth()
109 for i in timet:
110 print results[i]
111 return self.truth, self.truth-med, self.truth-avg
112
113 def plot(self,pitch,wplot,oplots,outplot=None):
114 import numarray
115 import Gnuplot
116
117 self.eval(pitch)
118 downtime = self.params.step*numarray.arange(len(pitch))
119 oplots.append(Gnuplot.Data(downtime,pitch,with='lines',
120 title=self.params.pitchmode))
121
122
123 def plotplot(self,wplot,oplots,outplot=None,multiplot = 1):
124 from aubio.gnuplot import gnuplot_init, audio_to_array, make_audio_plot
125 import re
126 import Gnuplot
127 # audio data
128 time,data = audio_to_array(self.input)
129 f = make_audio_plot(time,data)
130
131 # check if ground truth exists
132 timet,pitcht = self.gettruth()
133 if timet and pitcht:
134 oplots = [Gnuplot.Data(timet,pitcht,with='lines',
135 title='ground truth')] + oplots
136
137 t = Gnuplot.Data(0,0,with='impulses')
138
139 g = gnuplot_init(outplot)
140 g('set title \'%s\'' % (re.sub('.*/','',self.input)))
141 g('set multiplot')
142 # hack to align left axis
143 g('set lmargin 15')
144 # plot waveform and onsets
145 g('set size 1,0.3')
146 g('set origin 0,0.7')
147 g('set xrange [0:%f]' % max(time))
148 g('set yrange [-1:1]')
149 g.ylabel('amplitude')
150 g.plot(f)
151 g('unset title')
152 # plot onset detection function
153
154
155 g('set size 1,0.7')
156 g('set origin 0,0')
157 g('set xrange [0:%f]' % max(time))
158 g('set yrange [100:%f]' % self.params.pitchmax)
159 g('set key right top')
160 g('set noclip one')
161 g('set format x ""')
162 g('set log y')
163 #g.xlabel('time (s)')
164 g.ylabel('f0 (Hz)')
165 if multiplot:
166 for i in range(len(oplots)):
167 # plot onset detection functions
168 g('set size 1,%f' % (0.7/(len(oplots))))
169 g('set origin 0,%f' % (float(i)*0.7/(len(oplots))))
170 g('set xrange [0:%f]' % max(time))
171 g.plot(oplots[i])
172 else:
173 g.plot(*oplots)
174 g('unset multiplot')
175
python/aubio/task/silence.py+28−0
@@ -0,0 +1,28 @@
1from aubio.task.task import task
2from aubio.aubioclass import *
3
4class tasksilence(task):
5 wassilence = 1
6 issilence = 1
7 def __call__(self):
8 task.__call__(self)
9 if (aubio_silence_detection(self.myvec(),self.params.silence)==1):
10 if self.wassilence == 1: self.issilence = 1
11 else: self.issilence = 2
12 self.wassilence = 1
13 else:
14 if self.wassilence <= 0: self.issilence = 0
15 else: self.issilence = -1
16 self.wassilence = 0
17 if self.issilence == -1:
18 return max(self.frameread-self.params.delay,0.), -1
19 elif self.issilence == 2:
20 return max(self.frameread+self.params.delay,0.), 2
21
22 def fprint(self,foo):
23 print self.params.step*foo[0],
24 if foo[1] == 2: print "OFF"
25 else: print "ON"
26
27
28
python/aubio/task/task.py+54−0
@@ -0,0 +1,54 @@
1from aubio.aubioclass import *
2from params import taskparams
3
4class task(taskparams):
5 """ default template class to apply tasks on a stream """
6 def __init__(self,input,output=None,params=None):
7 """ open the input file and initialize default argument
8 parameters should be set *before* calling this method.
9 """
10 import time
11 self.tic = time.time()
12 if params == None: self.params = taskparams()
13 else: self.params = params
14 self.frameread = 0
15 self.readsize = self.params.hopsize
16 self.input = input
17 self.filei = sndfile(self.input)
18 self.srate = self.filei.samplerate()
19 self.channels = self.filei.channels()
20 self.params.step = float(self.params.hopsize)/float(self.srate)
21 self.myvec = fvec(self.params.hopsize,self.channels)
22 self.output = output
23
24 def __call__(self):
25 self.readsize = self.filei.read(self.params.hopsize,self.myvec)
26 self.frameread += 1
27
28 def compute_all(self):
29 """ Compute data """
30 mylist = []
31 while(self.readsize==self.params.hopsize):
32 tmp = self()
33 if tmp:
34 mylist.append(tmp)
35 if self.params.verbose:
36 self.fprint(tmp)
37 return mylist
38
39 def fprint(self,foo):
40 print foo
41
42 def eval(self,results):
43 """ Eval data """
44 pass
45
46 def plot(self):
47 """ Plot data """
48 pass
49
50 def time(self):
51 import time
52 print "CPU time is now %f seconds," % time.clock(),
53 print "task execution took %f seconds" % (time.time() - self.tic)
54
python/aubio/task/utils.py+74−0
@@ -0,0 +1,74 @@
1from aubio.aubioclass import *
2
3def get_onset_mode(nvalue):
4 """ utility function to convert a string to aubio_onsetdetection_type """
5 if nvalue == 'complexdomain' or nvalue == 'complex' :
6 return aubio_onset_complex
7 elif nvalue == 'hfc' :
8 return aubio_onset_hfc
9 elif nvalue == 'phase' :
10 return aubio_onset_phase
11 elif nvalue == 'specdiff' :
12 return aubio_onset_specdiff
13 elif nvalue == 'energy' :
14 return aubio_onset_energy
15 elif nvalue == 'kl' :
16 return aubio_onset_kl
17 elif nvalue == 'mkl' :
18 return aubio_onset_mkl
19 elif nvalue == 'dual' :
20 return 'dual'
21 else:
22 import sys
23 print "unknown onset detection function selected"
24 sys.exit(1)
25
26def get_pitch_mode(nvalue):
27 """ utility function to convert a string to aubio_pitchdetection_type """
28 if nvalue == 'mcomb' :
29 return aubio_pitch_mcomb
30 elif nvalue == 'yin' :
31 return aubio_pitch_yin
32 elif nvalue == 'fcomb' :
33 return aubio_pitch_fcomb
34 elif nvalue == 'schmitt':
35 return aubio_pitch_schmitt
36 else:
37 import sys
38 print "error: unknown pitch detection function selected"
39 sys.exit(1)
40
41def check_onset_mode(option, opt, value, parser):
42 """ wrapper function to convert a list of modes to
43 aubio_onsetdetection_type """
44 nvalues = parser.rargs[0].split(',')
45 val = []
46 for nvalue in nvalues:
47 val.append(get_onset_mode(nvalue))
48 setattr(parser.values, option.dest, val)
49
50def check_pitch_mode(option, opt, value, parser):
51 """ utility function to convert a string to aubio_pitchdetection_type"""
52 nvalues = parser.rargs[0].split(',')
53 val = []
54 for nvalue in nvalues:
55 val.append(get_pitch_mode(nvalue))
56 setattr(parser.values, option.dest, val)
57
58def check_pitchm_mode(option, opt, value, parser):
59 """ utility function to convert a string to aubio_pitchdetection_mode """
60 nvalue = parser.rargs[0]
61 if nvalue == 'freq' :
62 setattr(parser.values, option.dest, aubio_pitchm_freq)
63 elif nvalue == 'midi' :
64 setattr(parser.values, option.dest, aubio_pitchm_midi)
65 elif nvalue == 'cent' :
66 setattr(parser.values, option.dest, aubio_pitchm_cent)
67 elif nvalue == 'bin' :
68 setattr(parser.values, option.dest, aubio_pitchm_bin)
69 else:
70 import sys
71 print "error: unknown pitch detection output selected"
72 sys.exit(1)
73
74
python/aubio/tasks.py+0−587
@@ -1,587 +0,0 @@
1from aubioclass import *
2
3def get_onset_mode(nvalue):
4 """ utility function to convert a string to aubio_onsetdetection_type """
5 if nvalue == 'complexdomain' or nvalue == 'complex' :
6 return aubio_onset_complex
7 elif nvalue == 'hfc' :
8 return aubio_onset_hfc
9 elif nvalue == 'phase' :
10 return aubio_onset_phase
11 elif nvalue == 'specdiff' :
12 return aubio_onset_specdiff
13 elif nvalue == 'energy' :
14 return aubio_onset_energy
15 elif nvalue == 'kl' :
16 return aubio_onset_kl
17 elif nvalue == 'mkl' :
18 return aubio_onset_mkl
19 elif nvalue == 'dual' :
20 return 'dual'
21 else:
22 import sys
23 print "unknown onset detection function selected"
24 sys.exit(1)
25
26def get_pitch_mode(nvalue):
27 """ utility function to convert a string to aubio_pitchdetection_type """
28 if nvalue == 'mcomb' :
29 return aubio_pitch_mcomb
30 elif nvalue == 'yin' :
31 return aubio_pitch_yin
32 elif nvalue == 'fcomb' :
33 return aubio_pitch_fcomb
34 elif nvalue == 'schmitt':
35 return aubio_pitch_schmitt
36 else:
37 import sys
38 print "error: unknown pitch detection function selected"
39 sys.exit(1)
40
41def check_onset_mode(option, opt, value, parser):
42 """ wrapper function to convert a list of modes to
43 aubio_onsetdetection_type """
44 nvalues = parser.rargs[0].split(',')
45 val = []
46 for nvalue in nvalues:
47 val.append(get_onset_mode(nvalue))
48 setattr(parser.values, option.dest, val)
49
50def check_pitch_mode(option, opt, value, parser):
51 """ utility function to convert a string to aubio_pitchdetection_type"""
52 nvalues = parser.rargs[0].split(',')
53 val = []
54 for nvalue in nvalues:
55 val.append(get_pitch_mode(nvalue))
56 setattr(parser.values, option.dest, val)
57
58def check_pitchm_mode(option, opt, value, parser):
59 """ utility function to convert a string to aubio_pitchdetection_mode """
60 nvalue = parser.rargs[0]
61 if nvalue == 'freq' :
62 setattr(parser.values, option.dest, aubio_pitchm_freq)
63 elif nvalue == 'midi' :
64 setattr(parser.values, option.dest, aubio_pitchm_midi)
65 elif nvalue == 'cent' :
66 setattr(parser.values, option.dest, aubio_pitchm_cent)
67 elif nvalue == 'bin' :
68 setattr(parser.values, option.dest, aubio_pitchm_bin)
69 else:
70 import sys
71 print "error: unknown pitch detection output selected"
72 sys.exit(1)
73
74class taskparams(object):
75 """ default parameters for task classes """
76 def __init__(self,input=None,output=None):
77 self.silence = -70
78 self.derivate = False
79 self.localmin = False
80 self.delay = 4.
81 self.storefunc = False
82 self.bufsize = 512
83 self.hopsize = 256
84 self.samplerate = 44100
85 self.tol = 0.05
86 self.mintol = 0.0
87 self.step = float(self.hopsize)/float(self.samplerate)
88 self.threshold = 0.1
89 self.onsetmode = 'dual'
90 self.pitchmode = 'yin'
91 self.pitchsmooth = 7
92 self.pitchmin=100.
93 self.pitchmax=1000.
94 self.dcthreshold = -1.
95 self.omode = aubio_pitchm_freq
96 self.verbose = False
97
98class task(taskparams):
99 """ default template class to apply tasks on a stream """
100 def __init__(self,input,output=None,params=None):
101 """ open the input file and initialize default argument
102 parameters should be set *before* calling this method.
103 """
104 import time
105 self.tic = time.time()
106 if params == None: self.params = taskparams()
107 else: self.params = params
108 self.frameread = 0
109 self.readsize = self.params.hopsize
110 self.input = input
111 self.filei = sndfile(self.input)
112 self.srate = self.filei.samplerate()
113 self.channels = self.filei.channels()
114 self.params.step = float(self.params.hopsize)/float(self.srate)
115 self.myvec = fvec(self.params.hopsize,self.channels)
116 self.output = output
117
118 def __call__(self):
119 self.readsize = self.filei.read(self.params.hopsize,self.myvec)
120 self.frameread += 1
121
122 def compute_all(self):
123 """ Compute data """
124 mylist = []
125 while(self.readsize==self.params.hopsize):
126 tmp = self()
127 if tmp:
128 mylist.append(tmp)
129 if self.params.verbose:
130 self.fprint(tmp)
131 return mylist
132
133 def fprint(self,foo):
134 print foo
135
136 def eval(self,results):
137 """ Eval data """
138 pass
139
140 def plot(self):
141 """ Plot data """
142 pass
143
144 def time(self):
145 import time
146 print "CPU time is now %f seconds," % time.clock(),
147 print "task execution took %f seconds" % (time.time() - self.tic)
148
149class tasksilence(task):
150 wassilence = 1
151 issilence = 1
152 def __call__(self):
153 task.__call__(self)
154 if (aubio_silence_detection(self.myvec(),self.params.silence)==1):
155 if self.wassilence == 1: self.issilence = 1
156 else: self.issilence = 2
157 self.wassilence = 1
158 else:
159 if self.wassilence <= 0: self.issilence = 0
160 else: self.issilence = -1
161 self.wassilence = 0
162 if self.issilence == -1:
163 return max(self.frameread-self.params.delay,0.), -1
164 elif self.issilence == 2:
165 return max(self.frameread+self.params.delay,0.), 2
166
167 def fprint(self,foo):
168 print self.params.step*foo[0],
169 if foo[1] == 2: print "OFF"
170 else: print "ON"
171
172class taskpitch(task):
173 def __init__(self,input,params=None):
174 task.__init__(self,input,params=params)
175 self.shortlist = [0. for i in range(self.params.pitchsmooth)]
176 self.pitchdet = pitchdetection(mode=get_pitch_mode(self.params.pitchmode),
177 bufsize=self.params.bufsize,
178 hopsize=self.params.hopsize,
179 channels=self.channels,
180 samplerate=self.srate,
181 omode=self.params.omode)
182
183 def __call__(self):
184 from median import short_find
185 task.__call__(self)
186 if (aubio_silence_detection(self.myvec(),self.params.silence)==1):
187 freq = -1.
188 else:
189 freq = self.pitchdet(self.myvec)
190 minpitch = self.params.pitchmin
191 maxpitch = self.params.pitchmax
192 if maxpitch and freq > maxpitch :
193 freq = -1.
194 elif minpitch and freq < minpitch :
195 freq = -1.
196 if self.params.pitchsmooth:
197 self.shortlist.append(freq)
198 self.shortlist.pop(0)
199 smoothfreq = short_find(self.shortlist,
200 len(self.shortlist)/2)
201 return smoothfreq
202 else:
203 return freq
204
205 def compute_all(self):
206 """ Compute data """
207 mylist = []
208 while(self.readsize==self.params.hopsize):
209 freq = self()
210 mylist.append(freq)
211 if self.params.verbose:
212 self.fprint("%s\t%s" % (self.frameread*self.params.step,freq))
213 return mylist
214
215 def gettruth(self):
216 """ extract ground truth array in frequency """
217 import os.path
218 """ from wavfile.txt """
219 datafile = self.input.replace('.wav','.txt')
220 if datafile == self.input: datafile = ""
221 """ from file.<midinote>.wav """
222 # FIXME very weak check
223 floatpit = self.input.split('.')[-2]
224
225 if not os.path.isfile(datafile) and not len(self.input.split('.')) < 3:
226 print "no ground truth "
227 return False,False
228 elif floatpit:
229 try:
230 self.truth = aubio_miditofreq(float(floatpit))
231 print "ground truth found in filename:", self.truth
232 tasksil = tasksilence(self.input)
233 time,pitch =[],[]
234 while(tasksil.readsize==tasksil.params.hopsize):
235 tasksil()
236 time.append(tasksil.params.step*tasksil.frameread)
237 if not tasksil.issilence:
238 pitch.append(self.truth)
239 else:
240 pitch.append(-1.)
241 return time,pitch #0,aubio_miditofreq(float(floatpit))
242 except ValueError:
243 # FIXME very weak check
244 if not os.path.isfile(datafile):
245 print "no ground truth found"
246 return 0,0
247 else:
248 from aubio.txtfile import read_datafile
249 values = read_datafile(datafile)
250 time, pitch = [], []
251 for i in range(len(values)):
252 time.append(values[i][0])
253 pitch.append(values[i][1])
254 return time,pitch
255
256 def eval(self,results):
257 def mmean(l):
258 return sum(l)/max(float(len(l)),1)
259
260 from median import percental
261 timet,pitcht = self.gettruth()
262 res = []
263 for i in results:
264 #print i,self.truth
265 if i <= 0: pass
266 else: res.append(self.truth-i)
267 if not res or len(res) < 3:
268 avg = self.truth; med = self.truth
269 else:
270 avg = mmean(res)
271 med = percental(res,len(res)/2)
272 return self.truth, self.truth-med, self.truth-avg
273
274 def plot(self,pitch,wplot,oplots,outplot=None):
275 import numarray
276 import Gnuplot
277
278 downtime = self.params.step*numarray.arange(len(pitch))
279 oplots.append(Gnuplot.Data(downtime,pitch,with='lines',
280 title=self.params.pitchmode))
281
282
283 def plotplot(self,wplot,oplots,outplot=None,multiplot = 1):
284 from aubio.gnuplot import gnuplot_init, audio_to_array, make_audio_plot
285 import re
286 import Gnuplot
287 # audio data
288 time,data = audio_to_array(self.input)
289 f = make_audio_plot(time,data)
290
291 # check if ground truth exists
292 timet,pitcht = self.gettruth()
293 if timet and pitcht:
294 oplots = [Gnuplot.Data(timet,pitcht,with='lines',
295 title='ground truth')] + oplots
296
297 t = Gnuplot.Data(0,0,with='impulses')
298
299 g = gnuplot_init(outplot)
300 g('set title \'%s\'' % (re.sub('.*/','',self.input)))
301 g('set multiplot')
302 # hack to align left axis
303 g('set lmargin 15')
304 # plot waveform and onsets
305 g('set size 1,0.3')
306 g('set origin 0,0.7')
307 g('set xrange [0:%f]' % max(time))
308 g('set yrange [-1:1]')
309 g.ylabel('amplitude')
310 g.plot(f)
311 g('unset title')
312 # plot onset detection function
313
314
315 g('set size 1,0.7')
316 g('set origin 0,0')
317 g('set xrange [0:%f]' % max(time))
318 g('set yrange [100:%f]' % self.params.pitchmax)
319 g('set key right top')
320 g('set noclip one')
321 g('set format x ""')
322 g('set log y')
323 #g.xlabel('time (s)')
324 g.ylabel('f0 (Hz)')
325 if multiplot:
326 for i in range(len(oplots)):
327 # plot onset detection functions
328 g('set size 1,%f' % (0.7/(len(oplots))))
329 g('set origin 0,%f' % (float(i)*0.7/(len(oplots))))
330 g('set xrange [0:%f]' % max(time))
331 g.plot(oplots[i])
332 else:
333 g.plot(*oplots)
334 g('unset multiplot')
335
336
337class taskonset(task):
338 def __init__(self,input,output=None,params=None):
339 """ open the input file and initialize arguments
340 parameters should be set *before* calling this method.
341 """
342 task.__init__(self,input,params=params)
343 self.opick = onsetpick(self.params.bufsize,
344 self.params.hopsize,
345 self.channels,
346 self.myvec,
347 self.params.threshold,
348 mode=get_onset_mode(self.params.onsetmode),
349 dcthreshold=self.params.dcthreshold,
350 derivate=self.params.derivate)
351 self.olist = []
352 self.ofunc = []
353 self.maxofunc = 0
354 self.last = 0
355 if self.params.localmin:
356 self.ovalist = [0., 0., 0., 0., 0.]
357
358 def __call__(self):
359 task.__call__(self)
360 isonset,val = self.opick.do(self.myvec)
361 if (aubio_silence_detection(self.myvec(),self.params.silence)):
362 isonset=0
363 if self.params.storefunc:
364 self.ofunc.append(val)
365 if self.params.localmin:
366 if val > 0: self.ovalist.append(val)
367 else: self.ovalist.append(0)
368 self.ovalist.pop(0)
369 if (isonset == 1):
370 if self.params.localmin:
371 # find local minima before peak
372 i=len(self.ovalist)-1
373 while self.ovalist[i-1] < self.ovalist[i] and i > 0:
374 i -= 1
375 now = (self.frameread+1-i)
376 else:
377 now = self.frameread
378 # take back delay
379 if self.params.delay != 0.: now -= self.params.delay
380 if now < 0 :
381 now = 0
382 if self.params.mintol:
383 # prune doubled
384 if (now - self.last) > self.params.mintol:
385 self.last = now
386 return now, val
387 else:
388 return now, val
389
390
391 def fprint(self,foo):
392 print self.params.step*foo[0]
393
394 def eval(self,inputdata,ftru,mode='roc',vmode=''):
395 from txtfile import read_datafile
396 from onsetcompare import onset_roc, onset_diffs, onset_rocloc
397 ltru = read_datafile(ftru,depth=0)
398 lres = []
399 for i in range(len(inputdata)): lres.append(inputdata[i][0]*self.params.step)
400 if vmode=='verbose':
401 print "Running with mode %s" % self.params.onsetmode,
402 print " and threshold %f" % self.params.threshold,
403 print " on file", self.input
404 #print ltru; print lres
405 if mode == 'local':
406 l = onset_diffs(ltru,lres,self.params.tol)
407 mean = 0
408 for i in l: mean += i
409 if len(l): mean = "%.3f" % (mean/len(l))
410 else: mean = "?0"
411 return l, mean
412 elif mode == 'roc':
413 self.orig, self.missed, self.merged, \
414 self.expc, self.bad, self.doubled = \
415 onset_roc(ltru,lres,self.params.tol)
416 elif mode == 'rocloc':
417 self.v = {}
418 self.v['orig'], self.v['missed'], self.v['Tm'], \
419 self.v['expc'], self.v['bad'], self.v['Td'], \
420 self.v['l'], self.v['labs'] = \
421 onset_rocloc(ltru,lres,self.params.tol)
422
423 def plot(self,onsets,ofunc,wplot,oplots,nplot=False):
424 import Gnuplot, Gnuplot.funcutils
425 import aubio.txtfile
426 import os.path
427 import numarray
428 from aubio.onsetcompare import onset_roc
429
430 x1,y1,y1p = [],[],[]
431 oplot = []
432 if self.params.onsetmode in ('mkl','kl'): ofunc[0:10] = [0] * 10
433
434 self.lenofunc = len(ofunc)
435 self.maxofunc = max(ofunc)
436 # onset detection function
437 downtime = numarray.arange(len(ofunc))*self.params.step
438 oplot.append(Gnuplot.Data(downtime,ofunc,with='lines',title=self.params.onsetmode))
439
440 # detected onsets
441 if not nplot:
442 for i in onsets:
443 x1.append(i[0]*self.params.step)
444 y1.append(self.maxofunc)
445 y1p.append(-self.maxofunc)
446 #x1 = numarray.array(onsets)*self.params.step
447 #y1 = self.maxofunc*numarray.ones(len(onsets))
448 if x1:
449 oplot.append(Gnuplot.Data(x1,y1,with='impulses'))
450 wplot.append(Gnuplot.Data(x1,y1p,with='impulses'))
451
452 oplots.append(oplot)
453
454 # check if ground truth datafile exists
455 datafile = self.input.replace('.wav','.txt')
456 if datafile == self.input: datafile = ""
457 if not os.path.isfile(datafile):
458 self.title = "" #"(no ground truth)"
459 else:
460 t_onsets = aubio.txtfile.read_datafile(datafile)
461 x2 = numarray.array(t_onsets).resize(len(t_onsets))
462 y2 = self.maxofunc*numarray.ones(len(t_onsets))
463 wplot.append(Gnuplot.Data(x2,y2,with='impulses'))
464
465 tol = 0.050
466
467 orig, missed, merged, expc, bad, doubled = \
468 onset_roc(x2,x1,tol)
469 self.title = "GD %2.3f%% FP %2.3f%%" % \
470 ((100*float(orig-missed-merged)/(orig)),
471 (100*float(bad+doubled)/(orig)))
472
473
474 def plotplot(self,wplot,oplots,outplot=None):
475 from aubio.gnuplot import gnuplot_init, audio_to_array, make_audio_plot
476 import re
477 # audio data
478 time,data = audio_to_array(self.input)
479 wplot = [make_audio_plot(time,data)] + wplot
480 self.title = self.input
481 # prepare the plot
482 g = gnuplot_init(outplot)
483
484 g('set multiplot')
485
486 # hack to align left axis
487 g('set lmargin 6')
488 g('set tmargin 0')
489 g('set format x ""')
490 g('set format y ""')
491 g('set noytics')
492
493 for i in range(len(oplots)):
494 # plot onset detection functions
495 g('set size 1,%f' % (0.7/(len(oplots))))
496 g('set origin 0,%f' % (float(i)*0.7/(len(oplots))))
497 g('set xrange [0:%f]' % (self.lenofunc*self.params.step))
498 g.plot(*oplots[i])
499
500 g('set tmargin 3.0')
501 g('set xlabel "time (s)" 1,0')
502 g('set format x "%1.1f"')
503
504 g('set title \'%s %s\'' % (re.sub('.*/','',self.input),self.title))
505
506 # plot waveform and onsets
507 g('set size 1,0.3')
508 g('set origin 0,0.7')
509 g('set xrange [0:%f]' % max(time))
510 g('set yrange [-1:1]')
511 g.ylabel('amplitude')
512 g.plot(*wplot)
513
514 g('unset multiplot')
515
516class taskcut(task):
517 def __init__(self,input,slicetimes,params=None,output=None):
518 """ open the input file and initialize arguments
519 parameters should be set *before* calling this method.
520 """
521 task.__init__(self,input,output=None,params=params)
522 self.newname = "%s%s%09.5f%s%s" % (self.input.split(".")[0].split("/")[-1],".",
523 self.frameread*self.params.step,".",self.input.split(".")[-1])
524 self.fileo = sndfile(self.newname,model=self.filei)
525 self.myvec = fvec(self.params.hopsize,self.channels)
526 self.mycopy = fvec(self.params.hopsize,self.channels)
527 self.slicetimes = slicetimes
528
529 def __call__(self):
530 task.__call__(self)
531 # write to current file
532 if len(self.slicetimes) and self.frameread >= self.slicetimes[0][0]:
533 self.slicetimes.pop(0)
534 # write up to 1st zero crossing
535 zerocross = 0
536 while ( abs( self.myvec.get(zerocross,0) ) > self.params.zerothres ):
537 zerocross += 1
538 writesize = self.fileo.write(zerocross,self.myvec)
539 fromcross = 0
540 while (zerocross < self.readsize):
541 for i in range(self.channels):
542 self.mycopy.set(self.myvec.get(zerocross,i),fromcross,i)
543 fromcross += 1
544 zerocross += 1
545 del self.fileo
546 self.fileo = sndfile("%s%s%09.5f%s%s" %
547 (self.input.split(".")[0].split("/")[-1],".",
548 self.frameread*self.params.step,".",self.input.split(".")[-1]),model=self.filei)
549 writesize = self.fileo.write(fromcross,self.mycopy)
550 else:
551 writesize = self.fileo.write(self.readsize,self.myvec)
552
553class taskbeat(taskonset):
554 def __init__(self,input,params=None,output=None):
555 """ open the input file and initialize arguments
556 parameters should be set *before* calling this method.
557 """
558 taskonset.__init__(self,input,output=None,params=params)
559 self.btwinlen = 512**2/self.params.hopsize
560 self.btstep = self.btwinlen/4
561 self.btoutput = fvec(self.btstep,self.channels)
562 self.dfframe = fvec(self.btwinlen,self.channels)
563 self.bt = beattracking(self.btwinlen,self.channels)
564 self.pos2 = 0
565
566 def __call__(self):
567 taskonset.__call__(self)
568 # write to current file
569 if self.pos2 == self.btstep - 1 :
570 self.bt.do(self.dfframe,self.btoutput)
571 for i in range (self.btwinlen - self.btstep):
572 self.dfframe.set(self.dfframe.get(i+self.btstep,0),i,0)
573 for i in range(self.btwinlen - self.btstep, self.btwinlen):
574 self.dfframe.set(0,i,0)
575 self.pos2 = -1;
576 self.pos2 += 1
577 val = self.opick.pp.getval()
578 self.dfframe.set(val,self.btwinlen - self.btstep + self.pos2,0)
579 i=0
580 for i in range(1,int( self.btoutput.get(0,0) ) ):
581 if self.pos2 == self.btoutput.get(i,0) and \
582 aubio_silence_detection(self.myvec(),
583 self.params.silence)!=1:
584 return self.frameread, 0
585
586 def eval(self,results):
587 pass
python/aubiocut+1−1
@@ -5,7 +5,7 @@ · 4 unmodified lines
5"""5"""
6 6
7import sys7import sys
8from aubio.tasks import *8from aubio.task import *
9 9
10usage = "usage: %s [options] -i soundfile" % sys.argv[0]10usage = "usage: %s [options] -i soundfile" % sys.argv[0]
11 11
python/aubiopitch+1−1
@@ -5,7 +5,7 @@ · 4 unmodified lines
5"""5"""
6 6
7import sys7import sys
8from aubio.tasks import *8from aubio.task import *
9 9
10usage = "usage: %s [options] -i soundfile" % sys.argv[0]10usage = "usage: %s [options] -i soundfile" % sys.argv[0]
11 11

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t