lib/aubio/__init__.py: add header and docstring
[aubio.git] / tests / demo / bench / pitch / bench-pitch-isolated
1 #! /usr/bin/python
2
3 from aubio.bench.node import *
4 from aubio.task import *
5
6 class benchpitch(bench):
7         
8         """ list of values to store per file """
9         valuenames = ['mode']
10         """ list of lists to store per file """
11         valuelists = ['truth', 'osil', 'esil', 'opit', 'epit', 'echr', 
12                'Msil', 'Mpit', 'Mchr',
13                'TotalPit', 'TotalPit', 'TotalChr' ]
14         """ list of values to print per dir """
15         printnames_total = [ 'mode', 'MinPit', 'MaxPit', 'TotalSil', 'TotalPit', 'TotalChr']
16         printnames_notes = [ 'mode', 'Note', 'Sil', 'Pit', 'Chr']
17         printnames = printnames_notes 
18
19         """ per dir """
20         formats = {'mode': "%12s" , 
21                 'truth': "%s",
22                 'osil': "%s", 'esil': "%s", 
23                 'opit': "%s", 'epit': "%s", 'echr': "%s",
24     'Note': "%s", 'Sil': "%s", 'Chr': "%s", 'Pit': "%s",
25                 'TotalPit': "%s", 'TotalSil': "%s", 'TotalChr': "%s",
26                 'MinPit': "%s", 'MaxPit': "%s",
27                 'Msil': "%s", 'Mpit': "%s", 'Mchr': "%s"}
28
29         def dir_eval(self):
30                 """ evaluate statistical data over the directory """
31                 v = self.v
32                 v['mode']      = self.params.pitchmode
33
34         def file_exec(self,input,output):
35                 filetask = self.task(input,params=self.params)
36                 computed_data = filetask.compute_all()
37                 osil, esil, opit, epit, echr = filetask.eval(computed_data,tol=0.5)
38                 self.v['truth'].append(int(filetask.truth))
39                 assert opit > 0
40                 
41                 self.v['osil'].append(osil)
42                 self.v['esil'].append(esil)
43                 self.v['opit'].append(opit)
44                 self.v['epit'].append(epit)
45                 self.v['echr'].append(echr)
46
47                 self.v['Msil'].append(esil/float(osil)*100.)
48                 self.v['Mpit'].append(epit/float(opit)*100.)
49                 self.v['Mchr'].append(echr/float(opit)*100.)
50                 #print results#, computed_data
51                 #print input, results, results - float(input.split('.')[-2])
52                         
53         def run_bench(self,modes=['schmitt'],multiplot=0):
54                 from os.path import basename
55                 self.modes = modes
56                 self.pretty_titles()
57                 d = []
58                 for mode in self.modes:
59                         self.params.pitchmode = mode
60                         self.dir_exec()
61                         self.dir_eval()
62                         truth   = [i for i in range(min(self.v['truth']),max(self.v['truth'])+1)]
63                         allOsil = [0 for i in range(min(self.v['truth']),max(self.v['truth'])+1)]
64                         allEsil = [0 for i in range(min(self.v['truth']),max(self.v['truth'])+1)]
65                         allOpit = [0 for i in range(min(self.v['truth']),max(self.v['truth'])+1)]
66                         allEpit = [0 for i in range(min(self.v['truth']),max(self.v['truth'])+1)]
67                         allEchr = [0 for i in range(min(self.v['truth']),max(self.v['truth'])+1)]
68                         allMsil = [0 for i in range(min(self.v['truth']),max(self.v['truth'])+1)]
69                         allMpit = [0 for i in range(min(self.v['truth']),max(self.v['truth'])+1)]
70                         allMchr = [0 for i in range(min(self.v['truth']),max(self.v['truth'])+1)]
71                         for i in range(len(self.v['truth'])):
72                                 allOsil[self.v['truth'][i]-min(self.v['truth'])] += self.v['osil'][i]
73                                 allEsil[self.v['truth'][i]-min(self.v['truth'])] += self.v['esil'][i]
74                                 allOpit[self.v['truth'][i]-min(self.v['truth'])] += self.v['opit'][i]
75                                 allEpit[self.v['truth'][i]-min(self.v['truth'])] += self.v['epit'][i]
76                                 allEchr[self.v['truth'][i]-min(self.v['truth'])] += self.v['echr'][i]
77                         for i in range(len(truth)):
78                                 allOsil[i] = max(1,allOsil[i])
79                                 allOpit[i] = max(1,allOpit[i])
80                                 allMsil[i] = allEsil[i]/float(allOsil[i])*100.
81                                 allMpit[i] = allEpit[i]/float(allOpit[i])*100.
82                                 allMchr[i] = allEchr[i]/float(allOpit[i])*100.
83                                 self.v['Sil'], self.v['Pit'], self.v['Chr'] = allMsil[i], allMpit[i], allMchr[i]
84                                 self.v['Note'] = truth[i]
85                                 #self.printnames = self.printnames_notes
86                                 self.pretty_print()
87                         self.v['TotalSil'] = sum(allMsil)/len(truth)
88                         self.v['TotalPit'] = sum(allMpit)/len(truth)
89                         self.v['TotalChr'] = sum(allMchr)/len(truth)
90                         self.v['MinPit'] = min(truth) 
91                         self.v['MaxPit'] = max(truth) 
92                         #self.printnames = self.printnames_total
93                         #self.pretty_print()
94
95                         plot = []
96                         self.plotpitchtessiture(plot,
97                                 truth, 
98                                 allMpit,
99                                 plottitle="%s %s" % (self.v['mode'],self.params.bufsize),
100                                 plotmode='lines')
101                         """
102                         self.plotpitchtessiture(plot,
103                                 truth, 
104                                 allMchr,
105                                 plottitle="%s %s" % (self.v['mode'],"%12"),
106                                 plotmode='lines')
107                         self.plotpitchtessiture(plot,
108                                 truth, 
109                                 allMsil,
110                                 plottitle="%s %s" % (self.v['mode'],"sil"),
111                                 plotmode='lines')
112                         """
113                         title = basename(self.datadir)
114                         if multiplot:
115                                 d.append(plot)
116                         else:
117                                 d += plot
118                 outplot = "_-_".join(('pitchtessiture',title))
119                 self.xmin = min(self.v['truth']) #20.
120                 self.xmax = max(self.v['truth'])
121                 for ext in ('ps','png','svg'): #,''):
122                         self.plotplotpitchtessiture(d,
123                                 plottitle="".join(['Performance against MIDI Note number (',
124                                         title,
125                                         ", %s" % len(self.sndlist), " samples)"]),
126                                 outplot=outplot,
127                                 extension=ext,multiplot=multiplot)
128                 #d.append('beta = .25,orig(x) title \"-2 octave\"')
129                 #d.append('beta = .50,orig(x) title \"-1 octave\"')
130                 #d.append('beta = 1.0,orig(x) title \"original\"')
131                 #d.append('beta = 2.0,orig(x) title \"+1 octave\"')
132
133         """
134         Plot functions 
135         """
136
137         def plotpitchtessiture(self,d,lx,ly,plottitle="",plotmode='linespoints'):
138                 import Gnuplot, Gnuplot.funcutils
139                 d.append(Gnuplot.Data(lx, ly, with=plotmode, title="%s" % (plottitle) ))
140
141         def plotplotpitchtessiture(self,d,plottitle='',outplot=0,extension='',multiplot=1):
142                 from aubio.gnuplot import gnuplot_create
143                 g = gnuplot_create(outplot=outplot,extension=extension) 
144                 #g.title(plottitle)
145                 #g('orig(x) = beta*x')
146                 g.title(plottitle)
147                 g('set yrange [50:100]')
148                 # erase axis
149                 g('set xrange [%f:%f]' % (self.xmin,self.xmax)) #(self.xmax - (self.xmax-self.xmin)*5./4.,self.xmax))
150                 #g.plot(*d)
151                 g('set border 3')
152                 g('set xtics nomirror')
153                 g('set ytics nomirror')
154                 g('set key bottom')
155                 if multiplot:
156                         g('set multiplot')
157                         for i in range(len(d)):
158                                 # plot onset detection functions
159                                 g('set size   1,%f' % ( 1.0/float(len(d)) ) )
160                                 g('set origin 0,%f' % ( 1.0*float(len(d)-i-1)/float(len(d)) ) )
161                                 #g.ylabel('%Correct detections')
162                                 g('set xrange [%f:%f]' % (self.xmin,self.xmax)) #(self.xmax - (self.xmax-self.xmin)*5./4.,self.xmax))
163                                 g.plot(*d[i])
164                                 g('unset title')
165                         g('unset multiplot')
166                 else:
167                         g.plot(*d)
168
169
170 if __name__ == "__main__":
171         import sys
172         if len(sys.argv) > 1: datapath = sys.argv[1]
173         else: print "error: a path is required"; sys.exit(1)
174         if len(sys.argv) > 2:
175                 for each in sys.argv[3:-1]: print each
176         modes = ['schmitt', 'yin', 'yinfft', 'mcomb', 'fcomb']
177         #modes = ['mcomb']
178
179         params = taskparams()
180         params.bufsize = 2048 # 4096 
181         params.hopsize = 256
182         params.silence = -60.
183         params.pitchsmooth = 0 
184         params.pitchmax = 20000
185         params.pitchmin = 20
186         params.pitchyinfft = 0.95
187         benchpitch = benchpitch(datapath,params=params)
188         benchpitch.task = taskpitch
189
190         #benchpitch.titles  = [ 'mode', 'thres', 'avg', 'avgdist' ]
191         #benchpitch.formats = ["%12s" , "| %6s", "| %6s", "| %6s", "| %6s", "| %6s" ]
192         try:
193                 benchpitch.run_bench(modes=modes)
194         except KeyboardInterrupt:
195                 print "Interrupted by user"
196                 sys.exit(1)
197
198         sys.exit(0)