shithub: aubio

Download patch

ref: 54a2ca2f34f36fd9fedb79b07575541a68eee65c
parent: b712146c4cd22929e97320510e48d30e9145e9b4
parent: 59c4e5d37cb40cb0955859b29000ddfa9da73994
author: Paul Brossier <piem@piem.org>
date: Fri Mar 22 09:31:06 EDT 2013

merge from develop

--- a/doc/web.cfg
+++ b/doc/web.cfg
@@ -714,6 +714,7 @@
                          ../src/pitch/pitchschmitt.h \
                          ../src/pitch/pitchfcomb.h \
                          ../src/tempo/beattracking.h \
+                         ../src/utils/hist.h \
                          ../src/utils/scale.h \
                          ../src/utils.h
 
--- /dev/null
+++ b/python.old/tests_demo_bench/onset/bench-delay
@@ -1,0 +1,62 @@
+#! /usr/bin/python
+
+from aubio.bench.onset import benchonset
+from aubio.task.onset import taskonset
+from aubio.task.params import taskparams
+
+class mybenchonset(benchonset):
+
+	def run_bench(self,modes=['dual'],thresholds=[0.5]):
+		from os.path import dirname,basename
+		self.thresholds = thresholds
+		self.pretty_titles()
+
+		for mode in modes:
+			d = []
+			self.params.onsetmode = mode
+			self.params.localmin = True
+			self.params.delay = 1. 
+			self.params.threshold = thresholds[0]
+			#
+			self.params.localmin = False 
+			self.params.delay = 0. 
+			self.dir_eval_print()
+			self.plotdiffs(d,plottitle="Causal")
+			#
+			self.params.localmin = True
+			self.params.delay = 0. 
+			self.dir_eval_print()
+			self.plotdiffs(d,plottitle="Local min")
+
+			self.params.localmin = False 
+			self.params.delay = 6. 
+			self.dir_eval_print()
+			self.plotdiffs(d,plottitle="Fixed delay")
+
+			#self.plotplotdiffs(d)
+			outplot = "_-_".join(("delay",mode,basename(self.datadir) ))
+			for ext in ("png","svg","ps"):
+				self.plotplotdiffs(d,outplot=outplot,extension=ext)
+
+if __name__ == "__main__":
+	import sys
+	if len(sys.argv) > 1: datapath = sys.argv[1]
+	else: print "ERR: a path is required"; sys.exit(1)
+	modes = ['complex', 'energy', 'phase', 'hfc', 'specdiff', 'kl', 'mkl', 'dual']
+	#thresholds = [ 0.01, 0.05, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2]
+	#modes = [ 'hfc' ]
+	thresholds = [0.5]
+
+	#datapath = "%s%s" % (DATADIR,'/onset/DB/*/')
+	respath = '/var/tmp/DB-testings'
+
+	benchonset = mybenchonset(datapath,respath,checkres=True,checkanno=True)
+	benchonset.params = taskparams()
+	benchonset.task = taskonset
+	benchonset.valuesdict = {}
+
+	try:
+		#benchonset.auto_learn2(modes=modes)
+		benchonset.run_bench(modes=modes,thresholds=thresholds)
+	except KeyboardInterrupt:
+		sys.exit(1)
--- /dev/null
+++ b/python.old/tests_demo_bench/onset/bench-onset
@@ -1,0 +1,68 @@
+#! /usr/bin/python
+
+from aubio.task import *
+
+from aubio.bench.onset import mmean, stdev, benchonset
+
+class mybenchonset(benchonset):
+
+	def run_bench(self,modes=['dual'],thresholds=[0.5]):
+		from os.path import dirname,basename
+		self.thresholds = thresholds
+		self.pretty_titles()
+		d,e,f,g = [],[],[],[]
+		for mode in modes:
+			self.vlist = []
+			self.params.onsetmode = mode
+			#self.params.localmin = True
+
+			for threshold in self.thresholds:
+				self.params.threshold = threshold
+				self.dir_eval_print()
+				self.vlist.append(self.v)
+			self.plotroc(d)
+			self.plotfmeas(e)
+			self.plotpr(f)
+			#self.plothistcat(g)
+
+
+
+		#self.plotplotroc(d)
+		#self.plotplotfmeas(e)
+		#self.plotplotpr(f)
+		outplot = basename(self.datadir)
+		for ext in ("png","svg","ps"):
+			self.plotplotroc(d,outplot=outplot,extension=ext)
+			self.plotplotfmeas(e,outplot=outplot,extension=ext)
+			self.plotplotpr(f,outplot=outplot,extension=ext)
+			#self.plotplothistcat(g,outplot=outplot,extension=ext)
+
+if __name__ == "__main__":
+	import sys
+	if len(sys.argv) > 1: datapath = sys.argv[1]
+	else: print "ERR: a path is required"; sys.exit(1)
+	modes = ['complex', 'energy', 'phase', 'hfc', 'specdiff', 'kl', 'mkl', 'dual']
+	thresholds = [ 0.01, 0.05, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2]
+	#modes = [ 'hfc' ]
+	#thresholds = [0.5]
+
+	#datapath = "%s%s" % (DATADIR,'/onset/DB/*/')
+	respath = '/var/tmp/DB-testings'
+
+	benchonset = mybenchonset(datapath,respath,checkres=True,checkanno=True)
+	benchonset.params = taskparams()
+	benchonset.params.dcthreshold = -1.
+	benchonset.params.silence = -100.
+	benchonset.params.delay = 5. 
+	benchonset.params.bufsize = 1024 
+	benchonset.params.hopsize = 256 
+	benchonset.params.step = float(benchonset.params.hopsize)/float(benchonset.params.samplerate)
+	benchonset.params.mintol = 4.1 
+	benchonset.task = taskonset
+	benchonset.valuesdict = {}
+
+	try:
+		#benchonset.auto_learn2(modes=modes)
+		benchonset.run_bench(modes=modes,thresholds=thresholds)
+	except KeyboardInterrupt:
+		sys.exit(1)
--- /dev/null
+++ b/python.old/tests_demo_bench/onset/bench-window
@@ -1,0 +1,59 @@
+#! /usr/bin/python
+
+from aubio.bench.onset import benchonset
+from aubio.task.onset import taskonset
+from aubio.task.params import taskparams
+
+class mybenchonset(benchonset):
+
+	def run_bench(self,modes=['dual'],thresholds=[0.5]):
+		from os.path import dirname,basename
+		self.thresholds = thresholds
+		self.pretty_titles()
+
+		for mode in modes:
+
+			self.params.onsetmode = mode
+			self.params.localmin = True
+			self.params.delay = 1. 
+			self.params.threshold = thresholds[0]
+			self.params.localmin = False 
+			#
+			for delay in (0., 4.):
+				d = []
+				self.params.delay = delay 
+				for buf in (2048, 1024, 512):
+					for hop in (buf/2, buf/4):
+						self.params.bufsize = buf 
+						self.params.hopsize = hop 
+						self.params.step = float(self.params.hopsize)/float(self.params.samplerate)
+						self.dir_eval_print()
+						self.plotdiffs(d,plottitle="%s %s" % (buf,hop))
+				#plotplotdiffs(d)
+				outplot = "_-_".join(("window",mode,"delay-%s" % int(delay),
+					basename(self.datadir) ))
+				for ext in ("png","svg","ps"):
+					self.plotplotdiffs(d,outplot=outplot,extension=ext)
+
+if __name__ == "__main__":
+	import sys
+	if len(sys.argv) > 1: datapath = sys.argv[1]
+	else: print "ERR: a path is required"; sys.exit(1)
+	modes = ['complex', 'energy', 'phase', 'hfc', 'specdiff', 'kl', 'mkl', 'dual']
+	#thresholds = [ 0.01, 0.05, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2]
+	#modes = [ 'hfc' ]
+	thresholds = [0.5]
+
+	#datapath = "%s%s" % (DATADIR,'/onset/DB/*/')
+	respath = '/var/tmp/DB-testings'
+
+	benchonset = mybenchonset(datapath,respath,checkres=True,checkanno=True)
+	benchonset.params = taskparams()
+	benchonset.task = taskonset
+	benchonset.valuesdict = {}
+
+	try:
+		#benchonset.auto_learn2(modes=modes)
+		benchonset.run_bench(modes=modes,thresholds=thresholds)
+	except KeyboardInterrupt:
+		sys.exit(1)
--- /dev/null
+++ b/python.old/tests_demo_bench/pitch/bench-pitch-isolated
@@ -1,0 +1,198 @@
+#! /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',
+	       'TotalPit', 'TotalPit', 'TotalChr' ]
+	""" list of values to print per dir """
+	printnames_total = [ 'mode', 'MinPit', 'MaxPit', 'TotalSil', 'TotalPit', 'TotalChr']
+	printnames_notes = [ 'mode', 'Note', 'Sil', 'Pit', 'Chr']
+	printnames = printnames_notes 
+
+	""" per dir """
+	formats = {'mode': "%12s" , 
+		'truth': "%s",
+		'osil': "%s", 'esil': "%s", 
+		'opit': "%s", 'epit': "%s", 'echr': "%s",
+    'Note': "%s", 'Sil': "%s", 'Chr': "%s", 'Pit': "%s",
+		'TotalPit': "%s", 'TotalSil': "%s", 'TotalChr': "%s",
+		'MinPit': "%s", 'MaxPit': "%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,tol=0.5)
+		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'],multiplot=0):
+		from os.path import basename
+		self.modes = modes
+		self.pretty_titles()
+		d = []
+		for mode in self.modes:
+			self.params.pitchmode = mode
+			self.dir_exec()
+			self.dir_eval()
+			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)):
+				allOsil[i] = max(1,allOsil[i])
+				allOpit[i] = max(1,allOpit[i])
+				allMsil[i] = allEsil[i]/float(allOsil[i])*100.
+				allMpit[i] = allEpit[i]/float(allOpit[i])*100.
+				allMchr[i] = allEchr[i]/float(allOpit[i])*100.
+				self.v['Sil'], self.v['Pit'], self.v['Chr'] = allMsil[i], allMpit[i], allMchr[i]
+				self.v['Note'] = truth[i]
+				#self.printnames = self.printnames_notes
+				self.pretty_print()
+			self.v['TotalSil'] = sum(allMsil)/len(truth)
+			self.v['TotalPit'] = sum(allMpit)/len(truth)
+			self.v['TotalChr'] = sum(allMchr)/len(truth)
+			self.v['MinPit'] = min(truth) 
+			self.v['MaxPit'] = max(truth) 
+			#self.printnames = self.printnames_total
+			#self.pretty_print()
+
+			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)
+			if multiplot:
+				d.append(plot)
+			else:
+				d += plot
+		outplot = "_-_".join(('pitchtessiture',title))
+		self.xmin = min(self.v['truth']) #20.
+		self.xmax = 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,multiplot=multiplot)
+		#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.title(plottitle)
+		g('set yrange [50:100]')
+		# erase axis
+		g('set xrange [%f:%f]' % (self.xmin,self.xmax)) #(self.xmax - (self.xmax-self.xmin)*5./4.,self.xmax))
+		#g.plot(*d)
+		g('set border 3')
+		g('set xtics nomirror')
+		g('set ytics nomirror')
+		g('set key bottom')
+		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)) ) )
+				#g.ylabel('%Correct detections')
+				g('set xrange [%f:%f]' % (self.xmin,self.xmax)) #(self.xmax - (self.xmax-self.xmin)*5./4.,self.xmax))
+				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', 'yinfft', 'mcomb', 'fcomb']
+	#modes = ['mcomb']
+
+	params = taskparams()
+	params.bufsize = 2048 # 4096 
+	params.hopsize = 256
+	params.silence = -60.
+	params.pitchsmooth = 0 
+	params.pitchmax = 20000
+	params.pitchmin = 20
+	params.pitchyinfft = 0.95
+	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)
--- /dev/null
+++ b/python.old/tests_demo_bench/pitch/bench-pitch-plot-isolated
@@ -1,0 +1,63 @@
+#! /usr/bin/python
+
+if __name__ == '__main__':
+  import sys, Gnuplot
+  from aubio.gnuplot import gnuplot_create
+  from aubio.txtfile import read_datafile
+  from aubio.plot.keyboard import draw_keyboard
+  lines = []
+  titles = []
+  for file in range(len(sys.argv)-1):
+    l = read_datafile(sys.argv[file+1])
+    notes, score = [],[]
+    for i in range(len(l)):
+      notes.append(l[i][0])
+      score.append(l[i][2])
+    lines.append(Gnuplot.Data(notes,score,
+      with='linespoints',
+      title=sys.argv[file+1].split('.')[-1]))
+    titles.append(sys.argv[file+1].split('.')[-1])
+  blacks,whites = draw_keyboard(firstnote = notes[0], lastnote = notes[-1], 
+    y0= 40, y1 = 50)
+
+  g = gnuplot_create(sys.argv[file+1].split('.')[-3],'ps')
+  #g = gnuplot_create('','')
+  #g = gnuplot_create('/tmp/test','eps')
+  g('set yrange [40:100]')
+  #g('set xrange [%f:%f]' % (notes[0],notes[-1]+60))
+  g('set size 0.5')
+  g('set key outside')
+
+  g('set border 3')
+  g('set xtics nomirror')
+  g('set ytics nomirror')
+  multiplot = 1
+  oplots = lines
+  g('set size 1,2')
+  if multiplot:
+    height = 2.
+    g('set lmargin 10')
+    #g('set rmargin 15')
+    g('set multiplot')
+    g('set yrange [50:100]')
+    g('set xrange [%f:%f]' % (notes[0],notes[-1]))
+    g('set xtics %f,12' % notes[0])
+    g('set nokey')
+    for i in range(len(oplots)):
+      g.ylabel(titles[i])
+      g('set size %f,%f' % (1.,height*.85/float(len(oplots))))
+      g('set origin 0,%f' % (height*(.15+.85*float(len(oplots)-i-1)/float(len(oplots)))))
+      g.plot(oplots[i])
+    g('set title "Raw pitch accuracy (%) against midi note numbers"')
+    g('set noxtics')
+    g('set noytics')
+    g('set size %f,%f' % (1.,.15*height))
+    g('set origin 0,%f' % 0)
+    g('set yrange [40:50]')
+    g('set xrange [%f:%f]' % (notes[0],notes[-1]))
+    g.xlabel('')
+    g.ylabel('')
+    g.plot(whites,blacks)
+    g('unset multiplot')
+  else:
+    g.plot(whites,blacks,*lines)
--- /dev/null
+++ b/python.old/tests_demo_bench/tempo/demo-tempo
@@ -1,0 +1,313 @@
+#! /usr/bin/python
+
+""" this file was written by Paul Brossier 
+  it is released under the GNU/GPL license.
+"""
+
+import sys,time
+from aubio.task import taskbeat,taskparams
+from aubio.aubioclass import fvec, aubio_autocorr
+from aubio.gnuplot import gnuplot_create, gnuplot_addargs
+from aubio.aubiowrapper import *
+from math import exp,log
+
+usage = "usage: %s [options] -i soundfile" % sys.argv[0]
+
+def parse_args():
+        from optparse import OptionParser
+        parser = OptionParser(usage=usage)
+        parser.add_option("-i","--input",
+                          action="store", dest="filename", 
+                          help="input sound file")
+        parser.add_option("-n","--printframe",
+                          action="store", dest="printframe", default=-1, 
+                          help="make a plot of the n_th frame")
+        gnuplot_addargs(parser)
+        (options, args) = parser.parse_args()
+        if not options.filename: 
+                 print "no file name given\n", usage
+                 sys.exit(1)
+        return options, args
+
+def plotdata(x,y,plottitle="",**keyw):
+	import Gnuplot
+	return Gnuplot.Data(x, y, title="%s" % plottitle,**keyw)
+
+options, args = parse_args()
+filename = options.filename
+xsize = float(options.xsize)
+ysize = float(options.ysize)
+
+printframe = int(options.printframe)
+
+if options.outplot and printframe > 0: 
+  extension = options.outplot.split('.')[-1] 
+  outplot = '.'.join(options.outplot.split('.')[:-1])
+else: 
+  extension = ''
+  outplot = None
+f = gnuplot_create(outplot=outplot,extension=extension,options=options)
+
+params = taskparams()
+params.onsetmode = 'specdiff'
+task = taskbeat(filename,params=params)
+
+hopsize = params.hopsize
+bufsize = params.bufsize
+btstep = task.btstep
+winlen = task.btwinlen
+laglen = winlen/4
+step = winlen/4
+
+timesig = 0
+maxnumelem = 4
+gp = 0
+counter = 0
+flagconst = 0
+constthresh = 3.901
+g_var      = 3.901
+rp = 0
+rp1 = 0
+rp2 = 0
+g_mu = 0
+
+rayparam = 48/512.*winlen
+
+#t     = [i for i in range(hopsize)]
+#tlong = [i for i in range(hopsize*(btstep-1))]
+#tall  = [i for i in range(hopsize*btstep)]
+#a     = [0 for i in range(hopsize*btstep)]
+dfx = [i for i in range(winlen)]
+dfframe = [0 for i in range(winlen)]
+dfrev = [0 for i in range(winlen)]
+acframe = [0 for i in range(winlen)]
+
+localacf = [0 for i in range(winlen)]
+inds = [0 for i in range(maxnumelem)]
+
+acx = [i for i in range(laglen)]
+acfout  = [0 for i in range(laglen)]
+
+phwv  = [0 for i in range(2*laglen)]
+phwvx = [i for i in range(2*laglen)]
+
+dfwvnorm = exp(log(2.0)*(winlen+2.)/rayparam);
+dfwv = [exp(log(2.)*(i+1.)/rayparam)/dfwvnorm for i in range(winlen)]
+
+gwv = [exp(-.5*(j+1.-g_mu)**2/g_var**2) for j in range(laglen)]
+rwv = [(i+1.)/rayparam**2 * exp(-(i+1.)**2 / (2.*rayparam)**2)
+        for i in range(0,laglen)] 
+acf = fvec(winlen,1)
+
+nrframe = 0
+while (task.readsize == params.hopsize):
+  task()
+  #print task.pos2
+  #a[:-hopsize] = [i for i in a[-(btstep-1)*hopsize:]]
+  #a[-hopsize:] = [task.myvec.get(i,0) for i in t]
+
+  #g('set xrange [%f:%f]' % (t[0],t[-1]))
+  #time.sleep(.2)
+  if task.pos2==btstep-1:
+    nrframe += 1
+    dfframe = [task.dfframe.get(i,0) for i in range(winlen)]
+    if printframe == nrframe or printframe == -1:
+      d  = [[plotdata(range(-winlen,0),dfframe,plottitle="onset detection", with='lines')]]
+    # start beattracking_do
+    for i in range(winlen):
+      dfrev[winlen-1-i] = 0.
+      dfrev[winlen-1-i] = dfframe[i]*dfwv[i]
+    aubio_autocorr(task.dfframe(),acf()); 
+    acframe = [acf.get(i,0) for i in range(winlen)]
+    if not timesig:
+      numelem = 4
+    else:
+      numelem = timesig
+
+    old = 0
+    acfout = [0 for i in range(winlen/4)]
+    for i in range(1,laglen-1):
+      for a in range(1,numelem+1):
+        for b in range (1-a,a):
+          acfout[i] += acframe[a*(i+1)+b-1] * 1./(2.*a-1.)*rwv[i]
+          if old < acfout[i]:
+            old = acfout[i]
+            maxi = i
+    rp = max(maxi,1);
+
+    if printframe == nrframe or printframe == -1:
+      rwvs = [rwv[i]*max(acframe) for i in range(len(rwv))]
+      d += [[plotdata(acx,acfout,plottitle="comb filterbank", with='lines', axes='x1y1'),
+          plotdata([rp,rp],[1.2*old,min(acfout)],plottitle="period", with='impulses', axes='x1y1'),
+          plotdata(acx,rwvs,plottitle="L_w", with='lines', axes='x1y1')]]
+
+    # getperiod
+    inds = [0 for i in range(maxnumelem)]
+    localacf = [0 for i in range(winlen)]
+    period = 0
+    for a in range(1,4+1):
+      for b in range(1-a,a):
+        localacf[a*rp+b-1] = acframe[a*rp+b-1]
+    for i in range(numelem):
+      maxindex = 0
+      maxval = 0.0
+      for j in range(rp*(i+1)+i):
+        if localacf[j] > maxval:
+          maxval = localacf[j]
+          maxind = j
+        localacf[j] = 0
+      inds[i] = maxind
+    for i in range(numelem):
+      period += inds[i]/(i+1.)
+    period = period/numelem
+    #print "period", period
+
+    # checkstate 
+    if gp:
+      # context dependant model
+      acfout = [0 for i in range(winlen/4)]
+      old = 0
+      for i in range(laglen-1):
+        for a in range(timesig):
+          for b in range(1-a,a):
+            acfout[i] += acframe[a*(i+1)+b-1] * gwv[i]
+        if old < acfout[i]:
+          old = acfout[i]
+          maxi = i
+      gp = maxi
+    else:
+      # general model
+      gp = 0
+    #print "gp", gp
+    if printframe == nrframe or printframe == -1:
+      gwvs = [gwv[i]*max(acfout) for i in range(len(gwv))]
+      d += [[plotdata(acx,acfout,plottitle="comb filterbank", with='lines', axes='x1y1'),
+          plotdata(gp,old,plottitle="period", with='impulses', axes='x1y1'),
+          plotdata(acx,gwvs,plottitle="L_{gw}", with='lines', axes='x1y1')]]
+
+    if counter == 0:
+      # initial step
+      if abs(gp-rp) > 2.*constthresh:
+        flagstep = 1
+        counter  = 3
+      else:
+        flagstep = 0
+    #print "flagstep", flagstep
+    #print "rp2,rp1,rp", rp2,rp1,rp
+    acfw = [dfframe[i]*dfwv[i] for i in range(winlen)]
+
+    if counter == 1 and flagstep == 1:
+      # "3rd frame after flagstep set"
+      if abs(2.*rp-rp1- rp2) < constthresh:
+        flagconst = 1
+        counter = 0
+      else:
+        flagconst = 0
+        counter = 2
+    elif counter > 0:
+      counter -= 1
+
+    rp2 = rp1; rp1 = rp
+
+    if flagconst:
+      # "first run of new hypothesis"
+      gp = rp
+      g_mu = gp
+      timesig = 4 #FIXME
+      gwv = [exp(-.5*(j+1.-g_mu)**2/g_var**2) for j in range(laglen)]
+      flagconst = 0
+      bp = gp
+      phwv = [1 for i in range(2*laglen)]
+    elif timesig:
+      # "contex dependant"
+      bp = gp
+      if step > lastbeat:
+        phwv = [exp(-.5*(1.+j-step+lastbeat)**2/(bp/8.)) for j in range(2*laglen)]
+      else:
+        print "NOT using phase weighting"
+        phwv = [1 for i in range(2*laglen)]
+    else:
+      # "initial state"
+      bp = rp
+      phwv = [1 for i in range(2*laglen)]
+
+    while bp < 25:
+      print "WARNING, doubling the beat period"
+      bp *= 2
+
+    # 
+    phout = [0. for i in range(winlen)]
+
+    kmax = int(winlen/float(bp));
+
+    old = 0
+    for i in range(bp):
+      phout[i] = 0.
+      for k in range(kmax):
+        phout[i] += dfrev[i+bp*k] * phwv[i]
+      if phout[i] > old:
+        old = phout[i]
+        maxi = i
+    maxindex = maxi 
+    if (maxindex == winlen - 1): maxindex = 0
+    phase = 1 + maxindex
+    i = 1
+    beat = bp - phase
+    beats= []
+    if beat >= 0: beats.append(beat)
+    while beat+bp < step: 
+      beat += bp
+      beats.append(beat)
+    lastbeat = beat
+    #print beats,
+    #print "the lastbeat is", lastbeat
+
+    # plot all this
+    if printframe == nrframe or printframe == -1:
+      phwvs = [phwv[i]*max(phout) for i in range(len(phwv))]
+      d += [[plotdata(range(-laglen,0),phwvs[laglen:0:-1],plottitle="A_{gw}", with='lines',axes='x1y1'),
+          plotdata(range(-laglen,0),phout[laglen:0:-1],plottitle="df", with='lines'),
+          plotdata(-phase,old,plottitle="phase", with='impulses', axes='x1y1'),
+          plotdata([i for i in beats],[old for i in beats],plottitle="predicted", with='impulses')
+          ]]
+    #d += [[plotdata(dfx,dfwv,plottitle="phase weighting", with='lines', axes='x1y2'),
+    #    plotdata(dfx,dfrev,plottitle="df reverse", with='lines', axes='x1y1')]]
+    #d += [[plotdata(dfx,phout,plottitle="phase", with='lines', axes='x1y2')]]
+    #d += [[plotdata(dfx,dfwv,plottitle="phase weighting", with='lines', axes='x1y2'),
+    #    plotdata(dfx,dfrev,plottitle="df reverse", with='lines', axes='x1y1')]]
+    #d += [[plotdata(dfx,phout,plottitle="phase", with='lines', axes='x1y2')]]
+
+      f('set lmargin 4')
+      f('set rmargin 4')
+      f('set size %f,%f' % (1.0*xsize,1.0*ysize) )
+      f('set key spacing 1.3')
+      f('set multiplot')
+
+      f('set size %f,%f' % (1.0*xsize,0.33*ysize) )
+      f('set orig %f,%f' % (0.0*xsize,0.66*ysize) )
+      f('set xrange [%f:%f]' % (-winlen,0) )
+      f.title('Onset detection function')
+      f.xlabel('time (df samples)')
+      f.plot(*d[0])
+      f('set size %f,%f' % (0.5*xsize,0.33*ysize) )
+      f('set orig %f,%f' % (0.0*xsize,0.33*ysize) )
+      f('set xrange [%f:%f]' % (0,laglen) )
+      f.title('Period detection: Rayleygh weighting')
+      f.xlabel('lag (df samples)')
+      f.plot(*d[1])
+      f('set size %f,%f' % (0.5*xsize,0.33*ysize) )
+      f('set orig %f,%f' % (0.5*xsize,0.33*ysize) )
+      f('set xrange [%f:%f]' % (0,laglen) )
+      f.title('Period detection: Gaussian weighting')
+      f.xlabel('lag (df samples)')
+      f.plot(*d[2])
+      f('set size %f,%f' % (1.0*xsize,0.33*ysize) )
+      f('set orig %f,%f' % (0.0*xsize,0.00*ysize) )
+      f('set xrange [%f:%f]' % (-laglen,laglen) )
+      f.title('Phase detection and predicted beats')
+      f.xlabel('time (df samples)')
+      f.plot(*d[3])
+      f('set nomultiplot')
+    if printframe == -1: a = sys.stdin.read()
+    elif 0 < printframe and printframe < nrframe:
+      break
--- /dev/null
+++ b/python.old/tests_demo_bench/tempo/demo-tempo-acf
@@ -1,0 +1,157 @@
+#! /usr/bin/python
+
+""" this file was written by Paul Brossier 
+  it is released under the GNU/GPL license.
+"""
+
+import sys,time
+from aubio.task import taskbeat,taskparams
+from aubio.aubioclass import fvec, aubio_autocorr
+from aubio.gnuplot import gnuplot_create, gnuplot_addargs
+from aubio.aubiowrapper import *
+from math import exp,log
+
+usage = "usage: %s [options] -i soundfile" % sys.argv[0]
+
+def parse_args():
+        from optparse import OptionParser
+        parser = OptionParser(usage=usage)
+        parser.add_option("-i","--input",
+                          action="store", dest="filename", 
+                          help="input sound file")
+        parser.add_option("-n","--printframe",
+                          action="store", dest="printframe", default=-1, 
+                          help="make a plot of the n_th frame")
+        gnuplot_addargs(parser)
+        (options, args) = parser.parse_args()
+        if not options.filename: 
+                 print "no file name given\n", usage
+                 sys.exit(1)
+        return options, args
+
+def plotdata(x,y,plottitle="",**keyw):
+	import Gnuplot
+	return Gnuplot.Data(x, y, title="%s" % plottitle,**keyw)
+
+options, args = parse_args()
+filename = options.filename
+xsize = float(options.xsize)
+ysize = float(options.ysize)
+
+printframe = int(options.printframe)
+
+if options.outplot and printframe > 0: 
+  extension = options.outplot.split('.')[-1] 
+  outplot = '.'.join(options.outplot.split('.')[:-1])
+else: 
+  extension = ''
+  outplot = None
+f = gnuplot_create(outplot,extension,options)
+
+params = taskparams()
+params.onsetmode = 'specdiff'
+task = taskbeat(filename,params=params)
+
+hopsize = params.hopsize
+bufsize = params.bufsize
+btstep = task.btstep
+winlen = task.btwinlen
+laglen = winlen/4
+step = winlen/4
+
+timesig = 0
+maxnumelem = 4
+gp = 0
+counter = 0
+flagconst = 0
+constthresh = 3.901
+g_var      = 3.901
+rp = 0
+rp1 = 0
+rp2 = 0
+g_mu = 0
+
+rayparam = 48/512.*winlen
+
+t     = [i for i in range(hopsize)]
+#tlong = [i for i in range(hopsize*(btstep-1))]
+#tall  = [i for i in range(hopsize*btstep)]
+sig    = [0 for i in range(hopsize*btstep*4)]
+dfx = [i for i in range(winlen)]
+dfframe = [0 for i in range(winlen)]
+dfrev = [0 for i in range(winlen)]
+acframe = [0 for i in range(winlen/2)]
+
+localacf = [0 for i in range(winlen)]
+inds = [0 for i in range(maxnumelem)]
+
+acx = [i for i in range(laglen)]
+acfout  = [0 for i in range(laglen)]
+
+phwv  = [0 for i in range(2*laglen)]
+phwvx = [i for i in range(2*laglen)]
+
+dfwvnorm = exp(log(2.0)*(winlen+2.)/rayparam);
+dfwv = [exp(log(2.)*(i+1.)/rayparam)/dfwvnorm for i in range(winlen)]
+
+gwv = [exp(-.5*(j+1.-g_mu)**2/g_var**2) for j in range(laglen)]
+rwv = [(i+1.)/rayparam**2 * exp(-(i+1.)**2 / (2.*rayparam)**2)
+        for i in range(0,laglen)] 
+acf = fvec(winlen,1)
+
+nrframe = 0
+while (task.readsize == params.hopsize):
+  task()
+  #print task.pos2
+  sig[:-hopsize] = [i for i in sig[-(btstep*4-1)*hopsize:]]
+  sig[-hopsize:] = [task.myvec.get(i,0) for i in t]
+
+  #g('set xrange [%f:%f]' % (t[0],t[-1]))
+  #time.sleep(.2)
+  if task.pos2==btstep-1:
+    nrframe += 1
+    dfframe = [task.dfframe.get(i,0) for i in range(winlen)]
+    # start beattracking_do
+    for i in range(winlen):
+      dfrev[winlen-1-i] = 0.
+      dfrev[winlen-1-i] = dfframe[i]*dfwv[i]
+    aubio_autocorr(task.dfframe(),acf()); 
+    acframe = [acf.get(i,0) for i in range(winlen/2)]
+    if printframe == nrframe or printframe == -1:
+      d  = [[plotdata(range(0,btstep*hopsize*4,4),sig[0:-1:4],plottitle="input signal", with='lines')]]
+      d  += [[plotdata(range(-winlen,0),dfframe,plottitle="onset detection", with='lines')]]
+      d  += [[plotdata(range(winlen/2),acframe,plottitle="autocorrelation", with='lines')]]
+
+    # plot all this
+    if printframe == nrframe or printframe == -1:
+
+      f('set lmargin 4')
+      f('set rmargin 4')
+      f('set size %f,%f' % (1.0*xsize,1.0*ysize) )
+      f('set key spacing 1.3')
+      f('set multiplot')
+
+      f('set size %f,%f' % (1.0*xsize,0.33*ysize) )
+      f('set orig %f,%f' % (0.0*xsize,0.66*ysize) )
+      f('set xrange [%f:%f]' % (0,btstep*hopsize*4) )
+      f('set yrange [%f:%f]' % (-1.2*max(sig),1.2*max(sig)) )
+      f.title('Input signal')
+      f.xlabel('time (samples)')
+      f.plot(*d[0])
+      f('set size %f,%f' % (1.0*xsize,0.33*ysize) )
+      f('set orig %f,%f' % (0.0*xsize,0.33*ysize) )
+      f('set xrange [%f:%f]' % (-winlen,0) )
+      f('set autoscale y')
+      f.title('Onset detection function')
+      f.xlabel('time (df samples)')
+      f.plot(*d[1])
+      f('set size %f,%f' % (1.0*xsize,0.33*ysize) )
+      f('set orig %f,%f' % (0.0*xsize,0.00*ysize) )
+      f('set xrange [%f:%f]' % (0,winlen/2) )
+      f.title('Autocorrelation')
+      f.xlabel('lag (df samples)')
+      f.plot(*d[2])
+      f('set nomultiplot')
+    if printframe == -1: a = sys.stdin.read()
+    elif 0 < printframe and printframe < nrframe:
+      break
--- /dev/null
+++ b/python.old/tests_examples/aubioonset.py
@@ -1,0 +1,41 @@
+from template import program_test_case
+
+class aubioonset_unit(program_test_case):
+  
+  import os.path
+  filename = os.path.join('..','..','sounds','woodblock.aiff')
+  progname = os.path.join('..','..','examples','aubioonset')
+
+  def test_aubioonset_with_inf_silence(self):
+    """ test aubioonset with -s 0  """
+    self.command += " -s 0" 
+    self.getOutput()
+    assert len(self.output) == 0, self.output
+
+class aubioonset_unit_finds_onset(aubioonset_unit):
+
+  def test_aubioonset(self):
+    """ test aubioonset with default parameters """
+    self.getOutput()
+    assert len(str(self.output)) != 0, "no output produced with command:\n" \
+      + self.command
+
+  def test_aubioonset_with_no_silence(self):
+    """ test aubioonset with -s -100 """ 
+    self.command += " -s -100 " 
+    self.getOutput()
+    # only one onset in woodblock.aiff
+    self.assertNotEqual(0, len(str(self.output)), \
+      "no output produced with command:\n" + self.command)
+    self.assertEqual(1, len(self.output.split('\n')) )
+    # onset should be at 0.00000
+    self.assertEqual(0, float(self.output.strip()))
+
+list_of_onset_modes = ["energy", "specdiff", "hfc", "complex", "phase", \
+                      "kl", "mkl", "specflux"]
+
+for name in list_of_onset_modes:
+  exec("class aubioonset_"+name+"_unit(aubioonset_unit):\n\
+  options = \" -O "+name+" \"")
+
+if __name__ == '__main__': unittest.main()
--- /dev/null
+++ b/python.old/tests_examples/aubiopitch.py
@@ -1,0 +1,69 @@
+from template import *
+
+import os.path
+
+class aubiopitch_test_case(program_test_case):
+
+  import os.path
+  filename = os.path.join('..','..','sounds','woodblock.aiff')
+  progname = "PYTHONPATH=../../python:../../python/aubio/.libs " + \
+              os.path.join('..','..','python','aubiopitch')
+
+  def test_aubiopitch(self):
+    """ test aubiopitch with default parameters """
+    self.getOutput()
+    # FIXME: useless check
+    self.assertEqual(len(self.output.split('\n')), 1)
+    #self.assertEqual(float(self.output.strip()), 0.)
+
+  def test_aubiopitch_verbose(self):
+    """ test aubiopitch with -v parameter """
+    self.command += " -v "
+    self.getOutput()
+    # FIXME: loose checking: make sure at least 8 lines are printed
+    assert len(self.output) >= 8
+
+  def test_aubiopitch_devnull(self):
+    """ test aubiopitch on /dev/null """
+    self.filename = "/dev/null"
+    # exit status should not be 0
+    self.getOutput(expected_status = 256)
+    # and there should be an error message
+    assert len(self.output) > 0
+    # that looks like this 
+    output_lines = self.output.split('\n')
+    #assert output_lines[0] == "Unable to open input file /dev/null."
+    #assert output_lines[1] == "Supported file format but file is malformed."
+    #assert output_lines[2] == "Could not open input file /dev/null."
+
+mode_names = ["yinfft", "yin", "fcomb", "mcomb", "schmitt"]
+for name in mode_names:
+  exec("class aubiopitch_test_case_" + name + "(aubiopitch_test_case):\n\
+    options = \" -m " + name + " \"")
+
+class aubiopitch_test_yinfft(program_test_case):
+
+  filename = os.path.join('..','..','sounds','16568__acclivity__TwoCows.wav')
+  url = "http://www.freesound.org/samplesViewSingle.php?id=16568"
+  progname = "PYTHONPATH=../../python:../../python/aubio/.libs " + \
+              os.path.join('..','..','python','aubiopitch')
+  options  = " -m yinfft -t 0.75 "
+
+  def test_aubiopitch(self):
+    """ test aubiopitch with default parameters """
+    if not os.path.isfile(self.filename):
+      print "Warning: file 16568_acclivity_TwoCows.wav was not found in %s" % os.path.dirname(self.filename) 
+      print "download it from %s to actually run test" % url
+      return
+    self.getOutput()
+    expected_output = open(os.path.join('examples','aubiopitch','yinfft'+'.'+os.path.basename(self.filename)+'.txt')).read()
+    lines = 0
+    for line_out, line_exp in zip(self.output.split('\n'), expected_output.split('\n')):
+      try:
+        assert line_exp == line_out, line_exp + " vs. " + line_out + " at line " + str(lines)
+      except:
+        open(os.path.join('examples','aubiopitch','yinfft'+'.'+os.path.basename(self.filename)+'.txt.out'),'w').write(self.output)
+        raise
+      lines += 1
+
+if __name__ == '__main__': unittest.main()
--- /dev/null
+++ b/python.old/tests_examples/aubiopitch/yinfft.16568__acclivity__TwoCows.wav.txt
@@ -1,0 +1,566 @@
+0.0232199546485	-1.0
+0.0464399092971	-1.0
+0.0696598639456	-1.0
+0.0928798185941	-1.0
+0.116099773243	-1.0
+0.139319727891	-1.0
+0.16253968254	-1.0
+0.185759637188	-1.0
+0.208979591837	-1.0
+0.232199546485	-1.0
+0.255419501134	-1.0
+0.278639455782	-1.0
+0.301859410431	-1.0
+0.325079365079	-1.0
+0.348299319728	-1.0
+0.371519274376	-1.0
+0.394739229025	-1.0
+0.417959183673	-1.0
+0.441179138322	-1.0
+0.464399092971	-1.0
+0.487619047619	-1.0
+0.510839002268	-1.0
+0.534058956916	-1.0
+0.557278911565	-1.0
+0.580498866213	-1.0
+0.603718820862	-1.0
+0.62693877551	-1.0
+0.650158730159	-1.0
+0.673378684807	-1.0
+0.696598639456	-1.0
+0.719818594104	-1.0
+0.743038548753	-1.0
+0.766258503401	-1.0
+0.78947845805	-1.0
+0.812698412698	-1.0
+0.835918367347	-1.0
+0.859138321995	-1.0
+0.882358276644	-1.0
+0.905578231293	-1.0
+0.928798185941	-1.0
+0.95201814059	-1.0
+0.975238095238	-1.0
+0.998458049887	-1.0
+1.02167800454	-1.0
+1.04489795918	-1.0
+1.06811791383	392.768096924
+1.09133786848	115.522140503
+1.11455782313	116.574150085
+1.13777777778	117.720863342
+1.16099773243	120.00163269
+1.18421768707	123.633300781
+1.20743764172	426.787963867
+1.23065759637	141.312179565
+1.25387755102	144.336975098
+1.27709750567	148.604934692
+1.30031746032	150.864654541
+1.32353741497	154.889007568
+1.34675736961	156.505081177
+1.36997732426	158.878829956
+1.39319727891	160.931289673
+1.41641723356	163.155059814
+1.43963718821	324.814025879
+1.46285714286	167.016983032
+1.48607709751	168.871704102
+1.50929705215	170.665634155
+1.5325170068	172.353149414
+1.55573696145	174.764205933
+1.5789569161	176.318893433
+1.60217687075	178.282669067
+1.6253968254	179.82383728
+1.64861678005	181.488952637
+1.67183673469	183.1927948
+1.69505668934	184.449371338
+1.71827664399	185.715484619
+1.74149659864	186.702224731
+1.76471655329	187.907455444
+1.78793650794	188.703475952
+1.81115646259	189.502182007
+1.83437641723	190.250213623
+1.85759637188	190.834747314
+1.88081632653	190.98348999
+1.90403628118	190.847137451
+1.92725623583	190.805847168
+1.95047619048	191.00831604
+1.97369614512	191.377182007
+1.99691609977	191.935241699
+2.02013605442	192.395782471
+2.04335600907	192.534378052
+2.06657596372	192.404174805
+2.08979591837	192.085708618
+2.11301587302	191.410400391
+2.13623582766	191.070388794
+2.15945578231	190.677963257
+2.18267573696	190.020675659
+2.20589569161	189.669265747
+2.22911564626	189.298828125
+2.25233560091	188.546142578
+2.27555555556	186.856491089
+2.2987755102	184.917297363
+2.32199546485	183.044509888
+2.3452154195	181.399368286
+2.36843537415	179.126312256
+2.3916553288	175.22946167
+2.41487528345	171.139190674
+2.4380952381	338.55368042
+2.46131519274	162.799713135
+2.48453514739	320.075500488
+2.50775510204	148.602432251
+2.53097505669	139.503982544
+2.55419501134	340.922271729
+2.57741496599	326.436950684
+2.60063492063	333.484558105
+2.62385487528	-1.0
+2.64707482993	-1.0
+2.67029478458	-1.0
+2.69351473923	-1.0
+2.71673469388	-1.0
+2.73995464853	-1.0
+2.76317460317	-1.0
+2.78639455782	-1.0
+2.80961451247	-1.0
+2.83283446712	-1.0
+2.85605442177	-1.0
+2.87927437642	-1.0
+2.90249433107	-1.0
+2.92571428571	-1.0
+2.94893424036	-1.0
+2.97215419501	-1.0
+2.99537414966	-1.0
+3.01859410431	-1.0
+3.04181405896	-1.0
+3.06503401361	-1.0
+3.08825396825	-1.0
+3.1114739229	-1.0
+3.13469387755	-1.0
+3.1579138322	-1.0
+3.18113378685	-1.0
+3.2043537415	-1.0
+3.22757369615	-1.0
+3.25079365079	-1.0
+3.27401360544	-1.0
+3.29723356009	-1.0
+3.32045351474	-1.0
+3.34367346939	-1.0
+3.36689342404	-1.0
+3.39011337868	-1.0
+3.41333333333	-1.0
+3.43655328798	-1.0
+3.45977324263	-1.0
+3.48299319728	-1.0
+3.50621315193	-1.0
+3.52943310658	-1.0
+3.55265306122	-1.0
+3.57587301587	-1.0
+3.59909297052	-1.0
+3.62231292517	-1.0
+3.64553287982	-1.0
+3.66875283447	-1.0
+3.69197278912	-1.0
+3.71519274376	-1.0
+3.73841269841	-1.0
+3.76163265306	-1.0
+3.78485260771	-1.0
+3.80807256236	-1.0
+3.83129251701	-1.0
+3.85451247166	-1.0
+3.8777324263	-1.0
+3.90095238095	-1.0
+3.9241723356	-1.0
+3.94739229025	-1.0
+3.9706122449	-1.0
+3.99383219955	-1.0
+4.0170521542	-1.0
+4.04027210884	-1.0
+4.06349206349	-1.0
+4.08671201814	-1.0
+4.10993197279	-1.0
+4.13315192744	-1.0
+4.15637188209	-1.0
+4.17959183673	-1.0
+4.20281179138	-1.0
+4.22603174603	-1.0
+4.24925170068	-1.0
+4.27247165533	-1.0
+4.29569160998	-1.0
+4.31891156463	-1.0
+4.34213151927	-1.0
+4.36535147392	-1.0
+4.38857142857	-1.0
+4.41179138322	-1.0
+4.43501133787	-1.0
+4.45823129252	-1.0
+4.48145124717	-1.0
+4.50467120181	-1.0
+4.52789115646	-1.0
+4.55111111111	-1.0
+4.57433106576	-1.0
+4.59755102041	-1.0
+4.62077097506	-1.0
+4.64399092971	-1.0
+4.66721088435	-1.0
+4.690430839	-1.0
+4.71365079365	-1.0
+4.7368707483	-1.0
+4.76009070295	-1.0
+4.7833106576	-1.0
+4.80653061224	-1.0
+4.82975056689	-1.0
+4.85297052154	-1.0
+4.87619047619	-1.0
+4.89941043084	-1.0
+4.92263038549	-1.0
+4.94585034014	-1.0
+4.96907029478	-1.0
+4.99229024943	-1.0
+5.01551020408	-1.0
+5.03873015873	-1.0
+5.06195011338	-1.0
+5.08517006803	-1.0
+5.10839002268	-1.0
+5.13160997732	-1.0
+5.15482993197	-1.0
+5.17804988662	-1.0
+5.20126984127	-1.0
+5.22448979592	-1.0
+5.24770975057	-1.0
+5.27092970522	-1.0
+5.29414965986	-1.0
+5.31736961451	-1.0
+5.34058956916	-1.0
+5.36380952381	-1.0
+5.38702947846	-1.0
+5.41024943311	-1.0
+5.43346938776	-1.0
+5.4566893424	-1.0
+5.47990929705	-1.0
+5.5031292517	-1.0
+5.52634920635	-1.0
+5.549569161	-1.0
+5.57278911565	-1.0
+5.59600907029	-1.0
+5.61922902494	-1.0
+5.64244897959	-1.0
+5.66566893424	-1.0
+5.68888888889	-1.0
+5.71210884354	-1.0
+5.73532879819	-1.0
+5.75854875283	-1.0
+5.78176870748	-1.0
+5.80498866213	-1.0
+5.82820861678	-1.0
+5.85142857143	-1.0
+5.87464852608	-1.0
+5.89786848073	-1.0
+5.92108843537	-1.0
+5.94430839002	-1.0
+5.96752834467	-1.0
+5.99074829932	-1.0
+6.01396825397	-1.0
+6.03718820862	-1.0
+6.06040816327	-1.0
+6.08362811791	-1.0
+6.10684807256	-1.0
+6.13006802721	-1.0
+6.15328798186	-1.0
+6.17650793651	-1.0
+6.19972789116	-1.0
+6.2229478458	-1.0
+6.24616780045	-1.0
+6.2693877551	-1.0
+6.29260770975	-1.0
+6.3158276644	-1.0
+6.33904761905	-1.0
+6.3622675737	-1.0
+6.38548752834	-1.0
+6.40870748299	-1.0
+6.43192743764	-1.0
+6.45514739229	-1.0
+6.47836734694	-1.0
+6.50158730159	187.887435913
+6.52480725624	143.988250732
+6.54802721088	147.904678345
+6.57124716553	151.674087524
+6.59446712018	3221.32983398
+6.61768707483	3159.02587891
+6.64090702948	160.395706177
+6.66412698413	162.535690308
+6.68734693878	164.282516479
+6.71056689342	166.054779053
+6.73378684807	167.578659058
+6.75700680272	169.234619141
+6.78022675737	171.029663086
+6.80344671202	173.257110596
+6.82666666667	174.64654541
+6.84988662132	175.149429321
+6.87310657596	175.456039429
+6.89632653061	176.283660889
+6.91954648526	177.318511963
+6.94276643991	178.066696167
+6.96598639456	178.517211914
+6.98920634921	179.053573608
+7.01242630385	179.549285889
+7.0356462585	180.029403687
+7.05886621315	180.64515686
+7.0820861678	180.8934021
+7.10530612245	180.952774048
+7.1285260771	181.48147583
+7.15174603175	182.092208862
+7.17496598639	183.082504272
+7.19818594104	183.907089233
+7.22140589569	184.607666016
+7.24462585034	185.0181427
+7.26784580499	185.282440186
+7.29106575964	185.946502686
+7.31428571429	186.74571228
+7.33750566893	187.205505371
+7.36072562358	187.595703125
+7.38394557823	187.939483643
+7.40716553288	188.01159668
+7.43038548753	187.807418823
+7.45360544218	187.751464844
+7.47682539683	187.811416626
+7.50004535147	187.951507568
+7.52326530612	188.168029785
+7.54648526077	188.630828857
+7.56970521542	188.946014404
+7.59292517007	189.095901489
+7.61614512472	189.302886963
+7.63936507937	189.673339844
+7.66258503401	189.881591797
+7.68580498866	189.865234375
+7.70902494331	189.865234375
+7.73224489796	189.595870972
+7.75546485261	188.954116821
+7.77868480726	188.192108154
+7.8019047619	187.352645874
+7.82512471655	186.524551392
+7.8483446712	184.967712402
+7.87156462585	183.589355469
+7.8947845805	182.828231812
+7.91800453515	181.968215942
+7.9412244898	180.796981812
+7.96444444444	180.0
+7.98766439909	179.184524536
+8.01088435374	178.799484253
+8.03410430839	178.29347229
+8.05732426304	178.088272095
+8.08054421769	177.894317627
+8.10376417234	177.693618774
+8.12698412698	177.905075073
+8.15020408163	178.041549683
+8.17342403628	178.045135498
+8.19664399093	177.650650024
+8.21986394558	177.32208252
+8.24308390023	176.611938477
+8.26630385488	175.525878906
+8.28952380952	172.121078491
+8.31274376417	584.997009277
+8.33596371882	575.042358398
+8.35918367347	465.681121826
+8.38240362812	447.307037354
+8.40562358277	-1.0
+8.42884353741	-1.0
+8.45206349206	-1.0
+8.47528344671	-1.0
+8.49850340136	-1.0
+8.52172335601	-1.0
+8.54494331066	-1.0
+8.56816326531	-1.0
+8.59138321995	-1.0
+8.6146031746	-1.0
+8.63782312925	-1.0
+8.6610430839	-1.0
+8.68426303855	-1.0
+8.7074829932	-1.0
+8.73070294785	-1.0
+8.75392290249	-1.0
+8.77714285714	-1.0
+8.80036281179	-1.0
+8.82358276644	-1.0
+8.84680272109	-1.0
+8.87002267574	-1.0
+8.89324263039	-1.0
+8.91646258503	-1.0
+8.93968253968	-1.0
+8.96290249433	-1.0
+8.98612244898	-1.0
+9.00934240363	-1.0
+9.03256235828	-1.0
+9.05578231293	-1.0
+9.07900226757	-1.0
+9.10222222222	-1.0
+9.12544217687	-1.0
+9.14866213152	-1.0
+9.17188208617	-1.0
+9.19510204082	-1.0
+9.21832199546	-1.0
+9.24154195011	-1.0
+9.26476190476	-1.0
+9.28798185941	-1.0
+9.31120181406	-1.0
+9.33442176871	-1.0
+9.35764172336	-1.0
+9.380861678	-1.0
+9.40408163265	-1.0
+9.4273015873	-1.0
+9.45052154195	-1.0
+9.4737414966	-1.0
+9.49696145125	-1.0
+9.5201814059	-1.0
+9.54340136054	-1.0
+9.56662131519	-1.0
+9.58984126984	-1.0
+9.61306122449	-1.0
+9.63628117914	-1.0
+9.65950113379	-1.0
+9.68272108844	-1.0
+9.70594104308	-1.0
+9.72916099773	-1.0
+9.75238095238	-1.0
+9.77560090703	-1.0
+9.79882086168	-1.0
+9.82204081633	-1.0
+9.84526077098	-1.0
+9.86848072562	-1.0
+9.89170068027	-1.0
+9.91492063492	-1.0
+9.93814058957	-1.0
+9.96136054422	-1.0
+9.98458049887	-1.0
+10.0078004535	-1.0
+10.0310204082	-1.0
+10.0542403628	-1.0
+10.0774603175	-1.0
+10.1006802721	-1.0
+10.1239002268	-1.0
+10.1471201814	-1.0
+10.1703401361	-1.0
+10.1935600907	-1.0
+10.2167800454	-1.0
+10.24	-1.0
+10.2632199546	-1.0
+10.2864399093	100.193115234
+10.3096598639	-1.0
+10.3328798186	326.038757324
+10.3560997732	104.222053528
+10.3793197279	105.370048523
+10.4025396825	106.595123291
+10.4257596372	107.893875122
+10.4489795918	108.992500305
+10.4721995465	109.93119812
+10.4954195011	110.819335938
+10.5186394558	112.031303406
+10.5418594104	113.389472961
+10.5650793651	114.239830017
+10.5882993197	116.827377319
+10.6115192744	119.250427246
+10.634739229	122.184356689
+10.6579591837	148.222839355
+10.6811791383	150.104660034
+10.704399093	153.361968994
+10.7276190476	155.115112305
+10.7508390023	158.433624268
+10.7740589569	161.372955322
+10.7972789116	163.421096802
+10.8204988662	167.165771484
+10.8437188209	170.329452515
+10.8669387755	173.311584473
+10.8901587302	175.445571899
+10.9133786848	177.304244995
+10.9365986395	179.024490356
+10.9598185941	180.073501587
+10.9830385488	180.826629639
+11.0062585034	181.559936523
+11.029478458	182.487792969
+11.0526984127	183.303192139
+11.0759183673	183.976135254
+11.099138322	184.650161743
+11.1223582766	185.613876343
+11.1455782313	186.123062134
+11.1687981859	186.852523804
+11.1920181406	187.531890869
+11.2152380952	188.232284546
+11.2384580499	189.20135498
+11.2616780045	189.485900879
+11.2848979592	190.094390869
+11.3081179138	190.636749268
+11.3313378685	191.252670288
+11.3545578231	191.647476196
+11.3777777778	192.673187256
+11.4009977324	193.018920898
+11.4242176871	193.641860962
+11.4474376417	194.307373047
+11.4706575964	194.234619141
+11.493877551	194.290252686
+11.5170975057	194.641845703
+11.5403174603	194.663314819
+11.563537415	194.719177246
+11.5867573696	194.149108887
+11.6099773243	194.166213989
+11.6331972789	194.136291504
+11.6564172336	193.786529541
+11.6796371882	192.605865479
+11.7028571429	190.785202026
+11.7260770975	188.578399658
+11.7492970522	182.544433594
+11.7725170068	173.676742554
+11.7957369615	415.019744873
+11.8189569161	417.989685059
+11.8421768707	333.699066162
+11.8653968254	415.058837891
+11.88861678	352.025543213
+11.9118367347	-1.0
+11.9350566893	-1.0
+11.958276644	-1.0
+11.9814965986	-1.0
+12.0047165533	-1.0
+12.0279365079	-1.0
+12.0511564626	-1.0
+12.0743764172	-1.0
+12.0975963719	-1.0
+12.1208163265	-1.0
+12.1440362812	-1.0
+12.1672562358	-1.0
+12.1904761905	-1.0
+12.2136961451	-1.0
+12.2369160998	-1.0
+12.2601360544	-1.0
+12.2833560091	-1.0
+12.3065759637	-1.0
+12.3297959184	-1.0
+12.353015873	-1.0
+12.3762358277	-1.0
+12.3994557823	-1.0
+12.422675737	-1.0
+12.4458956916	-1.0
+12.4691156463	-1.0
+12.4923356009	-1.0
+12.5155555556	-1.0
+12.5387755102	-1.0
+12.5619954649	-1.0
+12.5852154195	-1.0
+12.6084353741	-1.0
+12.6316553288	-1.0
+12.6548752834	-1.0
+12.6780952381	-1.0
+12.7013151927	-1.0
+12.7245351474	-1.0
+12.747755102	-1.0
+12.7709750567	-1.0
+12.7941950113	-1.0
+12.817414966	-1.0
+12.8406349206	-1.0
+12.8638548753	-1.0
+12.8870748299	-1.0
+12.9102947846	-1.0
+12.9335147392	-1.0
+12.9567346939	-1.0
+12.9799546485	-1.0
+13.0031746032	-1.0
+13.0263945578	-1.0
+13.0496145125	-1.0
+13.0728344671	-1.0
+13.0960544218	-1.0
+13.1192743764	-1.0
+13.1424943311	-1.0
--- /dev/null
+++ b/python/demos/demo_mel-energy.py
@@ -1,0 +1,70 @@
+#! /usr/bin/env python
+
+import sys
+from aubio import fvec, source, pvoc, filterbank
+from numpy import vstack, zeros
+
+win_s = 512                 # fft size
+hop_s = win_s / 4           # hop size
+
+if len(sys.argv) < 2:
+    print "Usage: %s <filename> [samplerate]" % sys.argv[0]
+    sys.exit(1)
+
+filename = sys.argv[1]
+
+samplerate = 0
+if len( sys.argv ) > 2: samplerate = int(sys.argv[2])
+
+s = source(filename, samplerate, hop_s)
+samplerate = s.samplerate
+
+pv = pvoc(win_s, hop_s)
+
+f = filterbank(40, win_s)
+f.set_mel_coeffs_slaney(samplerate)
+
+energies = zeros((40,))
+o = {}
+
+total_frames = 0
+downsample = 2
+
+while True:
+    samples, read = s()
+    fftgrain = pv(samples)
+    new_energies = f(fftgrain)
+    print '%f' % (total_frames / float(samplerate) ),
+    print ' '.join(['%f' % b for b in new_energies])
+    energies = vstack( [energies, new_energies] )
+    total_frames += read
+    if read < hop_s: break
+
+if 1:
+    print "done computing, now plotting"
+    import matplotlib.pyplot as plt
+    from demo_waveform_plot import get_waveform_plot
+    from demo_waveform_plot import set_xlabels_sample2time
+    fig = plt.figure()
+    plt.rc('lines',linewidth='.8')
+    wave = plt.axes([0.1, 0.75, 0.8, 0.19])
+    get_waveform_plot(filename, samplerate, block_size = hop_s, ax = wave )
+    wave.yaxis.set_visible(False)
+    wave.xaxis.set_visible(False)
+
+    n_plots = len(energies.T)
+    all_desc_times = [ x * hop_s  for x in range(len(energies)) ]
+    for i, band in enumerate(energies.T):
+        ax = plt.axes ( [0.1, 0.75 - ((i+1) * 0.65 / n_plots),  0.8, 0.65 / n_plots], sharex = wave )
+        ax.plot(all_desc_times, band, '-', label = 'band %d' % i)
+        #ax.set_ylabel(method, rotation = 0)
+        ax.xaxis.set_visible(False)
+        ax.yaxis.set_visible(False)
+        ax.axis(xmax = all_desc_times[-1], xmin = all_desc_times[0])
+        ax.annotate('band %d' % i, xy=(-10, 10),  xycoords='axes points',
+                horizontalalignment='right', verticalalignment='bottom',
+                )
+    set_xlabels_sample2time( ax, all_desc_times[-1], samplerate) 
+    #plt.ylabel('spectral descriptor value')
+    ax.xaxis.set_visible(True)
+    plt.show()
--- /dev/null
+++ b/python/demos/demo_mfcc.py
@@ -1,0 +1,68 @@
+#! /usr/bin/env python
+
+import sys
+from aubio import source, pvoc, mfcc
+from numpy import array, vstack, zeros
+
+win_s = 512                 # fft size
+hop_s = win_s / 4           # hop size
+n_filters = 40
+n_coeffs = 13
+samplerate = 44100
+
+if len(sys.argv) < 2:
+    print "Usage: %s <source_filename>" % sys.argv[0]
+    sys.exit(1)
+
+source_filename = sys.argv[1]
+
+samplerate = 0
+if len( sys.argv ) > 2: samplerate = int(sys.argv[2])
+
+s = source(source_filename, samplerate, hop_s)
+samplerate = s.samplerate
+p = pvoc(win_s, hop_s)
+m = mfcc(win_s, n_filters, n_coeffs, samplerate)
+
+desc = []
+tdesc = []
+
+mfccs = zeros([13,])
+frames_read = 0
+while True:
+    samples, read = s()
+    spec = p(samples)
+    mfcc_out = m(spec)
+    mfccs = vstack((mfccs, mfcc_out))
+    frames_read += read
+    if read < hop_s: break
+
+# do plotting
+from numpy import arange
+from demo_waveform_plot import get_waveform_plot
+from demo_waveform_plot import set_xlabels_sample2time
+import matplotlib.pyplot as plt
+
+fig = plt.figure()
+plt.rc('lines',linewidth='.8')
+wave = plt.axes([0.1, 0.75, 0.8, 0.19])
+
+get_waveform_plot( source_filename, samplerate, block_size = hop_s, ax = wave)
+wave.xaxis.set_visible(False)
+wave.yaxis.set_visible(False)
+
+all_times = arange(mfccs.shape[0]) * hop_s
+n_coeffs = mfccs.shape[1]
+for i in range(n_coeffs):
+    ax = plt.axes ( [0.1, 0.75 - ((i+1) * 0.65 / n_coeffs),  0.8, 0.65 / n_coeffs], sharex = wave )
+    ax.xaxis.set_visible(False)
+    ax.yaxis.set_visible(False)
+    ax.plot(all_times, mfccs.T[i])
+
+# add time to the last axis
+set_xlabels_sample2time( ax, frames_read, samplerate) 
+
+#plt.ylabel('spectral descriptor value')
+ax.xaxis.set_visible(True)
+wave.set_title('MFCC for %s' % source_filename)
+plt.show()
--- /dev/null
+++ b/python/demos/demo_miditofreq.py
@@ -1,0 +1,17 @@
+#! /usr/bin/env python
+
+from aubio import miditofreq
+from numpy import arange
+
+upsampling = 100.
+midi = arange(-10, 148 * upsampling)
+midi /= upsampling
+freq = miditofreq(midi)
+
+from matplotlib import pyplot as plt
+
+ax = plt.axes()
+ax.semilogy(midi, freq, '.')
+ax.set_xlabel('midi note')
+ax.set_ylabel('frequency (Hz)')
+plt.show()
--- a/python/demos/demo_specdesc.py
+++ b/python/demos/demo_specdesc.py
@@ -21,9 +21,9 @@
 
 pv = pvoc(win_s, hop_s)
 
