From 98df9f419f7c3b10300eeaa57bdbb0ef12ca2d9f Mon Sep 17 00:00:00 2001 From: Paul Brossier Date: Sat, 28 May 2005 21:06:33 +0000 Subject: [PATCH] cleaned up getonsets, merged aubioonset and aubiocut, added some options --- python/aubio/aubioclass.py | 124 ++++++++++++--------------- python/aubiocut | 168 +++++++++++++++++++++++++++---------- python/aubioonset | 72 ---------------- 3 files changed, 178 insertions(+), 186 deletions(-) delete mode 100755 python/aubioonset diff --git a/python/aubio/aubioclass.py b/python/aubio/aubioclass.py index 612de508..ab900208 100644 --- a/python/aubio/aubioclass.py +++ b/python/aubio/aubioclass.py @@ -95,9 +95,7 @@ class onsetpick: self.myonset.set(self.myonset.get(0,0)*self.myonset2.get(0,0),0,0) return self.pp.do(self.myonset),self.myonset.get(0,0) -def getonsetsfunc(filein,threshold,silence,bufsize=1024,hopsize=512,mode='dual'): - #bufsize = 1024 - #hopsize = bufsize/2 +def getonsets(filein,threshold=0.2,silence=-70.,bufsize=1024,hopsize=512,mode='dual',localmin=False,storefunc=False): frameread = 0 filei = sndfile(filein) channels = filei.channels() @@ -105,86 +103,74 @@ def getonsetsfunc(filein,threshold,silence,bufsize=1024,hopsize=512,mode='dual') readsize = filei.read(hopsize,myvec) opick = onsetpick(bufsize,hopsize,channels,myvec,threshold,mode=mode) mylist = list() - #ovalist = [0., 0., 0., 0., 0., 0.] - ovalist = [0., 0., 0., 0., 0.] - ofunclist = [] + if localmin: + ovalist = [0., 0., 0., 0., 0.] + if storefunc: + ofunclist = [] while(readsize): readsize = filei.read(hopsize,myvec) isonset,val = opick.do(myvec) if (aubio_silence_detection(myvec(),silence)): isonset=0 - ovalist.append(val) - ovalist.pop(0) - ofunclist.append(val) + if localmin: + ovalist.append(val) + ovalist.pop(0) + if storefunc: + ofunclist.append(val) if (isonset == 1): - i=len(ovalist)-1 - # find local minima before peak - while ovalist[i-1] < ovalist[i] and i > 0: - i -= 1 - now = (frameread+1-i) - if now > 0 : - mylist.append(now) + if localmin: + i=len(ovalist)-1 + # find local minima before peak + while ovalist[i-1] < ovalist[i] and i > 0: + i -= 1 + now = (frameread+1-i) else: - now = 0 - mylist.append(now) - frameread += 1 - return mylist, ofunclist - - -def getonsetscausal(filein,threshold,silence,bufsize=1024,hopsize=512,mode='dual'): - frameread = 0 - filei = sndfile(filein) - channels = filei.channels() - myvec = fvec(hopsize,channels) - readsize = filei.read(hopsize,myvec) - opick = onsetpick(bufsize,hopsize,channels,myvec,threshold,mode=mode) - mylist = list() - while(readsize): - readsize = filei.read(hopsize,myvec) - isonset,val = opick.do(myvec) - if (aubio_silence_detection(myvec(),silence)): - isonset=0 - if (isonset == 1): - now = frameread + now = frameread if now > 0 : mylist.append(now) else: now = 0 mylist.append(now) frameread += 1 - return mylist + if storefunc: return mylist, ofunclist + else: return mylist + +def cutfile(filein,slicetimes,zerothres=0.002,bufsize=1024,hopsize=512): + frameread = 0 + readsize = hopsize + filei = sndfile(filein) + framestep = hopsize/(filei.samplerate()+0.) + channels = filei.channels() + newname = "%s%f%s" % ("/tmp/",0.0000000,filein[-4:]) + fileo = sndfile(newname,model=filei) + myvec = fvec(hopsize,channels) + mycopy = fvec(hopsize,channels) + while(readsize==hopsize): + readsize = filei.read(hopsize,myvec) + # write to current file + if len(slicetimes) and frameread >= slicetimes[0]: + slicetimes.pop(0) + # write up to 1st zero crossing + zerocross = 0 + while ( abs( myvec.get(zerocross,0) ) > zerothres ): + zerocross += 1 + writesize = fileo.write(zerocross,myvec) + fromcross = 0 + while (zerocross < readsize): + for i in range(channels): + mycopy.set(myvec.get(zerocross,i),fromcross,i) + fromcross += 1 + zerocross += 1 + del fileo + fileo = sndfile("%s%s%f%s%s" % + (filein.split(".")[0].split("/")[-1],".", + frameread*framestep,".",filein.split(".")[-1]),model=filei) + writesize = fileo.write(fromcross,mycopy) + else: + writesize = fileo.write(readsize,myvec) + frameread += 1 + del fileo -def getonsets(filein,threshold=0.2,silence=-70.,bufsize=1024,hopsize=512,mode='dual'): - frameread = 0 - filei = sndfile(filein) - channels = filei.channels() - samplerate= filei.samplerate() - myvec = fvec(hopsize,channels) - readsize = filei.read(hopsize,myvec) - opick = onsetpick(bufsize,hopsize,channels,myvec,threshold,mode=mode) - mylist = list() - #ovalist = [0., 0., 0., 0., 0., 0.] - ovalist = [0., 0., 0., 0., 0.] - while(readsize): - readsize = filei.read(hopsize,myvec) - isonset,val = opick.do(myvec) - if (aubio_silence_detection(myvec(),silence)): - isonset=0 - ovalist.append(val) - ovalist.pop(0) - if (isonset == 1): - i=len(ovalist)-1 - # find local minima before peak - while ovalist[i-1] < ovalist[i] and i > 0: - i -= 1 - now = (frameread+1-i) - if now > 0 : - mylist.append(now) - else: - now = 0 - mylist.append(now) - frameread += 1 - return mylist class pitchpick: def __init__(self,bufsize,hopsize,channels,myvec,srate): diff --git a/python/aubiocut b/python/aubiocut index 523aec97..a83038a3 100755 --- a/python/aubiocut +++ b/python/aubiocut @@ -1,53 +1,131 @@ -#!/usr/bin/python +#! /usr/bin/python """ this file was written by Paul Brossier it is released under the GNU/GPL license. """ +import sys +import numarray from aubio.aubioclass import * -bufsize = 1024 -hopsize = bufsize/2 - -def cutfile(filein,slicetimes,zerothres=0.002): - frameread = 0 - readsize = hopsize - filei = sndfile(filein) - framestep = hopsize/(filei.samplerate()+0.) - channels = filei.channels() - newname = "%s%f%s" % ("/tmp/",0.0000000,filein[-4:]) - fileo = sndfile(newname,model=filei) - myvec = fvec(hopsize,channels) - mycopy = fvec(hopsize,channels) - while(readsize==hopsize): - readsize = filei.read(hopsize,myvec) - # write to current file - if len(slicetimes) and frameread >= slicetimes[0]: - slicetimes.pop(0) - # write up to 1st zero crossing - zerocross = 0 - while ( abs( myvec.get(zerocross,0) ) > zerothres ): - zerocross += 1 - writesize = fileo.write(zerocross,myvec) - fromcross = 0 - while (zerocross < readsize): - for i in range(channels): - mycopy.set(myvec.get(zerocross,i),fromcross,i) - fromcross += 1 - zerocross += 1 - del fileo - fileo = sndfile("%s%s%f%s%s" % - (filein.split(".")[0].split("/")[-1],".", - frameread*framestep,".",filein.split(".")[-1]),model=filei) - writesize = fileo.write(fromcross,mycopy) - else: - writesize = fileo.write(readsize,myvec) - frameread += 1 - del fileo +usage = "usage: %s [options] -i soundfile" % sys.argv[0] -import sys -filename = sys.argv[1] -threshold = 0.2 -if (len(sys.argv) > 2): threshold = sys.argv[2] -onsets = getonsets(filename,threshold) -cutfile(filename,onsets) +def check_mode(option, opt, value, parser): + nvalue = parser.rargs[0] + if nvalue == 'complexdomain' : + setattr(parser.values, option.dest, complexdomain) + elif nvalue == 'hfc' : + setattr(parser.values, option.dest, hfc) + elif nvalue == 'phase' : + setattr(parser.values, option.dest, phase) + elif nvalue == 'specdiff' : + setattr(parser.values, option.dest, specdiff) + elif nvalue == 'energy' : + setattr(parser.values, option.dest, energy) + elif nvalue == 'dual' : + setattr(parser.values, option.dest, 'dual') + +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("-m","--mode", action="callback", + callback=check_mode, dest="mode", default='dual', + help="onsetdetection mode [default=dual] \ + complexdomain|hfc|phase|specdiff|energy|dual") + parser.add_option("-B","--bufsize", + action="store", dest="bufsize", default=1024, + help="buffer size [default=1024]") + parser.add_option("-H","--hopsize", + action="store", dest="hopsize", default=512, + help="overlap size [default=512]") + parser.add_option("-t","--threshold", + action="store", dest="threshold", default=0.3, + help="onset peak picking threshold [default=0.3]") + parser.add_option("-s","--silence", + action="store", dest="silence", default=-70, + help="silence threshold [default=-70]") + parser.add_option("-M","--mintol", + action="store", dest="mintol", default=0.048, + help="minimum inter onset interval [default=0.048]") + parser.add_option("-D","--delay", + action="store", dest="delay", default=0.022, + help="number of seconds to take back [default=0.022]") + parser.add_option("-L","--localmin", + action="store_true", dest="localmin", default=False, + help="use local minima after peak detection") + parser.add_option("-c","--cut", + action="store_true", dest="cut", default=False, + help="cut input sound file at detected labels \ + best used with option -L") + # to be implemented + # plotting functions + parser.add_option("-d","--derivative", + action="store_true", dest="derivative", default=False, + help="NOT IMPLEMENTED derivate onset detection function") + parser.add_option("-p","--plot", + action="store_true", dest="doplot", default=False, + help="NOT IMPLEMENTED draw plot") + parser.add_option("-O","--outplot", + action="store", dest="output-plot", default=None, + help="NOT IMPLEMENTED save plot to output.{ps,png}") + parser.add_option("-z","--zerocross", + action="store_true", dest="zerocross", default=False, + help="NOT IMPLEMENTED zero crossing matching") + parser.add_option("-b","--beat", + action="store_true", dest="beat", default=False, + help="NOT IMPLEMENTED output beat locations") + parser.add_option("-v","--verbose", + action="store_true", dest="verbose", default=False, + help="make lots of noise [default]") + parser.add_option("-q","--quiet", + action="store_false", dest="verbose", default=False, + help="be quiet") + (options, args) = parser.parse_args() + if not options.filename: + print "no file name given\n", usage + sys.exit(1) + return options, args + +options, args = parse_args() + +filename = options.filename +samplerate = float(sndfile(filename).samplerate()) +hopsize = options.hopsize +bufsize = options.bufsize +threshold = float(options.threshold) +silence = float(options.silence) +mintol = float(options.mintol)*samplerate/hopsize +delay = float(options.delay) + +if options.beat: + #onsets = getbeats(filename,threshold,silence,mode=options.mode) + exit("not implemented yet") +else: + onsets = getonsets(filename,threshold,silence, + mode=options.mode,localmin=options.localmin, + bufsize=bufsize,hopsize=hopsize) + +# take back system delay +if delay != 0: + for i in range(len(onsets)): + onsets[i] -= delay*samplerate/hopsize + +# prune doubled +if mintol > 0: + last = -2*mintol + newonsets = [] + for new in onsets: + if (new - last > mintol): + newonsets.append(new) + last = new + onsets = newonsets + +# print times in second +if options.verbose: + for i in onsets: print "%f" % (i*hopsize/samplerate) + +if options.cut: + cutfile(filename,onsets,bufsize=bufsize,hopsize=hopsize) diff --git a/python/aubioonset b/python/aubioonset deleted file mode 100755 index a66df402..00000000 --- a/python/aubioonset +++ /dev/null @@ -1,72 +0,0 @@ -#! /usr/bin/python - -import sys -import numarray -from aubio.aubioclass import * - -usage = "usage: %s [options] soundfile" % sys.argv[0] - -def check_mode(option, opt, value, parser): - nvalue = parser.rargs[0] - if nvalue == 'complexdomain' : - setattr(parser.values, option.dest, complexdomain) - elif nvalue == 'hfc' : - setattr(parser.values, option.dest, hfc) - elif nvalue == 'phase' : - setattr(parser.values, option.dest, phase) - elif nvalue == 'specdiff' : - setattr(parser.values, option.dest, specdiff) - elif nvalue == 'energy' : - setattr(parser.values, option.dest, energy) - elif nvalue == 'dual' : - setattr(parser.values, option.dest, 'dual') - -def parse_args(): - from optparse import OptionParser - parser = OptionParser(usage=usage) - parser.add_option("-m","--mode", action="callback", - callback=check_mode, dest="mode", default='dual', - help="onsetdetection mode [default=dual] \ - complexdomain|hfc|phase|specdiff|energy|dual") - parser.add_option("-o","--outplot", - action="store", dest="outplot", default=None, - help="be quiet [default=None]") - parser.add_option("-t","--threshold", - action="store", dest="threshold", default=0.3, - help="onset detection threshold [default=0.3]") - parser.add_option("-s","--silence", - action="store", dest="silence", default=-70, - help="silence [default=-70]") - parser.add_option("-M","--mintol", - action="store", dest="mintol", default=0.048, - help="minimum inter onset interval [default=0.048]") - parser.add_option("-v","--verbose", - action="store_true", dest="verbose", default=False, - help="make lots of noise") - parser.add_option("-q","--quiet", - action="store_false", dest="verbose", default=True, - help="be quiet [default]") - (options, args) = parser.parse_args() - if not len(args): - print "no file name given\n", usage - sys.exit(1) - return options, args - -options, args = parse_args() - -filename = args[0] -threshold = float(options.threshold) -silence = float(options.silence) - -#onsets = getonsets(filename,threshold,silence,mode=options.mode) -onsets = getonsetscausal(filename,threshold,silence,mode=options.mode) - -# print all -#for i in onsets: print i*512./44100. -# prune doubled -last = -10. -mintol = float(options.mintol) -for i in onsets: - new = i*512./44100. - if (new - last > mintol): print "%f" % new - last = new -- 2.26.2