add aubioplot-onset, minor fixes on aubiocut and aubioclass.py
authorPaul Brossier <piem@altern.org>
Sun, 22 May 2005 22:40:33 +0000 (22:40 +0000)
committerPaul Brossier <piem@altern.org>
Sun, 22 May 2005 22:40:33 +0000 (22:40 +0000)
add aubioplot-onset, minor fixes on aubiocut and aubioclass.py

python/aubio/aubioclass.py
python/aubiocut
python/aubioplot-onset [new file with mode: 0755]

index a276b090d583ac076db41c3cd64ae1244b382592..612de508fa1e8d73e3ea04953b99b9ca254b2eda 100644 (file)
@@ -54,6 +54,7 @@ class pvoc:
         aubio_pvoc_rdo(self.pv,tc(),tf())
 
 class onsetdetection:
+    """ class for aubio_onsetdetection """
     def __init__(self,type,buf,chan):
         self.od = new_aubio_onsetdetection(type,buf,chan)
     def do(self,tc,tf):
@@ -62,6 +63,7 @@ class onsetdetection:
         aubio_onsetdetection_free(self.od)
 
 class peakpick:
+    """ class for aubio_peakpicker """
     def __init__(self,threshold=0.1):
         self.pp = new_aubio_peakpicker(threshold)
     def do(self,fv):
@@ -70,6 +72,7 @@ class peakpick:
         del_aubio_peakpicker(self.pp)
 
 class onsetpick:
+    """ superclass for aubio_pvoc + aubio_onsetdetection + aubio_peakpicker """
     def __init__(self,bufsize,hopsize,channels,myvec,threshold,mode='dual'):
         self.myfft    = cvec(bufsize,channels)
         self.pv       = pvoc(bufsize,hopsize,channels)
@@ -151,7 +154,6 @@ def getonsetscausal(filein,threshold,silence,bufsize=1024,hopsize=512,mode='dual
                 frameread += 1
         return mylist
 
-
 def getonsets(filein,threshold=0.2,silence=-70.,bufsize=1024,hopsize=512,mode='dual'):
         frameread = 0
         filei     = sndfile(filein)
@@ -184,7 +186,6 @@ def getonsets(filein,threshold=0.2,silence=-70.,bufsize=1024,hopsize=512,mode='d
                 frameread += 1
         return mylist
 
-
 class pitchpick:
     def __init__(self,bufsize,hopsize,channels,myvec,srate):
         self.myfft    = cvec(bufsize,channels)
index 39188b2e167a028ab9e4fc060d4aaffcbe43ac09..523aec9770c065be934ca2e2a2204c037efb2d2a 100755 (executable)
@@ -5,50 +5,49 @@
 """
 
 from aubio.aubioclass import *
-import sys
 
 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
 
-def cutfile(filein,onsets):
-        frameread = 0
-        zerothres = 0.002
-        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(onsets) and frameread >= onsets[0]:
-                    onsets.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
-
+import sys
 filename  = sys.argv[1]
-threshold = sys.argv[2]
+threshold = 0.2
+if (len(sys.argv) > 2): threshold = sys.argv[2]
 onsets    = getonsets(filename,threshold)
 cutfile(filename,onsets)
diff --git a/python/aubioplot-onset b/python/aubioplot-onset
new file mode 100755 (executable)
index 0000000..f43e57b
--- /dev/null
@@ -0,0 +1,124 @@
+#! /usr/bin/python
+
+import sys
+import numarray
+import Gnuplot, Gnuplot.funcutils
+from aubio.aubioclass import *
+import aubio.gnuplot
+import aubio.txtfile
+from aubio.onsetcompare import onset_roc
+
+
+usage = "usage: %s [options] soundfile" % sys.argv[0]
+
+def parse_args():
+        from optparse import OptionParser
+        parser = OptionParser(usage=usage)
+        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]")
+        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]")
+        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')
+        parser.add_option("-m","--mode",
+                          action="callback", callback=check_mode, dest="mode", default='dual', 
+                          help="onsetdetection mode [default=dual]")
+        parser.add_option("-o","--outplot",
+                          action="store", dest="outplot", default=None, 
+                          help="be quiet [default=None]")
+        (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] #FIXME should move to optparse
+threshold = float(options.threshold)
+silence   = float(options.silence)
+
+print options.mode
+onsets, ofunc   = getonsetsfunc(filename,threshold,silence,mode=options.mode)
+
+g = Gnuplot.Gnuplot(debug=1, persist=1)
+
+if options.outplot:
+        extension = options.outplot.split('.')[-1]
+        if extension == 'ps': extension = 'postscript'
+        g('set terminal %s' % extension)
+        g('set output \'%s\'' % options.outplot)
+
+g('set multiplot')
+
+# onset detection function 
+downtime = (512./44100.)*numarray.arange(len(ofunc))
+d = Gnuplot.Data(downtime,ofunc,with='lines') 
+
+# detected onsets
+x1 = (512./44100.)*numarray.array(onsets)
+y1 = max(ofunc)*numarray.ones(len(onsets))
+e = Gnuplot.Data(x1,-y1,with='impulses') 
+e2= Gnuplot.Data(x1,y1,with='impulses') 
+
+# truth
+import os.path
+datafile = filename.replace('.wav','.txt')
+if not os.path.isfile(datafile):
+        print "truth file not found"
+        t = Gnuplot.Data(0,0,with='impulses') 
+else:
+        t_onsets = aubio.txtfile.read_datafile(datafile)
+        y2 = max(ofunc)*numarray.ones(len(t_onsets))
+        x2 = numarray.array(t_onsets).resize(len(t_onsets))
+        t = Gnuplot.Data(x2,y2,with='impulses') 
+        
+        eps = 4*0.012 
+
+        orig, missed, merged, expc, bad, doubled = \
+                onset_roc(x2,x1,eps)
+        print  orig, missed, merged, expc, bad, doubled
+        print "GD %2.8f\t"        % (100*float(orig-missed-merged)/(orig)),
+        print "FP %2.8f\t"        % (100*float(bad+doubled)/(orig))       , 
+        print "GD-merged %2.8f\t" % (100*float(orig-missed)/(orig))       , 
+        print "FP-pruned %2.8f\t" % (100*float(bad)/(orig))                
+
+# audio data
+time,data = aubio.gnuplot.audio_to_array(filename)
+f = aubio.gnuplot.make_audio_plot(time,data)
+
+# hack to align left axis
+g('set lmargin 15')
+
+g('set size 1,0.3')
+g('set origin 0,0.7')
+g('set xrange [0:%f]' % max(time)) 
+g('set yrange [-1:1]') 
+g.ylabel('amplitude')
+g.plot(f,e,t)
+
+g('set size 1,0.7')
+g('set origin 0,0')
+g('set xrange [0:%f]' % (512./44100.*len(ofunc)))
+g('set yrange [0:%f]' % (max(ofunc)*1.01))
+g.xlabel('time')
+g.ylabel('onset detection value')
+
+g.plot(d,e2)
+
+g('unset multiplot')
+