-methods = ['default', 'energy', 'hfc', 'complex', 'phase', 'specdiff', 'kl', 'mkl',
-    'specflux', 'centroid', 'spread', 'skewness', 'kurtosis', 'slope', 'decrease',
-    'rolloff', ]
+methods = ['default', 'energy', 'hfc', 'complex', 'phase', 'specdiff', 'kl',
+        'mkl', 'specflux', 'centroid', 'slope', 'rolloff', 'spread', 'skewness',
+        'kurtosis', 'decrease',]
 
 all_descs = {}
 o = {}
@@ -39,12 +39,12 @@
 while True:
     samples, read = s()
     fftgrain = pv(samples)
-    print "%f" % ( total_frames / float(samplerate) ),
+    #print "%f" % ( total_frames / float(samplerate) ),
     for method in methods:
         specdesc_val = o[method](fftgrain)[0]
         all_descs[method] = hstack ( [all_descs[method], specdesc_val] )
-        print "%f" % specdesc_val,
-    print
+        #print "%f" % specdesc_val,
+    #print
     total_frames += read
     if read < hop_s: break
 
@@ -52,10 +52,11 @@
     print "done computing, now plotting"
     import matplotlib.pyplot as plt
     from demo_waveform_plot import get_waveform_plot
+    from demo_waveform_plot import set_xlabels_sample2time
     fig = plt.figure()
     plt.rc('lines',linewidth='.8')
     wave = plt.axes([0.1, 0.75, 0.8, 0.19])
