shithub: aubio

ref: f8a38c5cd73420c5106ee3f130ffde8cf0a1ee54
dir: /python/test/bench/pitch/bench-pitch/

View raw version
#! /usr/bin/python

from aubio.bench.node import *
from aubio.task import *

class benchpitch(bench):
	
	""" list of values to store per file """
	valuenames = ['mode']
	""" list of lists to store per file """
	valuelists = ['truth', 'osil', 'esil', 'opit', 'epit', 'echr', 
               'Msil', 'Mpit', 'Mchr']
	""" list of values to print per dir """
	printnames = [ 'mode', 'truth', 'Msil', 'Mpit', 'Mchr']

	""" per dir """
	formats = {'mode': "%12s" , 
		'truth': "%s",
		'osil': "%s", 'esil': "%s", 
		'opit': "%s", 'epit': "%s", 'echr': "%s",
		'Msil': "%s", 'Mpit': "%s", 'Mchr': "%s"}

	def dir_eval(self):
		""" evaluate statistical data over the directory """
		v = self.v
		v['mode']      = self.params.pitchmode

	def file_exec(self,input,output):
		filetask = self.task(input,params=self.params)
		computed_data = filetask.compute_all()
 		osil, esil, opit, epit, echr = filetask.eval(computed_data)
		self.v['truth'].append(int(filetask.truth))
		assert opit > 0
		
		self.v['osil'].append(osil)
		self.v['esil'].append(esil)
		self.v['opit'].append(opit)
		self.v['epit'].append(epit)
		self.v['echr'].append(echr)

		self.v['Msil'].append(esil/float(osil)*100.)
		self.v['Mpit'].append(epit/float(opit)*100.)
		self.v['Mchr'].append(echr/float(opit)*100.)
		#print results#, computed_data
		#print input, results, results - float(input.split('.')[-2])
			
	def run_bench(self,modes=['schmitt']):
		from os.path import basename
		self.modes = modes
		self.pretty_titles()
		d = []
		for mode in self.modes:
			self.params.pitchmode = mode
			self.dir_eval_print()
			truth   = [i for i in range(min(self.v['truth']),max(self.v['truth'])+1)]
			allOsil = [0 for i in range(min(self.v['truth']),max(self.v['truth'])+1)]
			allEsil = [0 for i in range(min(self.v['truth']),max(self.v['truth'])+1)]
			allOpit = [0 for i in range(min(self.v['truth']),max(self.v['truth'])+1)]
			allEpit = [0 for i in range(min(self.v['truth']),max(self.v['truth'])+1)]
			allEchr = [0 for i in range(min(self.v['truth']),max(self.v['truth'])+1)]
			allMsil = [0 for i in range(min(self.v['truth']),max(self.v['truth'])+1)]
			allMpit = [0 for i in range(min(self.v['truth']),max(self.v['truth'])+1)]
			allMchr = [0 for i in range(min(self.v['truth']),max(self.v['truth'])+1)]
			for i in range(len(self.v['truth'])):
				allOsil[self.v['truth'][i]-min(self.v['truth'])] += self.v['osil'][i]
				allEsil[self.v['truth'][i]-min(self.v['truth'])] += self.v['esil'][i]
				allOpit[self.v['truth'][i]-min(self.v['truth'])] += self.v['opit'][i]
				allEpit[self.v['truth'][i]-min(self.v['truth'])] += self.v['epit'][i]
				allEchr[self.v['truth'][i]-min(self.v['truth'])] += self.v['echr'][i]
			for i in range(len(truth)):
				allMsil[i] = allEsil[i]/float(allOsil[i])*100.
				allMpit[i] = allEpit[i]/float(allOpit[i])*100.
				allMchr[i] = allEchr[i]/float(allOpit[i])*100.

			plot = []
			self.plotpitchtessiture(plot,
				truth, 
				allMpit,
				plottitle="%s %s" % (self.v['mode'],self.params.bufsize),
				plotmode='lines')
			self.plotpitchtessiture(plot,
				truth, 
				allMchr,
				plottitle="%s %s" % (self.v['mode'],"%12"),
				plotmode='lines')
			"""
			self.plotpitchtessiture(plot,
				truth, 
				allMsil,
				plottitle="%s %s" % (self.v['mode'],"sil"),
				plotmode='lines')
			"""
			title = basename(self.datadir)
			d.append(plot)
		outplot = "_-_".join(('pitchtessiture',title))
		self.xmin = 20. #min(self.v['truth'])
		self.xmax = 110. #max(self.v['truth'])
		for ext in ('ps','png','svg',''):
			self.plotplotpitchtessiture(d,
				plottitle="".join(['Performance against MIDI Note number (',
					title,
					", %s" % len(self.sndlist), " samples)"]),
				outplot=outplot,
				extension=ext)
		#d.append('beta = .25,orig(x) title \"-2 octave\"')
		#d.append('beta = .50,orig(x) title \"-1 octave\"')
		#d.append('beta = 1.0,orig(x) title \"original\"')
		#d.append('beta = 2.0,orig(x) title \"+1 octave\"')

	"""
	Plot functions 
	"""

	def plotpitchtessiture(self,d,lx,ly,plottitle="",plotmode='linespoints'):
		import Gnuplot, Gnuplot.funcutils
		d.append(Gnuplot.Data(lx, ly, with=plotmode, title="%s" % (plottitle) ))

	def plotplotpitchtessiture(self,d,plottitle='',outplot=0,extension='',multiplot=1):
		from aubio.gnuplot import gnuplot_create
		g = gnuplot_create(outplot=outplot,extension=extension) 
		#g.title(plottitle)
		#g('orig(x) = beta*x')
		#g.xlabel('original pitch (Hz)')
		#g.ylabel('detected pitch (Hz)')
		#g('set key left top')
		#g('set log xy')
		#g('set xrange [50:2000]')
		g('set yrange [0:100]')
		#g.plot(*d)
		if multiplot:
			g('set multiplot')
			for i in range(len(d)):
				# plot onset detection functions
				g('set size   1,%f' % ( 1.0/float(len(d)) ) )
				g('set origin 0,%f' % ( 1.0*float(len(d)-i-1)/float(len(d)) ) )
				# erase axis
				g('set border 3')
				g('set xtics nomirror')
				g('set ytics nomirror')
				g('set key left top')
				g('set xrange [%f:%f]' % (self.xmin,self.xmax)) #(self.xmax - (self.xmax-self.xmin)*5./4.,self.xmax))
				#g.ylabel('%Correct detections')
				if i == len(d)-1:
					g.xlabel(plottitle)
				g.plot(*d[i])
				g('unset title')
			g('unset multiplot')
		else:
			g.plot(*d)


if __name__ == "__main__":
	import sys
	if len(sys.argv) > 1: datapath = sys.argv[1]
	else: print "error: a path is required"; sys.exit(1)
	if len(sys.argv) > 2:
		for each in sys.argv[3:-1]: print each
	modes = ['schmitt', 'yin', 'mcomb', 'fcomb']
	modes = ['schmitt', 'yin', 'fcomb']

	params = taskparams()
	params.bufsize = 2048 
	params.hopsize = params.bufsize/8
	params.silence = -60.
	params.pitchsmooth = 0 
	params.pitchmax = 20000
	params.pitchmin = 20
	benchpitch = benchpitch(datapath,params=params)
	benchpitch.task = taskpitch

	#benchpitch.titles  = [ 'mode', 'thres', 'avg', 'avgdist' ]
	#benchpitch.formats = ["%12s" , "| %6s", "| %6s", "| %6s", "| %6s", "| %6s" ]
	try:
		benchpitch.run_bench(modes=modes)
	except KeyboardInterrupt:
		print "Interrupted by user"
		sys.exit(1)

	sys.exit(0)