ref: 93e34637b3c0f591e779b0a31d88a02859489dc7
dir: /tests/demo/bench/tempo/demo-tempo/
#! /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