-    get_waveform_plot(filename, samplerate, ax = wave )
+    get_waveform_plot(filename, samplerate, block_size = hop_s, ax = wave )
     wave.yaxis.set_visible(False)
     wave.xaxis.set_visible(False)
 
@@ -73,12 +74,7 @@
         ax.annotate(method, xy=(-10, 10),  xycoords='axes points',
                 horizontalalignment='right', verticalalignment='bottom',
                 )
-    if all_desc_times[-1] / float(samplerate) > 60:
-        plt.xlabel('time (mm:ss)')
-        ax.set_xticklabels([ "%02d:%02d" % (t/float(samplerate)/60, (t/float(samplerate))%60) for t in ax.get_xticks()[:-1]], rotation = 50)
-    else:
-        plt.xlabel('time (ss.mm)')
-        ax.set_xticklabels([ "%02d.%02d" % (t/float(samplerate), 100*((t/float(samplerate))%1) ) for t in ax.get_xticks()[:-1]], rotation = 50)
+    set_xlabels_sample2time(ax, all_desc_times[-1], samplerate)
     #plt.ylabel('spectral descriptor value')
     ax.xaxis.set_visible(True)
     plt.show()
--- a/python/demos/demo_waveform_plot.py
+++ b/python/demos/demo_waveform_plot.py
@@ -4,15 +4,15 @@
 from aubio import pvoc, source
 from numpy import zeros, hstack
 
