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

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 @@
1+from aubio.aubioclass import *
2+from onset import taskonset
3+
4+class 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 @@
1+from task import task
2+from aubio.aubioclass import *
3+
4+class 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 @@
1+from aubio.task.task import task
2+from aubio.task.utils import *
3+from aubio.aubioclass import *
4+
5+class 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 @@
1+from aubio.aubioclass import aubio_pitchm_freq
2+
3+class 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 @@
1+from aubio.task.task import task
2+from aubio.task.silence import tasksilence
3+from aubio.task.utils import *
4+from aubio.aubioclass import *
5+
6+class 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 @@
1+from aubio.task.task import task
2+from aubio.aubioclass import *
3+
4+class 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 @@
1+from aubio.aubioclass import *
2+from params import taskparams
3+
4+class 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 @@
1+from aubio.aubioclass import *
2+
3+def 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+
26+def 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+
41+def 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+
50+def 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+
58+def 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 @@
1−from aubioclass import *
2−
3−def 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−
26−def 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−
41−def 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−
50−def 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−
58−def 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−class 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−
98−class 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−
149−class 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−
172−class 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−
337−class 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−
516−class 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−
553−class 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
55 """
66
77 import sys
8−from aubio.tasks import *
8+from aubio.task import *
99
1010 usage = "usage: %s [options] -i soundfile" % sys.argv[0]
1111
python/aubiopitch+1−1
@@ -5,7 +5,7 @@ · 4 unmodified lines
55 """
66
77 import sys
8−from aubio.tasks import *
8+from aubio.task import *
99
1010 usage = "usage: %s [options] -i soundfile" % sys.argv[0]
1111

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