From 5e491b3b070618e820e332e3d8196c0be3d3af3f Mon Sep 17 00:00:00 2001 From: Paul Brossier Date: Sun, 28 Aug 2005 17:58:31 +0000 Subject: [PATCH] massive changes from cam --- python/aubio/aubioclass.py | 173 ---------------------------------- python/aubio/gnuplot.py | 56 ++++++----- python/aubio/tasks.py | 185 +++++++++++++++++++++++++++++++++++++ python/aubiocut | 52 ++++++----- python/aubiopitch | 25 +++-- 5 files changed, 261 insertions(+), 230 deletions(-) create mode 100644 python/aubio/tasks.py diff --git a/python/aubio/aubioclass.py b/python/aubio/aubioclass.py index d28fdce0..b28fe492 100644 --- a/python/aubio/aubioclass.py +++ b/python/aubio/aubioclass.py @@ -105,179 +105,6 @@ class onsetpick: else: self.myonset.set(0.,0,0) return self.pp.do(self.myonset),self.myonset.get(0,0) -def check_onset_mode(option, opt, value, parser): - nvalue = parser.rargs[0] - if nvalue == 'complexdomain' or nvalue == 'complex' : - setattr(parser.values, option.dest, aubio_onset_complex) - elif nvalue == 'hfc' : - setattr(parser.values, option.dest, aubio_onset_hfc) - elif nvalue == 'phase' : - setattr(parser.values, option.dest, aubio_onset_phase) - elif nvalue == 'specdiff' : - setattr(parser.values, option.dest, aubio_onset_specdiff) - elif nvalue == 'energy' : - setattr(parser.values, option.dest, aubio_onset_energy) - elif nvalue == 'kl' : - setattr(parser.values, option.dest, aubio_onset_kl) - elif nvalue == 'mkl' : - setattr(parser.values, option.dest, aubio_onset_mkl) - elif nvalue == 'dual' : - setattr(parser.values, option.dest, 'dual') - else: - print "unknown onset detection function selected" - sys.exit(1) - -def check_pitch_mode(option, opt, value, parser): - nvalue = parser.rargs[0] - if nvalue == 'mcomb' : - setattr(parser.values, option.dest, aubio_pitch_mcomb) - elif nvalue == 'yin' : - setattr(parser.values, option.dest, aubio_pitch_yin) - elif nvalue == 'fcomb' : - setattr(parser.values, option.dest, aubio_pitch_fcomb) - elif nvalue == 'schmitt': - setattr(parser.values, option.dest, aubio_pitch_schmitt) - else: - print "error: unknown pitch detection function selected" - sys.exit(1) - -def check_pitchm_mode(option, opt, value, parser): - nvalue = parser.rargs[0] - if nvalue == 'freq' : - setattr(parser.values, option.dest, aubio_pitchm_freq) - elif nvalue == 'midi' : - setattr(parser.values, option.dest, aubio_pitchm_midi) - elif nvalue == 'cent' : - setattr(parser.values, option.dest, aubio_pitchm_cent) - elif nvalue == 'bin' : - setattr(parser.values, option.dest, aubio_pitchm_bin) - else: - print "error: unknown pitch detection output selected" - sys.exit(1) - - -def getonsets(filein,threshold=0.2,silence=-70.,bufsize=1024,hopsize=512, - mode='dual',localmin=False,storefunc=False,derivate=False): - 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,derivate=derivate) - mylist = list() - 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 - if localmin: - if val > 0: ovalist.append(val) - else: ovalist.append(0) - ovalist.pop(0) - if storefunc: - ofunclist.append(val) - if (isonset == 1): - 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 = frameread - if now > 0 : - mylist.append(now) - else: - now = 0 - mylist.append(now) - frameread += 1 - if storefunc: return mylist, ofunclist - else: return mylist - -def cutfile(filein,slicetimes,zerothres=0.008,bufsize=1024,hopsize=512): - frameread = 0 - readsize = hopsize - filei = sndfile(filein) - framestep = hopsize/(filei.samplerate()+0.) - channels = filei.channels() - newname = "%s%s%09.5f%s%s" % (filein.split(".")[0].split("/")[-1],".", - frameread*framestep,".",filein.split(".")[-1]) - 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%09.5f%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 getsilences(filein,hopsize=512,silence=-70): - frameread = 0 - filei = sndfile(filein) - srate = filei.samplerate() - channels = filei.channels() - myvec = fvec(hopsize,channels) - readsize = filei.read(hopsize,myvec) - mylist = [] - wassilence = 0 - while(readsize==hopsize): - readsize = filei.read(hopsize,myvec) - if (aubio_silence_detection(myvec(),silence)==1): - if wassilence == 0: - mylist.append(frameread) - wassilence == 1 - else: wassilence = 0 - frameread += 1 - return mylist - -def getpitch(filein,mode=aubio_pitch_mcomb,bufsize=1024,hopsize=512,omode=aubio_pitchm_freq, - samplerate=44100.,silence=-70): - frameread = 0 - filei = sndfile(filein) - srate = filei.samplerate() - channels = filei.channels() - myvec = fvec(hopsize,channels) - readsize = filei.read(hopsize,myvec) - pitchdet = pitchdetection(mode=mode,bufsize=bufsize,hopsize=hopsize, - channels=channels,samplerate=srate,omode=omode) - mylist = [] - while(readsize==hopsize): - readsize = filei.read(hopsize,myvec) - freq = pitchdet(myvec) - #print "%.3f %.2f" % (now,freq) - if (aubio_silence_detection(myvec(),silence)!=1): - mylist.append(freq) - else: - mylist.append(-1.) - frameread += 1 - return mylist - class pitchdetection: def __init__(self,mode=aubio_pitch_mcomb,bufsize=2048,hopsize=1024, channels=1,samplerate=44100.,omode=aubio_pitchm_freq): diff --git a/python/aubio/gnuplot.py b/python/aubio/gnuplot.py index e3bfebc7..15a80aec 100644 --- a/python/aubio/gnuplot.py +++ b/python/aubio/gnuplot.py @@ -150,17 +150,22 @@ def plot_onsets(filename, onsets, ofunc, samplerate=44100., hopsize=512, outplot import numarray from aubio.onsetcompare import onset_roc - if len(onsets) == 0: onsets = [0.]; - - # onset detection function - downtime = (hopsize/samplerate)*numarray.arange(len(ofunc)) - d = Gnuplot.Data(downtime,ofunc,with='lines') - - # detected onsets - x1 = (hopsize/samplerate)*numarray.array(onsets) - y1 = max(ofunc)*numarray.ones(len(onsets)) - e = Gnuplot.Data(x1,-y1,with='impulses') - e2= Gnuplot.Data(x1,y1,with='impulses') + d,d2 = [],[] + maxofunc = 0 + for i in range(len(onsets)): + if len(onsets[i]) == 0: onsets[i] = [0.]; + + # onset detection function + downtime = (hopsize/samplerate)*numarray.arange(len(ofunc[i])) + d.append(Gnuplot.Data(downtime,ofunc[i],with='lines')) + maxofunc = max(max(ofunc[i]), maxofunc) + + for i in range(len(onsets)): + # detected onsets + x1 = (hopsize/samplerate)*numarray.array(onsets[i]) + y1 = maxofunc*numarray.ones(len(onsets[i])) + d.append(Gnuplot.Data(x1,y1,with='impulses')) + d2.append(Gnuplot.Data(x1,-y1,with='impulses')) # check if datafile exists truth datafile = filename.replace('.wav','.txt') @@ -169,9 +174,9 @@ def plot_onsets(filename, onsets, ofunc, samplerate=44100., hopsize=512, outplot t = Gnuplot.Data(0,0,with='impulses') else: t_onsets = aubio.txtfile.read_datafile(datafile) - y2 = max(ofunc)*numarray.ones(len(t_onsets)) + y2 = maxofunc*numarray.ones(len(t_onsets)) x2 = numarray.array(t_onsets).resize(len(t_onsets)) - t = Gnuplot.Data(x2,y2,with='impulses') + d2.append(Gnuplot.Data(x2,y2,with='impulses')) tol = 0.050 @@ -188,7 +193,7 @@ def plot_onsets(filename, onsets, ofunc, samplerate=44100., hopsize=512, outplot # audio data time,data = audio_to_array(filename) - f = make_audio_plot(time,data) + d2.append(make_audio_plot(time,data)) # prepare the plot g = Gnuplot.Gnuplot(debug=1, persist=1) @@ -211,18 +216,18 @@ def plot_onsets(filename, onsets, ofunc, samplerate=44100., hopsize=512, outplot g('set xrange [0:%f]' % max(time)) g('set yrange [-1:1]') g.ylabel('amplitude') - g.plot(f,e,t) + g.plot(*d2) g('unset title') # plot onset detection function g('set size 1,0.7') g('set origin 0,0') - g('set xrange [0:%f]' % (hopsize/samplerate*len(ofunc))) - g('set yrange [0:%f]' % (max(ofunc)*1.01)) + g('set xrange [0:%f]' % (hopsize/samplerate*len(ofunc[0]))) + g('set yrange [0:%f]' % (maxofunc*1.01)) g.xlabel('time') g.ylabel('onset detection value') - g.plot(d,e2) + g.plot(*d) g('unset multiplot') @@ -232,9 +237,12 @@ def plot_pitch(filename, pitch, samplerate=44100., hopsize=512, outplot=None): import os.path import numarray - # onset detection function - downtime = (hopsize/samplerate)*numarray.arange(len(pitch)) - d = Gnuplot.Data(downtime,pitch,with='lines') + d = [] + maxpitch = 100 + for i in range(len(pitch)): + downtime = (hopsize/samplerate)*numarray.arange(len(pitch[i])) + d.append(Gnuplot.Data(downtime,pitch[i],with='lines')) + maxpitch = max(maxpitch,max(pitch[i][:])*1.1) # check if datafile exists truth datafile = filename.replace('.wav','.txt') @@ -290,10 +298,10 @@ def plot_pitch(filename, pitch, samplerate=44100., hopsize=512, outplot=None): # plot onset detection function g('set size 1,0.7') g('set origin 0,0') - g('set xrange [0:%f]' % (hopsize/samplerate*len(pitch))) - g('set yrange [0:%f]' % (max(pitch)*1.01)) + g('set xrange [0:%f]' % max(time)) + g('set yrange [40:%f]' % maxpitch) g.xlabel('time') g.ylabel('frequency (Hz)') - g.plot(d,t) + g.plot(*d) g('unset multiplot') diff --git a/python/aubio/tasks.py b/python/aubio/tasks.py new file mode 100644 index 00000000..be6bc75b --- /dev/null +++ b/python/aubio/tasks.py @@ -0,0 +1,185 @@ +from aubioclass import * + +def check_onset_mode(option, opt, value, parser): + """ utility function to convert a string to aubio_onsetdetection_type """ + nvalues = parser.rargs[0].split(',') + val = [] + for nvalue in nvalues: + if nvalue == 'complexdomain' or nvalue == 'complex' : + val.append(aubio_onset_complex) + elif nvalue == 'hfc' : + val.append(aubio_onset_hfc) + elif nvalue == 'phase' : + val.append(aubio_onset_phase) + elif nvalue == 'specdiff' : + val.append(aubio_onset_specdiff) + elif nvalue == 'energy' : + val.append(aubio_onset_energy) + elif nvalue == 'kl' : + val.append(aubio_onset_kl) + elif nvalue == 'mkl' : + val.append(aubio_onset_mkl) + elif nvalue == 'dual' : + val.append('dual') + else: + import sys + print "unknown onset detection function selected" + sys.exit(1) + setattr(parser.values, option.dest, val) + +def check_pitch_mode(option, opt, value, parser): + """ utility function to convert a string to aubio_pitchdetection_type""" + nvalues = parser.rargs[0].split(',') + val = [] + for nvalue in nvalues: + if nvalue == 'mcomb' : + val.append(aubio_pitch_mcomb) + elif nvalue == 'yin' : + val.append(aubio_pitch_yin) + elif nvalue == 'fcomb' : + val.append(aubio_pitch_fcomb) + elif nvalue == 'schmitt': + val.append(aubio_pitch_schmitt) + else: + import sys + print "error: unknown pitch detection function selected" + sys.exit(1) + setattr(parser.values, option.dest, val) + +def check_pitchm_mode(option, opt, value, parser): + """ utility function to convert a string to aubio_pitchdetection_mode """ + nvalue = parser.rargs[0] + if nvalue == 'freq' : + setattr(parser.values, option.dest, aubio_pitchm_freq) + elif nvalue == 'midi' : + setattr(parser.values, option.dest, aubio_pitchm_midi) + elif nvalue == 'cent' : + setattr(parser.values, option.dest, aubio_pitchm_cent) + elif nvalue == 'bin' : + setattr(parser.values, option.dest, aubio_pitchm_bin) + else: + import sys + print "error: unknown pitch detection output selected" + sys.exit(1) + + +def getonsets(filein,threshold=0.2,silence=-70.,bufsize=1024,hopsize=512, + mode='dual',localmin=False,storefunc=False,derivate=False): + 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,derivate=derivate) + mylist = list() + if localmin: + ovalist = [0., 0., 0., 0., 0.] + ofunclist = [] + while(readsize): + readsize = filei.read(hopsize,myvec) + isonset,val = opick.do(myvec) + if (aubio_silence_detection(myvec(),silence)): + isonset=0 + if localmin: + if val > 0: ovalist.append(val) + else: ovalist.append(0) + ovalist.pop(0) + if storefunc: + ofunclist.append(val) + if (isonset == 1): + 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 = frameread + if now > 0 : + mylist.append(now) + else: + now = 0 + mylist.append(now) + frameread += 1 + return mylist, ofunclist + +def cutfile(filein,slicetimes,zerothres=0.008,bufsize=1024,hopsize=512): + frameread = 0 + readsize = hopsize + filei = sndfile(filein) + framestep = hopsize/(filei.samplerate()+0.) + channels = filei.channels() + newname = "%s%s%09.5f%s%s" % (filein.split(".")[0].split("/")[-1],".", + frameread*framestep,".",filein.split(".")[-1]) + 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%09.5f%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 getsilences(filein,hopsize=512,silence=-70): + frameread = 0 + filei = sndfile(filein) + srate = filei.samplerate() + channels = filei.channels() + myvec = fvec(hopsize,channels) + readsize = filei.read(hopsize,myvec) + mylist = [] + wassilence = 0 + while(readsize==hopsize): + readsize = filei.read(hopsize,myvec) + if (aubio_silence_detection(myvec(),silence)==1): + if wassilence == 0: + mylist.append(frameread) + wassilence == 1 + else: wassilence = 0 + frameread += 1 + return mylist + +def getpitch(filein,mode=aubio_pitch_mcomb,bufsize=1024,hopsize=512,omode=aubio_pitchm_freq, + samplerate=44100.,silence=-70): + frameread = 0 + filei = sndfile(filein) + srate = filei.samplerate() + channels = filei.channels() + myvec = fvec(hopsize,channels) + readsize = filei.read(hopsize,myvec) + pitchdet = pitchdetection(mode=mode,bufsize=bufsize,hopsize=hopsize, + channels=channels,samplerate=srate,omode=omode) + mylist = [] + while(readsize==hopsize): + readsize = filei.read(hopsize,myvec) + freq = pitchdet(myvec) + #print "%.3f %.2f" % (now,freq) + if (aubio_silence_detection(myvec(),silence)!=1): + mylist.append(freq) + else: + mylist.append(-1.) + frameread += 1 + return mylist + diff --git a/python/aubiocut b/python/aubiocut index 11583ef8..d5fdd0b5 100755 --- a/python/aubiocut +++ b/python/aubiocut @@ -5,7 +5,7 @@ """ import sys -from aubio.aubioclass import * +from aubio.tasks import * usage = "usage: %s [options] -i soundfile" % sys.argv[0] @@ -88,6 +88,7 @@ threshold = float(options.threshold) zerothres = float(options.zerothres) silence = float(options.silence) mintol = float(options.mintol)*step +mode = options.mode # default take back system delay if options.delay: delay = float(options.delay) else: delay = 3./step @@ -97,39 +98,44 @@ if options.beat: exit("not implemented yet") elif options.silencecut: onsets = getsilences(filename,hopsize=hopsize,silence=silence) -elif options.plot: +elif options.plot: storefunc=True +else: storefunc=False + +lonsets, lofunc = [], [] +for i in range(len(mode)): onsets, ofunc = getonsets(filename,threshold,silence, - mode=options.mode,localmin=options.localmin, + mode=mode[i],localmin=options.localmin, derivate=options.derivate, bufsize=bufsize,hopsize=hopsize,storefunc=True) -else: - onsets = getonsets(filename,threshold,silence, - mode=options.mode,localmin=options.localmin, - derivate=options.derivate, - bufsize=bufsize,hopsize=hopsize) -# take back system delay -if delay != 0: - for i in range(len(onsets)): - onsets[i] -= delay*step + # take back system delay + if delay != 0: + for i in range(len(onsets)): + onsets[i] -= delay*step + + # prune doubled + if mintol > 0: + last = -2*mintol + newonsets = [] + for new in onsets: + if (new - last > mintol): + newonsets.append(new) + last = new + onsets = newonsets -# prune doubled -if mintol > 0: - last = -2*mintol - newonsets = [] - for new in onsets: - if (new - last > mintol): - newonsets.append(new) - last = new - onsets = newonsets + lonsets.append(onsets) + lofunc.append(ofunc) # print times in second if options.verbose: - for i in onsets: print "%f" % (i/step) + maxonset = 0 + for j in range(len(mode)): + for i in range(len(lonsets[j])): + print lonsets[j][i]/step if options.plot: from aubio.gnuplot import plot_onsets - plot_onsets(filename, onsets, ofunc, + plot_onsets(filename, lonsets, lofunc, samplerate=samplerate, hopsize=hopsize, outplot=options.outplot) if options.cut: diff --git a/python/aubiopitch b/python/aubiopitch index 525d5925..64f2bac0 100755 --- a/python/aubiopitch +++ b/python/aubiopitch @@ -4,9 +4,8 @@ it is released under the GNU/GPL license. """ - import sys -from aubio.aubioclass import * +from aubio.tasks import * usage = "usage: %s [options] -i soundfile" % sys.argv[0] @@ -73,6 +72,7 @@ def parse_args(): if options.mode == aubio_pitch_schmitt: options.bufsize = 2048 if options.mode == aubio_pitch_mcomb: options.bufsize = 4096 if options.mode == aubio_pitch_fcomb: options.bufsize = 4096 + else: options.bufsize = 2048 if not options.hopsize: options.hopsize = float(options.bufsize) / 2 if not options.filename: @@ -91,6 +91,7 @@ bufsize = int(options.bufsize) step = float(samplerate)/float(hopsize) threshold = float(options.threshold) silence = float(options.silence) +mode = options.mode #mintol = float(options.mintol)*step # default take back system delay if options.delay: delay = float(options.delay) @@ -99,11 +100,13 @@ else: delay = 2./step if options.note: exit("not implemented yet") else: - pitch = getpitch(filename, #threshold, - mode=options.mode, - omode=options.omode, - bufsize=bufsize,hopsize=hopsize, - silence=silence) + pitch = [] + for i in range(len(mode)): + pitch.append(getpitch(filename, #threshold, + mode=mode[i], + omode=options.omode, + bufsize=bufsize,hopsize=hopsize, + silence=silence)) ## take back system delay #if delay != 0: @@ -122,11 +125,13 @@ else: # print times in second if options.verbose: - for i in range(len(pitch)): - print "%f\t%f" % (i/step,pitch[i]) + for j in range(len(pitch[0])): + print "%f\t" % (j/step), + for i in range(len(pitch)): + print "%f\t" % pitch[i][j], + print if options.plot: from aubio.gnuplot import plot_pitch plot_pitch(filename, pitch, samplerate=samplerate, hopsize=hopsize, outplot=options.outplot) - -- 2.26.2