-def get_waveform_plot(filename, samplerate = 0, ax = None):
+def get_waveform_plot(filename, samplerate = 0, block_size = 4096, ax = None):
     import matplotlib.pyplot as plt
     if not ax:
         fig = plt.figure()
         ax = fig.add_subplot(111)
-    hop_s = 4096 # block size
+    hop_s = block_size
 
     allsamples_max = zeros(0,)
-    downsample = 2**3  # to plot n samples / hop_s
+    downsample = 2**4  # to plot n samples / hop_s
 
     a = source(filename, samplerate, hop_s)            # source file
     if samplerate == 0: samplerate = a.samplerate
@@ -25,8 +25,6 @@
         allsamples_max = hstack([allsamples_max, new_maxes])
         total_frames += read
         if read < hop_s: break
-    print samples.reshape(hop_s/downsample, downsample).shape
-
     allsamples_max = (allsamples_max > 0) * allsamples_max
     allsamples_max_times = [ ( float (t) / downsample ) * hop_s for t in range(len(allsamples_max)) ]
 
@@ -34,12 +32,19 @@
     ax.plot(allsamples_max_times, -allsamples_max, '-b')
     ax.axis(xmin = allsamples_max_times[0], xmax = allsamples_max_times[-1])
 
-    if allsamples_max_times[-1] / float(samplerate) > 60:
+    set_xlabels_sample2time(ax, allsamples_max_times[-1], samplerate)
+    return ax
+
+def set_xlabels_sample2time(ax, latest_sample, samplerate):
+    ax.axis(xmin = 0, xmax = latest_sample)
+    if latest_sample / float(samplerate) > 60:
         ax.set_xlabel('time (mm:ss)')
         ax.set_xticklabels([ "%02d:%02d" % (t/float(samplerate)/60, (t/float(samplerate))%60) for t in ax.get_xticks()[:-1]], rotation = 50)
     else:
         ax.set_xlabel('time (ss.mm)')
         ax.set_xticklabels([ "%02d.%02d" % (t/float(samplerate), 100*((t/float(samplerate))%1) ) for t in ax.get_xticks()[:-1]], rotation = 50)
+
+
 if __name__ == '__main__':
     import matplotlib.pyplot as plt
     if len(sys.argv) < 2:
--- a/python/ext/aubio-types.h
+++ b/python/ext/aubio-types.h
@@ -1,4 +1,4 @@
-#include "Python.h"
+#include <Python.h>
 #include <structmember.h>
 
 //#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
--- a/python/lib/aubio/__init__.py
+++ b/python/lib/aubio/__init__.py
@@ -1,10 +1,13 @@
+#! /usr/bin/env python
+
 import numpy
 from _aubio import *
 from midiconv import *
 
 class fvec(numpy.ndarray):
-
+    " a simple numpy array holding a vector of float32 "
     def __new__(self, length = 1024, **kwargs):
+        self.length = length
         if type(length) == type([]):
             return numpy.array(length, dtype='float32', **kwargs)
         return numpy.zeros(length, dtype='float32', **kwargs)
--- a/python/lib/gen_pyobject.py
+++ b/python/lib/gen_pyobject.py
@@ -21,6 +21,7 @@
 param_numbers = {
   'source': [0, 2],
   'sink':   [2, 0],
+  'sampler': [1, 1],
 }
 
 # TODO
@@ -100,6 +101,7 @@
     'tempo':        ['1'],
     'peakpicker':   ['1'],
     'source':       ['self->hop_size', '1'],
+    'sampler':      ['self->hop_size'],
 }
 
 # default value for variables
--- a/python/tests/test_phasevoc.py
+++ b/python/tests/test_phasevoc.py
@@ -7,9 +7,11 @@
 
 class aubio_pvoc_test_case(TestCase):
 
-  def test_members(self):
+  def test_members_automatic_sizes_default(self):
     f = pvoc()
     assert_equal ([f.win_s, f.hop_s], [1024, 512])
+
+  def test_members_automatic_sizes_not_null(self):
     f = pvoc(2048, 128)
     assert_equal ([f.win_s, f.hop_s], [2048, 128])
 
--- a/python/tests/test_source.py
+++ b/python/tests/test_source.py
@@ -54,8 +54,12 @@
 
     def test_wrong_hop_size(self):
         for p in list_of_sounds:
-            f = source(p, 0, -1)
-            print f.hop_size
+            try:
+                f = source(p, 0, -1)
+            except Exception, e:
+                print e
+            else:
+                self.fail('does not fail with wrong hop_size %d' % f.hop_size)
 
     def test_zero_hop_size(self):
         for p in list_of_sounds:
--- a/src/aubio.h
+++ b/src/aubio.h
@@ -185,6 +185,7 @@
 #include "io/source.h"
 #include "io/sink.h"
 #include "io/audio_unit.h"
+#include "synth/sampler.h"
 
 #if AUBIO_UNSTABLE
 #include "mathutils.h"
--- a/src/pitch/pitchyinfft.h
+++ b/src/pitch/pitchyinfft.h
@@ -27,9 +27,9 @@
   difference function, which allows spectral weighting. Because the difference
   function is tapered, the selection of the period is simplified.
  
-  Paul Brossier, ``Automatic annotation of musical audio for interactive
-  systems'', Chapter 3, Pitch Analysis, PhD thesis, Centre for Digital music,
-  Queen Mary University of London, London, UK, 2006.
+  Paul Brossier, [Automatic annotation of musical audio for interactive
+  systems](http://aubio.org/phd/), Chapter 3, Pitch Analysis, PhD thesis,
+  Centre for Digital music, Queen Mary University of London, London, UK, 2006.
 
   \example pitch/test-pitchyinfft.c
 
--- /dev/null
+++ b/src/synth/sampler.c
@@ -1,0 +1,129 @@
+/*
+  Copyright (C) 2003-2013 Paul Brossier <piem@aubio.org>
+
+  This file is part of aubio.
+
+  aubio is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  aubio is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with aubio.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+
+#include "config.h"
+#include "aubio_priv.h"
+#include "fvec.h"
+#include "fmat.h"
+#include "io/source.h"
+#include "synth/sampler.h"
+
+struct _aubio_sampler_t {
+  uint_t samplerate;
+  uint_t blocksize;
+  aubio_source_t *source;
+  fvec_t *source_output;
+  fmat_t *source_output_multi;
+  char_t *uri;
+  uint_t playing;
+};
+
+aubio_sampler_t *new_aubio_sampler(uint_t samplerate, uint_t blocksize)
+{
+  aubio_sampler_t *s = AUBIO_NEW(aubio_sampler_t);
+  s->samplerate = samplerate;
+  s->blocksize = blocksize;
+  s->source_output = new_fvec(blocksize);
+  s->source_output_multi = new_fmat(blocksize, 4);
+  s->source = NULL;
+  s->playing = 0;
+  return s;
+}
+
+uint_t aubio_sampler_load( aubio_sampler_t * o, char_t * uri )
+{
+  if (o->source) del_aubio_source(o->source);
+  o->uri = uri;
+  o->source = new_aubio_source(uri, o->samplerate, o->blocksize);
+  if (o->source) return 0;
+  AUBIO_ERR("sampler: failed loading %s", uri);
+  return 1;
+}
+
+void aubio_sampler_do ( aubio_sampler_t * o, fvec_t * input, fvec_t * output)
+{
+  uint_t read = 0, i;
+  if (o->playing) {
+    aubio_source_do (o->source, o->source_output, &read);
+    for (i = 0; i < output->length; i++) {
+      output->data[i] += o->source_output->data[i];
+    }
+    if (read < o->blocksize) o->playing = 0;
+  }
+  if (input && input != output) {
+    for (i = 0; i < output->length; i++) {
+      output->data[i] += input->data[i];
+    }
+  }
+}
+
+void aubio_sampler_do_multi ( aubio_sampler_t * o, fmat_t * input, fmat_t * output)
+{
+  uint_t read = 0, i, j;
+  if (o->playing) {
+    aubio_source_do_multi (o->source, o->source_output_multi, &read);
+    for (i = 0; i < output->height; i++) {
+      for (j = 0; j < output->length; j++) {
+        output->data[i][j] = o->source_output_multi->data[i][j];
+      }
+    }
+    if (read == 0) o->playing = 0;
+  }
+  if (input && input != output) {
+    for (i = 0; i < output->height; i++) {
+      for (j = 0; j < output->length; j++) {
+        output->data[i][j] += input->data[i][j];
+      }
+    }
+  }
+}
+
+uint_t aubio_sampler_get_playing ( aubio_sampler_t * o )
+{
+  return o->playing;
+}
+
+uint_t aubio_sampler_set_playing ( aubio_sampler_t * o, uint_t playing )
+{
+  o->playing = (playing == 1) ? 1 : 0;
+  return 0;
+}
+
+uint_t aubio_sampler_play ( aubio_sampler_t * o )
+{
+  aubio_source_seek (o->source, 0);
+  return aubio_sampler_set_playing (o, 1);
+}
+
+uint_t aubio_sampler_stop ( aubio_sampler_t * o )
+{
+  return aubio_sampler_set_playing (o, 0);
+}
+
+void del_aubio_sampler( aubio_sampler_t * o )
+{
+  if (o->source) {
+    del_aubio_source(o->source);
+  }
+  del_fvec(o->source_output);
+  del_fmat(o->source_output_multi);
+  AUBIO_FREE(o);
+}
--- /dev/null
+++ b/src/synth/sampler.h
@@ -1,0 +1,141 @@
+/*
+  Copyright (C) 2003-2013 Paul Brossier <piem@aubio.org>
+
+  This file is part of aubio.
+
+  aubio is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  aubio is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with aubio.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef _AUBIO_SYNTH_SAMPLER_H
+#define _AUBIO_SYNTH_SAMPLER_H
+
+/** \file
+
+  Load and play sound files.
+
+  This file loads a sample and gets ready to play it.
+
+  The `_do` function adds the new samples to the input, and write the result as
+  the output.
+
+  \example synth/test-sampler.c
+
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** sampler object */
+typedef struct _aubio_sampler_t aubio_sampler_t;
+
+/** create new sampler object
+
+  \param samplerate the sampling rate of the new sampler
+
+  \return the newly created ::aubio_sampler_t
+
+*/
+aubio_sampler_t * new_aubio_sampler(uint_t samplerate, uint_t hop_size);
+
+/** load source in sampler
+
+  \param o sampler, created by ::new_aubio_sampler
+  \param uri the uri of the source to load
+
+  \return 0 if successful, non-zero otherwise
+
+*/
+uint_t aubio_sampler_load( aubio_sampler_t * o, char_t * uri );
+
+/** process sampler function
+
+  \param o sampler, created by ::new_aubio_sampler
+  \param input input of the sampler, to be added to the output
+  \param output output of the sampler
+
+This function adds the new samples from the playing sample to the output.
+
+If `input` is not NULL and different from `output`, then the samples from `input`
+are added to the output.
+
+*/
+void aubio_sampler_do ( aubio_sampler_t * o, fvec_t * input, fvec_t * output);
+
+/** process sampler function, multiple channels
+
+  \param o sampler, created by ::new_aubio_sampler
+  \param input input of the sampler, to be added to the output
+  \param output output of the sampler
+
+This function adds the new samples from the playing sample to the output.
+
+If `input` is not NULL and different from `output`, then the samples from `input`
+are added to the output.
+
+*/
+void aubio_sampler_do_multi ( aubio_sampler_t * o, fmat_t * input, fmat_t * output);
+
+/** get current playing state
+
+  \param o sampler, created by ::new_aubio_sampler
+
+  \return 0 if not playing, 1 if playing
+
+*/
+uint_t aubio_sampler_get_playing ( aubio_sampler_t * o );
+
+/** set current playing state
+
+  \param o sampler, created by ::new_aubio_sampler
+  \param playing 0 for not playing, 1 for playing
+
+  \return 0 if successful, 1 otherwise
+
+*/
+uint_t aubio_sampler_set_playing ( aubio_sampler_t * o, uint_t playing );
+
+/** play sample from start
+
+  \param o sampler, created by ::new_aubio_sampler
+  \param playing 0 for not playing, 1 for playing
+
+  \return 0 if successful, 1 otherwise
+
+*/
+uint_t aubio_sampler_play ( aubio_sampler_t * o );
+
+/** stop sample from start
+
+  \param o sampler, created by ::new_aubio_sampler
+  \param playing 0 for not playing, 1 for playing
+
+  \return 0 if successful, 1 otherwise
+
+*/
+uint_t aubio_sampler_stop ( aubio_sampler_t * o );
+
+/** destroy ::aubio_sampler_t object
+
+  \param o sampler, created by ::new_aubio_sampler
+
+*/
+void del_aubio_sampler( aubio_sampler_t * o );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _AUBIO_SYNTH_SAMPLER_H */
--- a/src/tempo/tempo.h
+++ b/src/tempo/tempo.h
@@ -18,8 +18,8 @@
 
 */
 
-/** \file 
-  
+/** \file
+
   Tempo detection object
 
   This object stores all the memory required for tempo detection algorithm
@@ -39,39 +39,71 @@
 /** tempo detection structure */
 typedef struct _aubio_tempo_t aubio_tempo_t;
 
-/** create tempo detection object */
-aubio_tempo_t * new_aubio_tempo (char_t * method, 
+/** create tempo detection object
+
+  \param buf_size length of FFT
+  \param hop_size number of frames between two consecutive runs
+  \param samplerate sampling rate of the signal to analyze
+
+  \return newly created ::aubio_tempo_t if successful, `NULL` otherwise
+
+*/
+aubio_tempo_t * new_aubio_tempo (char_t * method,
     uint_t buf_size, uint_t hop_size, uint_t samplerate);
 
-/** execute tempo detection */
+/** execute tempo detection
+
+  \param o beat tracking object
+  \param input new samples
+  \param tempo output beats
+
+*/
 void aubio_tempo_do (aubio_tempo_t *o, fvec_t * input, fvec_t * tempo);
 
-/** set tempo detection silence threshold  */
+/** set tempo detection silence threshold
+
+  \param o beat tracking object
+  \param threshold new silence threshold, in dB
+
+  \return `0` if successful, non-zero otherwise
+
+*/
 uint_t aubio_tempo_set_silence(aubio_tempo_t * o, smpl_t silence);
 
-/** set tempo detection peak picking threshold  */
+/** set tempo detection peak picking threshold
+
+  \param o beat tracking object
+  \param threshold new threshold
+
+  \return `0` if successful, non-zero otherwise
+
+*/
 uint_t aubio_tempo_set_threshold(aubio_tempo_t * o, smpl_t threshold);
 
 /** get current tempo
 
-  \param bt beat tracking object
+  \param o beat tracking object
 
-  Returns the currently observed tempo, or 0 if no consistent value is found
+  \return the currently observed tempo, or `0` if no consistent value is found
 
 */
-smpl_t aubio_tempo_get_bpm(aubio_tempo_t * bt);
+smpl_t aubio_tempo_get_bpm(aubio_tempo_t * o);
 
 /** get current tempo confidence
 
-  \param bt beat tracking object
+  \param o beat tracking object
 
-  Returns the confidence with which the tempo has been observed, 0 if no
+  \return confidence with which the tempo has been observed, `0` if no
   consistent value is found.
 
 */
-smpl_t aubio_tempo_get_confidence(aubio_tempo_t * bt);
+smpl_t aubio_tempo_get_confidence(aubio_tempo_t * o);
 
-/** delete tempo detection object */
+/** delete tempo detection object
+
+  \param o beat tracking object
+
+*/
 void del_aubio_tempo(aubio_tempo_t * o);
 
 #ifdef __cplusplus
--- a/tests/demo/bench/onset/bench-delay
+++ /dev/null
@@ -1,62 +1,0 @@
-#! /usr/bin/python
-
-from aubio.bench.onset import benchonset
-from aubio.task.onset import taskonset
-from aubio.task.params import taskparams
-
-class mybenchonset(benchonset):
-
-	def run_bench(self,modes=['dual'],thresholds=[0.5]):
-		from os.path import dirname,basename
-		self.thresholds = thresholds
-		self.pretty_titles()
-
-		for mode in modes:
-			d = []
-			self.params.onsetmode = mode
-			self.params.localmin = True
-			self.params.delay = 1. 
-			self.params.threshold = thresholds[0]
-			#
-			self.params.localmin = False 
-			self.params.delay = 0. 
-			self.dir_eval_print()
-			self.plotdiffs(d,plottitle="Causal")
-			#
-			self.params.localmin = True
-			self.params.delay = 0. 
-			self.dir_eval_print()
-			self.plotdiffs(d,plottitle="Local min")
-
-			self.params.localmin = False 
-			self.params.delay = 6. 
-			self.dir_eval_print()
-			self.plotdiffs(d,plottitle="Fixed delay")
-
-			#self.plotplotdiffs(d)
-			outplot = "_-_".join(("delay",mode,basename(self.datadir) ))
-			for ext in ("png","svg","ps"):
-				self.plotplotdiffs(d,outplot=outplot,extension=ext)
-
-if __name__ == "__main__":
-	import sys
-	if len(sys.argv) > 1: datapath = sys.argv[1]
-	else: print "ERR: a path is required"; sys.exit(1)
-	modes = ['complex', 'energy', 'phase', 'hfc', 'specdiff', 'kl', 'mkl', 'dual']
-	#thresholds = [ 0.01, 0.05, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2]
-	#modes = [ 'hfc' ]
-	thresholds = [0.5]
-
-	#datapath = "%s%s" % (DATADIR,'/onset/DB/*/')
-	respath = '/var/tmp/DB-testings'
-
-	benchonset = mybenchonset(datapath,respath,checkres=True,checkanno=True)
-	benchonset.params = taskparams()
-	benchonset.task = taskonset
-	benchonset.valuesdict = {}
-
-	try:
-		#benchonset.auto_learn2(modes=modes)
-		benchonset.run_bench(modes=modes,thresholds=thresholds)
-	except KeyboardInterrupt:
-		sys.exit(1)
--- a/tests/demo/bench/onset/bench-onset
+++ /dev/null
@@ -1,68 +1,0 @@
-#! /usr/bin/python
-
-from aubio.task import *
-
-from aubio.bench.onset import mmean, stdev, benchonset
-
-class mybenchonset(benchonset):
-
-	def run_bench(self,modes=['dual'],thresholds=[0.5]):
-		from os.path import dirname,basename
-		self.thresholds = thresholds
-		self.pretty_titles()
-		d,e,f,g = [],[],[],[]
-		for mode in modes:
-			self.vlist = []
-			self.params.onsetmode = mode
-			#self.params.localmin = True
-
-			for threshold in self.thresholds:
-				self.params.threshold = threshold
-				self.dir_eval_print()
-				self.vlist.append(self.v)
-			self.plotroc(d)
-			self.plotfmeas(e)
-			self.plotpr(f)
-			#self.plothistcat(g)
-
-
-
-		#self.plotplotroc(d)
-		#self.plotplotfmeas(e)
-		#self.plotplotpr(f)
-		outplot = basename(self.datadir)
-		for ext in ("png","svg","ps"):
-			self.plotplotroc(d,outplot=outplot,extension=ext)
-			self.plotplotfmeas(e,outplot=outplot,extension=ext)
-			self.plotplotpr(f,outplot=outplot,extension=ext)
-			#self.plotplothistcat(g,outplot=outplot,extension=ext)
-
-if __name__ == "__main__":
-	import sys
-	if len(sys.argv) > 1: datapath = sys.argv[1]
-	else: print "ERR: a path is required"; sys.exit(1)
-	modes = ['complex', 'energy', 'phase', 'hfc', 'specdiff', 'kl', 'mkl', 'dual']
-	thresholds = [ 0.01, 0.05, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2]
-	#modes = [ 'hfc' ]
-	#thresholds = [0.5]
-
-	#datapath = "%s%s" % (DATADIR,'/onset/DB/*/')
-	respath = '/var/tmp/DB-testings'
-
-	benchonset = mybenchonset(datapath,respath,checkres=True,checkanno=True)
-	benchonset.params = taskparams()
-	benchonset.params.dcthreshold = -1.
-	benchonset.params.silence = -100.
-	benchonset.params.delay = 5. 
-	benchonset.params.bufsize = 1024 
-	benchonset.params.hopsize = 256 
-	benchonset.params.step = float(benchonset.params.hopsize)/float(benchonset.params.samplerate)
-	benchonset.params.mintol = 4.1 
-	benchonset.task = taskonset
-	benchonset.valuesdict = {}
-
-	try:
-		#benchonset.auto_learn2(modes=modes)
-		benchonset.run_bench(modes=modes,thresholds=thresholds)
-	except KeyboardInterrupt:
-		sys.exit(1)
--- a/tests/demo/bench/onset/bench-window
+++ /dev/null
@@ -1,59 +1,0 @@
-#! /usr/bin/python
-
-from aubio.bench.onset import benchonset
-from aubio.task.onset import taskonset
-from aubio.task.params import taskparams
-
-class mybenchonset(benchonset):
-
-	def run_bench(self,modes=['dual'],thresholds=[0.5]):
-		from os.path import dirname,basename
-		self.thresholds = thresholds
-		self.pretty_titles()
-
-		for mode in modes:
-
-			self.params.onsetmode = mode
-			self.params.localmin = True
-			self.params.delay = 1. 
-			self.params.threshold = thresholds[0]
-			self.params.localmin = False 
-			#
-			for delay in (0., 4.):
-				d = []
-				self.params.delay = delay 
-				for buf in (2048, 1024, 512):
-					for hop in (buf/2, buf/4):
-						self.params.bufsize = buf 
-						self.params.hopsize = hop 
-						self.params.step = float(self.params.hopsize)/float(self.params.samplerate)
-						self.dir_eval_print()
-						self.plotdiffs(d,plottitle="%s %s" % (buf,hop))
-				#plotplotdiffs(d)
-				outplot = "_-_".join(("window",mode,"delay-%s" % int(delay),
-					basename(self.datadir) ))
-				for ext in ("png","svg","ps"):
-					self.plotplotdiffs(d,outplot=outplot,extension=ext)
-
-if __name__ == "__main__":
-	import sys
-	if len(sys.argv) > 1: datapath = sys.argv[1]
-	else: print "ERR: a path is required"; sys.exit(1)
-	modes = ['complex', 'energy', 'phase', 'hfc', 'specdiff', 'kl', 'mkl', 'dual']
-	#thresholds = [ 0.01, 0.05, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2]
-	#modes = [ 'hfc' ]
-	thresholds = [0.5]
-
-	#datapath = "%s%s" % (DATADIR,'/onset/DB/*/')
-	respath = '/var/tmp/DB-testings'
-
-	benchonset = mybenchonset(datapath,respath,checkres=True,checkanno=True)
-	benchonset.params = taskparams()
-	benchonset.task = taskonset
-	benchonset.valuesdict = {}
-
-	try:
-		#benchonset.auto_learn2(modes=modes)
-		benchonset.run_bench(modes=modes,thresholds=thresholds)
-	except KeyboardInterrupt:
-		sys.exit(1)
--- a/tests/demo/bench/pitch/bench-pitch-isolated
+++ /dev/null
@@ -1,198 +1,0 @@
-#! /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',
-	       'TotalPit', 'TotalPit', 'TotalChr' ]
-	""" list of values to print per dir """
-	printnames_total = [ 'mode', 'MinPit', 'MaxPit', 'TotalSil', 'TotalPit', 'TotalChr']
-	printnames_notes = [ 'mode', 'Note', 'Sil', 'Pit', 'Chr']
-	printnames = printnames_notes 
-
-	""" per dir """
-	formats = {'mode': "%12s" , 
-		'truth': "%s",
-		'osil': "%s", 'esil': "%s", 
-		'opit': "%s", 'epit': "%s", 'echr': "%s",
-    'Note': "%s", 'Sil': "%s", 'Chr': "%s", 'Pit': "%s",
-		'TotalPit': "%s", 'TotalSil': "%s", 'TotalChr': "%s",
-		'MinPit': "%s", 'MaxPit': "%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,tol=0.5)
-		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'],multiplot=0):
-		from os.path import basename
-		self.modes = modes
-		self.pretty_titles()
-		d = []
-		for mode in self.modes:
-			self.params.pitchmode = mode
-			self.dir_exec()
-			self.dir_eval()
-			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)):
-				allOsil[i] = max(1,allOsil[i])
-				allOpit[i] = max(1,allOpit[i])
-				allMsil[i] = allEsil[i]/float(allOsil[i])*100.
-				allMpit[i] = allEpit[i]/float(allOpit[i])*100.
-				allMchr[i] = allEchr[i]/float(allOpit[i])*100.
-				self.v['Sil'], self.v['Pit'], self.v['Chr'] = allMsil[i], allMpit[i], allMchr[i]
-				self.v['Note'] = truth[i]
-				#self.printnames = self.printnames_notes
-				self.pretty_print()
-			self.v['TotalSil'] = sum(allMsil)/len(truth)
-			self.v['TotalPit'] = sum(allMpit)/len(truth)
-			self.v['TotalChr'] = sum(allMchr)/len(truth)
-			self.v['MinPit'] = min(truth) 
-			self.v['MaxPit'] = max(truth) 
-			#self.printnames = self.printnames_total
-			#self.pretty_print()
-
-			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)
-			if multiplot:
-				d.append(plot)
-			else:
-				d += plot
-		outplot = "_-_".join(('pitchtessiture',title))
-		self.xmin = min(self.v['truth']) #20.
-		self.xmax = 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,multiplot=multiplot)
-		#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.title(plottitle)
-		g('set yrange [50:100]')
-		# erase axis
-		g('set xrange [%f:%f]' % (self.xmin,self.xmax)) #(self.xmax - (self.xmax-self.xmin)*5./4.,self.xmax))
-		#g.plot(*d)
-		g('set border 3')
-		g('set xtics nomirror')
-		g('set ytics nomirror')
-		g('set key bottom')
-		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)) ) )
-				#g.ylabel('%Correct detections')
-				g('set xrange [%f:%f]' % (self.xmin,self.xmax)) #(self.xmax - (self.xmax-self.xmin)*5./4.,self.xmax))
-				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', 'yinfft', 'mcomb', 'fcomb']
-	#modes = ['mcomb']
-
-	params = taskparams()
-	params.bufsize = 2048 # 4096 
-	params.hopsize = 256
-	params.silence = -60.
-	params.pitchsmooth = 0 
-	params.pitchmax = 20000
-	params.pitchmin = 20
-	params.pitchyinfft = 0.95
-	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)
--- a/tests/demo/bench/pitch/bench-pitch-plot-isolated
+++ /dev/null
@@ -1,63 +1,0 @@
-#! /usr/bin/python
-
-if __name__ == '__main__':
-  import sys, Gnuplot
-  from aubio.gnuplot import gnuplot_create
-  from aubio.txtfile import read_datafile
-  from aubio.plot.keyboard import draw_keyboard
-  lines = []
-  titles = []
-  for file in range(len(sys.argv)-1):
-    l = read_datafile(sys.argv[file+1])
-    notes, score = [],[]
-    for i in range(len(l)):
-      notes.append(l[i][0])
-      score.append(l[i][2])
-    lines.append(Gnuplot.Data(notes,score,
-      with='linespoints',
-      title=sys.argv[file+1].split('.')[-1]))
-    titles.append(sys.argv[file+1].split('.')[-1])
-  blacks,whites = draw_keyboard(firstnote = notes[0], lastnote = notes[-1], 
-    y0= 40, y1 = 50)
-
-  g = gnuplot_create(sys.argv[file+1].split('.')[-3],'ps')
-  #g = gnuplot_create('','')
-  #g = gnuplot_create('/tmp/test','eps')
-  g('set yrange [40:100]')
-  #g('set xrange [%f:%f]' % (notes[0],notes[-1]+60))
-  g('set size 0.5')
-  g('set key outside')
-
-  g('set border 3')
-  g('set xtics nomirror')
-  g('set ytics nomirror')
-  multiplot = 1
-  oplots = lines
-  g('set size 1,2')
-  if multiplot:
-    height = 2.
-    g('set lmargin 10')
-    #g('set rmargin 15')
-    g('set multiplot')
-    g('set yrange [50:100]')
-    g('set xrange [%f:%f]' % (notes[0],notes[-1]))
-    g('set xtics %f,12' % notes[0])
-    g('set nokey')
-    for i in range(len(oplots)):
-      g.ylabel(titles[i])
-      g('set size %f,%f' % (1.,height*.85/float(len(oplots))))
-      g('set origin 0,%f' % (height*(.15+.85*float(len(oplots)-i-1)/float(len(oplots)))))
-      g.plot(oplots[i])
-    g('set title "Raw pitch accuracy (%) against midi note numbers"')
-    g('set noxtics')
-    g('set noytics')
-    g('set size %f,%f' % (1.,.15*height))
-    g('set origin 0,%f' % 0)
-    g('set yrange [40:50]')
-    g('set xrange [%f:%f]' % (notes[0],notes[-1]))
-    g.xlabel('')
-    g.ylabel('')
-    g.plot(whites,blacks)
-    g('unset multiplot')
-  else:
-    g.plot(whites,blacks,*lines)
--- a/tests/demo/bench/tempo/demo-tempo
+++ /dev/null
@@ -1,313 +1,0 @@
-#! /usr/bin/python
-
-""" this file was written by Paul Brossier 
-  it is released under the GNU/GPL license.
-"""
-
-import sys,time
-from aubio.task import taskbeat,taskparams
-from aubio.aubioclass import fvec, aubio_autocorr
-from aubio.gnuplot import gnuplot_create, gnuplot_addargs
-from aubio.aubiowrapper import *
-from math import exp,log
-
-usage = "usage: %s [options] -i soundfile" % sys.argv[0]
-
-def parse_args():
-        from optparse import OptionParser
-        parser = OptionParser(usage=usage)
-        parser.add_option("-i","--input",
-                          action="store", dest="filename", 
-                          help="input sound file")
-        parser.add_option("-n","--printframe",
-                          action="store", dest="printframe", default=-1, 
-                          help="make a plot of the n_th frame")
-        gnuplot_addargs(parser)
-        (options, args) = parser.parse_args()
-        if not options.filename: 
-                 print "no file name given\n", usage
-                 sys.exit(1)
-        return options, args
-
-def plotdata(x,y,plottitle="",**keyw):
-	import Gnuplot
-	return Gnuplot.Data(x, y, title="%s" % plottitle,**keyw)
-
-options, args = parse_args()
-filename = options.filename
-xsize = float(options.xsize)
-ysize = float(options.ysize)
-
-printframe = int(options.printframe)
-
-if options.outplot and printframe > 0: 
-  extension = options.outplot.split('.')[-1] 
-  outplot = '.'.join(options.outplot.split('.')[:-1])
-else: 
-  extension = ''
-  outplot = None
-f = gnuplot_create(outplot=outplot,extension=extension,options=options)
-
-params = taskparams()
-params.onsetmode = 'specdiff'
-task = taskbeat(filename,params=params)
-
-hopsize = params.hopsize
-bufsize = params.bufsize
-btstep = task.btstep
-winlen = task.btwinlen
-laglen = winlen/4
-step = winlen/4
-
-timesig = 0
-maxnumelem = 4
-gp = 0
-counter = 0
-flagconst = 0
-constthresh = 3.901
-g_var      = 3.901
-rp = 0
-rp1 = 0
-rp2 = 0
-g_mu = 0
-
-rayparam = 48/512.*winlen
-
-#t     = [i for i in range(hopsize)]
-#tlong = [i for i in range(hopsize*(btstep-1))]
-#tall  = [i for i in range(hopsize*btstep)]
-#a     = [0 for i in range(hopsize*btstep)]
-dfx = [i for i in range(winlen)]
-dfframe = [0 for i in range(winlen)]
-dfrev = [0 for i in range(winlen)]
-acframe = [0 for i in range(winlen)]
-
-localacf = [0 for i in range(winlen)]
-inds = [0 for i in range(maxnumelem)]
-
-acx = [i for i in range(laglen)]
-acfout  = [0 for i in range(laglen)]
-
-phwv  = [0 for i in range(2*laglen)]
-phwvx = [i for i in range(2*laglen)]
-
-dfwvnorm = exp(log(2.0)*(winlen+2.)/rayparam);
-dfwv = [exp(log(2.)*(i+1.)/rayparam)/dfwvnorm for i in range(winlen)]
-
-gwv = [exp(-.5*(j+1.-g_mu)**2/g_var**2) for j in range(laglen)]
-rwv = [(i+1.)/rayparam**2 * exp(-(i+1.)**2 / (2.*rayparam)**2)
-        for i in range(0,laglen)] 
-acf = fvec(winlen,1)
-
-nrframe = 0
-while (task.readsize == params.hopsize):
-  task()
-  #print task.pos2
-  #a[:-hopsize] = [i for i in a[-(btstep-1)*hopsize:]]
-  #a[-hopsize:] = [task.myvec.get(i,0) for i in t]
-
-  #g('set xrange [%f:%f]' % (t[0],t[-1]))
-  #time.sleep(.2)
-  if task.pos2==btstep-1:
-    nrframe += 1
-    dfframe = [task.dfframe.get(i,0) for i in range(winlen)]
-    if printframe == nrframe or printframe == -1:
-      d  = [[plotdata(range(-winlen,0),dfframe,plottitle="onset detection", with='lines')]]
-    # start beattracking_do
-    for i in range(winlen):
-      dfrev[winlen-1-i] = 0.
-      dfrev[winlen-1-i] = dfframe[i]*dfwv[i]
-    aubio_autocorr(task.dfframe(),acf()); 
-    acframe = [acf.get(i,0) for i in range(winlen)]
-    if not timesig:
-      numelem = 4
-    else:
-      numelem = timesig
-
-    old = 0
-    acfout = [0 for i in range(winlen/4)]
-    for i in range(1,laglen-1):
-      for a in range(1,numelem+1):
-        for b in range (1-a,a):
-          acfout[i] += acframe[a*(i+1)+b-1] * 1./(2.*a-1.)*rwv[i]
-          if old < acfout[i]:
-            old = acfout[i]
-            maxi = i
-    rp = max(maxi,1);
-
-    if printframe == nrframe or printframe == -1:
-      rwvs = [rwv[i]*max(acframe) for i in range(len(rwv))]
-      d += [[plotdata(acx,acfout,plottitle="comb filterbank", with='lines', axes='x1y1'),
-          plotdata([rp,rp],[1.2*old,min(acfout)],plottitle="period", with='impulses', axes='x1y1'),
-          plotdata(acx,rwvs,plottitle="L_w", with='lines', axes='x1y1')]]
-
-    # getperiod
-    inds = [0 for i in range(maxnumelem)]
-    localacf = [0 for i in range(winlen)]
-    period = 0
-    for a in range(1,4+1):
-      for b in range(1-a,a):
-        localacf[a*rp+b-1] = acframe[a*rp+b-1]
-    for i in range(numelem):
-      maxindex = 0
-      maxval = 0.0
-      for j in range(rp*(i+1)+i):
-        if localacf[j] > maxval:
-          maxval = localacf[j]
-          maxind = j
-        localacf[j] = 0
-      inds[i] = maxind
-    for i in range(numelem):
-      period += inds[i]/(i+1.)
-    period = period/numelem
-    #print "period", period
-
-    # checkstate 
-    if gp:
-      # context dependant model
-      acfout = [0 for i in range(winlen/4)]
-      old = 0
-      for i in range(laglen-1):
-        for a in range(timesig):
-          for b in range(1-a,a):
-            acfout[i] += acframe[a*(i+1)+b-1] * gwv[i]
-        if old < acfout[i]:
-          old = acfout[i]
-          maxi = i
-      gp = maxi
-    else:
-      # general model
-      gp = 0
-    #print "gp", gp
-    if printframe == nrframe or printframe == -1:
-      gwvs = [gwv[i]*max(acfout) for i in range(len(gwv))]
-      d += [[plotdata(acx,acfout,plottitle="comb filterbank", with='lines', axes='x1y1'),
-          plotdata(gp,old,plottitle="period", with='impulses', axes='x1y1'),
-          plotdata(acx,gwvs,plottitle="L_{gw}", with='lines', axes='x1y1')]]
-
-    if counter == 0:
-      # initial step
-      if abs(gp-rp) > 2.*constthresh:
-        flagstep = 1
-        counter  = 3
-      else:
-        flagstep = 0
-    #print "flagstep", flagstep
-    #print "rp2,rp1,rp", rp2,rp1,rp
-    acfw = [dfframe[i]*dfwv[i] for i in range(winlen)]
-
-    if counter == 1 and flagstep == 1:
-      # "3rd frame after flagstep set"
-      if abs(2.*rp-rp1- rp2) < constthresh:
-        flagconst = 1
-        counter = 0
-      else:
-        flagconst = 0
-        counter = 2
-    elif counter > 0:
-      counter -= 1
-
-    rp2 = rp1; rp1 = rp
-
-    if flagconst:
-      # "first run of new hypothesis"
-      gp = rp
-      g_mu = gp
-      timesig = 4 #FIXME
-      gwv = [exp(-.5*(j+1.-g_mu)**2/g_var**2) for j in range(laglen)]
-      flagconst = 0
-      bp = gp
-      phwv = [1 for i in range(2*laglen)]
-    elif timesig:
-      # "contex dependant"
-      bp = gp
-      if step > lastbeat:
-        phwv = [exp(-.5*(1.+j-step+lastbeat)**2/(bp/8.)) for j in range(2*laglen)]
-      else:
-        print "NOT using phase weighting"
-        phwv = [1 for i in range(2*laglen)]
-    else:
-      # "initial state"
-      bp = rp
-      phwv = [1 for i in range(2*laglen)]
-
-    while bp < 25:
-      print "WARNING, doubling the beat period"
-      bp *= 2
-
-    # 
-    phout = [0. for i in range(winlen)]
-
-    kmax = int(winlen/float(bp));
-
-    old = 0
-    for i in range(bp):
-      phout[i] = 0.
-      for k in range(kmax):
-        phout[i] += dfrev[i+bp*k] * phwv[i]
-      if phout[i] > old:
-        old = phout[i]
-        maxi = i
-    maxindex = maxi 
-    if (maxindex == winlen - 1): maxindex = 0
-    phase = 1 + maxindex
-    i = 1
-    beat = bp - phase
-    beats= []
-    if beat >= 0: beats.append(beat)
-    while beat+bp < step: 
-      beat += bp
-      beats.append(beat)
-    lastbeat = beat
-    #print beats,
-    #print "the lastbeat is", lastbeat
-
-    # plot all this
-    if printframe == nrframe or printframe == -1:
-      phwvs = [phwv[i]*max(phout) for i in range(len(phwv))]
-      d += [[plotdata(range(-laglen,0),phwvs[laglen:0:-1],plottitle="A_{gw}", with='lines',axes='x1y1'),
-          plotdata(range(-laglen,0),phout[laglen:0:-1],plottitle="df", with='lines'),
-          plotdata(-phase,old,plottitle="phase", with='impulses', axes='x1y1'),
-          plotdata([i for i in beats],[old for i in beats],plottitle="predicted", with='impulses')
-          ]]
-    #d += [[plotdata(dfx,dfwv,plottitle="phase weighting", with='lines', axes='x1y2'),
-    #    plotdata(dfx,dfrev,plottitle="df reverse", with='lines', axes='x1y1')]]
-    #d += [[plotdata(dfx,phout,plottitle="phase", with='lines', axes='x1y2')]]
-    #d += [[plotdata(dfx,dfwv,plottitle="phase weighting", with='lines', axes='x1y2'),
-    #    plotdata(dfx,dfrev,plottitle="df reverse", with='lines', axes='x1y1')]]
-    #d += [[plotdata(dfx,phout,plottitle="phase", with='lines', axes='x1y2')]]
-
-      f('set lmargin 4')
-      f('set rmargin 4')
-      f('set size %f,%f' % (1.0*xsize,1.0*ysize) )
-      f('set key spacing 1.3')
-      f('set multiplot')
-
-      f('set size %f,%f' % (1.0*xsize,0.33*ysize) )
-      f('set orig %f,%f' % (0.0*xsize,0.66*ysize) )
-      f('set xrange [%f:%f]' % (-winlen,0) )
-      f.title('Onset detection function')
-      f.xlabel('time (df samples)')
-      f.plot(*d[0])
-      f('set size %f,%f' % (0.5*xsize,0.33*ysize) )
-      f('set orig %f,%f' % (0.0*xsize,0.33*ysize) )
-      f('set xrange [%f:%f]' % (0,laglen) )
-      f.title('Period detection: Rayleygh weighting')
-      f.xlabel('lag (df samples)')
-      f.plot(*d[1])
-      f('set size %f,%f' % (0.5*xsize,0.33*ysize) )
-      f('set orig %f,%f' % (0.5*xsize,0.33*ysize) )
-      f('set xrange [%f:%f]' % (0,laglen) )
-      f.title('Period detection: Gaussian weighting')
-      f.xlabel('lag (df samples)')
-      f.plot(*d[2])
-      f('set size %f,%f' % (1.0*xsize,0.33*ysize) )
-      f('set orig %f,%f' % (0.0*xsize,0.00*ysize) )
-      f('set xrange [%f:%f]' % (-laglen,laglen) )
-      f.title('Phase detection and predicted beats')
-      f.xlabel('time (df samples)')
-      f.plot(*d[3])
-      f('set nomultiplot')
-    if printframe == -1: a = sys.stdin.read()
-    elif 0 < printframe and printframe < nrframe:
-      break
--- a/tests/demo/bench/tempo/demo-tempo-acf
+++ /dev/null
@@ -1,157 +1,0 @@
-#! /usr/bin/python
-
-""" this file was written by Paul Brossier 
-  it is released under the GNU/GPL license.
-"""
-
-import sys,time
-from aubio.task import taskbeat,taskparams
-from aubio.aubioclass import fvec, aubio_autocorr
-from aubio.gnuplot import gnuplot_create, gnuplot_addargs
-from aubio.aubiowrapper import *
-from math import exp,log
-
-usage = "usage: %s [options] -i soundfile" % sys.argv[0]
-
-def parse_args():
-        from optparse import OptionParser
-        parser = OptionParser(usage=usage)
-        parser.add_option("-i","--input",
-                          action="store", dest="filename", 
-                          help="input sound file")
-        parser.add_option("-n","--printframe",
-                          action="store", dest="printframe", default=-1, 
-                          help="make a plot of the n_th frame")
-        gnuplot_addargs(parser)
-        (options, args) = parser.parse_args()
-        if not options.filename: 
-                 print "no file name given\n", usage
-                 sys.exit(1)
-        return options, args
-
-def plotdata(x,y,plottitle="",**keyw):
-	import Gnuplot
-	return Gnuplot.Data(x, y, title="%s" % plottitle,**keyw)
-
-options, args = parse_args()
-filename = options.filename
-xsize = float(options.xsize)
-ysize = float(options.ysize)
-
-printframe = int(options.printframe)
-
-if options.outplot and printframe > 0: 
-  extension = options.outplot.split('.')[-1] 
-  outplot = '.'.join(options.outplot.split('.')[:-1])
-else: 
-  extension = ''
-  outplot = None
-f = gnuplot_create(outplot,extension,options)
-
-params = taskparams()
-params.onsetmode = 'specdiff'
-task = taskbeat(filename,params=params)
-
-hopsize = params.hopsize
-bufsize = params.bufsize
-btstep = task.btstep
-winlen = task.btwinlen
-laglen = winlen/4
-step = winlen/4
-
-timesig = 0
-maxnumelem = 4
-gp = 0
-counter = 0
-flagconst = 0
-constthresh = 3.901
-g_var      = 3.901
-rp = 0
-rp1 = 0
-rp2 = 0
-g_mu = 0
-
-rayparam = 48/512.*winlen
-
-t     = [i for i in range(hopsize)]
-#tlong = [i for i in range(hopsize*(btstep-1))]
-#tall  = [i for i in range(hopsize*btstep)]
-sig    = [0 for i in range(hopsize*btstep*4)]
-dfx = [i for i in range(winlen)]
-dfframe = [0 for i in range(winlen)]
-dfrev = [0 for i in range(winlen)]
-acframe = [0 for i in range(winlen/2)]
-
-localacf = [0 for i in range(winlen)]
-inds = [0 for i in range(maxnumelem)]
-
-acx = [i for i in range(laglen)]
-acfout  = [0 for i in range(laglen)]
-
-phwv  = [0 for i in range(2*laglen)]
-phwvx = [i for i in range(2*laglen)]
-
-dfwvnorm = exp(log(2.0)*(winlen+2.)/rayparam);
-dfwv = [exp(log(2.)*(i+1.)/rayparam)/dfwvnorm for i in range(winlen)]
-
-gwv = [exp(-.5*(j+1.-g_mu)**2/g_var**2) for j in range(laglen)]
-rwv = [(i+1.)/rayparam**2 * exp(-(i+1.)**2 / (2.*rayparam)**2)
-        for i in range(0,laglen)] 
-acf = fvec(winlen,1)
-
-nrframe = 0
-while (task.readsize == params.hopsize):
-  task()
-  #print task.pos2
-  sig[:-hopsize] = [i for i in sig[-(btstep*4-1)*hopsize:]]
-  sig[-hopsize:] = [task.myvec.get(i,0) for i in t]
-
-  #g('set xrange [%f:%f]' % (t[0],t[-1]))
-  #time.sleep(.2)
-  if task.pos2==btstep-1:
-    nrframe += 1
-    dfframe = [task.dfframe.get(i,0) for i in range(winlen)]
-    # start beattracking_do
-    for i in range(winlen):
-      dfrev[winlen-1-i] = 0.
-      dfrev[winlen-1-i] = dfframe[i]*dfwv[i]
-    aubio_autocorr(task.dfframe(),acf()); 
-    acframe = [acf.get(i,0) for i in range(winlen/2)]
-    if printframe == nrframe or printframe == -1:
-      d  = [[plotdata(range(0,btstep*hopsize*4,4),sig[0:-1:4],plottitle="input signal", with='lines')]]
-      d  += [[plotdata(range(-winlen,0),dfframe,plottitle="onset detection", with='lines')]]
-      d  += [[plotdata(range(winlen/2),acframe,plottitle="autocorrelation", with='lines')]]
-
-    # plot all this
-    if printframe == nrframe or printframe == -1:
-
-      f('set lmargin 4')
-      f('set rmargin 4')
-      f('set size %f,%f' % (1.0*xsize,1.0*ysize) )
-      f('set key spacing 1.3')
-      f('set multiplot')
-
-      f('set size %f,%f' % (1.0*xsize,0.33*ysize) )
-      f('set orig %f,%f' % (0.0*xsize,0.66*ysize) )
-      f('set xrange [%f:%f]' % (0,btstep*hopsize*4) )
-      f('set yrange [%f:%f]' % (-1.2*max(sig),1.2*max(sig)) )
-      f.title('Input signal')
-      f.xlabel('time (samples)')
-      f.plot(*d[0])
-      f('set size %f,%f' % (1.0*xsize,0.33*ysize) )
-      f('set orig %f,%f' % (0.0*xsize,0.33*ysize) )
-      f('set xrange [%f:%f]' % (-winlen,0) )
-      f('set autoscale y')
-      f.title('Onset detection function')
-      f.xlabel('time (df samples)')
-      f.plot(*d[1])
-      f('set size %f,%f' % (1.0*xsize,0.33*ysize) )
-      f('set orig %f,%f' % (0.0*xsize,0.00*ysize) )
-      f('set xrange [%f:%f]' % (0,winlen/2) )
-      f.title('Autocorrelation')
-      f.xlabel('lag (df samples)')
-      f.plot(*d[2])
-      f('set nomultiplot')
-    if printframe == -1: a = sys.stdin.read()
-    elif 0 < printframe and printframe < nrframe:
-      break
--- a/tests/python/examples/aubioonset.py
+++ /dev/null
@@ -1,41 +1,0 @@
-from template import program_test_case
-
-class aubioonset_unit(program_test_case):
-  
-  import os.path
-  filename = os.path.join('..','..','sounds','woodblock.aiff')
-  progname = os.path.join('..','..','examples','aubioonset')
-
-  def test_aubioonset_with_inf_silence(self):
-    """ test aubioonset with -s 0  """
-    self.command += " -s 0" 
-    self.getOutput()
-    assert len(self.output) == 0, self.output
-
-class aubioonset_unit_finds_onset(aubioonset_unit):
-
-  def test_aubioonset(self):
-    """ test aubioonset with default parameters """
-    self.getOutput()
-    assert len(str(self.output)) != 0, "no output produced with command:\n" \
-      + self.command
-
-  def test_aubioonset_with_no_silence(self):
-    """ test aubioonset with -s -100 """ 
-    self.command += " -s -100 " 
-    self.getOutput()
-    # only one onset in woodblock.aiff
-    self.assertNotEqual(0, len(str(self.output)), \
-      "no output produced with command:\n" + self.command)
-    self.assertEqual(1, len(self.output.split('\n')) )
-    # onset should be at 0.00000
-    self.assertEqual(0, float(self.output.strip()))
-
-list_of_onset_modes = ["energy", "specdiff", "hfc", "complex", "phase", \
-                      "kl", "mkl", "specflux"]
-
-for name in list_of_onset_modes:
-  exec("class aubioonset_"+name+"_unit(aubioonset_unit):\n\
-  options = \" -O "+name+" \"")
-
-if __name__ == '__main__': unittest.main()
--- a/tests/python/examples/aubiopitch.py
+++ /dev/null
@@ -1,69 +1,0 @@
-from template import *
-
-import os.path
-
-class aubiopitch_test_case(program_test_case):
-
-  import os.path
-  filename = os.path.join('..','..','sounds','woodblock.aiff')
-  progname = "PYTHONPATH=../../python:../../python/aubio/.libs " + \
-              os.path.join('..','..','python','aubiopitch')
-
-  def test_aubiopitch(self):
-    """ test aubiopitch with default parameters """
-    self.getOutput()
-    # FIXME: useless check
-    self.assertEqual(len(self.output.split('\n')), 1)
-    #self.assertEqual(float(self.output.strip()), 0.)
-
-  def test_aubiopitch_verbose(self):
-    """ test aubiopitch with -v parameter """
-    self.command += " -v "
-    self.getOutput()
-    # FIXME: loose checking: make sure at least 8 lines are printed
-    assert len(self.output) >= 8
-
-  def test_aubiopitch_devnull(self):
-    """ test aubiopitch on /dev/null """
-    self.filename = "/dev/null"
-    # exit status should not be 0
-    self.getOutput(expected_status = 256)
-    # and there should be an error message
-    assert len(self.output) > 0
-    # that looks like this 
-    output_lines = self.output.split('\n')
-    #assert output_lines[0] == "Unable to open input file /dev/null."
-    #assert output_lines[1] == "Supported file format but file is malformed."
-    #assert output_lines[2] == "Could not open input file /dev/null."
-
-mode_names = ["yinfft", "yin", "fcomb", "mcomb", "schmitt"]
-for name in mode_names:
-  exec("class aubiopitch_test_case_" + name + "(aubiopitch_test_case):\n\
-    options = \" -m " + name + " \"")
-
-class aubiopitch_test_yinfft(program_test_case):
-
-  filename = os.path.join('..','..','sounds','16568__acclivity__TwoCows.wav')
-  url = "http://www.freesound.org/samplesViewSingle.php?id=16568"
-  progname = "PYTHONPATH=../../python:../../python/aubio/.libs " + \
-              os.path.join('..','..','python','aubiopitch')
-  options  = " -m yinfft -t 0.75 "
-
-  def test_aubiopitch(self):
-    """ test aubiopitch with default parameters """
-    if not os.path.isfile(self.filename):
-      print "Warning: file 16568_acclivity_TwoCows.wav was not found in %s" % os.path.dirname(self.filename) 
-      print "download it from %s to actually run test" % url
-      return
-    self.getOutput()
-    expected_output = open(os.path.join('examples','aubiopitch','yinfft'+'.'+os.path.basename(self.filename)+'.txt')).read()
-    lines = 0
-    for line_out, line_exp in zip(self.output.split('\n'), expected_output.split('\n')):
-      try:
-        assert line_exp == line_out, line_exp + " vs. " + line_out + " at line " + str(lines)
-      except:
-        open(os.path.join('examples','aubiopitch','yinfft'+'.'+os.path.basename(self.filename)+'.txt.out'),'w').write(self.output)
-        raise
-      lines += 1
-
-if __name__ == '__main__': unittest.main()
--- a/tests/python/examples/aubiopitch/yinfft.16568__acclivity__TwoCows.wav.txt
+++ /dev/null
@@ -1,566 +1,0 @@
-0.0232199546485	-1.0
-0.0464399092971	-1.0
-0.0696598639456	-1.0
-0.0928798185941	-1.0
-0.116099773243	-1.0
-0.139319727891	-1.0
-0.16253968254	-1.0
-0.185759637188	-1.0
-0.208979591837	-1.0
-0.232199546485	-1.0
-0.255419501134	-1.0
-0.278639455782	-1.0
-0.301859410431	-1.0
-0.325079365079	-1.0
-0.348299319728	-1.0
-0.371519274376	-1.0
-0.394739229025	-1.0
-0.417959183673	-1.0
-0.441179138322	-1.0
-0.464399092971	-1.0
-0.487619047619	-1.0
-0.510839002268	-1.0
-0.534058956916	-1.0
-0.557278911565	-1.0
-0.580498866213	-1.0
-0.603718820862	-1.0
-0.62693877551	-1.0
-0.650158730159	-1.0
-0.673378684807	-1.0
-0.696598639456	-1.0
-0.719818594104	-1.0
-0.743038548753	-1.0
-0.766258503401	-1.0
-0.78947845805	-1.0
-0.812698412698	-1.0
-0.835918367347	-1.0
-0.859138321995	-1.0
-0.882358276644	-1.0
-0.905578231293	-1.0
-0.928798185941	-1.0
-0.95201814059	-1.0
-0.975238095238	-1.0
-0.998458049887	-1.0
-1.02167800454	-1.0
-1.04489795918	-1.0
-1.06811791383	392.768096924
-1.09133786848	115.522140503
-1.11455782313	116.574150085
-1.13777777778	117.720863342
-1.16099773243	120.00163269
-1.18421768707	123.633300781
-1.20743764172	426.787963867
-1.23065759637	141.312179565
-1.25387755102	144.336975098
-1.27709750567	148.604934692
-1.30031746032	150.864654541
-1.32353741497	154.889007568
-1.34675736961	156.505081177
-1.36997732426	158.878829956
-1.39319727891	160.931289673
-1.41641723356	163.155059814
-1.43963718821	324.814025879
-1.46285714286	167.016983032
-1.48607709751	168.871704102
-1.50929705215	170.665634155
-1.5325170068	172.353149414
-1.55573696145	174.764205933
-1.5789569161	176.318893433
-1.60217687075	178.282669067
-1.6253968254	179.82383728
-1.64861678005	181.488952637
-1.67183673469	183.1927948
-1.69505668934	184.449371338
-1.71827664399	185.715484619
-1.74149659864	186.702224731
-1.76471655329	187.907455444
-1.78793650794	188.703475952
-1.81115646259	189.502182007
-1.83437641723	190.250213623
-1.85759637188	190.834747314
-1.88081632653	190.98348999
-1.90403628118	190.847137451
-1.92725623583	190.805847168
-1.95047619048	191.00831604
-1.97369614512	191.377182007
-1.99691609977	191.935241699
-2.02013605442	192.395782471
-2.04335600907	192.534378052
-2.06657596372	192.404174805
-2.08979591837	192.085708618
-2.11301587302	191.410400391
-2.13623582766	191.070388794
-2.15945578231	190.677963257
-2.18267573696	190.020675659
-2.20589569161	189.669265747
-2.22911564626	189.298828125
-2.25233560091	188.546142578
-2.27555555556	186.856491089
-2.2987755102	184.917297363
-2.32199546485	183.044509888
-2.3452154195	181.399368286
-2.36843537415	179.126312256
-2.3916553288	175.22946167
-2.41487528345	171.139190674
-2.4380952381	338.55368042
-2.46131519274	162.799713135
-2.48453514739	320.075500488
-2.50775510204	148.602432251
-2.53097505669	139.503982544
-2.55419501134	340.922271729
-2.57741496599	326.436950684
-2.60063492063	333.484558105
-2.62385487528	-1.0
-2.64707482993	-1.0
-2.67029478458	-1.0
-2.69351473923	-1.0
-2.71673469388	-1.0
-2.73995464853	-1.0
-2.76317460317	-1.0
-2.78639455782	-1.0
-2.80961451247	-1.0
-2.83283446712	-1.0
-2.85605442177	-1.0
-2.87927437642	-1.0
-2.90249433107	-1.0
-2.92571428571	-1.0
-2.94893424036	-1.0
-2.97215419501	-1.0
-2.99537414966	-1.0
-3.01859410431	-1.0
-3.04181405896	-1.0
-3.06503401361	-1.0
-3.08825396825	-1.0
-3.1114739229	-1.0
-3.13469387755	-1.0
-3.1579138322	-1.0
-3.18113378685	-1.0
-3.2043537415	-1.0
-3.22757369615	-1.0
-3.25079365079	-1.0
-3.27401360544	-1.0
-3.29723356009	-1.0
-3.32045351474	-1.0
-3.34367346939	-1.0
-3.36689342404	-1.0
-3.39011337868	-1.0
-3.41333333333	-1.0
-3.43655328798	-1.0
-3.45977324263	-1.0
-3.48299319728	-1.0
-3.50621315193	-1.0
-3.52943310658	-1.0
-3.55265306122	-1.0
-3.57587301587	-1.0
-3.59909297052	-1.0
-3.62231292517	-1.0
-3.64553287982	-1.0
-3.66875283447	-1.0
-3.69197278912	-1.0
-3.71519274376	-1.0
-3.73841269841	-1.0
-3.76163265306	-1.0
-3.78485260771	-1.0
-3.80807256236	-1.0
-3.83129251701	-1.0
-3.85451247166	-1.0
-3.8777324263	-1.0
-3.90095238095	-1.0
-3.9241723356	-1.0
-3.94739229025	-1.0
-3.9706122449	-1.0
-3.99383219955	-1.0
-4.0170521542	-1.0
-4.04027210884	-1.0
-4.06349206349	-1.0
-4.08671201814	-1.0
-4.10993197279	-1.0
-4.13315192744	-1.0
-4.15637188209	-1.0
-4.17959183673	-1.0
-4.20281179138	-1.0
-4.22603174603	-1.0
-4.24925170068	-1.0
-4.27247165533	-1.0
-4.29569160998	-1.0
-4.31891156463	-1.0
-4.34213151927	-1.0
-4.36535147392	-1.0
-4.38857142857	-1.0
-4.41179138322	-1.0
-4.43501133787	-1.0
-4.45823129252	-1.0
-4.48145124717	-1.0
-4.50467120181	-1.0
-4.52789115646	-1.0
-4.55111111111	-1.0
-4.57433106576	-1.0
-4.59755102041	-1.0
-4.62077097506	-1.0
-4.64399092971	-1.0
-4.66721088435	-1.0
-4.690430839	-1.0
-4.71365079365	-1.0
-4.7368707483	-1.0
-4.76009070295	-1.0
-4.7833106576	-1.0
-4.80653061224	-1.0
-4.82975056689	-1.0
-4.85297052154	-1.0
-4.87619047619	-1.0
-4.89941043084	-1.0
-4.92263038549	-1.0
-4.94585034014	-1.0
-4.96907029478	-1.0
-4.99229024943	-1.0
-5.01551020408	-1.0
-5.03873015873	-1.0
-5.06195011338	-1.0
-5.08517006803	-1.0
-5.10839002268	-1.0
-5.13160997732	-1.0
-5.15482993197	-1.0
-5.17804988662	-1.0
-5.20126984127	-1.0
-5.22448979592	-1.0
-5.24770975057	-1.0
-5.27092970522	-1.0
-5.29414965986	-1.0
-5.31736961451	-1.0
-5.34058956916	-1.0
-5.36380952381	-1.0
-5.38702947846	-1.0
-5.41024943311	-1.0
-5.43346938776	-1.0
-5.4566893424	-1.0
-5.47990929705	-1.0
-5.5031292517	-1.0
-5.52634920635	-1.0
-5.549569161	-1.0
-5.57278911565	-1.0
-5.59600907029	-1.0
-5.61922902494	-1.0
-5.64244897959	-1.0
-5.66566893424	-1.0
-5.68888888889	-1.0
-5.71210884354	-1.0
-5.73532879819	-1.0
-5.75854875283	-1.0
-5.78176870748	-1.0
-5.80498866213	-1.0
-5.82820861678	-1.0
-5.85142857143	-1.0
-5.87464852608	-1.0
-5.89786848073	-1.0
-5.92108843537	-1.0
-5.94430839002	-1.0
-5.96752834467	-1.0
-5.99074829932	-1.0
-6.01396825397	-1.0
-6.03718820862	-1.0
-6.06040816327	-1.0
-6.08362811791	-1.0
-6.10684807256	-1.0
-6.13006802721	-1.0
-6.15328798186	-1.0
-6.17650793651	-1.0
-6.19972789116	-1.0
-6.2229478458	-1.0
-6.24616780045	-1.0
-6.2693877551	-1.0
-6.29260770975	-1.0
-6.3158276644	-1.0
-6.33904761905	-1.0
-6.3622675737	-1.0
-6.38548752834	-1.0
-6.40870748299	-1.0
-6.43192743764	-1.0
-6.45514739229	-1.0
-6.47836734694	-1.0
-6.50158730159	187.887435913
-6.52480725624	143.988250732
-6.54802721088	147.904678345
-6.57124716553	151.674087524
-6.59446712018	3221.32983398
-6.61768707483	3159.02587891
-6.64090702948	160.395706177
-6.66412698413	162.535690308
-6.68734693878	164.282516479
-6.71056689342	166.054779053
-6.73378684807	167.578659058
-6.75700680272	169.234619141
-6.78022675737	171.029663086
-6.80344671202	173.257110596
-6.82666666667	174.64654541
-6.84988662132	175.149429321
-6.87310657596	175.456039429
-6.89632653061	176.283660889
-6.91954648526	177.318511963
-6.94276643991	178.066696167
-6.96598639456	178.517211914
-6.98920634921	179.053573608
-7.01242630385	179.549285889
-7.0356462585	180.029403687
-7.05886621315	180.64515686
-7.0820861678	180.8934021
-7.10530612245	180.952774048
-7.1285260771	181.48147583
-7.15174603175	182.092208862
-7.17496598639	183.082504272
-7.19818594104	183.907089233
-7.22140589569	184.607666016
-7.24462585034	185.0181427
-7.26784580499	185.282440186
-7.29106575964	185.946502686
-7.31428571429	186.74571228
-7.33750566893	187.205505371
-7.36072562358	187.595703125
-7.38394557823	187.939483643
-7.40716553288	188.01159668
-7.43038548753	187.807418823
-7.45360544218	187.751464844
-7.47682539683	187.811416626
-7.50004535147	187.951507568
-7.52326530612	188.168029785
-7.54648526077	188.630828857
-7.56970521542	188.946014404
-7.59292517007	189.095901489
-7.61614512472	189.302886963
-7.63936507937	189.673339844
-7.66258503401	189.881591797
-7.68580498866	189.865234375
-7.70902494331	189.865234375
-7.73224489796	189.595870972
-7.75546485261	188.954116821
-7.77868480726	188.192108154
-7.8019047619	187.352645874
-7.82512471655	186.524551392
-7.8483446712	184.967712402
-7.87156462585	183.589355469
-7.8947845805	182.828231812
-7.91800453515	181.968215942
-7.9412244898	180.796981812
-7.96444444444	180.0
-7.98766439909	179.184524536
-8.01088435374	178.799484253
-8.03410430839	178.29347229
-8.05732426304	178.088272095
-8.08054421769	177.894317627
-8.10376417234	177.693618774
-8.12698412698	177.905075073
-8.15020408163	178.041549683
-8.17342403628	178.045135498
-8.19664399093	177.650650024
-8.21986394558	177.32208252
-8.24308390023	176.611938477
-8.26630385488	175.525878906
-8.28952380952	172.121078491
-8.31274376417	584.997009277
-8.33596371882	575.042358398
-8.35918367347	465.681121826
-8.38240362812	447.307037354
-8.40562358277	-1.0
-8.42884353741	-1.0
-8.45206349206	-1.0
-8.47528344671	-1.0
-8.49850340136	-1.0
-8.52172335601	-1.0
-8.54494331066	-1.0
-8.56816326531	-1.0
-8.59138321995	-1.0
-8.6146031746	-1.0
-8.63782312925	-1.0
-8.6610430839	-1.0
-8.68426303855	-1.0
-8.7074829932	-1.0
-8.73070294785	-1.0
-8.75392290249	-1.0
-8.77714285714	-1.0
-8.80036281179	-1.0
-8.82358276644	-1.0
-8.84680272109	-1.0
-8.87002267574	-1.0
-8.89324263039	-1.0
-8.91646258503	-1.0
-8.93968253968	-1.0
-8.96290249433	-1.0
-8.98612244898	-1.0
-9.00934240363	-1.0
-9.03256235828	-1.0
-9.05578231293	-1.0
-9.07900226757	-1.0
-9.10222222222	-1.0
-9.12544217687	-1.0
-9.14866213152	-1.0
-9.17188208617	-1.0
-9.19510204082	-1.0
-9.21832199546	-1.0
-9.24154195011	-1.0
-9.26476190476	-1.0
-9.28798185941	-1.0
-9.31120181406	-1.0
-9.33442176871	-1.0
-9.35764172336	-1.0
-9.380861678	-1.0
-9.40408163265	-1.0
-9.4273015873	-1.0
-9.45052154195	-1.0
-9.4737414966	-1.0
-9.49696145125	-1.0
-9.5201814059	-1.0
-9.54340136054	-1.0
-9.56662131519	-1.0
-9.58984126984	-1.0
-9.61306122449	-1.0
-9.63628117914	-1.0
-9.65950113379	-1.0
-9.68272108844	-1.0
-9.70594104308	-1.0
-9.72916099773	-1.0
-9.75238095238	-1.0
-9.77560090703	-1.0
-9.79882086168	-1.0
-9.82204081633	-1.0
-9.84526077098	-1.0
-9.86848072562	-1.0
-9.89170068027	-1.0
-9.91492063492	-1.0
-9.93814058957	-1.0
-9.96136054422	-1.0
-9.98458049887	-1.0
-10.0078004535	-1.0
-10.0310204082	-1.0
-10.0542403628	-1.0
-10.0774603175	-1.0
-10.1006802721	-1.0
-10.1239002268	-1.0
-10.1471201814	-1.0
-10.1703401361	-1.0
-10.1935600907	-1.0
-10.2167800454	-1.0
-10.24	-1.0
-10.2632199546	-1.0
-10.2864399093	100.193115234
-10.3096598639	-1.0
-10.3328798186	326.038757324
-10.3560997732	104.222053528
-10.3793197279	105.370048523
-10.4025396825	106.595123291
-10.4257596372	107.893875122
-10.4489795918	108.992500305
-10.4721995465	109.93119812
-10.4954195011	110.819335938
-10.5186394558	112.031303406
-10.5418594104	113.389472961
-10.5650793651	114.239830017
-10.5882993197	116.827377319
-10.6115192744	119.250427246
-10.634739229	122.184356689
-10.6579591837	148.222839355
-10.6811791383	150.104660034
-10.704399093	153.361968994
-10.7276190476	155.115112305
-10.7508390023	158.433624268
-10.7740589569	161.372955322
-10.7972789116	163.421096802
-10.8204988662	167.165771484
-10.8437188209	170.329452515
-10.8669387755	173.311584473
-10.8901587302	175.445571899
-10.9133786848	177.304244995
-10.9365986395	179.024490356
-10.9598185941	180.073501587
-10.9830385488	180.826629639
-11.0062585034	181.559936523
-11.029478458	182.487792969
-11.0526984127	183.303192139
-11.0759183673	183.976135254
-11.099138322	184.650161743
-11.1223582766	185.613876343
-11.1455782313	186.123062134
-11.1687981859	186.852523804
-11.1920181406	187.531890869
-11.2152380952	188.232284546
-11.2384580499	189.20135498
-11.2616780045	189.485900879
-11.2848979592	190.094390869
-11.3081179138	190.636749268
-11.3313378685	191.252670288
-11.3545578231	191.647476196
-11.3777777778	192.673187256
-11.4009977324	193.018920898
-11.4242176871	193.641860962
-11.4474376417	194.307373047
-11.4706575964	194.234619141
-11.493877551	194.290252686
-11.5170975057	194.641845703
-11.5403174603	194.663314819
-11.563537415	194.719177246
-11.5867573696	194.149108887
-11.6099773243	194.166213989
-11.6331972789	194.136291504
-11.6564172336	193.786529541
-11.6796371882	192.605865479
-11.7028571429	190.785202026
-11.7260770975	188.578399658
-11.7492970522	182.544433594
-11.7725170068	173.676742554
-11.7957369615	415.019744873
-11.8189569161	417.989685059
-11.8421768707	333.699066162
-11.8653968254	415.058837891
-11.88861678	352.025543213
-11.9118367347	-1.0
-11.9350566893	-1.0
-11.958276644	-1.0
-11.9814965986	-1.0
-12.0047165533	-1.0
-12.0279365079	-1.0
-12.0511564626	-1.0
-12.0743764172	-1.0
-12.0975963719	-1.0
-12.1208163265	-1.0
-12.1440362812	-1.0
-12.1672562358	-1.0
-12.1904761905	-1.0
-12.2136961451	-1.0
-12.2369160998	-1.0
-12.2601360544	-1.0
-12.2833560091	-1.0
-12.3065759637	-1.0
-12.3297959184	-1.0
-12.353015873	-1.0
-12.3762358277	-1.0
-12.3994557823	-1.0
-12.422675737	-1.0
-12.4458956916	-1.0
-12.4691156463	-1.0
-12.4923356009	-1.0
-12.5155555556	-1.0
-12.5387755102	-1.0
-12.5619954649	-1.0
-12.5852154195	-1.0
-12.6084353741	-1.0
-12.6316553288	-1.0
-12.6548752834	-1.0
-12.6780952381	-1.0
-12.7013151927	-1.0
-12.7245351474	-1.0
-12.747755102	-1.0
-12.7709750567	-1.0
-12.7941950113	-1.0
-12.817414966	-1.0
-12.8406349206	-1.0
-12.8638548753	-1.0
-12.8870748299	-1.0
-12.9102947846	-1.0
-12.9335147392	-1.0
-12.9567346939	-1.0
-12.9799546485	-1.0
-13.0031746032	-1.0
-13.0263945578	-1.0
-13.0496145125	-1.0
-13.0728344671	-1.0
-13.0960544218	-1.0
-13.1192743764	-1.0
-13.1424943311	-1.0
--- a/tests/src/io/test-sink.c
+++ b/tests/src/io/test-sink.c
@@ -33,8 +33,8 @@
     n_frames += read;
   } while ( read == hop_size );
 
-  PRINT_MSG("%d frames read from %s\n written to %s at %dHz\n",
-      n_frames, source_path, sink_path, samplerate);
+  PRINT_MSG("wrote %d frames at %dHz from %s written to %s\n",
+      n_frames, samplerate, source_path, sink_path);
 
 beach:
   del_aubio_source(i);
--- a/tests/src/io/test-source_multi.c
+++ b/tests/src/io/test-source_multi.c
@@ -43,9 +43,9 @@
   PRINT_MSG("read %d frames at %dHz (%d blocks) from %s\n", n_frames, samplerate,
     n_frames / hop_size, source_path);
 
+  del_fmat (mat);
   del_aubio_source (s);
 beach:
-  del_fmat (mat);
 
   return err;
 }
--- /dev/null
+++ b/tests/src/synth/test-sampler.c
@@ -1,0 +1,56 @@
+#include <aubio.h>
+#include "utils_tests.h"
+
+int main (int argc, char **argv)
+{
+  sint_t err = 0;
+
+  if (argc < 4) {
+    err = 2;
+    PRINT_ERR("not enough arguments\n");
+    PRINT_MSG("usage: %s <input_path> <output_path> <sample_path> [samplerate]\n", argv[0]);
+    return err;
+  }
+
+  uint_t samplerate = 0; // default is the samplerate of input_path
+  uint_t hop_size = 512;
+  uint_t n_frames = 0, read = 0;
+
+  char_t *source_path = argv[1];
+  char_t *sink_path = argv[2];
+  char_t *sample_path = argv[3];
+  if ( argc == 5 ) samplerate = atoi(argv[4]);
+
+  fvec_t *vec = new_fvec(hop_size);
+  aubio_source_t *source = new_aubio_source(source_path, samplerate, hop_size);
+  if (samplerate == 0 ) samplerate = aubio_source_get_samplerate(source);
+  aubio_sink_t *sink = new_aubio_sink(sink_path, samplerate);
+
+  aubio_sampler_t * sampler = new_aubio_sampler (samplerate, hop_size);
+
+  aubio_sampler_load (sampler, sample_path);
+
+  do {
+    aubio_source_do(source, vec, &read);
+    if (n_frames / hop_size == 10) {
+      aubio_sampler_play ( sampler );
+    }
+    if (n_frames / hop_size == 20) {
+      aubio_sampler_play ( sampler );
+    }
+    if (n_frames > 10.0 * samplerate) {
+      aubio_sampler_stop ( sampler );
+    }
+    aubio_sampler_do (sampler, vec, vec);
+    aubio_sink_do(sink, vec, read);
+    n_frames += read;
+  } while ( read == hop_size );
+
+  del_aubio_sampler(sampler);
+  del_aubio_source(source);
+  del_aubio_sink(sink);
+  del_fvec(vec);
+  aubio_cleanup();
+
+  return 0;
+}