History

merge from develop

Paul Brossier committed 13 years ago

Commit fc117d02 parents 5314432 88fc249129 files · +501 −1381Browse files

Showing the changes to python (87 of 129 files). Show all

Unified · Split

87 files
  1. python/Makefile.am +0 −5
  2. python/README +0 −30
  3. python/README.md +24 −0
  4. python/a_weighting_test_simple.expected +2 −0
  5. python/aubio-types.h +49 −0
  6. python/aubio/Makefile.am +0 −66
  7. python/aubio/__init__.py +7 −26
  8. python/aubio/aubioclass.py +0 −160
  9. python/aubio/bench/__init__.py +0 −0
  10. python/aubio/bench/broadcast.py +0 −25
  11. python/aubio/bench/config.py +0 −22
  12. python/aubio/bench/node.py +0 −224
  13. python/aubio/bench/onset.py +0 −303
  14. python/aubio/gnuplot.py +0 −222
  15. python/aubio/median.py +0 −69
  16. python/aubio/onsetcompare.py +0 −143
  17. python/aubio/plot/__init__.py +0 −0
  18. python/aubio/plot/keyboard.py +0 −46
  19. python/aubio/plot/notes.py +0 −90
  20. python/aubio/task/__init__.py +0 −9
  21. python/aubio/task/beat.py +0 −262
  22. python/aubio/task/cut.py +0 −42
  23. python/aubio/task/notes.py +0 −159
  24. python/aubio/task/onset.py +0 −220
  25. python/aubio/task/params.py +0 −33
  26. python/aubio/task/pitch.py +0 −234
  27. python/aubio/task/silence.py +0 −28
  28. python/aubio/task/task.py +0 −53
  29. python/aubio/txtfile.py +0 −47
  30. python/aubio/web/__init__.py +0 −0
  31. python/aubio/web/browser.py +0 −167
  32. python/aubio/web/html.py +0 −286
  33. python/aubio/wscript_build +0 −17
  34. python/aubiocompare-onset +0 −114
  35. python/aubiocut +0 −156
  36. python/aubiodiffs-onset +0 −86
  37. python/aubiofilter-notes +0 −94
  38. python/aubioinput.py +141 −0
  39. python/aubiomodule.c +161 −0
  40. python/aubionotes +0 −79
  41. python/aubiopitch +0 −131
  42. python/aubioplot-audio +0 −31
  43. python/aubioplot-notes +0 −31
  44. python/aubioplot-spec +0 −51
  45. python/aubioplot-yinfft +0 −135
  46. python/aubioproxy.c +153 −0
  47. python/aubioweb.py +0 −113
  48. python/aubiowraphell.h +90 −0
  49. python/bench-cluster-test +0 −9
  50. python/bench-test +0 −13
  51. python/build_linux +9 −0
  52. python/build_osx +9 −0
  53. python/c_weighting_test_simple.expected +2 −0
  54. python/demos/demo_beats_and_tempo.py +39 −0
  55. python/demos/demo_filterbank_slaney.py +21 −0
  56. python/demos/demo_filterbank_triangle_bands.py +47 −0
  57. python/demos/demo_onset_sinusoid.py +84 −0
  58. python/demos/demo_pitch_sinusoid.py +68 −0
  59. python/demos/demo_simple_robot_voice.py +29 −0
  60. python/demos/demo_sink.py +17 −0
  61. python/demos/demo_sink_create_woodblock.py +38 −0
  62. python/demos/demo_source.py +16 −0
  63. python/demos/demo_spectrogram.py +63 −0
  64. python/demos/demo_tss.py +47 −0
  65. python/gen_pyobject.py +526 −0
  66. python/generator.py +187 −0
  67. python/py-cvec.c +302 −0
  68. python/py-fft.c +107 −0
  69. python/py-filter.c +198 −0
  70. python/py-filterbank.c +183 −0
  71. python/py-phasevoc.c +118 −0
  72. python/run_all_tests +20 −0
  73. python/setup.py +41 −0
  74. python/tests/test_aubio.py +14 −0
  75. python/tests/test_cvec.py +50 −0
  76. python/tests/test_fft.py +113 −0
  77. python/tests/test_filter.py +68 −0
  78. python/tests/test_filterbank.py +23 −0
  79. python/tests/test_filterbank_mel.py +51 −0
  80. python/tests/test_fvec.py +135 −0
  81. python/tests/test_onset.py +20 −0
  82. python/tests/test_peakpicker.py +115 −0
  83. python/tests/test_phasevoc.py +65 −0
  84. python/tests/test_pitch.py +101 −0
  85. python/tests/test_source.py +27 −0
  86. python/tests/test_specdesc.py +238 −0
  87. python/wscript_build +0 −6
python/Makefile.am+0−5
@@ -1,5 +0,0 @@
1−EXTRA_DIST = README
2−SUBDIRS = aubio
3−dist_bin_SCRIPTS = aubiocut aubiopitch
4−dist_noinst_SCRIPTS = aubiocompare-onset aubioplot-notes \
5− aubiofilter-notes aubionotes aubiocompare-onset aubioweb.py
python/README+0−30
@@ -1,30 +0,0 @@
1−# Here you will find some examples of python scripts and some evaluation
2−# routines. The python interface for libaubio is generated using Swig.
3−
4−# To have it working before installation, you will need to set LD_LIBRARY_PATH.
5−# for instance, to run the python script from within aubio/python/, you can use
6−# '. README'
7−
8−export LD_LIBRARY_PATH=../src/.libs:../ext/.libs
9−export PYTHONPATH=aubio/.libs
10−
11−echo """
12−
13−the aubio/ directory should be organised as follow:
14−
15− aubiowrapper.py,_aubiowrapper.so, aubio_wrap.c, aubio_wrap.o
16− swig generated aubio interface
17− aubioclass.py
18− human usable interface
19− plot/
20− everything required to plot
21− web/
22− tools to use aubioweb.py
23− bench/
24− tools to explore a database of sound file and run benchmarks on it
25− eval/
26− tools to evaluate the performance of aubio extractors
27− aubioweb.py
28− a hack to pipe aubio in mod_python
29−
30−"""
python/README.md+24−0
@@ -0,0 +1,24 @@
1+Python aubio module
2+===================
3+
4+This module wraps the aubio library for python using the numpy module.
5+
6+See the [Python/C API Reference
7+Manual] (http://docs.python.org/c-api/index.html) and the [Numpy/C API
8+Reference](http://docs.scipy.org/doc/numpy/reference/c-api.html)
9+
10+Compiling python aubio on Mac OS X
11+----------------------------------
12+
13+You should now be able to build the aubio python module out of the box on a
14+recent version of OS X (10.8.x). Make sure the variables are correct in the
15+file `build_osx` before running it:
16+
17+ $ ./build_osx
18+
19+Additionally, you can fetch tools such [matplotlib](http://matplotlib.org/) to
20+use the demo scripts. One easy way to do it is to fetch the fully fledged
21+[Scipy superpack](http://fonnesbeck.github.com/ScipySuperpack/)
22+
23+ $ curl -O https://raw.github.com/fonnesbeck/ScipySuperpack/master/install_superpack.sh
24+ $ sh install_superpack.sh
python/a_weighting_test_simple.expected+2−0
@@ -0,0 +1,2 @@
1+ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 5.00000000e-01 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
2+ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.27870563e-01 2.58244342e-01 1.18719361e-01 -4.02623805e-02 -5.61812129e-02 -5.24739734e-02 -4.72329276e-02 -4.23394349e-02 -3.79219586e-02 -3.39473148e-02 -3.03724479e-02 -2.71574847e-02 -2.42664433e-02 -2.16669285e-02 -1.93297810e-02 -1.72287543e-02 -1.53402241e-02 -1.36429261e-02 -1.21177207e-02 -1.07473802e-02
python/aubio-types.h+49−0
@@ -0,0 +1,49 @@
1+#include <Python.h>
2+#include <structmember.h>
3+#define NO_IMPORT_ARRAY
4+#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
5+#include <numpy/arrayobject.h>
6+#define AUBIO_UNSTABLE 1
7+#include <aubio.h>
8+
9+#define Py_default_vector_length 1024
10+#define Py_default_vector_height 1
11+
12+#define Py_aubio_default_samplerate 44100
13+
14+#if HAVE_AUBIO_DOUBLE
15+#error "Ouch! Python interface for aubio has not been much tested yet."
16+#define AUBIO_NPY_SMPL NPY_DOUBLE
17+#else
18+#define AUBIO_NPY_SMPL NPY_FLOAT
19+#endif
20+
21+// special python type for cvec
22+typedef struct
23+{
24+ PyObject_HEAD
25+ cvec_t * o;
26+ uint_t length;
27+ uint_t channels;
28+} Py_cvec;
29+extern PyTypeObject Py_cvecType;
30+
31+// defined in aubio-proxy.c
32+extern PyObject *PyAubio_CFvecToArray (fvec_t * self);
33+extern fvec_t *PyAubio_ArrayToCFvec (PyObject * self);
34+
35+extern Py_cvec *PyAubio_CCvecToPyCvec (cvec_t * self);
36+extern cvec_t *PyAubio_ArrayToCCvec (PyObject *input);
37+
38+extern PyObject *PyAubio_CFmatToArray (fmat_t * self);
39+extern fmat_t *PyAubio_ArrayToCFmat (PyObject *input);
40+
41+// hand written wrappers
42+extern PyTypeObject Py_filterType;
43+
44+extern PyTypeObject Py_filterbankType;
45+
46+extern PyTypeObject Py_fftType;
47+
48+extern PyTypeObject Py_pvocType;
49+
python/aubio/Makefile.am+0−66
@@ -1,66 +0,0 @@
1−nobase_pkgpython_PYTHON = \
2− __init__.py \
3− onsetcompare.py \
4− gnuplot.py \
5− median.py \
6− txtfile.py \
7− aubioclass.py \
8− task/__init__.py \
9− task/params.py \
10− task/onset.py \
11− task/silence.py \
12− task/cut.py \
13− task/beat.py \
14− task/task.py \
15− task/pitch.py \
16− task/notes.py \
17− bench/__init__.py \
18− bench/broadcast.py \
19− bench/config.py \
20− bench/node.py \
21− bench/onset.py \
22− plot/__init__.py \
23− plot/keyboard.py \
24− web/__init__.py \
25− web/browser.py \
26− web/html.py
27−
28−nodist_pkgpython_PYTHON = aubiowrapper.py _aubiowrapper.so
29−
30−_aubiowrapper.so: _aubiowrapper.la
31−
32−if MINGW
33−SWLDFLAGS = -L${prefix}/bin -lpython${PYTHON_VERSION}
34−else
35−if DARWIN
36−SWLDFLAGS = -bundle -framework Python
37−else
38−SWLDFLAGS = -shared
39−endif
40−endif
41−
42−CLEANFILES = *.pyc *.so *.o aubio_wrap.c aubiowrapper.py
43−
44−NOWARN_CFLAGS = -Wno-missing-prototypes -Wno-missing-declarations \
45− -Wno-strict-aliasing
46−
47−AM_CFLAGS = @AUBIO_CFLAGS@ @SNDFILE_CFLAGS@ \
48− $(NOWARN_CFLAGS) $(SWCFLAGS) \
49− -I$(top_builddir)/src -I$(top_srcdir)/src \
50− -I$(top_srcdir)/examples \
51− -I/usr/include/python${PYTHON_VERSION} \
52− -I${prefix}/include/python${PYTHON_VERSION} \
53− -I/usr/include \
54− -I${prefix}/include
55−
56−AUBIO_LDFLAGS = $(SWLDFLAGS) \
57− @SNDFILE_LIBS@ \
58− -L$(top_builddir)/src -laubio
59−
60−pkgpyexec_LTLIBRARIES = _aubiowrapper.la
61−
62−_aubiowrapper_la_LDFLAGS = -module -avoid-version $(AUBIO_LDFLAGS)
63−_aubiowrapper_la_SOURCES = aubio_wrap.c $(top_srcdir)/examples/sndfileio.c
64−
65−aubio_wrap.c aubiowrapper.py:
66− $(SWIG) -outdir . -o aubio_wrap.c -python $(top_srcdir)/swig/aubio.i
python/aubio/__init__.py+7−26
@@ -1,28 +1,9 @@
1−"""Copyright (C) 2004 Paul Brossier <piem@altern.org>
2−print aubio.__LICENSE__ for the terms of use
3−"""
1+import numpy
2+from _aubio import *
43
5−__LICENSE__ = """\
6− Copyright (C) 2004-2009 Paul Brossier <piem@aubio.org>
4+class fvec(numpy.ndarray):
75
8− This file is part of aubio.
9−
10− aubio is free software: you can redistribute it and/or modify
11− it under the terms of the GNU General Public License as published by
12− the Free Software Foundation, either version 3 of the License, or
13− (at your option) any later version.
14−
15− aubio is distributed in the hope that it will be useful,
16− but WITHOUT ANY WARRANTY; without even the implied warranty of
17− MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18− GNU General Public License for more details.
19−
20− You should have received a copy of the GNU General Public License
21− along with aubio. If not, see <http://www.gnu.org/licenses/>.
22−"""
23−
24−#from aubioclass import *
25−#from onsetcompare import *
26−#from median import *
27−#from noteroc import *
28−#from txtfile import *
6+ def __new__(self, length = 1024, **kwargs):
7+ if type(length) == type([]):
8+ return numpy.array(length, dtype='float32', **kwargs)
9+ return numpy.zeros(length, dtype='float32', **kwargs)
python/aubio/aubioclass.py+0−160
@@ -1,160 +0,0 @@
1−from aubiowrapper import *
2−
3−class fvec:
4− def __init__(self,size):
5− self.vec = new_fvec(size)
6− def __call__(self):
7− return self.vec
8− def __del__(self):
9− del_fvec(self())
10− def get(self,pos):
11− return fvec_read_sample(self(),pos)
12− def set(self,value,pos):
13− return fvec_write_sample(self(),value,pos)
14− def data(self):
15− return fvec_get_data(self())
16−
17−class cvec:
18− def __init__(self,size):
19− self.vec = new_cvec(size)
20− def __call__(self):
21− return self.vec
22− def __del__(self):
23− del_cvec(self())
24− def get(self,pos):
25− return self.get_norm(pos)
26− def set(self,val,pos):
27− self.set_norm(val,pos)
28− def get_norm(self,pos):
29− return cvec_read_norm(self(),pos)
30− def set_norm(self,val,pos):
31− cvec_write_norm(self(),val,pos)
32− def get_phas(self,pos):
33− return cvec_read_phas(self(),pos)
34− def set_phas(self,val,pos):
35− cvec_write_phas(self(),val,pos)
36−
37−class sndfile:
38− def __init__(self,filename,model=None):
39− if (model!=None):
40− self.file = new_aubio_sndfile_wo(model.file,filename)
41− else:
42− self.file = new_aubio_sndfile_ro(filename)
43− if self.file == None:
44− raise IOError, "failed opening file %s" % filename
45− def __del__(self):
46− if self.file != None: del_aubio_sndfile(self.file)
47− def info(self):
48− aubio_sndfile_info(self.file)
49− def samplerate(self):
50− return aubio_sndfile_samplerate(self.file)
51− def channels(self):
52− return aubio_sndfile_channels(self.file)
53− def read(self,nfram,vecread):
54− return aubio_sndfile_read_mono(self.file,nfram,vecread())
55− def write(self,nfram,vecwrite):
56− return aubio_sndfile_write(self.file,nfram,vecwrite())
57−
58−class pvoc:
59− def __init__(self,buf,hop):
60− self.pv = new_aubio_pvoc(buf,hop)
61− def __del__(self):
62− del_aubio_pvoc(self.pv)
63− def do(self,tf,tc):
64− aubio_pvoc_do(self.pv,tf(),tc())
65− def rdo(self,tc,tf):
66− aubio_pvoc_rdo(self.pv,tc(),tf())
67−
68−class onsetdetection:
69− """ class for aubio_specdesc """
70− def __init__(self,mode,buf):
71− self.od = new_aubio_specdesc(mode,buf)
72− def do(self,tc,tf):
73− aubio_specdesc_do(self.od,tc(),tf())
74− def __del__(self):
75− del_aubio_specdesc(self.od)
76−
77−class peakpick:
78− """ class for aubio_peakpicker """
79− def __init__(self,threshold=0.1):
80− self.pp = new_aubio_peakpicker()
81− self.out = new_fvec(1)
82− aubio_peakpicker_set_threshold (self.pp, threshold)
83− def do(self,fv):
84− aubio_peakpicker_do(self.pp, fv(), self.out)
85− return fvec_read_sample(self.out, 0)
86− def getval(self):
87− return aubio_peakpicker_get_adaptive_threshold(self.pp)
88− def __del__(self):
89− del_aubio_peakpicker(self.pp)
90−
91−class onsetpick:
92− """ superclass for aubio_pvoc + aubio_specdesc + aubio_peakpicker """
93− def __init__(self,bufsize,hopsize,myvec,threshold,mode='dual',derivate=False,dcthreshold=0):
94− self.myfft = cvec(bufsize)
95− self.pv = pvoc(bufsize,hopsize)
96− if mode in ['dual'] :
97− self.myod = onsetdetection("hfc",bufsize)
98− self.myod2 = onsetdetection("mkl",bufsize)
99− self.myonset = fvec(1)
100− self.myonset2 = fvec(1)
101− else:
102− self.myod = onsetdetection(mode,bufsize)
103− self.myonset = fvec(1)
104− self.mode = mode
105− self.pp = peakpick(float(threshold))
106− self.derivate = derivate
107− self.dcthreshold = dcthreshold
108− self.oldval = 0.
109−
110− def do(self,myvec):
111− self.pv.do(myvec,self.myfft)
112− self.myod.do(self.myfft,self.myonset)
113− if self.mode == 'dual':
114− self.myod2.do(self.myfft,self.myonset2)
115− self.myonset.set(self.myonset.get(0)*self.myonset2.get(0),0)
116− if self.derivate:
117− val = self.myonset.get(0)
118− dval = val - self.oldval
119− self.oldval = val
120− if dval > 0: self.myonset.set(dval,0)
121− else: self.myonset.set(0.,0,0)
122− isonset, dval = self.pp.do(self.myonset),self.myonset.get(0)
123− if self.dcthreshold:
124− if dval < self.dcthreshold: isonset = 0
125− return isonset, dval
126−
127−class pitch:
128− def __init__(self,mode="mcomb",bufsize=2048,hopsize=1024,
129− samplerate=44100.,omode="freq",tolerance=0.1):
130− self.pitchp = new_aubio_pitch(mode,bufsize,hopsize,
131− samplerate)
132− self.mypitch = fvec(1)
133− aubio_pitch_set_unit(self.pitchp,omode)
134− aubio_pitch_set_tolerance(self.pitchp,tolerance)
135− #self.filt = filter(srate,"adsgn")
136− def __del__(self):
137− del_aubio_pitch(self.pitchp)
138− def __call__(self,myvec):
139− aubio_pitch_do(self.pitchp,myvec(), self.mypitch())
140− return self.mypitch.get(0)
141−
142−class filter:
143− def __init__(self,srate,type=None):
144− if (type=="adsgn"):
145− self.filter = new_aubio_adsgn_filter(srate)
146− def __del__(self):
147− #del_aubio_filter(self.filter)
148− pass
149− def __call__(self,myvec):
150− aubio_filter_do(self.filter,myvec())
151−
152−class beattracking:
153− """ class for aubio_beattracking """
154− def __init__(self,winlen,channels):
155− self.p = new_aubio_beattracking(winlen,channels)
156− def do(self,dfframe,out):
157− return aubio_beattracking_do(self.p,dfframe(),out())
158− def __del__(self):
159− del_aubio_beattracking(self.p)
160−
python/aubio/bench/__init__.py+0−0

Empty file deleted.

python/aubio/bench/broadcast.py+0−25
@@ -1,25 +0,0 @@
1−from config import *
2−
3−class run_broadcast:
4− def __init__(self,command,*args):
5− for host in REMOTEHOSTS:
6− command(host,args[0],args[1:])
7−
8−def remote_sync(host,path='',options=''):
9− optstring = ''
10− for i in options:
11− optstring = "%s %s" % (optstring,i)
12− print RSYNC_CMD,optstring,RSYNC_OPT,' --delete',
13− print '%s%s%s%s%s' % (path,'/ ',host,':',path)
14−
15−
16−def fetch_results(host,path='',options=''):
17− optstring = ''
18− for i in options:
19− optstring = "%s %s" % (optstring,i)
20− print RSYNC_CMD,optstring,RSYNC_OPT,' --update',
21− print '%s%s%s%s%s' % (host,':',path,'/ ',path)
22−
23−def remote_queue(host,command,options=''):
24− print 'oarsub -p "hostname = \'',host,'\'',command
25−
python/aubio/bench/config.py+0−22
@@ -1,22 +0,0 @@
1−
2−filefound = 0
3−try:
4− filename = "/etc/aubio-bench.conf"
5− execfile(filename)
6− filefound = 1
7−except IOError:
8− print "no system wide configuration file found in", filename
9−
10−try:
11− import os
12− filename = "%s%s%s" % (os.getenv('HOME'),os.sep,".aubio-bench.conf")
13− execfile(filename)
14− filefound = 1
15−except IOError:
16− #print "no user configuration file found in", filename
17− pass
18−
19−if filefound == 0:
20− import sys
21− print "error: no configuration file found at all"
22− sys.exit(1)
python/aubio/bench/node.py+0−224
@@ -1,224 +0,0 @@
1−from config import *
2−import commands,sys
3−import re
4−
5−def runcommand(cmd,debug=0):
6− if VERBOSE >= VERBOSE_CMD or debug: print cmd
7− if debug: return
8− status, output = commands.getstatusoutput(cmd)
9− if status == 0 or VERBOSE >= VERBOSE_OUT:
10− output = output.split('\n')
11− if VERBOSE >= VERBOSE_OUT:
12− for i in output:
13− if i: print i
14− if not status == 0:
15− print 'error:',status,output
16− print 'command returning error was',cmd
17− #sys.exit(1)
18− if output == '' or output == ['']: return
19− return output
20−
21−def list_files(datapath,filter='f', maxdepth = -1):
22− if not os.path.exists(datapath):
23− print
24− print "ERR: no directory %s were found" % datapath
25− sys.exit(1)
26− if maxdepth >= 0: maxstring = " -maxdepth %d " % maxdepth
27− else: maxstring = ""
28− cmd = '%s' * 6 % ('find ',datapath,maxstring,' -type ',filter, "| sort -n")
29− return runcommand(cmd)
30−
31−def list_wav_files(datapath,maxdepth = -1):
32− return list_files(datapath, filter="f -name '*.wav'",maxdepth = maxdepth)
33−
34−sndfile_filter = "f -name '*.wav' -o -name '*.aif' -o -name '*.aiff'"
35−
36−def list_snd_files(datapath,maxdepth = -1):
37− return list_files(datapath, filter=sndfile_filter,
38− maxdepth = maxdepth)
39−
40−def list_res_files(datapath,maxdepth = -1):
41− return list_files(datapath, filter="f -name '*.txt'", maxdepth = maxdepth)
42−
43−def list_dirs(datapath):
44− return list_files(datapath, filter="d")
45−
46−def mkdir(path):
47− cmd = '%s%s' % ('mkdir -p ',path)
48− return runcommand(cmd)
49−
50−def act_on_data (action,datapath,respath=None,suffix='.txt',filter='f',sub='\.wav$',**keywords):
51− """ execute action(datafile,resfile) on all files in datapath """
52− dirlist = list_files(datapath,filter=filter)
53− if dirlist == ['']: dirlist = []
54− if respath:
55− respath_in_datapath = re.split(datapath, respath,maxsplit=1)[1:]
56− if(respath_in_datapath and suffix == ''):
57− print 'error: respath in datapath and no suffix used'
58− for i in dirlist:
59− j = re.split(datapath, i,maxsplit=1)[1]
60− j = re.sub(sub,'',j)
61− #j = "%s%s%s"%(respath,j,suffix)
62− if respath:
63− j = "%s%s"%(respath,j)
64− if sub != '':
65− j = re.sub(sub,suffix,j)
66− else:
67− j = "%s%s" % (j,suffix)
68− action(i,j,**keywords)
69−
70−def act_on_results (action,datapath,respath,filter='d'):
71− """ execute action(respath) an all subdirectories in respath """
72− dirlist = list_files(datapath,filter='d')
73− respath_in_datapath = re.split(datapath, respath,maxsplit=1)[1:]
74− if(respath_in_datapath and not filter == 'd' and suffix == ''):
75− print 'warning: respath is in datapath'
76− for i in dirlist:
77− s = re.split(datapath, i ,maxsplit=1)[1]
78− action("%s%s%s"%(respath,'/',s))
79−
80−def act_on_files (action,listfiles,listres=None,suffix='.txt',filter='f',sub='\.wav$',**keywords):
81− """ execute action(respath) an all subdirectories in respath """
82− if listres and len(listfiles) <= len(listres):
83− for i in range(len(listfiles)):
84− action(listfiles[i],listres[i],**keywords)
85− else:
86− for i in listfiles:
87− action(i,None,**keywords)
88−
89−class bench:
90− """ class to run benchmarks on directories """
91− def __init__(self,datadir,resdir=None,checkres=False,checkanno=False,params=[]):
92− from aubio.task.params import taskparams
93− self.datadir = datadir
94− # path to write results path to
95− self.resdir = resdir
96− # list of annotation files
97− self.reslist = []
98− # list used to gather results
99− self.results = []
100− if not params: self.params = taskparams()
101− else: self.params = params
102− print "Checking data directory", self.datadir
103− self.checkdata()
104− if checkanno: self.checkanno()
105− if checkres: self.checkres()
106−
107− def checkdata(self):
108− if os.path.isfile(self.datadir):
109− self.dirlist = os.path.dirname(self.datadir)
110− elif os.path.isdir(self.datadir):
111− self.dirlist = list_dirs(self.datadir)
112− # allow dir* matching through find commands?
113− else:
114− print "ERR: path not understood"
115− sys.exit(1)
116− print "Listing directories in data directory",
117− if self.dirlist:
118− print " (%d elements)" % len(self.dirlist)
119− else:
120− print " (0 elements)"
121− print "ERR: no directory %s were found" % self.datadir
122− sys.exit(1)
123− print "Listing sound files in data directory",
124− self.sndlist = list_snd_files(self.datadir)
125− if self.sndlist:
126− print " (%d elements)" % len(self.sndlist)
127− else:
128− print " (0 elements)"
129− print "ERR: no sound files were found in", self.datadir
130− sys.exit(1)
131−
132− def checkanno(self):
133− print "Listing annotations in data directory",
134− self.reslist = list_res_files(self.datadir)
135− print " (%d elements)" % len(self.reslist)
136− #for each in self.reslist: print each
137− if not self.reslist or len(self.reslist) < len (self.sndlist):
138− print "ERR: not enough annotations"
139− return -1
140− else:
141− print "Found enough annotations"
142−
143− def checkres(self):
144− print "Creating results directory"
145− act_on_results(mkdir,self.datadir,self.resdir,filter='d')
146−
147− def pretty_print(self,sep='|'):
148− for i in self.printnames:
149− print self.formats[i] % self.v[i], sep,
150− print
151−
152− def pretty_titles(self,sep='|'):
153− for i in self.printnames:
154− print self.formats[i] % i, sep,
155− print
156−
157− def dir_exec(self):
158− """ run file_exec on every input file """
159− self.l , self.labs = [], []
160− self.v = {}
161− for i in self.valuenames:
162− self.v[i] = []
163− for i in self.valuelists:
164− self.v[i] = []
165− act_on_files(self.file_exec,self.sndlist,self.reslist, \
166− suffix='',filter=sndfile_filter)
167−
168− def dir_eval(self):
169− pass
170−
171− def file_gettruth(self,input):
172− """ get ground truth filenames """
173− from os.path import isfile
174− ftrulist = []
175− # search for match as filetask.input,".txt"
176− ftru = '.'.join(input.split('.')[:-1])
177− ftru = '.'.join((ftru,'txt'))
178− if isfile(ftru):
179− ftrulist.append(ftru)
180− else:
181− # search for matches for filetask.input in the list of results
182− for i in range(len(self.reslist)):
183− check = '.'.join(self.reslist[i].split('.')[:-1])
184− check = '_'.join(check.split('_')[:-1])
185− if check == '.'.join(input.split('.')[:-1]):
186− ftrulist.append(self.reslist[i])
187− return ftrulist
188−
189− def file_exec(self,input,output):
190− """ create filetask, extract data, evaluate """
191− filetask = self.task(input,params=self.params)
192− computed_data = filetask.compute_all()
193− ftrulist = self.file_gettruth(filetask.input)
194− for i in ftrulist:
195− filetask.eval(computed_data,i,mode='rocloc',vmode='')
196− """ append filetask.v to self.v """
197− for i in self.valuenames:
198− self.v[i].append(filetask.v[i])
199− for j in self.valuelists:
200− if filetask.v[j]:
201− for i in range(len(filetask.v[j])):
202− self.v[j].append(filetask.v[j][i])
203−
204− def file_eval(self):
205− pass
206−
207− def file_plot(self):
208− pass
209−
210− def dir_plot(self):
211− pass
212−
213− def run_bench(self):
214− for mode in self.modes:
215− self.params.mode = mode
216− self.dir_exec()
217− self.dir_eval()
218− self.dir_plot()
219−
220− def dir_eval_print(self):
221− self.dir_exec()
222− self.dir_eval()
223− self.pretty_print()
224−
python/aubio/bench/onset.py+0−303
@@ -1,303 +0,0 @@
1−
2−from aubio.bench.node import *
3−from os.path import dirname,basename
4−
5−def mmean(l):
6− return sum(l)/max(float(len(l)),1)
7−
8−def stdev(l):
9− smean = 0
10− if not len(l): return smean
11− lmean = mmean(l)
12− for i in l:
13− smean += (i-lmean)**2
14− smean *= 1. / len(l)
15− return smean**.5
16−
17−class benchonset(bench):
18−
19− """ list of values to store per file """
20− valuenames = ['orig','missed','Tm','expc','bad','Td']
21− """ list of lists to store per file """
22− valuelists = ['l','labs']
23− """ list of values to print per dir """
24− printnames = [ 'mode', 'thres', 'dist', 'prec', 'recl',
25− 'GD', 'FP',
26− 'Torig', 'Ttrue', 'Tfp', 'Tfn', 'TTm', 'TTd',
27− 'aTtrue', 'aTfp', 'aTfn', 'aTm', 'aTd',
28− 'mean', 'smean', 'amean', 'samean']
29−
30− """ per dir """
31− formats = {'mode': "%12s" , 'thres': "%5.4s",
32− 'dist': "%5.4s", 'prec': "%5.4s", 'recl': "%5.4s",
33− 'Torig': "%5.4s", 'Ttrue': "%5.4s", 'Tfp': "%5.4s", 'Tfn': "%5.4s",
34− 'TTm': "%5.4s", 'TTd': "%5.4s",
35− 'aTtrue':"%5.4s", 'aTfp': "%5.4s", 'aTfn': "%5.4s",
36− 'aTm': "%5.4s", 'aTd': "%5.4s",
37− 'mean': "%5.6s", 'smean': "%5.6s",
38− 'amean': "%5.6s", 'samean': "%5.6s",
39− "GD": "%5.4s", "FP": "%5.4s",
40− "GDm": "%5.4s", "FPd": "%5.4s",
41− "bufsize": "%5.4s", "hopsize": "%5.4s",
42− "time": "%5.4s"}
43−
44− def dir_eval(self):
45− """ evaluate statistical data over the directory """
46− v = self.v
47−
48− v['mode'] = self.params.onsetmode
49− v['thres'] = self.params.threshold
50− v['bufsize'] = self.params.bufsize
51− v['hopsize'] = self.params.hopsize
52− v['silence'] = self.params.silence
53− v['mintol'] = self.params.mintol
54−
55− v['Torig'] = sum(v['orig'])
56− v['TTm'] = sum(v['Tm'])
57− v['TTd'] = sum(v['Td'])
58− v['Texpc'] = sum(v['expc'])
59− v['Tbad'] = sum(v['bad'])
60− v['Tmissed'] = sum(v['missed'])
61− v['aTm'] = mmean(v['Tm'])
62− v['aTd'] = mmean(v['Td'])
63−
64− v['mean'] = mmean(v['l'])
65− v['smean'] = stdev(v['l'])
66−
67− v['amean'] = mmean(v['labs'])
68− v['samean'] = stdev(v['labs'])
69−
70− # old type calculations
71− # good detection rate
72− v['GD'] = 100.*(v['Torig']-v['Tmissed']-v['TTm'])/v['Torig']
73− # false positive rate
74− v['FP'] = 100.*(v['Tbad']+v['TTd'])/v['Torig']
75− # good detection counting merged detections as good
76− v['GDm'] = 100.*(v['Torig']-v['Tmissed'])/v['Torig']
77− # false positives counting doubled as good
78− v['FPd'] = 100.*v['Tbad']/v['Torig']
79−
80− # mirex type annotations
81− totaltrue = v['Texpc']-v['Tbad']-v['TTd']
82− totalfp = v['Tbad']+v['TTd']
83− totalfn = v['Tmissed']+v['TTm']
84− self.v['Ttrue'] = totaltrue
85− self.v['Tfp'] = totalfp
86− self.v['Tfn'] = totalfn
87− # average over the number of annotation files
88− N = float(len(self.reslist))
89− self.v['aTtrue'] = totaltrue/N
90− self.v['aTfp'] = totalfp/N
91− self.v['aTfn'] = totalfn/N
92−
93− # F-measure
94− self.P = 100.*float(totaltrue)/max(totaltrue + totalfp,1)
95− self.R = 100.*float(totaltrue)/max(totaltrue + totalfn,1)
96− #if self.R < 0: self.R = 0
97− self.F = 2.* self.P*self.R / max(float(self.P+self.R),1)
98− self.v['dist'] = self.F
99− self.v['prec'] = self.P
100− self.v['recl'] = self.R
101−
102−
103− """
104− Plot functions
105− """
106−
107− def plotroc(self,d,plottitle=""):
108− import Gnuplot, Gnuplot.funcutils
109− gd = []
110− fp = []
111− for i in self.vlist:
112− gd.append(i['GD'])
113− fp.append(i['FP'])
114− d.append(Gnuplot.Data(fp, gd, with_='linespoints',
115− title="%s %s" % (plottitle,i['mode']) ))
116−
117− def plotplotroc(self,d,outplot=0,extension='ps'):
118− import Gnuplot, Gnuplot.funcutils
119− from sys import exit
120− g = Gnuplot.Gnuplot(debug=0, persist=1)
121− if outplot:
122− if extension == 'ps': ext, extension = '.ps' , 'postscript'
123− elif extension == 'png': ext, extension = '.png', 'png'
124− elif extension == 'svg': ext, extension = '.svg', 'svg'
125− else: exit("ERR: unknown plot extension")
126− g('set terminal %s' % extension)
127− g('set output \'roc-%s%s\'' % (outplot,ext))
128− xmax = 30 #max(fp)
129− ymin = 50
130− g('set xrange [0:%f]' % xmax)
131− g('set yrange [%f:100]' % ymin)
132− # grid set
133− g('set grid')
134− g('set xtics 0,5,%f' % xmax)
135− g('set ytics %f,5,100' % ymin)
136− g('set key 27,65')
137− #g('set format \"%g\"')
138− g.title(basename(self.datadir))
139− g.xlabel('false positives (%)')
140− g.ylabel('correct detections (%)')
141− g.plot(*d)
142−
143− def plotpr(self,d,plottitle=""):
144− import Gnuplot, Gnuplot.funcutils
145− x = []
146− y = []
147− for i in self.vlist:
148− x.append(i['prec'])
149− y.append(i['recl'])
150− d.append(Gnuplot.Data(x, y, with_='linespoints',
151− title="%s %s" % (plottitle,i['mode']) ))
152−
153− def plotplotpr(self,d,outplot=0,extension='ps'):
154− import Gnuplot, Gnuplot.funcutils
155− from sys import exit
156− g = Gnuplot.Gnuplot(debug=0, persist=1)
157− if outplot:
158− if extension == 'ps': ext, extension = '.ps' , 'postscript'
159− elif extension == 'png': ext, extension = '.png', 'png'
160− elif extension == 'svg': ext, extension = '.svg', 'svg'
161− else: exit("ERR: unknown plot extension")
162− g('set terminal %s' % extension)
163− g('set output \'pr-%s%s\'' % (outplot,ext))
164− g.title(basename(self.datadir))
165− g.xlabel('Recall (%)')
166− g.ylabel('Precision (%)')
167− g.plot(*d)
168−
169− def plotfmeas(self,d,plottitle=""):
170− import Gnuplot, Gnuplot.funcutils
171− x,y = [],[]
172− for i in self.vlist:
173− x.append(i['thres'])
174− y.append(i['dist'])
175− d.append(Gnuplot.Data(x, y, with_='linespoints',
176− title="%s %s" % (plottitle,i['mode']) ))
177−
178− def plotplotfmeas(self,d,outplot="",extension='ps', title="F-measure"):
179− import Gnuplot, Gnuplot.funcutils
180− from sys import exit
181− g = Gnuplot.Gnuplot(debug=0, persist=1)
182− if outplot:
183− if extension == 'ps': terminal = 'postscript'
184− elif extension == 'png': terminal = 'png'
185− elif extension == 'svg': terminal = 'svg'
186− else: exit("ERR: unknown plot extension")
187− g('set terminal %s' % terminal)
188− g('set output \'fmeas-%s.%s\'' % (outplot,extension))
189− g.xlabel('threshold \\delta')
190− g.ylabel('F-measure (%)')
191− g('set xrange [0:1.2]')
192− g('set yrange [0:100]')
193− g.title(basename(self.datadir))
194− # grid set
195− #g('set grid')
196− #g('set xtics 0,5,%f' % xmax)
197− #g('set ytics %f,5,100' % ymin)
198− #g('set key 27,65')
199− #g('set format \"%g\"')
200− g.plot(*d)
201−
202− def plotfmeasvar(self,d,var,plottitle=""):
203− import Gnuplot, Gnuplot.funcutils
204− x,y = [],[]
205− for i in self.vlist:
206− x.append(i[var])
207− y.append(i['dist'])
208− d.append(Gnuplot.Data(x, y, with_='linespoints',
209− title="%s %s" % (plottitle,i['mode']) ))
210−
211− def plotplotfmeasvar(self,d,var,outplot="",extension='ps', title="F-measure"):
212− import Gnuplot, Gnuplot.funcutils
213− from sys import exit
214− g = Gnuplot.Gnuplot(debug=0, persist=1)
215− if outplot:
216− if extension == 'ps': terminal = 'postscript'
217− elif extension == 'png': terminal = 'png'
218− elif extension == 'svg': terminal = 'svg'
219− else: exit("ERR: unknown plot extension")
220− g('set terminal %s' % terminal)
221− g('set output \'fmeas-%s.%s\'' % (outplot,extension))
222− g.xlabel(var)
223− g.ylabel('F-measure (%)')
224− #g('set xrange [0:1.2]')
225− g('set yrange [0:100]')
226− g.title(basename(self.datadir))
227− g.plot(*d)
228−
229− def plotdiffs(self,d,plottitle=""):
230− import Gnuplot, Gnuplot.funcutils
231− v = self.v
232− l = v['l']
233− mean = v['mean']
234− smean = v['smean']
235− amean = v['amean']
236− samean = v['samean']
237− val = []
238− per = [0] * 100
239− for i in range(0,100):
240− val.append(i*.001-.05)
241− for j in l:
242− if abs(j-val[i]) <= 0.001:
243− per[i] += 1
244− total = v['Torig']
245− for i in range(len(per)): per[i] /= total/100.
246−
247− d.append(Gnuplot.Data(val, per, with_='fsteps',
248− title="%s %s" % (plottitle,v['mode']) ))
249− #d.append('mean=%f,sigma=%f,eps(x) title \"\"'% (mean,smean))
250− #d.append('mean=%f,sigma=%f,eps(x) title \"\"'% (amean,samean))
251−
252−
253− def plotplotdiffs(self,d,outplot=0,extension='ps'):
254− import Gnuplot, Gnuplot.funcutils
255− from sys import exit
256− g = Gnuplot.Gnuplot(debug=0, persist=1)
257− if outplot:
258− if extension == 'ps': ext, extension = '.ps' , 'postscript'
259− elif extension == 'png': ext, extension = '.png', 'png'
260− elif extension == 'svg': ext, extension = '.svg', 'svg'
261− else: exit("ERR: unknown plot extension")
262− g('set terminal %s' % extension)
263− g('set output \'diffhist-%s%s\'' % (outplot,ext))
264− g('eps(x) = 1./(sigma*(2.*3.14159)**.5) * exp ( - ( x - mean ) ** 2. / ( 2. * sigma ** 2. ))')
265− g.title(basename(self.datadir))
266− g.xlabel('delay to hand-labelled onset (s)')
267− g.ylabel('% number of correct detections / ms ')
268− g('set xrange [-0.05:0.05]')
269− g('set yrange [0:20]')
270− g.plot(*d)
271−
272−
273− def plothistcat(self,d,plottitle=""):
274− import Gnuplot, Gnuplot.funcutils
275− total = v['Torig']
276− for i in range(len(per)): per[i] /= total/100.
277−
278− d.append(Gnuplot.Data(val, per, with_='fsteps',
279− title="%s %s" % (plottitle,v['mode']) ))
280− #d.append('mean=%f,sigma=%f,eps(x) title \"\"'% (mean,smean))
281− #d.append('mean=%f,sigma=%f,eps(x) title \"\"'% (amean,samean))
282−
283−
284− def plotplothistcat(self,d,outplot=0,extension='ps'):
285− import Gnuplot, Gnuplot.funcutils
286− from sys import exit
287− g = Gnuplot.Gnuplot(debug=0, persist=1)
288− if outplot:
289− if extension == 'ps': ext, extension = '.ps' , 'postscript'
290− elif extension == 'png': ext, extension = '.png', 'png'
291− elif extension == 'svg': ext, extension = '.svg', 'svg'
292− else: exit("ERR: unknown plot extension")
293− g('set terminal %s' % extension)
294− g('set output \'diffhist-%s%s\'' % (outplot,ext))
295− g('eps(x) = 1./(sigma*(2.*3.14159)**.5) * exp ( - ( x - mean ) ** 2. / ( 2. * sigma ** 2. ))')
296− g.title(basename(self.datadir))
297− g.xlabel('delay to hand-labelled onset (s)')
298− g.ylabel('% number of correct detections / ms ')
299− g('set xrange [-0.05:0.05]')
300− g('set yrange [0:20]')
301− g.plot(*d)
302−
303−
python/aubio/gnuplot.py+0−222
@@ -1,222 +0,0 @@
1−"""Copyright (C) 2004 Paul Brossier <piem@altern.org>
2−print aubio.__LICENSE__ for the terms of use
3−"""
4−
5−__LICENSE__ = """\
6− Copyright (C) 2004-2009 Paul Brossier <piem@aubio.org>
7−
8− This file is part of aubio.
9−
10− aubio is free software: you can redistribute it and/or modify
11− it under the terms of the GNU General Public License as published by
12− the Free Software Foundation, either version 3 of the License, or
13− (at your option) any later version.
14−
15− aubio is distributed in the hope that it will be useful,
16− but WITHOUT ANY WARRANTY; without even the implied warranty of
17− MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18− GNU General Public License for more details.
19−
20− You should have received a copy of the GNU General Public License
21− along with aubio. If not, see <http://www.gnu.org/licenses/>.
22−"""
23−
24−
25−def audio_to_array(filename):
26− import aubio.aubioclass
27− from numpy import arange
28− hopsize = 2048
29− filei = aubio.aubioclass.sndfile(filename)
30− framestep = 1/(filei.samplerate()+0.)
31− channels = filei.channels()
32− myvec = aubio.aubioclass.fvec(hopsize,channels)
33− data = []
34− readsize = hopsize
35− while (readsize==hopsize):
36− readsize = filei.read(hopsize,myvec)
37− #for i in range(channels):
38− i = 0
39− curpos = 0
40− while (curpos < readsize):
41− data.append(myvec.get(curpos,i))
42− curpos+=1
43− time = arange(len(data))*framestep
44− return time,data
45−
46−def plot_audio(filenames, g, options):
47− todraw = len(filenames)
48− xorig = 0.
49− xratio = 1./todraw
50− g('set multiplot;')
51− while (len(filenames)):
52− time,data = audio_to_array(filenames.pop(0))
53− if todraw==1:
54− if max(time) < 1.:
55− time = [t*1000. for t in time]
56− g.xlabel('Time (ms)')
57− else:
58− g.xlabel('Time (s)')
59− g.ylabel('Amplitude')
60− curplot = make_audio_plot(time,data)
61− g('set size %f,%f;' % (options.xsize*xratio,options.ysize) )
62− g('set origin %f,0.;' % (xorig) )
63− g('set style data lines; \
64− set yrange [-1.:1.]; \
65− set xrange [0:%f]' % time[-1])
66− g.plot(curplot)
67− xorig += options.xsize*xratio
68− g('unset multiplot;')
69−
70−def audio_to_spec(filename,minf = 0, maxf = 0, lowthres = -20.,
71− bufsize= 8192, hopsize = 1024):
72− from aubioclass import fvec,cvec,pvoc,sndfile
73− from math import log10
74− filei = sndfile(filename)
75− srate = float(filei.samplerate())
76− framestep = hopsize/srate
77− freqstep = srate/bufsize
78− channels = filei.channels()
79− myvec = fvec(hopsize,channels)
80− myfft = cvec(bufsize,channels)
81− pv = pvoc(bufsize,hopsize,channels)
82− data,time,freq = [],[],[]
83−
84− if maxf == 0.: maxf = bufsize/2
85− else: maxf = int(maxf/freqstep)
86− if minf: minf = int(minf/freqstep)
87− else: minf = 0
88−
89− for f in range(minf,maxf):
90− freq.append(f*freqstep)
91− readsize = hopsize
92− frameread = 0
93− while (readsize==hopsize):
94− readsize = filei.read(hopsize,myvec)
95− pv.do(myvec,myfft)
96− frame = []
97− i = 0 #for i in range(channels):
98− curpos = minf
99− while (curpos < maxf):
100− frame.append(max(lowthres,20.*log10(myfft.get(curpos,i)**2+0.00001)))
101− curpos+=1
102− time.append(frameread*framestep)
103− data.append(frame)
104− frameread += 1
105− # crop data if unfinished frames
106− if len(data[-1]) != len(data[0]):
107− data = data[0:-2]
108− time = time[0:-2]
109− # verify size consistency
110− assert len(data) == len(time)
111− assert len(data[0]) == len(freq)
112− return data,time,freq
113−
114−def plot_spec(filename, g, options):
115− import Gnuplot
116− data,time,freq = audio_to_spec(filename,
117− minf=options.minf,maxf=options.maxf,
118− bufsize=options.bufsize,hopsize=options.hopsize)
119− xorig = 0.
120− if max(time) < 1.:
121− time = [t*1000. for t in time]
122− g.xlabel('Time (ms)')
123− else:
124− g.xlabel('Time (s)')
125− if options.xsize < 0.5 and not options.log and max(time) > 1.:
126− freq = [f/1000. for f in freq]
127− options.minf /= 1000.
128− options.maxf /= 1000.
129− g.ylabel('Frequency (kHz)')
130− else:
131− g.ylabel('Frequency (Hz)')
132− g('set pm3d map')
133− g('set palette rgbformulae -25,-24,-32')
134− g('set cbtics 20')
135− #g('set colorbox horizontal')
136− g('set xrange [0.:%f]' % time[-1])
137− if options.log:
138− g('set log y')
139− g('set yrange [%f:%f]' % (max(10,options.minf),options.maxf))
140− else:
141− g('set yrange [%f:%f]' % (options.minf,options.maxf))
142− g.splot(Gnuplot.GridData(data,time,freq, binary=1))
143− #xorig += 1./todraw
144−
145−def downsample_audio(time,data,maxpoints=10000):
146− """ resample audio data to last only maxpoints """
147− from numpy import array, resize
148− length = len(time)
149− downsample = length/maxpoints
150− if downsample == 0: downsample = 1
151− x = resize(array(time),length)[0:-1:downsample]
152− y = resize(array(data),length)[0:-1:downsample]
153− return x,y
154−
155−def make_audio_plot(time,data,maxpoints=10000):
156− """ create gnuplot plot from an audio file """
157− import Gnuplot, Gnuplot.funcutils
158− x,y = downsample_audio(time,data,maxpoints=maxpoints)
159− return Gnuplot.Data(x,y,with_='lines')
160−
161−def make_audio_envelope(time,data,maxpoints=10000):
162− """ create gnuplot plot from an audio file """
163− from numpy import array
164− import Gnuplot, Gnuplot.funcutils
165− bufsize = 500
166− x = [i.mean() for i in resize(array(time), (len(time)/bufsize,bufsize))]
167− y = [i.mean() for i in resize(array(data), (len(time)/bufsize,bufsize))]
168− x,y = downsample_audio(x,y,maxpoints=maxpoints)
169− return Gnuplot.Data(x,y,with_='lines')
170−
171−def gnuplot_addargs(parser):
172− """ add common gnuplot argument to OptParser object """
173− parser.add_option("-x","--xsize",
174− action="store", dest="xsize", default=1.,
175− type='float',help="define xsize for plot")
176− parser.add_option("-y","--ysize",
177− action="store", dest="ysize", default=1.,
178− type='float',help="define ysize for plot")
179− parser.add_option("--debug",
180− action="store_true", dest="debug", default=False,
181− help="use gnuplot debug mode")
182− parser.add_option("--persist",
183− action="store_false", dest="persist", default=True,
184− help="do not use gnuplot persistant mode")
185− parser.add_option("--lmargin",
186− action="store", dest="lmargin", default=None,
187− type='int',help="define left margin for plot")
188− parser.add_option("--rmargin",
189− action="store", dest="rmargin", default=None,
190− type='int',help="define right margin for plot")
191− parser.add_option("--bmargin",
192− action="store", dest="bmargin", default=None,
193− type='int',help="define bottom margin for plot")
194− parser.add_option("--tmargin",
195− action="store", dest="tmargin", default=None,
196− type='int',help="define top margin for plot")
197− parser.add_option("-O","--outplot",
198− action="store", dest="outplot", default=None,
199− help="save plot to output.{ps,png}")
200−
201−def gnuplot_create(outplot='',extension='', options=None):
202− import Gnuplot
203− if options:
204− g = Gnuplot.Gnuplot(debug=options.debug, persist=options.persist)
205− else:
206− g = Gnuplot.Gnuplot(persist=1)
207− if not extension or not outplot: return g
208− if extension == 'ps': ext, extension = '.ps' , 'postscript'
209− elif extension == 'eps': ext, extension = '.eps' , 'postscript enhanced'
210− elif extension == 'epsc': ext, extension = '.eps' , 'postscript enhanced color'
211− elif extension == 'png': ext, extension = '.png', 'png'
212− elif extension == 'svg': ext, extension = '.svg', 'svg'
213− else: exit("ERR: unknown plot extension")
214− g('set terminal %s' % extension)
215− if options and options.lmargin: g('set lmargin %i' % options.lmargin)
216− if options and options.rmargin: g('set rmargin %i' % options.rmargin)
217− if options and options.bmargin: g('set bmargin %i' % options.bmargin)
218− if options and options.tmargin: g('set tmargin %i' % options.tmargin)
219− if outplot != "stdout":
220− g('set output \'%s%s\'' % (outplot,ext))
221− if options: g('set size %f,%f' % (options.xsize, options.ysize))
222− return g
python/aubio/median.py+0−69
@@ -1,69 +0,0 @@
1−"""Copyright (C) 2004 Paul Brossier <piem@altern.org>
2−print aubio.__LICENSE__ for the terms of use
3−"""
4−
5−__LICENSE__ = """\
6− Copyright (C) 2004-2009 Paul Brossier <piem@aubio.org>
7−
8− This file is part of aubio.
9−
10− aubio is free software: you can redistribute it and/or modify
11− it under the terms of the GNU General Public License as published by
12− the Free Software Foundation, either version 3 of the License, or
13− (at your option) any later version.
14−
15− aubio is distributed in the hope that it will be useful,
16− but WITHOUT ANY WARRANTY; without even the implied warranty of
17− MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18− GNU General Public License for more details.
19−
20− You should have received a copy of the GNU General Public License
21− along with aubio. If not, see <http://www.gnu.org/licenses/>.
22−"""
23−
24−"""
25−original author Tim Peters
26−modified by Paul Brossier <piem@altern.org>
27−inspired from http://www.ics.uci.edu/~eppstein/161/python/peters-selection.py
28−"""
29−
30−def short_find(a, rank):
31− """ find the rank-th value in sorted a """
32− # copy to b before sorting
33− b = a[:]
34− b.sort()
35− return b[rank - 1]
36−
37−def percental(a, rank):
38− """ Find the rank'th-smallest value in a, in worst-case linear time. """
39− n = len(a)
40− assert 1 <= rank <= n
41− if n <= 7:
42− return short_find(a, rank)
43−
44− ## Find median of median-of-7's.
45− ##medians = [short_find(a[i : i+7], 4) for i in xrange(0, n-6, 7)]
46− #median = find(medians, (len(medians) + 1) // 2)
47−
48− # modified to Find median
49− median = short_find([a[0], a[-1], a[n//2]], 2)
50−
51− # Partition around the median.
52− # a[:i] <= median
53− # a[j+1:] >= median
54− i, j = 0, n-1
55− while i <= j:
56− while a[i] < median:
57− i += 1
58− while a[j] > median:
59− j -= 1
60− if i <= j:
61− a[i], a[j] = a[j], a[i]
62− i += 1
63− j -= 1
64−
65− if rank <= i:
66− return percental(a[:i], rank)
67− else:
68− return percental(a[i:], rank - i)
69−
python/aubio/onsetcompare.py+0−143
@@ -1,143 +0,0 @@
1−"""Copyright (C) 2004 Paul Brossier <piem@altern.org>
2−print aubio.__LICENSE__ for the terms of use
3−"""
4−
5−__LICENSE__ = """\
6− Copyright (C) 2004-2009 Paul Brossier <piem@aubio.org>
7−
8− This file is part of aubio.
9−
10− aubio is free software: you can redistribute it and/or modify
11− it under the terms of the GNU General Public License as published by
12− the Free Software Foundation, either version 3 of the License, or
13− (at your option) any later version.
14−
15− aubio is distributed in the hope that it will be useful,
16− but WITHOUT ANY WARRANTY; without even the implied warranty of
17− MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18− GNU General Public License for more details.
19−
20− You should have received a copy of the GNU General Public License
21− along with aubio. If not, see <http://www.gnu.org/licenses/>.
22−"""
23−
24−""" this file contains routines to compare two lists of onsets or notes.
25−it somewhat implements the Receiver Operating Statistic (ROC).
26−see http://en.wikipedia.org/wiki/Receiver_operating_characteristic
27−"""
28−
29−def onset_roc(ltru, lexp, eps):
30− """ compute differences between two lists
31− orig = hits + missed + merged
32− expc = hits + bad + doubled
33− returns orig, missed, merged, expc, bad, doubled
34− """
35− orig, expc = len(ltru), len(lexp)
36− # if lexp is empty
37− if expc == 0 : return orig,orig,0,0,0,0
38− missed, bad, doubled, merged = 0, 0, 0, 0
39− # find missed and doubled ones first
40− for x in ltru:
41− correspond = 0
42− for y in lexp:
43− if abs(x-y) <= eps: correspond += 1
44− if correspond == 0: missed += 1
45− elif correspond > 1: doubled += correspond - 1
46− # then look for bad and merged ones
47− for y in lexp:
48− correspond = 0
49− for x in ltru:
50− if abs(x-y) <= eps: correspond += 1
51− if correspond == 0: bad += 1
52− elif correspond > 1: merged += correspond - 1
53− # check consistancy of the results
54− assert ( orig - missed - merged == expc - bad - doubled)
55− return orig, missed, merged, expc, bad, doubled
56−
57−def onset_diffs(ltru, lexp, eps):
58− """ compute differences between two lists
59− orig = hits + missed + merged
60− expc = hits + bad + doubled
61− returns orig, missed, merged, expc, bad, doubled
62− """
63− orig, expc = len(ltru), len(lexp)
64− # if lexp is empty
65− l = []
66− if expc == 0 : return l
67− # find missed and doubled ones first
68− for x in ltru:
69− correspond = 0
70− for y in lexp:
71− if abs(x-y) <= eps: l.append(y-x)
72− # return list of diffs
73− return l
74−
75−def onset_rocloc(ltru, lexp, eps):
76− """ compute differences between two lists
77− orig = hits + missed + merged
78− expc = hits + bad + doubled
79− returns orig, missed, merged, expc, bad, doubled
80− """
81− orig, expc = len(ltru), len(lexp)
82− l = []
83− labs = []
84− mean = 0
85− # if lexp is empty
86− if expc == 0 : return orig,orig,0,0,0,0,l,mean
87− missed, bad, doubled, merged = 0, 0, 0, 0
88− # find missed and doubled ones first
89− for x in ltru:
90− correspond = 0
91− for y in lexp:
92− if abs(x-y) <= eps: correspond += 1
93− if correspond == 0: missed += 1
94− elif correspond > 1: doubled += correspond - 1
95− # then look for bad and merged ones
96− for y in lexp:
97− correspond = 0
98− for x in ltru:
99− if abs(x-y) <= eps:
100− correspond += 1
101− l.append(y-x)
102− labs.append(abs(y-x))
103− if correspond == 0: bad += 1
104− elif correspond > 1: merged += correspond - 1
105− # check consistancy of the results
106− assert ( orig - missed - merged == expc - bad - doubled)
107− return orig, missed, merged, expc, bad, doubled, l, labs
108−
109−def notes_roc (la, lb, eps):
110− from numpy import transpose, add, resize
111− """ creates a matrix of size len(la)*len(lb) then look for hit and miss
112− in it within eps tolerance windows """
113− gdn,fpw,fpg,fpa,fdo,fdp = 0,0,0,0,0,0
114− m = len(la)
115− n = len(lb)
116− x = resize(la[:][0],(n,m))
117− y = transpose(resize(lb[:][0],(m,n)))
118− teps = (abs(x-y) <= eps[0])
119− x = resize(la[:][1],(n,m))
120− y = transpose(resize(lb[:][1],(m,n)))
121− tpitc = (abs(x-y) <= eps[1])
122− res = teps * tpitc
123− res = add.reduce(res,axis=0)
124− for i in range(len(res)) :
125− if res[i] > 1:
126− gdn+=1
127− fdo+=res[i]-1
128− elif res [i] == 1:
129− gdn+=1
130− fpa = n - gdn - fpa
131− return gdn,fpw,fpg,fpa,fdo,fdp
132−
133−def load_onsets(filename) :
134− """ load onsets targets / candidates files in arrays """
135− l = [];
136−
137− f = open(filename,'ro')
138− while 1:
139− line = f.readline().split()
140− if not line : break
141− l.append(float(line[0]))
142−
143− return l
python/aubio/plot/__init__.py+0−0

Empty file deleted.

python/aubio/plot/keyboard.py+0−46
@@ -1,46 +0,0 @@
1−
2−def draw_keyboard(firstnote = 21, lastnote = 108, y0 = 0, y1 = 1):
3− import Gnuplot
4− octaves = 10
5−
6− # build template of white notes
7− scalew = 12/7.
8− xw_temp = [i*scalew for i in range(0,7)]
9− # build template of black notes
10− scaleb = 6/7.
11− xb_temp = [i*scaleb for i in [1,3,7,9,11]]
12−
13− xb,xw = [],[]
14− for octave in range(octaves-1):
15− for i in xb_temp:
16− curnote = i+12*octave
17− if curnote > firstnote-1 and curnote < lastnote+1:
18− xb = xb + [curnote]
19− for octave in range(octaves-1):
20− for i in xw_temp:
21− curnote = i+12*octave
22− if curnote > firstnote-1 and curnote < lastnote+1:
23− xw = xw + [curnote]
24−
25− xwdelta = [1/2. * scalew for i in range(len(xw))]
26− yw = [y0+(y1-y0)*1/2. for i in range(len(xw))]
27− ywdelta = [(y1-y0)*1/2. for i in range(len(xw))]
28−
29− xbdelta = [2/3. * scaleb for i in range(len(xb))]
30− yb = [y0+(y1-y0)*2/3. for i in range(len(xb))]
31− ybdelta = [(y1-y0)*1/3. for i in range(len(xb))]
32−
33− whites = Gnuplot.Data(xw,yw,xwdelta,ywdelta,with_ = 'boxxyerrorbars')
34− blacks = Gnuplot.Data(xb,yb,xbdelta,ybdelta,with_ = 'boxxyerrorbars fill solid')
35−
36− return blacks,whites
37−
38−if __name__ == '__main__':
39− from aubio.gnuplot import gnuplot_create
40− blacks,whites = draw_keyboard(firstnote = 21, lastnote = 108)
41− g = gnuplot_create('','')
42− #g('set style fill solid .5')
43− #g('set xrange [60-.5:72+.5]')
44− #g('set yrange [-0.1:1.1]')
45−
46− g.plot(whites,blacks)
python/aubio/plot/notes.py+0−90
@@ -1,90 +0,0 @@
1−__LICENSE__ = """\
2− Copyright (C) 2004-2009 Paul Brossier <piem@aubio.org>
3−
4− This file is part of aubio.
5−
6− aubio is free software: you can redistribute it and/or modify
7− it under the terms of the GNU General Public License as published by
8− the Free Software Foundation, either version 3 of the License, or
9− (at your option) any later version.
10−
11− aubio is distributed in the hope that it will be useful,
12− but WITHOUT ANY WARRANTY; without even the implied warranty of
13− MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− GNU General Public License for more details.
15−
16− You should have received a copy of the GNU General Public License
17− along with aubio. If not, see <http://www.gnu.org/licenses/>.
18−"""
19−
20−def plotnote(la,title=None) :
21− if la[0,:].size() == 3:
22− d = plotnote_withends(la, plot_title=title)
23− else:
24− # scale data if in freq (for REF.txt files)
25− if max(la[:,1] > 128 ):
26− print "scaling frequency data to midi range"
27− la[:,1] /= 6.875
28− la[:,1] = log(la[:,1])/0.6931
29− la[:,1] *= 12
30− la[:,1] -= 3
31− d = plotnote_withoutends(la, plot_title=title)
32− return d
33−
34−def plotnote_multi(lalist,title=None,fileout=None) :
35− d=list()
36− for i in range(len(lalist)):
37− d.append(plotnote(lalist[i], title=title))
38− return d
39−
40−
41−def plotnote_withends(la,plot_title=None) :
42− from numpy import array
43− import Gnuplot, Gnuplot.funcutils
44− d=[]
45− x_widths = array(la[:,1]-la[:,0])/2.
46− d.append(Gnuplot.Data(
47− la[:,0]+x_widths, # x centers
48− la[:,2], # y centers
49− x_widths, # x errors
50− __notesheight*ones(len(la)), # y errors
51− title=plot_title,with_=('boxxyerrorbars fs 3')))
52− return d
53−
54−
55−def plotnote_withoutends(la,plot_title=None) :
56− """ bug: fails drawing last note """
57− from numpy import array
58− import Gnuplot, Gnuplot.funcutils
59− d=[]
60− x_widths = array(la[1:,0]-la[:-1,0])/2;
61− d.append(Gnuplot.Data(
62− la[:-1,0]+x_widths, # x centers
63− la[:-1,1], # y centers
64− x_widths, # x errors
65− __notesheight*ones(len(la)-1), # y errors
66− title=plot_title,with_=('boxxyerrorbars fs 3')))
67− return d
68−
69−def plotnote_do(d,fileout=None):
70− import Gnuplot, Gnuplot.funcutils
71− g = Gnuplot.Gnuplot(debug=1, persist=1)
72− g.gnuplot('set style fill solid border 1; \
73− set size ratio 1/6; \
74− set boxwidth 0.9 relative; \
75− set mxtics 2.5; \
76− set mytics 2.5; \
77− set xtics 5; \
78− set ytics 1; \
79− set grid xtics ytics mxtics mytics')
80−
81− g.xlabel('Time (s)')
82− g.ylabel('Midi pitch')
83− # do the plot
84− #g.gnuplot('set multiplot')
85− #for i in d:
86− g.plot(d[0])
87− #g.gnuplot('set nomultiplot')
88− if fileout != None:
89− g.hardcopy(fileout, enhanced=1, color=0)
90−
python/aubio/task/__init__.py+0−9
@@ -1,9 +0,0 @@
1−from aubio.aubioclass import *
2−from aubio.task.task import task
3−from aubio.task.params import taskparams
4−from aubio.task.silence import tasksilence
5−from aubio.task.onset import taskonset
6−from aubio.task.beat import taskbeat
7−from aubio.task.cut import taskcut
8−from aubio.task.pitch import taskpitch
9−from aubio.task.notes import tasknotes
python/aubio/task/beat.py+0−262
@@ -1,262 +0,0 @@
1−from aubio.aubioclass import *
2−from onset import taskonset
3−
4−class taskbeat(taskonset):
5− def __init__(self,input,params=None,output=None):
6− """ open the input file and initialize arguments
7− parameters should be set *before* calling this method.
8− """
9− taskonset.__init__(self,input,output=None,params=params)
10− self.btwinlen = 512**2/self.params.hopsize
11− self.btstep = self.btwinlen/4
12− self.btoutput = fvec(self.btstep,self.channels)
13− self.dfframe = fvec(self.btwinlen,self.channels)
14− self.bt = beattracking(self.btwinlen,self.channels)
15− self.pos2 = 0
16− self.old = -1000
17−
18− def __call__(self):
19− taskonset.__call__(self)
20− #results = taskonset.__call__(self)
21− # write to current file
22− if self.pos2 == self.btstep - 1 :
23− self.bt.do(self.dfframe,self.btoutput)
24− for i in range (self.btwinlen - self.btstep):
25− self.dfframe.set(self.dfframe.get(i+self.btstep,0),i,0)
26− for i in range(self.btwinlen - self.btstep, self.btwinlen):
27− self.dfframe.set(0,i,0)
28− self.pos2 = -1;
29− self.pos2 += 1
30− val = self.opick.pp.getval()
31− #if not results: val = 0
32− #else: val = results[1]
33− self.dfframe.set(val,self.btwinlen - self.btstep + self.pos2,0)
34− i=0
35− for i in range(1,int( self.btoutput.get(0,0) ) ):
36− if self.pos2 == self.btoutput.get(i,0) and \
37− aubio_silence_detection(self.myvec(),
38− self.params.silence)!=1:
39− now = self.frameread-0
40− period = (60 * self.params.samplerate) / ((now - self.old) * self.params.hopsize)
41− self.old = now
42− return now,period
43−
44− def eval(self,results,tol=0.20,tolcontext=0.25):
45− obeats = self.gettruth()
46− etime = [result[0] for result in results]
47− otime = [obeat[0] for obeat in obeats]
48− CML_tot, CML_max, CML_start, CML_end = 0,0,0,0
49− AML_tot, AML_max, AML_start, AML_end = 0,0,0,0
50− AMLd_tot, AMLd_max, AMLd_start, AMLd_end = 0,0,0,0
51− AMLh_tot, AMLh_max, AMLh_start, AMLh_end = 0,0,0,0
52− AMLo_tot, AMLo_max, AMLo_start, AMLo_end = 0,0,0,0
53− # results iteration
54− j = 1
55− # for each annotation
56− for i in range(2,len(otime)-2):
57− if j+1 >= len(etime): break
58− count = 0
59− # look for next matching beat
60− while otime[i] > etime[j] - (otime[i] - otime[i+1])*tol:
61− if count > 0:
62− #print "spurious etime"
63− if CML_end - CML_start > CML_max:
64− CML_max = CML_end - CML_start
65− CML_start, CML_end = j, j
66− if AMLh_end - AMLh_start > AMLh_max:
67− AMLh_max = AMLh_end - AMLh_start
68− AMLh_start, AMLh_end = j, j
69− if AMLd_end - AMLd_start > AMLd_max:
70− AMLd_max = AMLd_end - AMLd_start
71− AMLd_start, AMLd_end = j, j
72− if AMLo_end - AMLo_start > AMLo_max:
73− AMLo_max = AMLo_end - AMLo_start
74− AMLo_start, AMLo_end = j, j
75− j += 1
76− count += 1
77− if j+1 >= len(etime): break
78− #print otime[i-1],etime[j-1]," ",otime[i],etime[j]," ",otime[i+1],etime[j+1]
79− prevtempo = (otime[i] - otime[i-1])
80− nexttempo = (otime[i+1] - otime[i])
81−
82− current0 = (etime[j] > otime[i] - prevtempo*tol)
83− current1 = (etime[j] < otime[i] + prevtempo*tol)
84−
85− # check correct tempo
86− prev0 = (etime[j-1] > otime[i-1] - prevtempo*tolcontext)
87− prev1 = (etime[j-1] < otime[i-1] + prevtempo*tolcontext)
88− next0 = (etime[j+1] > otime[i+1] - nexttempo*tolcontext)
89− next1 = (etime[j+1] < otime[i+1] + nexttempo*tolcontext)
90−
91− # check for off beat
92− prevoffb0 = (etime[j-1] > otime[i-1] - prevtempo/2 - prevtempo*tolcontext)
93− prevoffb1 = (etime[j-1] < otime[i-1] - prevtempo/2 + prevtempo*tolcontext)
94− nextoffb0 = (etime[j+1] > otime[i+1] - nexttempo/2 - nexttempo*tolcontext)
95− nextoffb1 = (etime[j+1] < otime[i+1] - nexttempo/2 + nexttempo*tolcontext)
96−
97− # check half tempo
98− prevhalf0 = (etime[j-1] > otime[i-1] + prevtempo - prevtempo/2*tolcontext)
99− prevhalf1 = (etime[j-1] < otime[i-1] + prevtempo + prevtempo/2*tolcontext)
100− nexthalf0 = (etime[j+1] > otime[i+1] - nexttempo - nexttempo/2*tolcontext)
101− nexthalf1 = (etime[j+1] < otime[i+1] - nexttempo + nexttempo/2*tolcontext)
102−
103− # check double tempo
104− prevdoub0 = (etime[j-1] > otime[i-1] - prevtempo - prevtempo*2*tolcontext)
105− prevdoub1 = (etime[j-1] < otime[i-1] - prevtempo + prevtempo*2*tolcontext)
106− nextdoub0 = (etime[j+1] > otime[i+1] + nexttempo - nexttempo*2*tolcontext)
107− nextdoub1 = (etime[j+1] < otime[i+1] + nexttempo + nexttempo*2*tolcontext)
108−
109− if current0 and current1 and prev0 and prev1 and next0 and next1:
110− #print "YES!"
111− CML_end = j
112− CML_tot += 1
113− else:
114− if CML_end - CML_start > CML_max:
115− CML_max = CML_end - CML_start
116− CML_start, CML_end = j, j
117− if current0 and current1 and prevhalf0 and prevhalf1 and nexthalf0 and nexthalf1:
118− AMLh_end = j
119− AMLh_tot += 1
120− else:
121− if AMLh_end - AMLh_start > AMLh_max:
122− AMLh_max = AMLh_end - AMLh_start
123− AMLh_start, AMLh_end = j, j
124− if current0 and current1 and prevdoub0 and prevdoub1 and nextdoub0 and nextdoub1:
125− AMLd_end = j
126− AMLd_tot += 1
127− else:
128− if AMLd_end - AMLd_start > AMLd_max:
129− AMLd_max = AMLd_end - AMLd_start
130− AMLd_start, AMLd_end = j, j
131− if current0 and current1 and prevoffb0 and prevoffb1 and nextoffb0 and nextoffb1:
132− AMLo_end = j
133− AMLo_tot += 1
134− else:
135− if AMLo_end - AMLo_start > AMLo_max:
136− AMLo_max = AMLo_end - AMLo_start
137− AMLo_start, AMLo_end = j, j
138− # look for next matching beat
139− count = 0
140− while otime[i] > etime[j] - (otime[i] - otime[i+1])*tolcontext:
141− j += 1
142− if count > 0:
143− #print "spurious etime"
144− start = j
145− count += 1
146− total = float(len(otime))
147− CML_tot /= total
148− AMLh_tot /= total
149− AMLd_tot /= total
150− AMLo_tot /= total
151− CML_cont = CML_max/total
152− AMLh_cont = AMLh_max/total
153− AMLd_cont = AMLd_max/total
154− AMLo_cont = AMLo_max/total
155− return CML_cont, CML_tot, AMLh_cont, AMLh_tot, AMLd_cont, AMLd_tot, AMLo_cont, AMLo_tot
156−
157−# for i in allfreq:
158−# freq.append(float(i) / 2. / N * samplerate )
159−# while freq[i]>freqs[j]:
160−# j += 1
161−# a0 = weight[j-1]
162−# a1 = weight[j]
163−# f0 = freqs[j-1]
164−# f1 = freqs[j]
165−# if f0!=0:
166−# iweight.append((a1-a0)/(f1-f0)*freq[i] + (a0 - (a1 - a0)/(f1/f0 -1.)))
167−# else:
168−# iweight.append((a1-a0)/(f1-f0)*freq[i] + a0)
169−# while freq[i]>freqs[j]:
170−# j += 1
171−
172− def eval2(self,results,tol=0.2):
173− truth = self.gettruth()
174− obeats = [i[0] for i in truth]
175− ebeats = [i[0]*self.params.step for i in results]
176− NP = max(len(obeats), len(ebeats))
177− N = int(round(max(max(obeats), max(ebeats))*100.)+100)
178− W = int(round(tol*100.*60./median([i[1] for i in truth], len(truth)/2)))
179− ofunc = [0 for i in range(N+W)]
180− efunc = [0 for i in range(N+W)]
181− for i in obeats: ofunc[int(round(i*100.)+W)] = 1
182− for i in ebeats: efunc[int(round(i*100.)+W)] = 1
183− assert len(obeats) == sum(ofunc)
184− autocor = 0; m =0
185− for m in range (-W, W):
186− for i in range(W,N):
187− autocor += ofunc[i] * efunc[i-m]
188− autocor /= float(NP)
189− return autocor
190−
191− def evaluation(self,results,tol=0.2,start=5.):
192−
193− """ beat tracking evaluation function
194−
195− computes P-score of experimental results (ebeats)
196− against ground truth annotations (obeats) """
197−
198− from aubio.median import short_find as median
199− truth = self.gettruth()
200− ebeats = [i[0]*self.params.step for i in results]
201− obeats = [i[0] for i in truth]
202−
203− # trim anything found before start
204− while obeats[0] < start: obeats.pop(0)
205− while ebeats[0] < start: ebeats.pop(0)
206− # maximum number of beats found
207− NP = max(len(obeats), len(ebeats))
208− # length of ofunc and efunc vector
209− N = int(round(max(max(obeats), max(ebeats))*100.)+100)
210− # compute W median of ground truth tempi
211− tempi = []
212− for i in range(1,len(obeats)): tempi.append(obeats[i]-obeats[i-1])
213− W = int(round(tol*100.*median(tempi,len(tempi)/2)))
214− # build ofunc and efunc functions, starting with W zeros
215− ofunc = [0 for i in range(N+W)]
216− efunc = [0 for i in range(N+W)]
217− for i in obeats: ofunc[int(round(i*100.)+W)] = 1
218− for i in ebeats: efunc[int(round(i*100.)+W)] = 1
219− # optional: make sure we didn't miss any beats
220− assert len(obeats) == sum(ofunc)
221− assert len(ebeats) == sum(efunc)
222− # compute auto correlation
223− autocor = 0; m =0
224− for m in range (-W, W):
225− for i in range(W,N):
226− autocor += ofunc[i] * efunc[i-m]
227− autocor /= float(NP)
228− return autocor
229−
230− def gettruth(self):
231− import os.path
232− from aubio.txtfile import read_datafile
233− datafile = self.input.replace('.wav','.txt')
234− if not os.path.isfile(datafile):
235− print "no ground truth "
236− return False,False
237− else:
238− values = read_datafile(datafile,depth=0)
239− old = -1000
240− for i in range(len(values)):
241− now = values[i]
242− period = 60 / (now - old)
243− old = now
244− values[i] = [now,period]
245− return values
246−
247−
248− def plot(self,oplots,results):
249− import Gnuplot
250− oplots.append(Gnuplot.Data(results,with_='linespoints',title="auto"))
251−
252− def plotplot(self,wplot,oplots,outplot=None,extension=None,xsize=1.,ysize=1.,spectro=False):
253− import Gnuplot
254− from aubio.gnuplot import gnuplot_create, audio_to_array, make_audio_plot
255− import re
256− # audio data
257− #time,data = audio_to_array(self.input)
258− #f = make_audio_plot(time,data)
259−
260− g = gnuplot_create(outplot=outplot, extension=extension)
261− oplots = [Gnuplot.Data(self.gettruth(),with_='linespoints',title="orig")] + oplots
262− g.plot(*oplots)
python/aubio/task/cut.py+0−42
@@ -1,42 +0,0 @@
1−from task import task
2−from aubio.aubioclass import *
3−
4−class taskcut(task):
5− def __init__(self,input,slicetimes,params=None,output=None):
6− """ open the input file and initialize arguments
7− parameters should be set *before* calling this method.
8− """
9− from os.path import basename,splitext
10− task.__init__(self,input,output=None,params=params)
11− self.soundoutbase, self.soundoutext = splitext(basename(self.input))
12− self.newname = "%s%s%09.5f%s%s" % (self.soundoutbase,".",
13− self.frameread*self.params.step,".",self.soundoutext)
14− self.fileo = sndfile(self.newname,model=self.filei)
15− self.myvec = fvec(self.params.hopsize,self.channels)
16− self.mycopy = fvec(self.params.hopsize,self.channels)
17− self.slicetimes = slicetimes
18−
19− def __call__(self):
20− task.__call__(self)
21− # write to current file
22− if len(self.slicetimes) and self.frameread >= self.slicetimes[0][0]:
23− self.slicetimes.pop(0)
24− # write up to 1st zero crossing
25− zerocross = 0
26− while ( abs( self.myvec.get(zerocross,0) ) > self.params.zerothres ):
27− zerocross += 1
28− writesize = self.fileo.write(zerocross,self.myvec)
29− fromcross = 0
30− while (zerocross < self.readsize):
31− for i in range(self.channels):
32− self.mycopy.set(self.myvec.get(zerocross,i),fromcross,i)
33− fromcross += 1
34− zerocross += 1
35− del self.fileo
36− self.fileo = sndfile("%s%s%09.5f%s%s" % (self.soundoutbase,".",
37− self.frameread*self.params.step,".",self.soundoutext),model=self.filei)
38− writesize = self.fileo.write(fromcross,self.mycopy)
39− else:
40− writesize = self.fileo.write(self.readsize,self.myvec)
41−
42−
python/aubio/task/notes.py+0−159
@@ -1,159 +0,0 @@
1−
2−from aubio.task import task
3−from aubio.aubioclass import *
4−
5−class tasknotes(task):
6− def __init__(self,input,output=None,params=None):
7− task.__init__(self,input,params=params)
8− self.opick = onsetpick(self.params.bufsize,
9− self.params.hopsize,
10− self.channels,
11− self.myvec,
12− self.params.threshold,
13− mode=self.params.onsetmode,
14− dcthreshold=self.params.dcthreshold,
15− derivate=self.params.derivate)
16− self.pitchdet = pitch(mode=self.params.pitchmode,
17− bufsize=self.params.pbufsize,
18− hopsize=self.params.phopsize,
19− channels=self.channels,
20− samplerate=self.srate,
21− omode=self.params.omode)
22− self.olist = []
23− self.ofunc = []
24− self.maxofunc = 0
25− self.last = -1000
26− self.oldifreq = 0
27− if self.params.localmin:
28− self.ovalist = [0., 0., 0., 0., 0.]
29−
30− def __call__(self):
31− from aubio.median import short_find
32− task.__call__(self)
33− isonset,val = self.opick.do(self.myvec)
34− if (aubio_silence_detection(self.myvec(),self.params.silence)):
35− isonset=0
36− freq = -1.
37− else:
38− freq = self.pitchdet(self.myvec)
39− minpitch = self.params.pitchmin
40− maxpitch = self.params.pitchmax
41− if maxpitch and freq > maxpitch :
42− freq = -1.
43− elif minpitch and freq < minpitch :
44− freq = -1.
45− freq = aubio_freqtomidi(freq)
46− if self.params.pitchsmooth:
47− self.shortlist.append(freq)
48− self.shortlist.pop(0)
49− smoothfreq = short_find(self.shortlist,
50− len(self.shortlist)/2)
51− freq = smoothfreq
52− now = self.frameread
53− ifreq = int(round(freq))
54− if self.oldifreq == ifreq:
55− self.oldifreq = ifreq
56− else:
57− self.oldifreq = ifreq
58− ifreq = 0
59− # take back delay
60− if self.params.delay != 0.: now -= self.params.delay
61− if now < 0 :
62− now = 0
63− if (isonset == 1):
64− if self.params.mintol:
65− # prune doubled
66− if (now - self.last) > self.params.mintol:
67− self.last = now
68− return now, 1, freq, ifreq
69− else:
70− return now, 0, freq, ifreq
71− else:
72− return now, 1, freq, ifreq
73− else:
74− return now, 0, freq, ifreq
75−
76−
77− def fprint(self,foo):
78− print self.params.step*foo[0], foo[1], foo[2], foo[3]
79−
80− def compute_all(self):
81− """ Compute data """
82− now, onset, freq, ifreq = [], [], [], []
83− while(self.readsize==self.params.hopsize):
84− n, o, f, i = self()
85− now.append(n*self.params.step)
86− onset.append(o)
87− freq.append(f)
88− ifreq.append(i)
89− if self.params.verbose:
90− self.fprint((n,o,f,i))
91− return now, onset, freq, ifreq
92−
93− def plot(self,now,onset,freq,ifreq,oplots):
94− import Gnuplot
95−
96− oplots.append(Gnuplot.Data(now,freq,with_='lines',
97− title=self.params.pitchmode))
98− oplots.append(Gnuplot.Data(now,ifreq,with_='lines',
99− title=self.params.pitchmode))
100−
101− temponsets = []
102− for i in onset:
103− temponsets.append(i*1000)
104− oplots.append(Gnuplot.Data(now,temponsets,with_='impulses',
105− title=self.params.pitchmode))
106−
107− def plotplot(self,wplot,oplots,outplot=None,multiplot = 0):
108− from aubio.gnuplot import gnuplot_init, audio_to_array, make_audio_plot
109− import re
110− import Gnuplot
111− # audio data
112− time,data = audio_to_array(self.input)
113− f = make_audio_plot(time,data)
114−
115− # check if ground truth exists
116− #timet,pitcht = self.gettruth()
117− #if timet and pitcht:
118− # oplots = [Gnuplot.Data(timet,pitcht,with_='lines',
119− # title='ground truth')] + oplots
120−
121− t = Gnuplot.Data(0,0,with_='impulses')
122−
123− g = gnuplot_init(outplot)
124− g('set title \'%s\'' % (re.sub('.*/','',self.input)))
125− g('set multiplot')
126− # hack to align left axis
127− g('set lmargin 15')
128− # plot waveform and onsets
129− g('set size 1,0.3')
130− g('set origin 0,0.7')
131− g('set xrange [0:%f]' % max(time))
132− g('set yrange [-1:1]')
133− g.ylabel('amplitude')
134− g.plot(f)
135− g('unset title')
136− # plot onset detection function
137−
138−
139− g('set size 1,0.7')
140− g('set origin 0,0')
141− g('set xrange [0:%f]' % max(time))
142− g('set yrange [20:100]')
143− g('set key right top')
144− g('set noclip one')
145− #g('set format x ""')
146− #g('set log y')
147− #g.xlabel('time (s)')
148− g.ylabel('f0 (Hz)')
149− if multiplot:
150− for i in range(len(oplots)):
151− # plot onset detection functions
152− g('set size 1,%f' % (0.7/(len(oplots))))
153− g('set origin 0,%f' % (float(i)*0.7/(len(oplots))))
154− g('set xrange [0:%f]' % max(time))
155− g.plot(oplots[i])
156− else:
157− g.plot(*oplots)
158− #g('unset multiplot')
159−
python/aubio/task/onset.py+0−220
@@ -1,220 +0,0 @@
1−from aubio.task.task import task
2−from aubio.aubioclass import *
3−
4−class taskonset(task):
5− def __init__(self,input,output=None,params=None):
6− """ open the input file and initialize arguments
7− parameters should be set *before* calling this method.
8− """
9− task.__init__(self,input,params=params)
10− self.opick = onsetpick(self.params.bufsize,
11− self.params.hopsize,
12− self.myvec,
13− self.params.threshold,
14− mode=self.params.onsetmode,
15− dcthreshold=self.params.dcthreshold,
16− derivate=self.params.derivate)
17− self.olist = []
18− self.ofunc = []
19− self.maxofunc = 0
20− self.last = 0
21− if self.params.localmin:
22− self.ovalist = [0., 0., 0., 0., 0.]
23−
24− def __call__(self):
25− task.__call__(self)
26− isonset,val = self.opick.do(self.myvec)
27− if (aubio_silence_detection(self.myvec(),self.params.silence)):
28− isonset=0
29− if self.params.storefunc:
30− self.ofunc.append(val)
31− if self.params.localmin:
32− if val > 0: self.ovalist.append(val)
33− else: self.ovalist.append(0)
34− self.ovalist.pop(0)
35− if (isonset > 0.):
36− if self.params.localmin:
37− # find local minima before peak
38− i=len(self.ovalist)-1
39− while self.ovalist[i-1] < self.ovalist[i] and i > 0:
40− i -= 1
41− now = (self.frameread+1-i)
42− else:
43− now = self.frameread
44− # take back delay
45− if self.params.delay != 0.: now -= self.params.delay
46− if now < 0 :
47− now = 0
48− if self.params.mintol:
49− # prune doubled
50− if (now - self.last) > self.params.mintol:
51− self.last = now
52− return now, val
53− else:
54− return now, val
55−
56−
57− def fprint(self,foo):
58− print self.params.step*foo[0]
59−
60− def eval(self,inputdata,ftru,mode='roc',vmode=''):
61− from aubio.txtfile import read_datafile
62− from aubio.onsetcompare import onset_roc, onset_diffs, onset_rocloc
63− ltru = read_datafile(ftru,depth=0)
64− lres = []
65− for i in range(len(inputdata)): lres.append(inputdata[i][0]*self.params.step)
66− if vmode=='verbose':
67− print "Running with mode %s" % self.params.onsetmode,
68− print " and threshold %f" % self.params.threshold,
69− print " on file", self.input
70− #print ltru; print lres
71− if mode == 'local':
72− l = onset_diffs(ltru,lres,self.params.tol)
73− mean = 0
74− for i in l: mean += i
75− if len(l): mean = "%.3f" % (mean/len(l))
76− else: mean = "?0"
77− return l, mean
78− elif mode == 'roc':
79− self.orig, self.missed, self.merged, \
80− self.expc, self.bad, self.doubled = \
81− onset_roc(ltru,lres,self.params.tol)
82− elif mode == 'rocloc':
83− self.v = {}
84− self.v['orig'], self.v['missed'], self.v['Tm'], \
85− self.v['expc'], self.v['bad'], self.v['Td'], \
86− self.v['l'], self.v['labs'] = \
87− onset_rocloc(ltru,lres,self.params.tol)
88−
89− def plot(self,onsets,ofunc,wplot,oplots,nplot=False):
90− import Gnuplot, Gnuplot.funcutils
91− import aubio.txtfile
92− import os.path
93− from numpy import arange, array, ones
94− from aubio.onsetcompare import onset_roc
95−
96− x1,y1,y1p = [],[],[]
97− oplot = []
98− if self.params.onsetmode in ('mkl','kl'): ofunc[0:10] = [0] * 10
99−
100− self.lenofunc = len(ofunc)
101− self.maxofunc = max(ofunc)
102− # onset detection function
103− downtime = arange(len(ofunc))*self.params.step
104− oplot.append(Gnuplot.Data(downtime,ofunc,with_='lines',title=self.params.onsetmode))
105−
106− # detected onsets
107− if not nplot:
108− for i in onsets:
109− x1.append(i[0]*self.params.step)
110− y1.append(self.maxofunc)
111− y1p.append(-self.maxofunc)
112− #x1 = array(onsets)*self.params.step
113− #y1 = self.maxofunc*ones(len(onsets))
114− if x1:
115− oplot.append(Gnuplot.Data(x1,y1,with_='impulses'))
116− wplot.append(Gnuplot.Data(x1,y1p,with_='impulses'))
117−
118− oplots.append((oplot,self.params.onsetmode,self.maxofunc))
119−
120− # check if ground truth datafile exists
121− datafile = self.input.replace('.wav','.txt')
122− if datafile == self.input: datafile = ""
123− if not os.path.isfile(datafile):
124− self.title = "" #"(no ground truth)"
125− else:
126− t_onsets = aubio.txtfile.read_datafile(datafile)
127− x2 = array(t_onsets).resize(len(t_onsets))
128− y2 = self.maxofunc*ones(len(t_onsets))
129− wplot.append(Gnuplot.Data(x2,y2,with_='impulses'))
130−
131− tol = 0.050
132−
133− orig, missed, merged, expc, bad, doubled = \
134− onset_roc(x2,x1,tol)
135− self.title = "GD %2.3f%% FP %2.3f%%" % \
136− ((100*float(orig-missed-merged)/(orig)),
137− (100*float(bad+doubled)/(orig)))
138−
139−
140− def plotplot(self,wplot,oplots,outplot=None,extension=None,xsize=1.,ysize=1.,spectro=False):
141− from aubio.gnuplot import gnuplot_create, audio_to_array, make_audio_plot, audio_to_spec
142− import re
143− # prepare the plot
144− g = gnuplot_create(outplot=outplot, extension=extension)
145− g('set title \'%s\'' % (re.sub('.*/','',self.input)))
146− if spectro:
147− g('set size %f,%f' % (xsize,1.3*ysize) )
148− else:
149− g('set size %f,%f' % (xsize,ysize) )
150− g('set multiplot')
151−
152− # hack to align left axis
153− g('set lmargin 3')
154− g('set rmargin 6')
155−
156− if spectro:
157− import Gnuplot
158− minf = 50
159− maxf = 500
160− data,time,freq = audio_to_spec(self.input,minf=minf,maxf=maxf)
161− g('set size %f,%f' % (1.24*xsize , 0.34*ysize) )
162− g('set origin %f,%f' % (-0.12,0.65*ysize))
163− g('set xrange [0.:%f]' % time[-1])
164− g('set yrange [%f:%f]' % (minf,maxf))
165− g('set pm3d map')
166− g('unset colorbox')
167− g('set lmargin 0')
168− g('set rmargin 0')
169− g('set tmargin 0')
170− g('set palette rgbformulae -25,-24,-32')
171− g.xlabel('time (s)',offset=(0,1.))
172− g.ylabel('freq (Hz)')
173− g('set origin 0,%f' % (1.0*ysize) )
174− g('set format x "%1.1f"')
175− #if log:
176− # g('set yrange [%f:%f]' % (max(10,minf),maxf))
177− # g('set log y')
178− g.splot(Gnuplot.GridData(data,time,freq, binary=1, title=''))
179− else:
180− # plot waveform and onsets
181− time,data = audio_to_array(self.input)
182− wplot = [make_audio_plot(time,data)] + wplot
183− g('set origin 0,%f' % (0.7*ysize) )
184− g('set size %f,%f' % (xsize,0.3*ysize))
185− g('set format y "%1f"')
186− g('set xrange [0:%f]' % max(time))
187− g('set yrange [-1:1]')
188− g('set noytics')
189− g('set y2tics -1,1')
190− g.xlabel('time (s)',offset=(0,0.7))
191− g.ylabel('amplitude')
192− g.plot(*wplot)
193−
194− # default settings for next plots
195− g('unset title')
196− g('set format x ""')
197− g('set format y "%3e"')
198− g('set tmargin 0')
199− g.xlabel('')
200−
201− N = len(oplots)
202− y = 0.7*ysize # the vertical proportion of the plot taken by onset functions
203− delta = 0.035 # the constant part of y taken by last plot label and data
204− for i in range(N):
205− # plot onset detection functions
206− g('set size %f,%f' % ( xsize, (y-delta)/N))
207− g('set origin 0,%f' % ((N-i-1)*(y-delta)/N + delta ))
208− g('set nokey')
209− g('set xrange [0:%f]' % (self.lenofunc*self.params.step))
210− g('set yrange [0:%f]' % (1.1*oplots[i][2]))
211− g('set y2tics ("0" 0, "%d" %d)' % (round(oplots[i][2]),round(oplots[i][2])))
212− g.ylabel(oplots[i][1])
213− if i == N-1:
214− g('set size %f,%f' % ( xsize, (y-delta)/N + delta ) )
215− g('set origin 0,0')
216− g.xlabel('time (s)', offset=(0,0.7))
217− g('set format x')
218− g.plot(*oplots[i][0])
219−
220− g('unset multiplot')
python/aubio/task/params.py+0−33
@@ -1,33 +0,0 @@
1−
2−class taskparams(object):
3− """ default parameters for task classes """
4− def __init__(self,input=None,output=None):
5− self.silence = -90
6− self.derivate = False
7− self.localmin = False
8− self.delay = 4.
9− self.storefunc = False
10− self.bufsize = 512
11− self.hopsize = 256
12− self.pbufsize = 2048
13− self.phopsize = 512
14− self.samplerate = 44100
15− self.tol = 0.05
16− self.mintol = 0.0
17− self.step = float(self.hopsize)/float(self.samplerate)
18− self.threshold = 0.1
19− self.onsetmode = 'dual'
20− self.pitchmode = 'yin'
21− # best threshold for yin monophonic Mirex04 (depth of f0)
22− self.yinthresh = 0.15
23− # best thresh for yinfft monophonic Mirex04 (tradeoff sil/gd)
24− # also best param for yinfft polyphonic Mirex04
25− self.yinfftthresh = 0.85
26− self.pitchsmooth = 0
27− self.pitchmin=20.
28− self.pitchmax=20000.
29− self.pitchdelay = -0.5
30− self.dcthreshold = -1.
31− self.omode = "freq"
32− self.verbose = False
33−
python/aubio/task/pitch.py+0−234
@@ -1,234 +0,0 @@
1−from aubio.task.task import task
2−from aubio.task.silence import tasksilence
3−from aubio.aubioclass import *
4−
5−class taskpitch(task):
6− def __init__(self,input,params=None):
7− task.__init__(self,input,params=params)
8− self.shortlist = [0. for i in range(self.params.pitchsmooth)]
9− if self.params.pitchmode == 'yin':
10− tolerance = self.params.yinthresh
11− elif self.params.pitchmode == 'yinfft':
12− tolerance = self.params.yinfftthresh
13− else:
14− tolerance = 0.
15− self.pitchdet = pitch(mode=self.params.pitchmode,
16− bufsize=self.params.bufsize,
17− hopsize=self.params.hopsize,
18− samplerate=self.srate,
19− omode=self.params.omode,
20− tolerance = tolerance)
21−
22− def __call__(self):
23− from aubio.median import short_find
24− task.__call__(self)
25− if (aubio_silence_detection(self.myvec(),self.params.silence)==1):
26− freq = -1.
27− else:
28− freq = self.pitchdet(self.myvec)
29− minpitch = self.params.pitchmin
30− maxpitch = self.params.pitchmax
31− if maxpitch and freq > maxpitch :
32− freq = -1.
33− elif minpitch and freq < minpitch :
34− freq = -1.
35− if self.params.pitchsmooth:
36− self.shortlist.append(freq)
37− self.shortlist.pop(0)
38− smoothfreq = short_find(self.shortlist,
39− len(self.shortlist)/2)
40− return smoothfreq
41− else:
42− return freq
43−
44− def compute_all(self):
45− """ Compute data """
46− mylist = []
47− while(self.readsize==self.params.hopsize):
48− freq = self()
49− mylist.append(freq)
50− if self.params.verbose:
51− self.fprint("%s\t%s" % (self.frameread*self.params.step,freq))
52− return mylist
53−
54− def gettruth(self):
55− """ extract ground truth array in frequency """
56− import os.path
57− """ from wavfile.txt """
58− datafile = self.input.replace('.wav','.txt')
59− if datafile == self.input: datafile = ""
60− """ from file.<midinote>.wav """
61− # FIXME very weak check
62− floatpit = self.input.split('.')[-2]
63− if not os.path.isfile(datafile) and len(self.input.split('.')) < 3:
64− print "no ground truth "
65− return False,False
66− elif floatpit:
67− try:
68− self.truth = float(floatpit)
69− #print "ground truth found in filename:", self.truth
70− tasksil = tasksilence(self.input,params=self.params)
71− time,pitch =[],[]
72− while(tasksil.readsize==tasksil.params.hopsize):
73− tasksil()
74− time.append(tasksil.params.step*(tasksil.frameread))
75− if not tasksil.issilence:
76− pitch.append(self.truth)
77− else:
78− pitch.append(-1.)
79− return time,pitch
80− except ValueError:
81− # FIXME very weak check
82− if not os.path.isfile(datafile):
83− print "no ground truth found"
84− return 0,0
85− else:
86− from aubio.txtfile import read_datafile
87− values = read_datafile(datafile)
88− time, pitch = [], []
89− for i in range(len(values)):
90− time.append(values[i][0])
91− if values[i][1] == 0.0:
92− pitch.append(-1.)
93− else:
94− pitch.append(aubio_freqtomidi(values[i][1]))
95− return time,pitch
96−
97− def oldeval(self,results):
98− def mmean(l):
99− return sum(l)/max(float(len(l)),1)
100−
101− from aubio.median import percental
102− timet,pitcht = self.gettruth()
103− res = []
104− for i in results:
105− #print i,self.truth
106− if i <= 0: pass
107− else: res.append(self.truth-i)
108− if not res or len(res) < 3:
109− avg = self.truth; med = self.truth
110− else:
111− avg = mmean(res)
112− med = percental(res,len(res)/2)
113− return self.truth, self.truth-med, self.truth-avg
114−
115− def eval(self,pitch,tol=0.5):
116− timet,pitcht = self.gettruth()
117− pitch = [aubio_freqtomidi(i) for i in pitch]
118− for i in range(len(pitch)):
119− if pitch[i] == "nan" or pitch[i] == -1:
120− pitch[i] = -1
121− time = [ (i+self.params.pitchdelay)*self.params.step for i in range(len(pitch)) ]
122− #print len(timet),len(pitcht)
123− #print len(time),len(pitch)
124− if len(timet) != len(time):
125− time = time[1:len(timet)+1]
126− pitch = pitch[1:len(pitcht)+1]
127− #pitcht = [aubio_freqtomidi(i) for i in pitcht]
128− for i in range(len(pitcht)):
129− if pitcht[i] == "nan" or pitcht[i] == "-inf" or pitcht[i] == -1:
130− pitcht[i] = -1
131− assert len(timet) == len(time)
132− assert len(pitcht) == len(pitch)
133− osil, esil, opit, epit, echr = 0, 0, 0, 0, 0
134− for i in range(len(pitcht)):
135− if pitcht[i] == -1: # currently silent
136− osil += 1 # count a silence
137− if pitch[i] <= 0. or pitch[i] == "nan":
138− esil += 1 # found a silence
139− else:
140− opit +=1
141− if abs(pitcht[i] - pitch[i]) < tol:
142− epit += 1
143− echr += 1
144− elif abs(pitcht[i] - pitch[i]) % 12. < tol:
145− echr += 1
146− #else:
147− # print timet[i], pitcht[i], time[i], pitch[i]
148− #print "origsilence", "foundsilence", "origpitch", "foundpitch", "orig pitchroma", "found pitchchroma"
149− #print 100.*esil/float(osil), 100.*epit/float(opit), 100.*echr/float(opit)
150− return osil, esil, opit, epit, echr
151−
152− def plot(self,pitch,wplot,oplots,titles,outplot=None):
153− import Gnuplot
154−
155− time = [ (i+self.params.pitchdelay)*self.params.step for i in range(len(pitch)) ]
156− pitch = [aubio_freqtomidi(i) for i in pitch]
157− oplots.append(Gnuplot.Data(time,pitch,with_='lines',
158− title=self.params.pitchmode))
159− titles.append(self.params.pitchmode)
160−
161−
162− def plotplot(self,wplot,oplots,titles,outplot=None,extension=None,xsize=1.,ysize=1.,multiplot = 1, midi = 1, truth = 1):
163− from aubio.gnuplot import gnuplot_create , audio_to_array, make_audio_plot
164− import re
165− import Gnuplot
166−
167− # check if ground truth exists
168− if truth:
169− timet,pitcht = self.gettruth()
170− if timet and pitcht:
171− oplots = [Gnuplot.Data(timet,pitcht,with_='lines',
172− title='ground truth')] + oplots
173−
174− g = gnuplot_create(outplot=outplot, extension=extension)
175− g('set title \'%s\'' % (re.sub('.*/','',self.input)))
176− g('set size %f,%f' % (xsize,ysize) )
177− g('set multiplot')
178− # hack to align left axis
179− g('set lmargin 4')
180− g('set rmargin 4')
181− # plot waveform
182− time,data = audio_to_array(self.input)
183− wplot = [make_audio_plot(time,data)]
184− g('set origin 0,%f' % (0.7*ysize) )
185− g('set size %f,%f' % (xsize,0.3*ysize))
186− #g('set format y "%1f"')
187− g('set xrange [0:%f]' % max(time))
188− g('set yrange [-1:1]')
189− g('set noytics')
190− g('set y2tics -1,1')
191− g.xlabel('time (s)',offset=(0,0.7))
192− g.ylabel('amplitude')
193− g.plot(*wplot)
194−
195− # default settings for next plots
196− g('unset title')
197− g('set format x ""')
198− g('set format y "%3e"')
199− g('set tmargin 0')
200− g.xlabel('')
201− g('set noclip one')
202−
203− if not midi:
204− g('set log y')
205− #g.xlabel('time (s)')
206− g.ylabel('f0 (Hz)')
207− g('set yrange [100:%f]' % self.params.pitchmax)
208− else:
209− g.ylabel('midi')
210− g('set yrange [%f:%f]' % (aubio_freqtomidi(self.params.pitchmin), aubio_freqtomidi(self.params.pitchmax)))
211− g('set y2tics %f,%f' % (round(aubio_freqtomidi(self.params.pitchmin)+.5),12))
212−
213− if multiplot:
214− N = len(oplots)
215− y = 0.7*ysize # the vertical proportion of the plot taken by onset functions
216− delta = 0.035 # the constant part of y taken by last plot label and data
217− for i in range(N):
218− # plot pitch detection functions
219− g('set size %f,%f' % ( xsize, (y-delta)/N))
220− g('set origin 0,%f' % ((N-i-1)*(y-delta)/N + delta ))
221− g('set nokey')
222− g('set xrange [0:%f]' % max(time))
223− g.ylabel(titles[i])
224− if i == N-1:
225− g('set size %f,%f' % (xsize, (y-delta)/N + delta ) )
226− g('set origin 0,0')
227− g.xlabel('time (s)', offset=(0,0.7))
228− g('set format x')
229− g.plot(oplots[i])
230− else:
231− g('set key right top')
232− g.plot(*oplots)
233− g('unset multiplot')
234−
python/aubio/task/silence.py+0−28
@@ -1,28 +0,0 @@
1−from aubio.task.task import task
2−from aubio.aubioclass import *
3−
4−class tasksilence(task):
5− wassilence = 1
6− issilence = 1
7− def __call__(self):
8− task.__call__(self)
9− if (aubio_silence_detection(self.myvec(),self.params.silence)==1):
10− if self.wassilence == 1: self.issilence = 1
11− else: self.issilence = 2
12− self.wassilence = 1
13− else:
14− if self.wassilence <= 0: self.issilence = 0
15− else: self.issilence = -1
16− self.wassilence = 0
17− if self.issilence == -1:
18− return max(self.frameread-self.params.delay,0.), -1
19− elif self.issilence == 2:
20− return max(self.frameread+self.params.delay,0.), 2
21−
22− def fprint(self,foo):
23− print self.params.step*foo[0],
24− if foo[1] == 2: print "OFF"
25− else: print "ON"
26−
27−
28−
python/aubio/task/task.py+0−53
@@ -1,53 +0,0 @@
1−from aubio.aubioclass import *
2−from params import taskparams
3−
4−class task(taskparams):
5− """ default template class to apply tasks on a stream """
6− def __init__(self,input,output=None,params=None):
7− """ open the input file and initialize default argument
8− parameters should be set *before* calling this method.
9− """
10− import time
11− self.tic = time.time()
12− if params == None: self.params = taskparams()
13− else: self.params = params
14− self.frameread = 0
15− self.readsize = self.params.hopsize
16− self.input = input
17− self.filei = sndfile(self.input)
18− self.srate = self.filei.samplerate()
19− self.params.step = float(self.params.hopsize)/float(self.srate)
20− self.myvec = fvec(self.params.hopsize)
21− self.output = output
22−
23− def __call__(self):
24− self.readsize = self.filei.read(self.params.hopsize,self.myvec)
25− self.frameread += 1
26−
27− def compute_all(self):
28− """ Compute data """
29− mylist = []
30− while(self.readsize==self.params.hopsize):
31− tmp = self()
32− if tmp:
33− mylist.append(tmp)
34− if self.params.verbose:
35− self.fprint(tmp)
36− return mylist
37−
38− def fprint(self,foo):
39− print foo
40−
41− def eval(self,results):
42− """ Eval data """
43− pass
44−
45− def plot(self):
46− """ Plot data """
47− pass
48−
49− def time(self):
50− import time
51− #print "CPU time is now %f seconds," % time.clock(),
52− #print "task execution took %f seconds" % (time.time() - self.tic)
53− return time.time() - self.tic
python/aubio/txtfile.py+0−47
@@ -1,47 +0,0 @@
1−"""Copyright (C) 2004 Paul Brossier <piem@altern.org>
2−print aubio.__LICENSE__ for the terms of use
3−"""
4−
5−__LICENSE__ = """\
6− Copyright (C) 2004-2009 Paul Brossier <piem@aubio.org>
7−
8− This file is part of aubio.
9−
10− aubio is free software: you can redistribute it and/or modify
11− it under the terms of the GNU General Public License as published by
12− the Free Software Foundation, either version 3 of the License, or
13− (at your option) any later version.
14−
15− aubio is distributed in the hope that it will be useful,
16− but WITHOUT ANY WARRANTY; without even the implied warranty of
17− MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18− GNU General Public License for more details.
19−
20− You should have received a copy of the GNU General Public License
21− along with aubio. If not, see <http://www.gnu.org/licenses/>.
22−"""
23−
24−def read_datafile(filename,depth=-1):
25− """read list data from a text file (columns of float)"""
26− if filename == '--' or filename == '-':
27− import sys
28− fres = sys.stdin
29− else:
30− fres = open(filename,'ro')
31− l = []
32− while 1:
33− tmp = fres.readline()
34− if not tmp : break
35− else: tmp = tmp.split()
36− if depth > 0:
37− for i in range(min(depth,len(tmp))):
38− tmp[i] = float(tmp[i])
39− l.append(tmp)
40− elif depth == 0:
41− l.append(float(tmp[0]))
42− else:
43− for i in range(len(tmp)):
44− tmp[i] = float(tmp[i])
45− l.append(tmp)
46− return l
47−
python/aubio/web/__init__.py+0−0

Empty file deleted.

python/aubio/web/browser.py+0−167
@@ -1,167 +0,0 @@
1− #
2− # Copyright 2004 Apache Software Foundation
3− #
4− # Licensed under the Apache License, Version 2.0 (the "License"); you
5− # may not use this file except in compliance with the License. You
6− # may obtain a copy of the License at
7− #
8− # http://www.apache.org/licenses/LICENSE-2.0
9− #
10− # Unless required by applicable law or agreed to in writing, software
11− # distributed under the License is distributed on an "AS IS" BASIS,
12− # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
13− # implied. See the License for the specific language governing
14− # permissions and limitations under the License.
15− #
16− # Originally developed by Gregory Trubetskoy.
17− #
18− # $Id: publisher.py,v 1.36 2004/02/16 19:47:27 grisha Exp $
19−
20−"""
21− This handler is conceputally similar to Zope's ZPublisher, except
22− that it:
23−
24− 1. Is written specifically for mod_python and is therefore much faster
25− 2. Does not require objects to have a documentation string
26− 3. Passes all arguments as simply string
27− 4. Does not try to match Python errors to HTTP errors
28− 5. Does not give special meaning to '.' and '..'.
29−
30− This is a modified version of mod_python.publisher.handler Only the first
31− directory argument is matched, the rest is left for path_info. A default
32− one must be provided.
33−
34−"""
35−
36−from mod_python import apache
37−from mod_python import util
38−from mod_python.publisher import resolve_object,process_auth,imp_suffixes
39−
40−import sys
41−import os
42−import re
43−
44−from types import *
45−
46−def configure_handler(req,default):
47−
48− req.allow_methods(["GET", "POST"])
49− if req.method not in ["GET", "POST"]:
50− raise apache.SERVER_RETURN, apache.HTTP_METHOD_NOT_ALLOWED
51−
52− func_path = ""
53− if req.path_info:
54− func_path = req.path_info[1:] # skip first /
55− #func_path = func_path.replace("/", ".")
56− #if func_path[-1:] == ".":
57− # func_path = func_path[:-1]
58− # changed: only keep the first directory
59− func_path = re.sub('/.*','',func_path)
60−
61− # default to 'index' if no path_info was given
62− if not func_path:
63− func_path = "index"
64−
65− # if any part of the path begins with "_", abort
66− if func_path[0] == '_' or func_path.count("._"):
67− raise apache.SERVER_RETURN, apache.HTTP_NOT_FOUND
68−
69− ## import the script
70− path, module_name = os.path.split(req.filename)
71− if not module_name:
72− module_name = "index"
73−
74− # get rid of the suffix
75− # explanation: Suffixes that will get stripped off
76− # are those that were specified as an argument to the
77− # AddHandler directive. Everything else will be considered
78− # a package.module rather than module.suffix
79− exts = req.get_addhandler_exts()
80− if not exts:
81− # this is SetHandler, make an exception for Python suffixes
82− exts = imp_suffixes
83− if req.extension: # this exists if we're running in a | .ext handler
84− exts += req.extension[1:]
85− if exts:
86− suffixes = exts.strip().split()
87− exp = "\\." + "$|\\.".join(suffixes)
88− suff_matcher = re.compile(exp) # python caches these, so its fast
89− module_name = suff_matcher.sub("", module_name)
90−
91− # import module (or reload if needed)
92− # the [path] argument tells import_module not to allow modules whose
93− # full path is not in [path] or below.
94− config = req.get_config()
95− autoreload=int(config.get("PythonAutoReload", 1))
96− log=int(config.get("PythonDebug", 0))
97− try:
98− module = apache.import_module(module_name,
99− autoreload=autoreload,
100− log=log,
101− path=[path])
102− except ImportError:
103− et, ev, etb = sys.exc_info()
104− # try again, using default module, perhaps this is a
105− # /directory/function (as opposed to /directory/module/function)
106− func_path = module_name
107− module_name = "index"
108− try:
109− module = apache.import_module(module_name,
110− autoreload=autoreload,
111− log=log,
112− path=[path])
113− except ImportError:
114− # raise the original exception
115− raise et, ev, etb
116−
117− # does it have an __auth__?
118− realm, user, passwd = process_auth(req, module)
119−
120− # resolve the object ('traverse')
121− try:
122− object = resolve_object(req, module, func_path, realm, user, passwd)
123− except AttributeError:
124− # changed, return the default path instead
125− #raise apache.SERVER_RETURN, apache.HTTP_NOT_FOUND
126− object = default
127− # not callable, a class or an unbound method
128− if (not callable(object) or
129− type(object) is ClassType or
130− (hasattr(object, 'im_self') and not object.im_self)):
131−
132− result = str(object)
133−
134− else:
135− # callable, (but not a class or unbound method)
136−
137− # process input, if any
138− req.form = util.FieldStorage(req, keep_blank_values=1)
139−
140− result = util.apply_fs_data(object, req.form, req=req)
141−
142− if result or req.bytes_sent > 0 or req.next:
143−
144− if result is None:
145− result = ""
146− else:
147− result = str(result)
148−
149− # unless content_type was manually set, we will attempt
150− # to guess it
151− if not req._content_type_set:
152− # make an attempt to guess content-type
153− if result[:100].strip()[:6].lower() == '<html>' \
154− or result.find('</') > 0:
155− req.content_type = 'text/html'
156− else:
157− req.content_type = 'text/plain'
158−
159− if req.method != "HEAD":
160− req.write(result)
161− else:
162− req.write("")
163− return apache.OK
164− else:
165− req.log_error("mod_python.publisher: %s returned nothing." % `object`)
166− return apache.HTTP_INTERNAL_SERVER_ERROR
167−
python/aubio/web/html.py+0−286
@@ -1,286 +0,0 @@
1−from aubio.bench.node import *
2−
3−def parse_args(req):
4− req.basehref = BASEHREF
5− req.datadir = DATADIR
6− if req.path_info: path_info = req.path_info
7− else: path_info = '/'
8− location = re.sub('^/show_[a-z0-9]*/','',path_info)
9− location = re.sub('^/play_[a-z0-9]*/','',location)
10− location = re.sub('^/index/','',location)
11− location = re.sub('^/','',location)
12− location = re.sub('/$','',location)
13− datapath = "%s/%s" % (DATADIR,location)
14− respath = "%s/%s" % (DATADIR,location)
15− last = re.sub('/$','',location)
16− last = last.split('/')[-1]
17− first = path_info.split('/')[1]
18− # store some of this in the mp_request
19− req.location, req.datapath, req.respath = location, datapath, respath
20− req.first, req.last = first, last
21−
22− if location:
23− if not (os.path.isfile(datapath) or
24− os.path.isdir(datapath) or
25− location in ['feedback','email']):
26− # the path was not understood
27− from mod_python import apache
28− req.write("<html> path not found %s</html>" % (datapath))
29− raise apache.SERVER_RETURN, apache.OK
30− #from mod_python import apache
31− #raise apache.SERVER_RETURN, apache.HTTP_NOT_FOUND
32−
33−def navigation(req):
34− """ main html navigation header """
35− from mod_python import psp
36− req.content_type = "text/html"
37− parse_args(req)
38− datapath = req.datapath
39− location = req.location
40−
41− # deal with session
42− if req.sess.is_new():
43− msg = "<b>Welcome %s</b><br>" % req.sess['login']
44− else:
45− msg = "<b>Welcome back %s</b><br>" % req.sess['login']
46−
47− # start writing
48− tmpl = psp.PSP(req, filename='header.tmpl')
49− tmpl.run(vars = { 'title': "aubioweb / %s / %s" % (req.first,location),
50− 'basehref': '/~piem/',
51− 'message': msg,
52− 'action': req.first})
53−
54− req.write("<h2>Content of ")
55− print_link(req,"","/")
56− y = location.split('/')
57− for i in range(len(y)-1):
58− print_link(req,"/".join(y[:i+1]),y[i])
59− req.write(" / ")
60− req.write("%s</h2>\n" % y[-1])
61−
62− a = {'show_info' : 'info',
63− 'show_sound': 'waveform',
64− 'show_onset': 'onset',
65− 'index' : 'index',
66− 'show_pitch': 'pitch',
67− 'play_m3u': 'stream (m3u/ogg)',
68− 'play_ogg': 'save (ogg)',
69− 'play_wav': 'save (wav)',
70− }
71−
72− # print task lists (only remaining tasks)
73− print_link(req,re.sub('%s.*'%req.last,'',location),"go up")
74− akeys = a.keys(); akeys.sort();
75− curkey = req.first
76− for akey in akeys:
77− if akey != curkey:
78− req.write(":: ")
79− print_link(req,"/".join((akey,location)),a[akey])
80− else:
81− req.write(":: ")
82− req.write("<b>%s</b>" % a[akey])
83− req.write("<br>")
84−
85− # list the content of the directories
86− listdir,listfiles = [],[]
87− if os.path.isdir(datapath):
88− listfiles = list_snd_files(datapath)
89− listdir = list_dirs(datapath)
90− listdir.pop(0) # kick the current dir
91− elif os.path.isfile(datapath):
92− listfiles = [datapath]
93− listdir = [re.sub(req.last,'',location)]
94−
95− link_list(req,listdir,title="Subdirectories")
96− link_list(req,listfiles,title="Files")
97−
98−def footer(req):
99− """ html navigation footer """
100− from mod_python import psp
101− tmpl = psp.PSP(req, filename='footer.tmpl')
102− tmpl.run(vars = { 'time': -req.mtime+req.request_time })
103−
104−def apply_on_data(req, func,**keywords):
105− # bug: hardcoded snd file filter
106− act_on_data(func,req.datapath,req.respath,
107− filter="f -maxdepth 1 -name '*.wav' -o -name '*.aif'",**keywords)
108−
109−def print_link(req,target,name,basehref=BASEHREF):
110− req.write("<a href='%s/%s'>%s</a>\n" % (basehref,target,name))
111−
112−def print_img(req,target,name='',basehref=BASEHREF):
113− if name == '': name = target
114− req.write("<img src='%s/%s' alt='%s' title='%s'>\n" % (basehref,target,name,name))
115−
116−def link_list(req,targetlist,basehref=BASEHREF,title=None):
117− if len(targetlist) > 1:
118− if title: req.write("<h3>%s</h3>"%title)
119− req.write('<ul>')
120− for i in targetlist:
121− s = re.split('%s/'%DATADIR,i,maxsplit=1)[1]
122− if s:
123− req.write('<li>')
124− print_link(req,s,s)
125− req.write('</li>')
126− req.write('</ul>')
127−
128−def print_list(req,list):
129− req.write("<pre>\n")
130− for i in list: req.write("%s\n" % i)
131− req.write("</pre>\n")
132−
133−def print_command(req,command):
134− req.write("<h4>%s</h4>\n" % re.sub('%%','%',command))
135− def print_runcommand(input,output):
136− cmd = re.sub('(%)?%i','%s' % input, command)
137− cmd = re.sub('(%)?%o','%s' % output, cmd)
138− print_list(req,runcommand(cmd))
139− apply_on_data(req,print_runcommand)
140−
141−def datapath_to_location(input):
142− location = re.sub(DATADIR,'',input)
143− return re.sub('^/*','',location)
144−
145−## drawing hacks
146−def draw_func(req,func):
147− import re
148− req.content_type = "image/png"
149− # build location (strip the func_path, add DATADIR)
150− location = re.sub('^/draw_[a-z]*/','%s/'%DATADIR,req.path_info)
151− location = re.sub('.png$','',location)
152− if not os.path.isfile(location):
153− from mod_python import apache
154− raise apache.SERVER_RETURN, apache.HTTP_NOT_FOUND
155− # replace location in func
156− cmd = re.sub('(%)?%i','%s' % location, func)
157− # add PYTHONPATH at the beginning,
158− cmd = "%s%s 2> /dev/null" % (PYTHONPATH,cmd)
159− for each in runcommand(cmd):
160− req.write("%s\n"%each)
161−
162−def show_task(req,task):
163− def show_task_file(input,output,task):
164− location = datapath_to_location(input)
165− print_img(req,"draw_%s/%s" % (task,location))
166− navigation(req)
167− req.write("<h3>%s</h3>\n" % task)
168− apply_on_data(req,show_task_file,task=task)
169− footer(req)
170−
171−## waveform_foo
172−def draw_sound(req):
173− draw_func(req,"aubioplot-audio %%i stdout 2> /dev/null")
174−
175−def show_sound(req):
176− show_task(req,"sound")
177−
178−## pitch foo
179−def draw_pitch(req,threshold='0.3'):
180− draw_func(req,"aubiopitch -i %%i -p -m schmitt,yin,fcomb,mcomb -t %s -O stdout" % threshold)
181−
182−def show_pitch(req):
183− show_task(req,"pitch")
184−
185−## onset foo
186−def draw_onset(req,threshold='0.3'):
187− draw_func(req,"aubiocut -i %%i -p -m complex -t %s -O stdout" % threshold)
188−
189−def show_onset(req,threshold='0.3',details=''):
190− def onset_file(input,output):
191− location = datapath_to_location(input)
192− print_img(req,"draw_onset/%s?threshold=%s"%(location,threshold))
193− print_link(req,"?threshold=%s" % (float(threshold)-0.1),"-")
194− req.write("%s\n" % threshold)
195− print_link(req,"?threshold=%s" % (float(threshold)+0.1),"+")
196− # bug: hardcoded sndfile extension
197− anote = re.sub('\.wav$','.txt',input)
198− if anote == input: anote = ""
199− res = get_extract(input,threshold)
200− if os.path.isfile(anote):
201− tru = get_anote(anote)
202− print_list(req,get_results(tru,res,0.05))
203− else:
204− req.write("no ground truth found<br>\n")
205− if details:
206− req.write("<h4>Extraction</h4>\n")
207− print_list(req,res)
208− else:
209− req.write("<a href='%s/show_onset/%s?details=yes&amp;threshold=%s'>details</a><br>\n" %
210− (req.basehref,location,threshold))
211− if details and os.path.isfile(anote):
212− req.write("<h4>Computed differences</h4>\n")
213− ldiffs = get_diffs(tru,res,0.05)
214− print_list(req,ldiffs)
215− req.write("<h4>Annotations</h4>\n")
216− print_list(req,tru)
217− navigation(req)
218− req.write("<h3>Onset</h3>\n")
219− apply_on_data(req,onset_file)
220− footer(req)
221−
222−def get_anote(anote):
223− import aubio.onsetcompare
224− # FIXME: should import with txtfile.read_datafile
225− return aubio.onsetcompare.load_onsets(anote)
226−
227−def get_diffs(anote,extract,tol):
228− import aubio.onsetcompare
229− return aubio.onsetcompare.onset_diffs(anote,extract,tol)
230−
231−def get_extract(datapath,threshold='0.3'):
232− cmd = "%saubiocut -v -m complex -t %s -i %s" % (PYTHONPATH,threshold,datapath)
233− lo = runcommand(cmd)
234− for i in range(len(lo)): lo[i] = float(lo[i])
235− return lo
236−
237−def get_results(anote,extract,tol):
238− import aubio.onsetcompare
239− orig, missed, merged, expc, bad, doubled = aubio.onsetcompare.onset_roc(anote,extract,tol)
240− s =("GD %2.8f\t" % (100*float(orig-missed-merged)/(orig)),
241− "FP %2.8f\t" % (100*float(bad+doubled)/(orig)) ,
242− "GD-merged %2.8f\t" % (100*float(orig-missed)/(orig)) ,
243− "FP-pruned %2.8f\t" % (100*float(bad)/(orig)) )
244− return s
245−
246−# play m3u foo
247−def play_m3u(req):
248− def show_task_file(input,output,task):
249− location = datapath_to_location(input)
250− req.write("http://%s%s/play_ogg/%s\n" % (HOSTNAME,BASEHREF,re.sub("play_m3u",task,location)))
251− req.content_type = "audio/mpegurl"
252− parse_args(req)
253− apply_on_data(req,show_task_file,task="play_ogg")
254−
255−# play wav foo
256−def play_wav(req):
257− req.content_type = "audio/x-wav"
258− func = "cat %%i"
259− # build location (strip the func_path, add DATADIR)
260− location = re.sub('^/play_wav/','%s/'%DATADIR,req.path_info)
261− if not os.path.isfile(location):
262− from mod_python import apache
263− raise apache.SERVER_RETURN, apache.HTTP_NOT_FOUND
264− # replace location in func
265− cmd = re.sub('(%)?%i','%s' % location, func)
266− # add PYTHONPATH at the beginning,
267− cmd = "%s 2> /dev/null" % cmd
268− for each in runcommand(cmd):
269− req.write("%s\n"%each)
270−
271−# play ogg foo
272−def play_ogg(req):
273− req.content_type = "application/ogg"
274− func = "oggenc -o - %%i"
275− # build location (strip the func_path, add DATADIR)
276− location = re.sub('^/play_ogg/','%s/'%DATADIR,req.path_info)
277− location = re.sub('.ogg$','',location)
278− if not os.path.isfile(location):
279− from mod_python import apache
280− raise apache.SERVER_RETURN, apache.HTTP_NOT_FOUND
281− # replace location in func
282− cmd = re.sub('(%)?%i','%s' % location, func)
283− # add PYTHONPATH at the beginning,
284− cmd = "%s 2> /dev/null" % cmd
285− for each in runcommand(cmd):
286− req.write("%s\n"%each)
python/aubio/wscript_build+0−17
@@ -1,17 +0,0 @@
1−# vim:set syntax=python:
2−
3−pyaubio = ctx.new_task_gen(name = 'python-aubio',
4− features = 'c cshlib pyext',
5− source = '../../swig/aubio.i',
6− add_objects = 'sndfileio',
7− target = '_aubiowrapper',
8− use = ['aubio'],
9− uselib = ['SNDFILE'],
10− swig_flags = '-python -Wall',
11− includes = '. ../../src ../../examples')
12−pyaubio.install_path = '${PYTHONDIR}/${PACKAGE}'
13−
14−# install python files
15−ctx.install_files('${PYTHONDIR}/${PACKAGE}/', ctx.path.ant_glob('**/*.py'))
16−# install swig generated python file
17−ctx.install_files('${PYTHONDIR}/${PACKAGE}/', '../../swig/aubiowrapper.py')
python/aubiocompare-onset+0−114
@@ -1,114 +0,0 @@
1−#! /usr/bin/python
2−
3−"""Copyright (C) 2004 Paul Brossier <piem@altern.org>
4−
5−print aubio.__LICENSE__ for the terms of use
6−
7−or see LICENSE.txt in the aubio installation directory.
8−"""
9−__LICENSE__ = """\
10− Copyright (C) 2004-2009 Paul Brossier <piem@aubio.org>
11−
12− This file is part of aubio.
13−
14− aubio is free software: you can redistribute it and/or modify
15− it under the terms of the GNU General Public License as published by
16− the Free Software Foundation, either version 3 of the License, or
17− (at your option) any later version.
18−
19− aubio is distributed in the hope that it will be useful,
20− but WITHOUT ANY WARRANTY; without even the implied warranty of
21− MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22− GNU General Public License for more details.
23−
24− You should have received a copy of the GNU General Public License
25− along with aubio. If not, see <http://www.gnu.org/licenses/>.
26−"""
27−
28−
29−__HELP__ = """\
30−# required arguments
31− -c targetfilename
32− -o detectfilename
33−(both must be text files with 1 time a line expressed in seconds)
34−
35−# optional arguments
36− -D <delay> delay in seconds
37− -v verbose mode
38− -d debug mode
39−
40−# output
41−results:number of correct detections
42− number of incorrect detections
43− number of doubled detections
44− number of total detections
45− number of total targets
46−
47−# example:
48−$ aubioonset-comp -c checked-onsets.txt -o handlab-onsets.txt -v
49−( gd fp dd ) tot / real
50−( 5 4 0 ) 9 / 9
51−55.5555555556 %GD 44.4444444444 %FP 0.0 %OD
52−
53−# bugs
54−does not scale to very long lists
55−"""
56−
57−import sys
58−from aubio.onsetcompare import onset_roc, onset_diffs
59−from aubio.txtfile import read_datafile
60−
61−# default values
62−fileo=None;filec=None;vmode=None;dmode=None;delay=0.
63−# default tolerance is 50 ms
64−#tol = 0.050
65−tol = 0.048
66−# default mode is onset
67−mode = 'onset'
68−
69−while len(sys.argv) >=2:
70− option = sys.argv[1]; del sys.argv[1]
71− if option == '-h': print __HELP__; sys.exit()
72− if option == '-o': fileo = sys.argv[1]; del sys.argv[1]
73− if option == '-c': filec = sys.argv[1]; del sys.argv[1]
74− if option == '-v': vmode = 'verbose'
75− if option == '-d': dmode = 'debug'
76− if option == '-D': delay = float(sys.argv[1]); del sys.argv[1]
77− if option == '-tol': tol = float(sys.argv[1]); del sys.argv[1]
78− if option == '-l': mode = 'localisation'
79−
80−# arguments required
81−if (not fileo) or (not filec):
82− print 'wrong set of arguments. use \'-h\' for help'
83− sys.exit('error: needs at least \'-c targets.txt -o detected.txt\'')
84−
85−# load files
86−ltru, lres = read_datafile(fileo,depth=0),read_datafile(filec,depth=0)
87−
88−# delay onsets as required with -D
89−if delay:
90− for i in range(len(lres)):
91− lres[i] = lres[i] + delay
92−# compute errors types
93−if mode == 'localisation':
94− l = onset_diffs(ltru,lres,tol)
95− for i in l: print "%.3f" % i
96−else:
97− orig, missed, merged, expc, bad, doubled = onset_roc(ltru,lres,tol)
98−
99− # print results
100− #print "orig, missed, merged, expc, bad, doubled:"
101− if vmode=='verbose':
102− print "orig", orig
103− print "expc", expc
104− print "missed",missed
105− print "merged", merged
106− print "bad", bad
107− print "doubled", doubled
108− print "correct", orig-missed-merged
109− print "GD %2.8f\t" % (100*float(orig-missed-merged)/(orig)),
110− print "FP %2.8f\t" % (100*float(bad+doubled)/(orig)) ,
111− print "GD-merged %2.8f\t" % (100*float(orig-missed)/(orig)) ,
112− print "FP-pruned %2.8f\t" % (100*float(bad)/(orig))
113− else:
114− print orig, missed, merged, expc, bad, doubled
python/aubiocut+0−156
@@ -1,156 +0,0 @@
1−#! /usr/bin/python
2−
3−""" this file was written by Paul Brossier
4− it is released under the GNU/GPL license.
5−"""
6−
7−import sys
8−from aubio.task import *
9−
10−usage = "usage: %s [options] -i soundfile" % sys.argv[0]
11−
12−def parse_args():
13− from optparse import OptionParser
14− parser = OptionParser(usage=usage)
15− parser.add_option("-i","--input",
16− action="store", dest="filename",
17− help="input sound file")
18− parser.add_option("-m","--mode",
19− action="store", dest="mode", default='dual',
20− help="onset detection mode [default=dual] \
21− complexdomain|hfc|phase|specdiff|energy|kl|mkl|dual")
22− parser.add_option("-B","--bufsize",
23− action="store", dest="bufsize", default=512,
24− help="buffer size [default=512]")
25− parser.add_option("-H","--hopsize",
26− action="store", dest="hopsize", default=256,
27− help="overlap size [default=256]")
28− parser.add_option("-t","--threshold",
29− action="store", dest="threshold", default=0.3,
30− help="onset peak picking threshold [default=0.3]")
31− parser.add_option("-C","--dcthreshold",
32− action="store", dest="dcthreshold", default=1.,
33− help="onset peak picking DC component [default=1.]")
34− parser.add_option("-s","--silence",
35− action="store", dest="silence", default=-70,
36− help="silence threshold [default=-70]")
37− parser.add_option("-M","--mintol",
38− action="store", dest="mintol", default=0.048,
39− help="minimum inter onset interval [default=0.048]")
40− parser.add_option("-D","--delay",
41− action="store", dest="delay",
42− help="number of seconds to take back [default=system]\
43− default system delay is 3*hopsize/samplerate")
44− parser.add_option("-L","--localmin",
45− action="store_true", dest="localmin", default=False,
46− help="use local minima after peak detection")
47− parser.add_option("-c","--cut",
48− action="store_true", dest="cut", default=False,
49− help="cut input sound file at detected labels \
50− best used with option -L")
51− parser.add_option("-d","--derivate",
52− action="store_true", dest="derivate", default=False,
53− help="derivate onset detection function")
54− parser.add_option("-S","--silencecut",
55− action="store_true", dest="silencecut", default=False,
56− help="outputs silence locations")
57− parser.add_option("-z","--zerocross",
58− action="store", dest="zerothres", default=0.008,
59− help="zero-crossing threshold for slicing [default=0.00008]")
60− # plotting functions
61− parser.add_option("-p","--plot",
62− action="store_true", dest="plot", default=False,
63− help="draw plot")
64− parser.add_option("-x","--xsize",
65− action="store", dest="xsize", default=1.,
66− type='float', help="define xsize for plot")
67− parser.add_option("-y","--ysize",
68− action="store", dest="ysize", default=1.,
69− type='float', help="define ysize for plot")
70− parser.add_option("-f","--function",
71− action="store_true", dest="func", default=False,
72− help="print detection function")
73− parser.add_option("-n","--no-onsets",
74− action="store_true", dest="nplot", default=False,
75− help="do not plot detected onsets")
76− parser.add_option("-O","--outplot",
77− action="store", dest="outplot", default=None,
78− help="save plot to output.{ps,png}")
79− parser.add_option("-F","--spectrogram",
80− action="store_true", dest="spectro", default=False,
81− help="add spectrogram to the plot")
82− parser.add_option("-v","--verbose",
83− action="store_true", dest="verbose", default=True,
84− help="make lots of noise [default]")
85− parser.add_option("-q","--quiet",
86− action="store_false", dest="verbose", default=True,
87− help="be quiet")
88− # to be implemented
89− parser.add_option("-b","--beat",
90− action="store_true", dest="beat", default=False,
91− help="output beat locations")
92− (options, args) = parser.parse_args()
93− if not options.filename:
94− print "no file name given\n", usage
95− sys.exit(1)
96− return options, args
97−
98−options, args = parse_args()
99−
100−filename = options.filename
101−params = taskparams()
102−params.hopsize = int(options.hopsize)
103−params.bufsize = int(options.bufsize)
104−params.threshold = float(options.threshold)
105−params.dcthreshold = float(options.dcthreshold)
106−params.zerothres = float(options.zerothres)
107−params.silence = float(options.silence)
108−params.mintol = float(options.mintol)
109−params.verbose = options.verbose
110−# default take back system delay
111−if options.delay: params.delay = int(float(options.delay)/params.step)
112−
113−dotask = taskonset
114−if options.beat:
115− dotask = taskbeat
116−elif options.silencecut:
117− dotask = tasksilence
118−elif options.plot or options.func:
119− params.storefunc=True
120−else:
121− params.storefunc=False
122−
123−lonsets, lofunc = [], []
124−wplot,oplots = [],[]
125−modes = options.mode.split(',')
126−for i in range(len(modes)):
127− params.onsetmode = modes[i]
128− filetask = dotask(filename,params=params)
129− onsets = filetask.compute_all()
130−
131− #lonsets.append(onsets)
132− if not options.silencecut:
133− ofunc = filetask.ofunc
134− lofunc.append(ofunc)
135−
136− if options.plot:
137− if options.beat:
138− filetask.plot(oplots, onsets)
139− else:
140− filetask.plot(onsets, ofunc, wplot, oplots, nplot=options.nplot)
141−
142− if options.func:
143− for i in ofunc:
144− print i
145−
146−if options.outplot:
147− extension = options.outplot.split('.')[-1]
148− outplot = '.'.join(options.outplot.split('.')[:-1])
149−else:
150− extension,outplot = None,None
151−if options.plot: filetask.plotplot(wplot, oplots, outplot=outplot, extension=extension,
152− xsize=options.xsize,ysize=options.ysize,spectro=options.spectro)
153−
154−if options.cut:
155− a = taskcut(filename,onsets,params=params)
156− a.compute_all()
python/aubiodiffs-onset+0−86
@@ -1,86 +0,0 @@
1−#! /usr/bin/python
2−
3−__LICENSE__ = """\
4− Copyright (C) 2004-2009 Paul Brossier <piem@aubio.org>
5−
6− This file is part of aubio.
7−
8− aubio is free software: you can redistribute it and/or modify
9− it under the terms of the GNU General Public License as published by
10− the Free Software Foundation, either version 3 of the License, or
11− (at your option) any later version.
12−
13− aubio is distributed in the hope that it will be useful,
14− but WITHOUT ANY WARRANTY; without even the implied warranty of
15− MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16− GNU General Public License for more details.
17−
18− You should have received a copy of the GNU General Public License
19− along with aubio. If not, see <http://www.gnu.org/licenses/>.
20−"""
21−
22−__HELP__ = """\
23−# required arguments
24− -c targetfilename
25− -o detectfilename
26−(both must be text files with 1 time a line expressed in seconds)
27−
28−# optional arguments
29− -D <delay> delay in seconds
30− -v verbose mode
31− -d debug mode
32−
33−# output
34−results:number of correct detections
35− number of incorrect detections
36− number of doubled detections
37− number of total detections
38− number of total targets
39−
40−# example:
41−$ aubioonset-comp -c checked-onsets.txt -o handlab-onsets.txt -v
42−( gd fp dd ) tot / real
43−( 5 4 0 ) 9 / 9
44−55.5555555556 %GD 44.4444444444 %FP 0.0 %OD
45−
46−# bugs
47−does not scale to very long lists
48−"""
49−
50−import sys
51−from aubio.onsetcompare import onset_diffs
52−from aubio.txtfile import read_datafile
53−
54−# default values
55−fileo=None;filec=None;vmode=None;dmode=None;delay=0.
56−# default tolerance is 50 ms
57−#tol = 0.050
58−tol = 0.048
59−
60−while len(sys.argv) >=2:
61− option = sys.argv[1]; del sys.argv[1]
62− if option == '-h': print __HELP__; sys.exit()
63− if option == '-o': fileo = sys.argv[1]; del sys.argv[1]
64− if option == '-c': filec = sys.argv[1]; del sys.argv[1]
65− if option == '-v': vmode = 'verbose'
66− if option == '-d': dmode = 'debug'
67− if option == '-D': delay = float(sys.argv[1]); del sys.argv[1]
68− if option == '-tol': tol = float(sys.argv[1]); del sys.argv[1]
69−
70−# arguments required
71−if (not fileo) or (not filec):
72− print 'wrong set of arguments. use \'-h\' for help'
73− sys.exit('error: needs at least \'-c targets.txt -o detected.txt\'')
74−
75−# load files
76−ltru, lres = read_datafile(fileo,depth=0),read_datafile(filec,depth=0)
77−
78−# delay onsets as required with -D
79−if delay:
80− for i in range(len(lres)):
81− lres[i] = lres[i] + delay
82−# compute errors types
83−l = onset_diffs(ltru,lres,tol)
84−# print with 1ms precision
85−for i in l: print "%.3f" % float(i)
86−
python/aubiofilter-notes+0−94
@@ -1,94 +0,0 @@
1−#!/usr/bin/python
2−
3−""" this file is used to get filter the (old) output format of aubionotes """
4−
5−# default parameters
6−__eps = [0.250,0.50] # minimum length, pitch tolerance (ms,midipitch)
7−__plot = 0 # -P (command line switch)
8−__delay = 0.0 # -D <value> (fixed delay for score alignement)
9−__winlength = 10 # -w <value> (window length for pitch estimation in frames)
10−
11−import getopt
12−import sys
13−
14−def parse_args (sysargs):
15− from getopt import gnu_getopt
16− shortopts ='i:o:t:p:w:D:P:'
17− longopts =('input=','output=','tolpitch=','toltime=','winlength=','delay','plot=')
18− args,tmp = gnu_getopt(sysargs,shortopts,longopts)
19− assert len(args) > 1
20− plot = __plot
21− delay = __delay
22− eps = __eps
23− winlength = __winlength
24− plot = __plot
25− fileout = '/tmp/testprint.ps'
26− args.sort()
27− for i in range(len(args)): # a bad way
28− if args[i][0] == '-i' or args[i][0] == '--input':
29− fileorg = args[i][1]
30− if args[i][0] == '-o' or args[i][0] == '--output':
31− fileerr = args[i][1]
32− if args[i][0] == '-t' or args[i][0] == '--toltime':
33− eps[0] = float(args[i][1])
34− if args[i][0] == '-p' or args[i][0] == '--tolpitch':
35− eps[1] = float(args[i][1])
36− if args[i][0] == '-D' or args[i][0] == '--delay':
37− delay = float(args[i][1])
38− if args[i][0] == '-w' or args[i][0] == '--winlength':
39− winlength = int(args[i][1])
40− if args[i][0] == '-P' or args[i][0] == '--plot':
41− plot = 1
42− fileout = args[i][1]
43− return fileorg,fileerr,eps,winlength,plot,delay,fileout
44−
45−def usage():
46− print __file__, "with at least some arguments"
47−
48−def main():
49− try:
50− opts,args = getopt.getopt(sys.argv[1:],
51− "hvo:i:p:P",
52− ["help", "output=", "verbose", "input=", "plot="])
53− except getopt.GetoptError:
54− usage()
55− sys.exit(2)
56−
57− input = None
58− output = None
59− verbose = False
60− winlength = __winlength
61− plot = __plot
62− eps = __eps
63−
64− for o, a in opts:
65− if o in ("-v", "--verbose"):
66− verbose = True
67− if o in ("-h", "--help"):
68− usage()
69− sys.exit(2)
70− if o in ("--output"):
71− output = a
72− if o in ("-i", "--input"):
73− input = a
74− if o in ("-P", "--plot"):
75− plot = 1
76−
77− assert input != None and input != "", "no input file"
78−
79− from aubio import notefilter,txtfile,gnuplot
80− """ load midi and raw data """
81− from numpy import array
82− notelist = array(txtfile.read_datafile(input))
83− """ filter it out """
84− notelist_filtered = notefilter.segraw_onsets4(notelist,winlength,eps)
85− if verbose == 1 :
86− for a,b in notelist_filtered:
87− print a,b
88− """ plot results """
89− if plot == 1 :
90− gnuplot.plotnote(notelist_filtered,title=input,fileout=output)
91−
92−if __name__ == "__main__":
93− main()
94−
python/aubioinput.py+141−0
@@ -0,0 +1,141 @@
1+#! /usr/bin/python
2+
3+import pygst
4+pygst.require('0.10')
5+import gst
6+import gobject
7+gobject.threads_init ()
8+
9+def gst_buffer_to_numpy_array(buffer, chan):
10+ import numpy
11+ samples = numpy.frombuffer(buffer.data, dtype=numpy.float32)
12+ if chan == 1:
13+ return samples.T
14+ else:
15+ samples.resize([len(samples)/chan, chan])
16+ return samples.T
17+
18+class AubioSink(gst.BaseSink):
19+ _caps = gst.caps_from_string('audio/x-raw-float, \
20+ rate=[ 1, 2147483647 ], \
21+ channels=[ 1, 2147483647 ], \
22+ endianness={ 1234, 4321 }, \
23+ width=32')
24+
25+ __gsttemplates__ = (
26+ gst.PadTemplate ("sink",
27+ gst.PAD_SINK,
28+ gst.PAD_ALWAYS,
29+ _caps),
30+ )
31+
32+ def __init__(self, name, process):
33+ self.__gobject_init__()
34+ self.set_name(name)
35+ self.process = process
36+ self.adapter = gst.Adapter()
37+ self.set_property('sync', False)
38+ self.pos = 0
39+
40+ def set_property(self, name, value):
41+ if name == 'hopsize':
42+ # blocksize is in byte, convert from hopsize
43+ from struct import calcsize
44+ self.set_property('blocksize', value * calcsize('f'))
45+ else:
46+ super(gst.BaseSink, self).set_property(name, value)
47+
48+ def do_render(self, buffer):
49+ blocksize = self.get_property('blocksize')
50+ caps = buffer.get_caps()
51+ chan = caps[0]['channels']
52+ self.adapter.push(buffer)
53+ while self.adapter.available() >= blocksize:
54+ block = self.adapter.take_buffer(blocksize)
55+ v = gst_buffer_to_numpy_array(block, chan)
56+ if self.process:
57+ self.process(v, self.pos)
58+ self.pos += 1
59+ remaining = self.adapter.available()
60+ if remaining < blocksize and remaining > 0:
61+ block = self.adapter.take_buffer(remaining)
62+ v = gst_buffer_to_numpy_array(block, chan)
63+ if self.process:
64+ self.process(v, self.pos)
65+ self.pos += 1
66+ return gst.FLOW_OK
67+
68+gobject.type_register(AubioSink)
69+
70+class aubioinput(gst.Bin):
71+
72+ ret = 0
73+
74+ def __init__(self, uri, process = None, hopsize = 512,
75+ caps = None):
76+ if uri.startswith('/'):
77+ from urllib import quote
78+ uri = 'file://'+quote(uri)
79+ src = gst.element_factory_make('uridecodebin')
80+ src.set_property('uri', uri)
81+ src.connect('pad-added', self.source_pad_added_cb)
82+ conv = gst.element_factory_make('audioconvert')
83+ self.conv = conv
84+ rsmpl = gst.element_factory_make('audioresample')
85+ capsfilter = gst.element_factory_make('capsfilter')
86+ if caps:
87+ capsfilter.set_property('caps', gst.caps_from_string(caps))
88+ sink = AubioSink("AubioSink", process = process)
89+ sink.set_property('hopsize', hopsize) # * calcsize('f'))
90+
91+ self.pipeline = gst.Pipeline()
92+
93+ self.bus = self.pipeline.get_bus()
94+ self.bus.add_signal_watch()
95+ self.bus.connect('message', self.on_eos)
96+
97+ self.apad = conv.get_pad('sink')
98+
99+ self.pipeline.add(src, conv, rsmpl, capsfilter, sink)
100+
101+ gst.element_link_many(conv, rsmpl, capsfilter, sink)
102+
103+ self.mainloop = gobject.MainLoop()
104+ self.pipeline.set_state(gst.STATE_PLAYING)
105+
106+ def run(self):
107+ self.mainloop.run()
108+ return self.ret
109+
110+ def source_pad_added_cb(self, src, pad):
111+ name = pad.get_caps()[0].get_name()
112+ if name == 'audio/x-raw-float' or name == 'audio/x-raw-int':
113+ pad.link(self.conv.get_pad("sink"))
114+
115+ def source_pad_removed_cb(self, src, pad):
116+ pad.unlink(self.conv.get_pad("sink"))
117+
118+ def on_eos(self, bus, msg):
119+ if msg.type == gst.MESSAGE_EOS:
120+ self.bus.remove_signal_watch()
121+ self.pipeline.set_state(gst.STATE_PAUSED)
122+ self.mainloop.quit()
123+ elif msg.type == gst.MESSAGE_ERROR:
124+ print "ERROR", msg.parse_error()
125+ self.bus.remove_signal_watch()
126+ self.pipeline.set_state(gst.STATE_PAUSED)
127+ self.mainloop.quit()
128+ self.ret = 1 # set return value to 1 in case of error
129+
130+if __name__ == '__main__':
131+ import sys
132+ if len(sys.argv) < 2:
133+ print "Usage: %s <filename>" % sys.argv[0]
134+ sys.exit(1)
135+ for filename in sys.argv[1:]:
136+ peak = [0.] # use a mutable
137+ def process(buf, hop):
138+ peak[0] = max( peak[0], abs(buf.max()) )
139+ a = aubioinput(filename, process = process, hopsize = 512)
140+ if a.run() == 0: # only display the results if no
141+ print "Finished reading %s, peak value is %f" % (filename, max(peak))
python/aubiomodule.c+161−0
@@ -0,0 +1,161 @@
1+#include <Python.h>
2+#define PY_ARRAY_UNIQUE_SYMBOL PyArray_API
3+#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
4+#include <numpy/arrayobject.h>
5+
6+#include "aubio-types.h"
7+#include "generated/aubio-generated.h"
8+
9+static char Py_alpha_norm_doc[] = "compute alpha normalisation factor";
10+
11+static PyObject *
12+Py_alpha_norm (PyObject * self, PyObject * args)
13+{
14+ PyObject *input;
15+ fvec_t *vec;
16+ smpl_t alpha;
17+ PyObject *result;
18+
19+ if (!PyArg_ParseTuple (args, "Of:alpha_norm", &input, &alpha)) {
20+ return NULL;
21+ }
22+
23+ if (input == NULL) {
24+ return NULL;
25+ }
26+
27+ vec = PyAubio_ArrayToCFvec (input);
28+
29+ if (vec == NULL) {
30+ return NULL;
31+ }
32+
33+ // compute the function
34+ result = Py_BuildValue ("f", fvec_alpha_norm (vec, alpha));
35+ if (result == NULL) {
36+ return NULL;
37+ }
38+
39+ return result;
40+}
41+
42+static char Py_zero_crossing_rate_doc[] = "compute zero crossing rate";
43+
44+static PyObject *
45+Py_zero_crossing_rate (PyObject * self, PyObject * args)
46+{
47+ PyObject *input;
48+ fvec_t *vec;
49+ PyObject *result;
50+
51+ if (!PyArg_ParseTuple (args, "O:zero_crossing_rate", &input)) {
52+ return NULL;
53+ }
54+
55+ if (input == NULL) {
56+ return NULL;
57+ }
58+
59+ vec = PyAubio_ArrayToCFvec (input);
60+
61+ if (vec == NULL) {
62+ return NULL;
63+ }
64+
65+ // compute the function
66+ result = Py_BuildValue ("f", aubio_zero_crossing_rate (vec));
67+ if (result == NULL) {
68+ return NULL;
69+ }
70+
71+ return result;
72+}
73+
74+static char Py_min_removal_doc[] = "compute zero crossing rate";
75+
76+static PyObject *
77+Py_min_removal(PyObject * self, PyObject * args)
78+{
79+ PyObject *input;
80+ fvec_t *vec;
81+
82+ if (!PyArg_ParseTuple (args, "O:min_removal", &input)) {
83+ return NULL;
84+ }
85+
86+ if (input == NULL) {
87+ return NULL;
88+ }
89+
90+ vec = PyAubio_ArrayToCFvec (input);
91+
92+ if (vec == NULL) {
93+ return NULL;
94+ }
95+
96+ // compute the function
97+ fvec_min_removal (vec);
98+
99+ // since this function does not return, we could return None
100+ //return Py_None;
101+ // however it is convenient to return the modified vector
102+ return (PyObject *) PyAubio_CFvecToArray(vec);
103+ // or even without converting it back to an array
104+ //Py_INCREF(vec);
105+ //return (PyObject *)vec;
106+}
107+
108+static PyMethodDef aubio_methods[] = {
109+ {"alpha_norm", Py_alpha_norm, METH_VARARGS, Py_alpha_norm_doc},
110+ {"zero_crossing_rate", Py_zero_crossing_rate, METH_VARARGS,
111+ Py_zero_crossing_rate_doc},
112+ {"min_removal", Py_min_removal, METH_VARARGS, Py_min_removal_doc},
113+ {NULL, NULL} /* Sentinel */
114+};
115+
116+static char aubio_module_doc[] = "Python module for the aubio library";
117+
118+PyMODINIT_FUNC
119+init_aubio (void)
120+{
121+ PyObject *m;
122+ int err;
123+
124+ if ( (PyType_Ready (&Py_cvecType) < 0)
125+ || (PyType_Ready (&Py_filterType) < 0)
126+ || (PyType_Ready (&Py_filterbankType) < 0)
127+ || (PyType_Ready (&Py_fftType) < 0)
128+ || (PyType_Ready (&Py_pvocType) < 0)
129+ // generated objects
130+ || (generated_types_ready() < 0 )
131+ ) {
132+ return;
133+ }
134+
135+ m = Py_InitModule3 ("_aubio", aubio_methods, aubio_module_doc);
136+
137+ if (m == NULL) {
138+ return;
139+ }
140+
141+ err = _import_array ();
142+
143+ if (err != 0) {
144+ fprintf (stderr,
145+ "Unable to import Numpy C API from aubio module (error %d)\n", err);
146+ }
147+
148+ Py_INCREF (&Py_cvecType);
149+ PyModule_AddObject (m, "cvec", (PyObject *) & Py_cvecType);
150+ Py_INCREF (&Py_filterType);
151+ PyModule_AddObject (m, "digital_filter", (PyObject *) & Py_filterType);
152+ Py_INCREF (&Py_filterbankType);
153+ PyModule_AddObject (m, "filterbank", (PyObject *) & Py_filterbankType);
154+ Py_INCREF (&Py_fftType);
155+ PyModule_AddObject (m, "fft", (PyObject *) & Py_fftType);
156+ Py_INCREF (&Py_pvocType);
157+ PyModule_AddObject (m, "pvoc", (PyObject *) & Py_pvocType);
158+
159+ // generated objects
160+ add_generated_objects(m);
161+}
python/aubionotes+0−79
@@ -1,79 +0,0 @@
1−#!/usr/bin/python
2−
3−def do(filein,threshold):
4−
5− import aubio.aubioclass
6− import aubio.median
7− from math import floor
8− hopsize = 512
9− bufsize = 4096
10− channels = 1
11− frameread = 0
12− silthres = -80.
13− filei = aubio.aubioclass.sndfile(filein)
14− srate = filei.samplerate()
15− myvec = aubio.aubioclass.fvec(hopsize,channels)
16− readsize = filei.read(hopsize,myvec)
17− ppick = aubio.aubioclass.pitchpick(bufsize,hopsize,channels,myvec,srate)
18− opick = aubio.aubioclass.onsetpick(bufsize,hopsize,channels,myvec,threshold)
19− mylist = list()
20−
21− wassilence = 0
22− lastpitch = 0
23− starttime = 0
24− while(readsize==hopsize):
25− readsize = filei.read(hopsize,myvec)
26− val = ppick.do(myvec)
27− midival = aubio.aubioclass.bintomidi(val,srate,bufsize)
28− isonset,onset = opick.do(myvec)
29− now = (frameread)*hopsize/(srate+0.)
30− issilence = aubio.aubioclass.aubio_silence_detection(myvec.vec,silthres)
31−
32− estmidival = 0
33− if (issilence == 1):
34− if (wassilence == 0):
35− #outputnow
36− endtime = (frameread-3)*hopsize/(srate+0.)
37− if len(mylist) > 5 :
38− estmidival = aubio.median.percental(mylist,len(mylist)/2)
39− print "sil", starttime, endtime, estmidival
40− #resetnow
41− mylist = list()
42− else:
43− wassilence = 1
44− else:
45− if isonset == 1:
46− if (wassilence == 0):
47− #outputnow
48− endtime = (frameread-3)*hopsize/(srate+0.)
49− #estmidival = aubio.median.percental(around(array(mylist)),len(mylist)//2)
50− if len(mylist) > 5 :
51− estmidival = aubio.median.percental(mylist,len(mylist)/2)
52− print starttime, endtime, estmidival
53− #resetnow
54− mylist = list()
55− #store start time
56− starttime = (frameread-3)*hopsize/(srate+0.)
57− else:
58− """
59− if(listfull):
60− #outputnow
61− endtime = (frameread-3)*hopsize/(srate+0.)
62− print starttime, endtime, estimmidival
63− else:
64− """
65− #bufferize
66− if midival > 50 and midival < 75:
67− mylist.append(floor(midival))
68− wassilence = 0
69−
70−
71− #elif( midival > 45 ):
72− # mylist.append(( now , midival+12 ))
73− #mylist.append(toappend)
74− frameread += 1
75−
76−
77−if __name__ == "__main__":
78− import sys
79− do(sys.argv[1],sys.argv[2])
python/aubiopitch+0−131
@@ -1,131 +0,0 @@
1−#!/usr/bin/python
2−
3−""" this file was written by Paul Brossier
4− it is released under the GNU/GPL license.
5−"""
6−
7−import sys
8−from aubio.task import *
9−
10−usage = "usage: %s [options] -i soundfile" % sys.argv[0]
11−
12−
13−def parse_args():
14− from optparse import OptionParser
15− parser = OptionParser(usage=usage)
16− parser.add_option("-i","--input",
17− action="store", dest="filename",
18− help="input sound file")
19− parser.add_option("-m","--mode",
20− action="store", dest="mode", default='yinfft',
21− help="pitch detection mode [default=mcomb] \
22− mcomb|yin|fcomb|schmitt")
23− parser.add_option("-u","--units",
24− action="store", dest="omode", default="freq",
25− help="output pitch in units [default=Hz] \
26− freq|midi|cent|bin")
27− parser.add_option("-B","--bufsize",
28− action="store", dest="bufsize", default=None,
29− help="buffer size [default=2048]")
30− parser.add_option("-H","--hopsize",
31− action="store", dest="hopsize", default=None,
32− help="overlap size [default=512]")
33− parser.add_option("-t","--threshold",
34− action="store", dest="threshold", default=0.1,
35− help="pitch threshold (for yin) [default=0.1]")
36− parser.add_option("-s","--silence",
37− action="store", dest="silence", default=-70,
38− help="silence threshold [default=-70]")
39− parser.add_option("-D","--delay",
40− action="store", dest="delay",
41− help="number of seconds frames to take back [default=0]")
42− parser.add_option("-S","--smoothing",
43− action="store", dest="smoothing", default=False,
44− help="use a median filter of N frames [default=0]")
45− parser.add_option("-M","--maximum",
46− action="store", dest="pitchmax", default=False,
47− help="maximum pitch value to look for (Hz) [default=20000]")
48− parser.add_option("-l","--minimum",
49− action="store", dest="pitchmin", default=False,
50− help="minimum pitch value to look for (Hz) [default=20]")
51− # to be implemented
52− parser.add_option("-n","--note",
53− action="store_true", dest="note", default=False,
54− help="NOT IMPLEMENTED output notes")
55− # plotting functions
56− parser.add_option("-T","--plottruth",
57− action="store_true", dest="plottruth", default=False,
58− help="draw plot of the ground truth pitch track")
59− parser.add_option("-p","--plot",
60− action="store_true", dest="plot", default=False,
61− help="draw plot of the pitch track")
62− parser.add_option("-x","--xsize",
63− action="store", dest="xsize", default=1.,
64− type='float', help="define xsize for plot")
65− parser.add_option("-y","--ysize",
66− action="store", dest="ysize", default=1.,
67− type='float', help="define ysize for plot")
68− parser.add_option("-O","--outplot",
69− action="store", dest="outplot", default=None,
70− help="save the plot to output.{ps,png,svg} instead of displaying it")
71− parser.add_option("-v","--verbose",
72− action="store_true", dest="verbose", default=True,
73− help="make lots of noise")
74− parser.add_option("-q","--quiet",
75− action="store_false", dest="verbose", default=True,
76− help="be quiet")
77− (options, args) = parser.parse_args()
78− if not options.bufsize:
79− if options.mode == "yin": options.bufsize = 1024
80− if options.mode == "schmitt": options.bufsize = 2048
81− if options.mode == "mcomb": options.bufsize = 4096
82− if options.mode == "fcomb": options.bufsize = 4096
83− else: options.bufsize = 2048
84− if not options.hopsize:
85− options.hopsize = float(options.bufsize) / 2
86− if not options.filename:
87− print "no file name given\n", usage
88− sys.exit(1)
89− return options, args
90−
91−options, args = parse_args()
92−
93−#print options.bufsize, options.hopsize
94−
95−filename = options.filename
96−params = taskparams()
97−params.samplerate = float(sndfile(filename).samplerate())
98−params.hopsize = int(options.hopsize)
99−params.bufsize = int(options.bufsize)
100−params.step = params.samplerate/float(params.hopsize)
101−params.yinthresh = float(options.threshold)
102−params.silence = float(options.silence)
103−params.verbose = options.verbose
104−if options.smoothing: params.pitchsmooth = int(options.smoothing)
105−if options.pitchmax: params.pitchmax = int(options.pitchmax)
106−if options.pitchmin: params.pitchmin = int(options.pitchmin)
107−#mintol = float(options.mintol)*step
108−# default take back system delay
109−if options.delay: params.pitchdelay = float(options.delay)
110−
111−if options.note:
112− exit("not implemented yet")
113−
114−wplot,oplots,titles = [],[],[]
115−modes = options.mode.split(',')
116−for i in range(len(modes)):
117− pitch = []
118− params.pitchmode = modes[i]
119− filetask = taskpitch(filename,params=params)
120− pitch = filetask.compute_all()
121− #print filetask.eval(pitch[i])
122− if options.plot: filetask.plot(pitch,wplot,oplots,titles)
123−
124−if options.outplot:
125− extension = options.outplot.split('.')[-1]
126− outplot = '.'.join(options.outplot.split('.')[:-1])
127−else:
128− extension,outplot = None,None
129−if options.plot:
130− filetask.plotplot(wplot,oplots,titles,outplot=outplot,extension=extension,
131− xsize=options.xsize,ysize=options.ysize,truth=options.plottruth)
python/aubioplot-audio+0−31
@@ -1,31 +0,0 @@
1−#!/usr/bin/python
2−
3−import sys
4−from aubio.gnuplot import gnuplot_create,gnuplot_addargs,plot_audio
5−
6−usage = "usage: %s [options] -i soundfile" % sys.argv[0]
7−
8−def parse_args():
9− from optparse import OptionParser
10− parser = OptionParser(usage=usage)
11− parser.add_option("-i","--input",
12− action="store", dest="filename",
13− help="input sound file")
14− gnuplot_addargs(parser)
15− (options, args) = parser.parse_args()
16− if not options.filename:
17− print "no file name given\n", usage
18− sys.exit(1)
19− return options, args
20−
21−options, args = parse_args()
22−
23−if options.outplot:
24− extension = options.outplot.split('.')[-1]
25− outplot = '.'.join(options.outplot.split('.')[:-1])
26−else:
27− extension = ''
28− outplot = None
29−
30−g = gnuplot_create(outplot,extension,options)
31−plot_audio(options.filename.split(','), g, options)
python/aubioplot-notes+0−31
@@ -1,31 +0,0 @@
1−#!/usr/bin/python
2−
3−def parse_args (sysargs):
4− from getopt import gnu_getopt
5− shortopts ='i:o:'
6− longopts =('input=','output=')
7− args,tmp = gnu_getopt(sysargs,shortopts,longopts)
8− args.sort()
9− filein,fileout= None,None
10− for i in range(len(args)): # a bad way
11− if args[i][0] == '-i' or args[i][0] == '--input':
12− filein = args[i][1]
13− if args[i][0] == '-o' or args[i][0] == '--output':
14− fileout = args[i][1]
15− assert filein != None, 'precise filein'
16− return filein,fileout
17−
18−def main (sysargs) :
19− from aubio.txtfile import read_datafile
20− from aubio.gnuplot import plotnote,plotnote_do
21− from numpy import array
22− filein,fileout = parse_args(sysargs)
23− #print 'checking', fileerr, 'against', fileorg
24− """ load midi and raw data """
25− d = plotnote(array(read_datafile(filein)),title=filein)
26− plotnote_do(d,fileout=fileout)
27−
28−if __name__ == "__main__":
29− import sys
30− main(sys.argv[1:])
31−
python/aubioplot-spec+0−51
@@ -1,51 +0,0 @@
1−#! /usr/bin/python
2−
3−""" this file was written by Paul Brossier
4− it is released under the GNU/GPL license.
5−"""
6−
7−import sys
8−from aubio.gnuplot import gnuplot_create,gnuplot_addargs,plot_spec
9−
10−usage = "usage: %s [options] -i soundfile" % sys.argv[0]
11−
12−def parse_args():
13− from optparse import OptionParser
14− parser = OptionParser(usage=usage)
15− parser.add_option("-i","--input",
16− action="store", dest="filename",
17− help="input sound file")
18− parser.add_option("-M","--maxf",
19− action="store", dest="maxf", default=10000.,
20− type='float',help="higher frequency limit")
21− parser.add_option("-L","--minf",
22− action="store", dest="minf", default=0.,
23− type='float',help="lower frequency limit")
24− parser.add_option("-l","--log",
25− action="store_true", dest="log", default=False,
26− help="plot on a logarithmic scale")
27− parser.add_option("-B","--bufsize", type='int',
28− action="store", dest="bufsize", default=8192,
29− help="buffer size [default=8192]")
30− parser.add_option("-H","--hopsize", type='int',
31− action="store", dest="hopsize", default=1024,
32− help="overlap size [default=1024]")
33− gnuplot_addargs(parser)
34− (options, args) = parser.parse_args()
35− if not options.filename:
36− print "no file name given\n", usage
37− sys.exit(1)
38− return options, args
39−
40−options, args = parse_args()
41−filename = options.filename
42−
43−if options.outplot:
44− extension = options.outplot.split('.')[-1]
45− outplot = '.'.join(options.outplot.split('.')[:-1])
46−else:
47− extension = ''
48− outplot = None
49−
50−g = gnuplot_create(outplot,extension,options)
51−plot_spec(filename, g, options)
python/aubioplot-yinfft+0−135
@@ -1,135 +0,0 @@
1−#! /usr/bin/python
2−
3−""" this file was written by Paul Brossier
4− it is released under the GNU/GPL license.
5−"""
6−
7−import sys,time
8−from aubio.task import task,taskparams
9−from aubio.aubioclass import fvec
10−from aubio.gnuplot import gnuplot_create
11−from aubio.aubiowrapper import *
12−
13−usage = "usage: %s [options] -i soundfile" % sys.argv[0]
14−
15−def parse_args():
16− from optparse import OptionParser
17− parser = OptionParser(usage=usage)
18− parser.add_option("-i","--input",
19− action="store", dest="filename",
20− help="input sound file")
21− parser.add_option("-n","--printframe",
22− action="store", dest="printframe", default=-1,
23− help="make a plot of the n_th frame")
24− parser.add_option("-x","--xsize",
25− action="store", dest="xsize", default=1.,
26− help="define xsize for plot")
27− parser.add_option("-y","--ysize",
28− action="store", dest="ysize", default=1.,
29− help="define ysize for plot")
30− parser.add_option("-O","--outplot",
31− action="store", dest="outplot", default=None,
32− help="save plot to output.{ps,png}")
33− (options, args) = parser.parse_args()
34− if not options.filename:
35− print "no file name given\n", usage
36− sys.exit(1)
37− return options, args
38−
39−def plotdata(x,y,plottitle="",**keyw):
40− import Gnuplot
41− return Gnuplot.Data(x, y, title="%s" % plottitle,**keyw)
42−
43−options, args = parse_args()
44−filename = options.filename
45−xsize = float(options.xsize)
46−ysize = float(options.ysize)*2
47−
48−printframe = int(options.printframe)
49−if printframe == -1:
50− print "Will wait for ^D to skip to next plot"
51− print "Press enter before to print to file"
52−
53−
54−g = gnuplot_create()
55−params = taskparams()
56−params.hopsize = 2048 # 512
57−params.bufsize = params.hopsize #2048
58−taskfile = task(filename,params=params)
59−
60−yin = fvec(params.bufsize/2,1)
61−
62−t = [i for i in range(params.bufsize)]
63−a = [0 for i in range(params.bufsize)]
64−
65−while (taskfile.readsize == params.hopsize):
66− taskfile()
67−
68− n = [i for i in range(params.bufsize/2)]
69− a = [taskfile.myvec.get(i,0) for i in range(params.hopsize/2)]
70− aubio_pitchyin_diff(taskfile.myvec(),yin()) # compute d[t]
71− c = [yin.get(i,0) for i in range(params.bufsize/2)]
72− aubio_pitchyin_getcum(yin()) # compute d'[t]
73− y = [yin.get(i,0) for i in range(params.bufsize/2)]
74− thresh = [0.1 for i in range(params.bufsize/2)]
75− #t.append((i/float(params.hopsize)+taskfile.frameread)*params.step),t.pop(0)
76− d = [plotdata(n,a,plottitle="signal", with_='lines'),
77− plotdata(n,c,plottitle="d[t]",axes='x1y2', with_='lines lt 1'),
78− plotdata(n,y,plottitle="d'[t]",axes='x1y1', with_='lines lt 2'),
79− plotdata(n,thresh,plottitle="threshold",axes='x1y1', with_='lines lt 3')]
80− #g('set xrange [%f:%f]' % (t[0],t[-1]))
81− #time.sleep(.2)
82− g.reset()
83− g('set yrange [-1:3]')
84− g('set xrange [0:%d]' % (params.bufsize/2))
85− g('set title \"%s\"' % "Example of period detection using YIN")
86− if printframe == -1:
87− g.replot(*d)
88− a = sys.stdin.read()
89− if a == "\n" or printframe == taskfile.frameread:
90− from os.path import basename
91− outplot = "_".join([basename(sys.argv[0]),'_'.join(basename(filename).split('.')),"%d" % taskfile.frameread])
92− print outplot
93− f = gnuplot_create(outplot=outplot,extension='ps')
94− f('set size %f,%f;' % (xsize,ysize) )
95− f('set lmargin %f' % (15*xsize))
96− f('set rmargin %f' % (10*xsize))
97− #f('set title \"%s\"' % "Example of period detection using YIN")
98− f('set multiplot')
99− f.ylabel('amplitude',offset=(+.5,0))
100− f.xlabel('time (samples)')
101− f('set size %f,%f;' % (xsize,ysize*0.4) )
102− f('set orig %f,%f;' % (0,ysize*0.6) )
103− sigmax = max(abs(min(a)),abs(max(a)))
104− f('set yrange [%f:%f]' % (-1.3*sigmax,1.3*sigmax))
105− f('set xrange [0:%d]' % (params.bufsize/2))
106− f.plot(d[0])
107−
108− f.ylabel('')
109− f.xlabel('lag (samples)')
110− f('set bmargin %f' % (4*ysize))
111− f('set size %f,%f;' % (xsize,ysize*0.6) )
112− f('set orig %f,%f;' % (0,0) )
113− f('set autoscale')
114− f('set xrange [0:%d]' % (params.bufsize/2))
115− f('set notitle')
116− f('set y2tics')
117− f('set ytics nomirror')
118− f('set noytics')
119− f('set key right')
120− f.plot(d[1])
121−
122− f.ylabel('amplitude')
123− f.xlabel('')
124− f('set y2tics nomirror')
125− f('set ytics nomirror')
126− f('set noy2tics')
127− f('set noxtics')
128− f('set ytics')
129− f('set key left')
130− f.plot(d[2],d[3])
131− #f('set yrange [-1:3]')
132− #f.plot(*d)
133− print "saved plot", outplot, 'ps'
134− elif printframe < taskfile.frameread:
135− break
python/aubioproxy.c+153−0
@@ -0,0 +1,153 @@
1+#include "aubio-types.h"
2+
3+fvec_t *
4+PyAubio_ArrayToCFvec (PyObject *input) {
5+ PyObject *array;
6+ fvec_t *vec;
7+ if (input == NULL) {
8+ PyErr_SetString (PyExc_ValueError, "input array is not a python object");
9+ goto fail;
10+ }
11+ // parsing input object into a Py_fvec
12+ if (PyArray_Check(input)) {
13+
14+ // we got an array, convert it to an fvec
15+ if (PyArray_NDIM ((PyArrayObject *)input) == 0) {
16+ PyErr_SetString (PyExc_ValueError, "input array is a scalar");
17+ goto fail;
18+ } else if (PyArray_NDIM ((PyArrayObject *)input) > 1) {
19+ PyErr_SetString (PyExc_ValueError,
20+ "input array has more than one dimensions");
21+ goto fail;
22+ }
23+
24+ if (!PyArray_ISFLOAT ((PyArrayObject *)input)) {
25+ PyErr_SetString (PyExc_ValueError, "input array should be float");
26+ goto fail;
27+ } else if (PyArray_TYPE ((PyArrayObject *)input) != AUBIO_NPY_SMPL) {
28+ PyErr_SetString (PyExc_ValueError, "input array should be float32");
29+ goto fail;
30+ } else {
31+ // input data type is float32, nothing else to do
32+ array = input;
33+ }
34+
35+ // vec = new_fvec (vec->length);
36+ // no need to really allocate fvec, just its struct member
37+ vec = (fvec_t *)malloc(sizeof(fvec_t));
38+ vec->length = PyArray_SIZE ((PyArrayObject *)array);
39+ vec->data = (smpl_t *) PyArray_GETPTR1 ((PyArrayObject *)array, 0);
40+
41+ } else if (PyObject_TypeCheck (input, &PyList_Type)) {
42+ PyErr_SetString (PyExc_ValueError, "does not convert from list yet");
43+ return NULL;
44+ } else {
45+ PyErr_SetString (PyExc_ValueError, "can only accept vector of float as input");
46+ return NULL;
47+ }
48+
49+ return vec;
50+
51+fail:
52+ return NULL;
53+}
54+
55+PyObject *
56+PyAubio_CFvecToArray (fvec_t * self)
57+{
58+ npy_intp dims[] = { self->length, 1 };
59+ return PyArray_SimpleNewFromData (1, dims, AUBIO_NPY_SMPL, self->data);
60+}
61+
62+Py_cvec *
63+PyAubio_CCvecToPyCvec (cvec_t * input) {
64+ Py_cvec *vec = (Py_cvec*) PyObject_New (Py_cvec, &Py_cvecType);
65+ vec->length = input->length;
66+ vec->o = input;
67+ Py_INCREF(vec);
68+ return vec;
69+}
70+
71+cvec_t *
72+PyAubio_ArrayToCCvec (PyObject *input) {
73+ if (PyObject_TypeCheck (input, &Py_cvecType)) {
74+ return ((Py_cvec*)input)->o;
75+ } else {
76+ PyErr_SetString (PyExc_ValueError, "input array should be float32");
77+ return NULL;
78+ }
79+}
80+
81+PyObject *
82+PyAubio_CFmatToArray (fmat_t * input)
83+{
84+ PyObject *array = NULL;
85+ uint_t i;
86+ npy_intp dims[] = { input->length, 1 };
87+ PyObject *concat = PyList_New (0), *tmp = NULL;
88+ for (i = 0; i < input->height; i++) {
89+ tmp = PyArray_SimpleNewFromData (1, dims, AUBIO_NPY_SMPL, input->data[i]);
90+ PyList_Append (concat, tmp);
91+ Py_DECREF (tmp);
92+ }
93+ array = PyArray_FromObject (concat, AUBIO_NPY_SMPL, 2, 2);
94+ Py_DECREF (concat);
95+ return array;
96+}
97+
98+fmat_t *
99+PyAubio_ArrayToCFmat (PyObject *input) {
100+ PyObject *array;
101+ fmat_t *mat;
102+ uint_t i;
103+ if (input == NULL) {
104+ PyErr_SetString (PyExc_ValueError, "input array is not a python object");
105+ goto fail;
106+ }
107+ // parsing input object into a Py_fvec
108+ if (PyArray_Check(input)) {
109+
110+ // we got an array, convert it to an fvec
111+ if (PyArray_NDIM ((PyArrayObject *)input) == 0) {
112+ PyErr_SetString (PyExc_ValueError, "input array is a scalar");
113+ goto fail;
114+ } else if (PyArray_NDIM ((PyArrayObject *)input) > 2) {
115+ PyErr_SetString (PyExc_ValueError,
116+ "input array has more than two dimensions");
117+ goto fail;
118+ }
119+
120+ if (!PyArray_ISFLOAT ((PyArrayObject *)input)) {
121+ PyErr_SetString (PyExc_ValueError, "input array should be float");
122+ goto fail;
123+ } else if (PyArray_TYPE ((PyArrayObject *)input) != AUBIO_NPY_SMPL) {
124+ PyErr_SetString (PyExc_ValueError, "input array should be float32");
125+ goto fail;
126+ } else {
127+ // input data type is float32, nothing else to do
128+ array = input;
129+ }
130+
131+ // no need to really allocate fvec, just its struct member
132+ mat = (fmat_t *)malloc(sizeof(fmat_t));
133+ mat->length = PyArray_DIM ((PyArrayObject *)array, 1);
134+ mat->height = PyArray_DIM ((PyArrayObject *)array, 0);
135+ mat->data = (smpl_t **)malloc(sizeof(smpl_t*) * mat->height);
136+ for (i=0; i< mat->height; i++) {
137+ mat->data[i] = (smpl_t*)PyArray_GETPTR1 ((PyArrayObject *)array, i);
138+ }
139+
140+ } else if (PyObject_TypeCheck (input, &PyList_Type)) {
141+ PyErr_SetString (PyExc_ValueError, "can not convert list to fmat");
142+ return NULL;
143+ } else {
144+ PyErr_SetString (PyExc_ValueError, "can only accept matrix of float as input");
145+ return NULL;
146+ }
147+
148+ return mat;
149+
150+fail:
151+ return NULL;
152+}
153+
python/aubioweb.py+0−113
@@ -1,113 +0,0 @@
1−#!/usr/bin/python
2−
3−doc = """
4−This script works with mod_python to browse a collection of annotated wav files
5−and results.
6−
7−you will need to have at least the following packages need to be installed (the
8−name of the command line tool is precised in parenthesis):
9−
10−libapache-mod-python (apache2 prefered)
11−sndfile-programs (sndfile-info)
12−vorbis-tools (oggenc)
13−python-gnuplot
14−python-numpy
15−
16−Try the command line tools in aubio/python to test your installation.
17−
18−NOTE: this script is probably horribly insecure.
19−
20−example configuration for apache to put in your preferred virtual host.
21−
22−<Directory /home/piem/public_html/aubioweb>
23− # Minimal config
24− AddHandler mod_python .py
25− # Disable these in production
26− PythonDebug On
27− PythonAutoReload on
28− # Default handler in url
29− PythonHandler aubioweb
30− ## Authentication stuff (optional)
31− #PythonAuthenHandler aubioweb
32− #AuthType Basic
33− #AuthName "Restricted Area"
34− #require valid-user
35− # make default listing
36− DirectoryIndex aubioweb/
37−</Directory>
38−
39−"""
40−
41−from aubio.web.html import *
42−
43−def handler(req):
44− from aubio.web.browser import *
45− from mod_python import Session
46− req.sess = Session.Session(req)
47− req.sess['login']='new aubio user'
48− req.sess.save()
49− return configure_handler(req,index)
50−
51−def index(req,threshold='0.3'):
52− navigation(req)
53− print_command(req,"sfinfo %%i")
54− return footer(req)
55−
56−def show_info(req,verbose=''):
57− navigation(req)
58− print_command(req,"sndfile-info %%i")
59− return footer(req)
60−
61−def feedback(req):
62− navigation(req)
63− req.write("""
64− Please provide feedback below:
65− <p>
66− <form action="/~piem/aubioweb/email" method="POST">
67− Name: <input type="text" name="name"><br>
68− Email: <input type="text" name="email"><br>
69− Comment: <textarea name="comment" rows=4 cols=20></textarea><br>
70− <input type="submit">
71− </form>
72− """)
73−
74−WEBMASTER='piem@calabaza'
75−SMTP_SERVER='localhost'
76−
77−def email(req,name,email,comment):
78− import smtplib
79− # make sure the user provided all the parameters
80− if not (name and email and comment):
81− return "A required parameter is missing, \
82− please go back and correct the error"
83− # create the message text
84− msg = """\
85−From: %s
86−Subject: feedback
87−To: %s
88−
89−I have the following comment:
90−
91−%s
92−
93−Thank You,
94−
95−%s
96−
97−""" % (email, WEBMASTER, comment, name)
98− # send it out
99− conn = smtplib.SMTP(SMTP_SERVER)
100− try:
101− conn.sendmail(email, [WEBMASTER], msg)
102− except smtplib.SMTPSenderRefused:
103− return """<html>please provide a valid email</html>"""
104−
105− conn.quit()
106− # provide feedback to the user
107− s = """\
108−<html>
109−Dear %s,<br>
110−Thank You for your kind comments, we
111−will get back to you shortly.
112−</html>""" % name
113− return s
python/aubiowraphell.h+90−0
@@ -0,0 +1,90 @@
1+#include "aubio-types.h"
2+
3+#define AUBIO_DECLARE(NAME, PARAMS...) \
4+typedef struct { \
5+ PyObject_HEAD \
6+ aubio_ ## NAME ## _t * o; \
7+ PARAMS; \
8+} Py_## NAME;
9+
10+#define AUBIO_INIT(NAME, PARAMS... ) \
11+static int \
12+Py_ ## NAME ## _init (Py_ ## NAME * self, PyObject * args, PyObject * kwds) \
13+{ \
14+ self->o = new_aubio_## NAME ( PARAMS ); \
15+ if (self->o == NULL) { \
16+ PyErr_SetString (PyExc_StandardError, "error creating object"); \
17+ return -1; \
18+ } \
19+\
20+ return 0; \
21+}
22+
23+#define AUBIO_DEL(NAME) \
24+static void \
25+Py_ ## NAME ## _del ( Py_ ## NAME * self) \
26+{ \
27+ del_aubio_ ## NAME (self->o); \
28+ self->ob_type->tp_free ((PyObject *) self); \
29+}
30+
31+#define AUBIO_MEMBERS_START(NAME) \
32+static PyMemberDef Py_ ## NAME ## _members[] = {
33+
34+#define AUBIO_MEMBERS_STOP(NAME) \
35+ {NULL} \
36+};
37+
38+#define AUBIO_METHODS(NAME) \
39+static PyMethodDef Py_ ## NAME ## _methods[] = { \
40+ {NULL} \
41+};
42+
43+
44+#define AUBIO_TYPEOBJECT(NAME, PYNAME) \
45+PyTypeObject Py_ ## NAME ## Type = { \
46+ PyObject_HEAD_INIT (NULL) \
47+ 0, \
48+ PYNAME, \
49+ sizeof (Py_ ## NAME), \
50+ 0, \
51+ (destructor) Py_ ## NAME ## _del, \
52+ 0, \
53+ 0, \
54+ 0, \
55+ 0, \
56+ 0, \
57+ 0, \
58+ 0, \
59+ 0, \
60+ 0, \
61+ (ternaryfunc)Py_ ## NAME ## _do, \
62+ 0, \
63+ 0, \
64+ 0, \
65+ 0, \
66+ Py_TPFLAGS_DEFAULT, \
67+ Py_ ## NAME ## _doc, \
68+ 0, \
69+ 0, \
70+ 0, \
71+ 0, \
72+ 0, \
73+ 0, \
74+ Py_ ## NAME ## _methods, \
75+ Py_ ## NAME ## _members, \
76+ 0, \
77+ 0, \
78+ 0, \
79+ 0, \
80+ 0, \
81+ 0, \
82+ (initproc) Py_ ## NAME ## _init, \
83+ 0, \
84+ Py_ ## NAME ## _new, \
85+};
86+
87+// some more helpers
88+#define AUBIO_NEW_VEC(name, type, lengthval) \
89+ name = (type *) PyObject_New (type, & type ## Type); \
90+ name->length = lengthval;
python/bench-cluster-test+0−9
@@ -1,9 +0,0 @@
1−#! /usr/bin/python
2−
3−from aubio.bench.broadcast import *
4−
5−run_broadcast(remote_sync,'/home/testing')
6−run_broadcast(remote_sync,'/home/testing','-n')
7−run_broadcast(fetch_results,'/home/testing','-n')
8−
9−run_broadcast(remote_queue,'echo coucou')
python/bench-test+0−13
@@ -1,13 +0,0 @@
1−#! /usr/bin/python
2−
3−from aubio.bench.node import *
4−
5−datapath = '/var/www'
6−respath = '/var/tmp'
7−
8−def my_print(input,output):
9− cmd = "%s %s %s" % ("time sleep 0.3; echo",input,output)
10− return runcommand(cmd,debug=0)
11−
12−act_on_results(mkdir,datapath,respath,filter='d')
13−act_on_data(my_print,datapath,respath,suffix='.txt')
python/build_linux+9−0
@@ -0,0 +1,9 @@
1+#! /bin/sh
2+
3+set -e
4+set -x
5+
6+python setup.py clean build
7+export PYTHONPATH=./build/lib.linux-x86_64-2.7/:./tests
8+export LD_LIBRARY_PATH=../build/src/
9+./run_all_tests --verbose
python/build_osx+9−0
@@ -0,0 +1,9 @@
1+#! /bin/sh
2+
3+set -e
4+set -x
5+
6+python setup.py clean build
7+export PYTHONPATH=./build/lib.macosx-10.6-intel-2.7:$PYTHONPATH
8+export DYLD_LIBRARY_PATH=../build/src
9+./run_all_tests --verbose
python/c_weighting_test_simple.expected+2−0
@@ -0,0 +1,2 @@
1+ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 5.00000000e-01 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
2+ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.08504281e-01 2.31621372e-01 1.38614617e-01 1.58040475e-02 -9.84900252e-04 -2.72686896e-03 -2.87772967e-03 -2.87932142e-03 -2.86783482e-03 -2.85529016e-03 -2.84270413e-03 -2.83016008e-03 -2.81766458e-03 -2.80521796e-03 -2.79282009e-03 -2.78047079e-03 -2.76816989e-03 -2.75591721e-03 -2.74371257e-03 -2.73155579e-03
python/demos/demo_beats_and_tempo.py+39−0
@@ -0,0 +1,39 @@
1+#! /usr/bin/env python
2+
3+import sys
4+from aubio import tempo, source
5+
6+win_s = 512 # fft size
7+hop_s = win_s / 2 # hop size
8+samplerate = 44100
9+
10+if len(sys.argv) < 2:
11+ print "Usage: %s <filename>" % sys.argv[0]
12+ sys.exit(1)
13+
14+filename = sys.argv[1]
15+beats = []
16+
17+s = source(filename, samplerate, hop_s)
18+t = tempo("default", win_s, hop_s)
19+
20+block_read = 0
21+while True:
22+ samples, read = s()
23+ isbeat = t(samples)
24+ if isbeat:
25+ thisbeat = (block_read * hop_s + isbeat[0]) / samplerate
26+ print "%.4f" % thisbeat
27+ beats.append (thisbeat)
28+ block_read += 1
29+ if read < hop_s: break
30+
31+periods = [60./(b - a) for a,b in zip(beats[:-1],beats[1:])]
32+
33+from numpy import mean, median
34+print 'mean period:', mean(periods), 'bpm'
35+print 'median period:', median(periods), 'bpm'
36+
37+from pylab import plot, show
38+plot(beats[1:], periods)
39+show()
python/demos/demo_filterbank_slaney.py+21−0
@@ -0,0 +1,21 @@
1+#! /usr/bin/env python
2+
3+from aubio import filterbank
4+from numpy import array, arange, vstack
5+
6+win_s = 8192
7+samplerate = 16000
8+
9+f = filterbank(40, win_s)
10+f.set_mel_coeffs_slaney(samplerate)
11+
12+from pylab import loglog, title, show, xlim, ylim, xlabel, ylabel
13+xlim([0,samplerate / 2])
14+times = vstack([arange(win_s / 2 + 1) * samplerate / win_s] * 40)
15+loglog(times.T, f.get_coeffs().T, '.-')
16+title('Mel frequency bands coefficients')
17+xlim([100, 7500])
18+ylim([1.0e-3, 2.0e-2])
19+xlabel('Frequency (Hz)')
20+ylabel('Amplitude')
21+show()
python/demos/demo_filterbank_triangle_bands.py+47−0
@@ -0,0 +1,47 @@
1+#! /usr/bin/env python
2+
3+from aubio import filterbank, fvec
4+from pylab import loglog, show, subplot, xlim, ylim, xlabel, ylabel, title
5+from numpy import vstack, arange
6+
7+win_s = 2048
8+samplerate = 48000
9+
10+freq_list = [60, 80, 200, 400, 800, 1600, 3200, 6400, 12800, 24000]
11+n_filters = len(freq_list) - 2
12+
13+f = filterbank(n_filters, win_s)
14+freqs = fvec(freq_list)
15+f.set_triangle_bands(freqs, samplerate)
16+
17+subplot(211)
18+title('Examples of filterbank built with set_triangle_bands and set_coeffs')
19+times = vstack([arange(win_s / 2 + 1) * samplerate / win_s] * n_filters)
20+loglog(times.T, f.get_coeffs().T, '.-')
21+xlim([50, samplerate/2])
22+ylim([1.0e-6, 2.0e-2])
23+ylabel('Amplitude')
24+
25+## build a new filterbank
26+
27+freq_list = [60, 80, 200, 400, 800, 1200, 1600, 3200, 6400, 10000, 15000, 24000]
28+n_filters = len(freq_list) - 2
29+
30+f = filterbank(n_filters, win_s)
31+freqs = fvec(freq_list)
32+f.set_triangle_bands(freqs, samplerate)
33+
34+coeffs = f.get_coeffs()
35+coeffs[4] *= 5.
36+
37+f.set_coeffs(coeffs)
38+
39+subplot(212)
40+times = vstack([arange(win_s / 2 + 1) * samplerate / win_s] * n_filters)
41+loglog(times.T, f.get_coeffs().T, '.-')
42+xlim([50, samplerate/2])
43+ylim([1.0e-6, 2.0e-2])
44+xlabel('Frequency (Hz)')
45+ylabel('Amplitude')
46+
47+show()
python/demos/demo_onset_sinusoid.py+84−0
@@ -0,0 +1,84 @@
1+#! /usr/bin/env python
2+
3+from numpy import random, sin, arange, ones, zeros
4+from math import pi
5+from aubio import fvec, onset
6+
7+def build_sinusoid(length, freqs, samplerate):
8+ return sin( 2. * pi * arange(length) * freqs / samplerate)
9+
10+def run_onset(p, input_vec):
11+ f = fvec (p.hop_size)
12+ cands = []
13+ count = 0
14+ for vec_slice in input_vec.reshape((-1, p.hop_size)):
15+ f[:] = vec_slice
16+ cands.append(o(f))
17+ return cands
18+
19+methods = ['default',
20+ 'energy',
21+ 'complex',
22+ 'phase',
23+ 'specdiff',
24+ 'kl',
25+ 'mkl',
26+ 'specflux',
27+ 'centroid',
28+ 'spread',
29+ 'skewness',
30+ 'kurtosis',
31+ 'slope',
32+ 'decrease',
33+ 'rolloff',
34+ ]
35+
36+cands = {}
37+buf_size = 2048
38+hop_size = 512
39+samplerate = 44100
40+sin_length = (samplerate * 10) % 512 * 512
41+freqs = zeros(sin_length)
42+
43+partition = sin_length / 8
44+pointer = 0
45+
46+pointer += partition
47+freqs[pointer: pointer + partition] = 440
48+
49+pointer += partition
50+pointer += partition
51+freqs[ pointer : pointer + partition ] = 740
52+
53+pointer += partition
54+freqs[ pointer : pointer + partition ] = 1480
55+
56+pointer += partition
57+pointer += partition
58+freqs[ pointer : pointer + partition ] = 400 + 5 * random.random(sin_length/8)
59+
60+a = build_sinusoid(sin_length, freqs, samplerate)
61+
62+for method in methods:
63+ o = onset(method, buf_size, hop_size, samplerate)
64+ cands[method] = run_onset(o, a)
65+
66+print "done computing"
67+
68+if 1:
69+ from pylab import plot, show, xlabel, ylabel, legend, ylim, subplot
70+ subplot (211)
71+ legend(methods+['ground truth'], 'upper right')
72+ xlabel('time (s)')
73+ ylabel('amplitude')
74+ ramp = arange(0, sin_length).astype('float') / samplerate
75+ plot(ramp, a, ':')
76+ subplot (212)
77+ ramp = arange(0, sin_length / hop_size).astype('float') * hop_size / samplerate
78+ for method in methods:
79+ plot(ramp, cands[method],'.-')
80+ legend(methods, 'upper right')
81+ xlabel('time (s)')
82+ ylabel('spectral descriptor value')
83+ show()
84+
python/demos/demo_pitch_sinusoid.py+68−0
@@ -0,0 +1,68 @@
1+#! /usr/bin/env python
2+
3+from numpy import random, sin, arange, ones, zeros
4+from math import pi
5+from aubio import fvec, pitch
6+
7+def build_sinusoid(length, freqs, samplerate):
8+ return sin( 2. * pi * arange(length) * freqs / samplerate)
9+
10+def run_pitch(p, input_vec):
11+ f = fvec (p.hop_size)
12+ cands = []
13+ count = 0
14+ for vec_slice in input_vec.reshape((-1, p.hop_size)):
15+ f[:] = vec_slice
16+ cands.append(p(f))
17+ return cands
18+
19+methods = ['default', 'schmitt', 'fcomb', 'mcomb', 'yin', 'yinfft']
20+
21+cands = {}
22+buf_size = 2048
23+hop_size = 512
24+samplerate = 44100
25+sin_length = (samplerate * 10) % 512 * 512
26+freqs = zeros(sin_length)
27+
28+partition = sin_length / 8
29+pointer = 0
30+
31+pointer += partition
32+freqs[pointer: pointer + partition] = 440
33+
34+pointer += partition
35+pointer += partition
36+freqs[ pointer : pointer + partition ] = 740
37+
38+pointer += partition
39+freqs[ pointer : pointer + partition ] = 1480
40+
41+pointer += partition
42+pointer += partition
43+freqs[ pointer : pointer + partition ] = 400 + 5 * random.random(sin_length/8)
44+
45+a = build_sinusoid(sin_length, freqs, samplerate)
46+
47+for method in methods:
48+ p = pitch(method, buf_size, hop_size, samplerate)
49+ cands[method] = run_pitch(p, a)
50+
51+print "done computing"
52+
53+if 1:
54+ from pylab import plot, show, xlabel, ylabel, legend, ylim
55+ ramp = arange(0, sin_length / hop_size).astype('float') * hop_size / samplerate
56+ for method in methods:
57+ plot(ramp, cands[method],'.-')
58+
59+ # plot ground truth
60+ ramp = arange(0, sin_length).astype('float') / samplerate
61+ plot(ramp, freqs, ':')
62+
63+ legend(methods+['ground truth'], 'upper right')
64+ xlabel('time (s)')
65+ ylabel('frequency (Hz)')
66+ ylim([0,2000])
67+ show()
68+
python/demos/demo_simple_robot_voice.py+29−0
@@ -0,0 +1,29 @@
1+#! /usr/bin/env python
2+
3+import sys
4+from aubio import source, sink, pvoc
5+
6+if __name__ == '__main__':
7+ if len(sys.argv) < 2:
8+ print 'usage: %s <inputfile> <outputfile>' % sys.argv[0]
9+ sys.exit(1)
10+ samplerate = 44100
11+ f = source(sys.argv[1], samplerate, 256)
12+ g = sink(sys.argv[2], samplerate)
13+ total_frames, read = 0, 256
14+
15+ win_s = 512 # fft size
16+ hop_s = win_s / 2 # hop size
17+ pv = pvoc(win_s, hop_s) # phase vocoder
18+
19+ while read:
20+ samples, read = f()
21+ spectrum = pv(samples) # compute spectrum
22+ spectrum.phas[:] = 0. # zero phase
23+ new_samples = pv.rdo(spectrum) # compute modified samples
24+ g(new_samples, read) # write to output
25+ total_frames += read
26+
27+ print "wrote", total_frames, "from", f.uri, "to", g.uri
28+
29+
python/demos/demo_sink.py+17−0
@@ -0,0 +1,17 @@
1+#! /usr/bin/env python
2+
3+import sys
4+from aubio import source, sink
5+
6+if __name__ == '__main__':
7+ if len(sys.argv) < 3:
8+ print 'usage: %s <inputfile> <outputfile>' % sys.argv[0]
9+ sys.exit(1)
10+ f = source(sys.argv[1], 8000, 256)
11+ g = sink(sys.argv[2], 8000)
12+ total_frames, read = 0, 256
13+ while read:
14+ vec, read = f()
15+ g(vec, read)
16+ total_frames += read
17+ print "read", total_frames / float(f.samplerate), "seconds from", f.uri
python/demos/demo_sink_create_woodblock.py+38−0
@@ -0,0 +1,38 @@
1+#! /usr/bin/env python
2+
3+import sys
4+from math import sin, pi
5+from aubio import sink
6+from numpy import array
7+
8+if len(sys.argv) != 2:
9+ print 'usage: %s <outputfile>' % sys.argv[0]
10+ sys.exit(1)
11+
12+samplerate = 44100 # in Hz
13+pitch = 2200 # in Hz
14+blocksize = 256 # in samples
15+duration = 0.02 # in seconds
16+
17+twopi = pi * 2.
18+
19+duration = int ( 44100 * duration ) # convert to samples
20+attack = 3
21+
22+period = int ( float(samplerate) / pitch )
23+sinetone = [ 0.7 * sin(twopi * i/ period) for i in range(period) ]
24+sinetone *= int ( duration / period )
25+sinetone = array(sinetone, dtype = 'float32')
26+
27+from math import exp, e
28+for i in range(len(sinetone)):
29+ sinetone[i] *= exp( - e * float(i) / len(sinetone))
30+for i in range(attack):
31+ sinetone[i] *= exp( e * (float(i) / attack - 1 ) )
32+
33+my_sink = sink(sys.argv[1], 44100)
34+
35+i = 0
36+while i + blocksize < duration:
37+ my_sink(sinetone[i:i+blocksize], blocksize)
38+ i += blocksize
python/demos/demo_source.py+16−0
@@ -0,0 +1,16 @@
1+#! /usr/bin/env python
2+
3+import sys
4+from aubio import source
5+
6+if __name__ == '__main__':
7+ if len(sys.argv) < 2:
8+ print 'usage: %s <inputfile>' % sys.argv[0]
9+ sys.exit(1)
10+ f = source(sys.argv[1], 1, 256)
11+ samplerate = f.get_samplerate()
12+ total_frames, read = 0, 256
13+ while read:
14+ vec, read = f()
15+ total_frames += read
16+ print "read", total_frames / float(samplerate), "seconds from", f.uri
python/demos/demo_spectrogram.py+63−0
@@ -0,0 +1,63 @@
1+#! /usr/bin/env python
2+
3+import sys
4+from aubio import pvoc, source
5+from numpy import array, arange, zeros, shape, log10, vstack
6+from pylab import imshow, show, cm, axis, ylabel, xlabel, xticks, yticks
7+
8+def get_spectrogram(filename):
9+ samplerate = 44100
10+ win_s = 512 # fft window size
11+ hop_s = win_s / 2 # hop size
12+ fft_s = win_s / 2 + 1 # spectrum bins
13+
14+ a = source(filename, samplerate, hop_s) # source file
15+ pv = pvoc(win_s, hop_s) # phase vocoder
16+ specgram = zeros([0, fft_s], dtype='float32') # numpy array to store spectrogram
17+
18+ # analysis
19+ while True:
20+ samples, read = a() # read file
21+ specgram = vstack((specgram,pv(samples).norm)) # store new norm vector
22+ if read < a.hop_size: break
23+
24+ # plotting
25+ imshow(log10(specgram.T + .001), origin = 'bottom', aspect = 'auto', cmap=cm.gray_r)
26+ axis([0, len(specgram), 0, len(specgram[0])])
27+ # show axes in Hz and seconds
28+ time_step = hop_s / float(samplerate)
29+ total_time = len(specgram) * time_step
30+ print "total time: %0.2fs" % total_time,
31+ print ", samplerate: %.2fkHz" % (samplerate / 1000.)
32+ n_xticks = 10
33+ n_yticks = 10
34+
35+ def get_rounded_ticks( top_pos, step, n_ticks ):
36+ top_label = top_pos * step
37+ # get the first label
38+ ticks_first_label = top_pos * step / n_ticks
39+ # round to the closest .1
40+ ticks_first_label = round ( ticks_first_label * 10. ) / 10.
41+ # compute all labels from the first rounded one
42+ ticks_labels = [ ticks_first_label * n for n in range(n_ticks) ] + [ top_label ]
43+ # get the corresponding positions
44+ ticks_positions = [ ticks_labels[n] / step for n in range(n_ticks) ] + [ top_pos ]
45+ # convert to string
46+ ticks_labels = [ "%.1f" % x for x in ticks_labels ]
47+ # return position, label tuple to use with x/yticks
48+ return ticks_positions, ticks_labels
49+
50+ # apply to the axis
51+ xticks( *get_rounded_ticks ( len(specgram), time_step, n_xticks ) )
52+ yticks( *get_rounded_ticks ( len(specgram[0]), (samplerate / 2. / 1000.) / len(specgram[0]), n_yticks ) )
53+ ylabel('Frequency (kHz)')
54+ xlabel('Time (s)')
55+
56+if __name__ == '__main__':
57+ if len(sys.argv) < 2:
58+ print "Usage: %s <filename>" % sys.argv[0]
59+ else:
60+ for soundfile in sys.argv[1:]:
61+ get_spectrogram(soundfile)
62+ # display graph
63+ show()
python/demos/demo_tss.py+47−0
@@ -0,0 +1,47 @@
1+#! /usr/bin/env python
2+
3+import sys
4+from aubio import source, sink, pvoc, tss
5+
6+if __name__ == '__main__':
7+ if len(sys.argv) < 2:
8+ print 'usage: %s <inputfile> <outputfile_transient> <outputfile_steady>' % sys.argv[0]
9+ sys.exit(1)
10+
11+ samplerate = 44100
12+ win_s = 512 # fft size
13+ hop_s = win_s / 2 # block size
14+ threshold = 0.26
15+
16+ f = source(sys.argv[1], samplerate, hop_s)
17+ g = sink(sys.argv[2], samplerate)
18+ h = sink(sys.argv[3], samplerate)
19+
20+ pv = pvoc(win_s, hop_s) # phase vocoder
21+ pw = pvoc(win_s, hop_s) # another phase vocoder
22+ t = tss(win_s, hop_s) # transient steady state separation
23+
24+ t.set_threshold(threshold)
25+
26+ read = hop_s
27+
28+ while read:
29+ samples, read = f() # read file
30+ spec = pv(samples) # compute spectrum
31+ trans_spec, stead_spec = t(spec) # transient steady-state separation
32+ transients = pv.rdo(trans_spec) # overlap-add synthesis of transients
33+ steadstate = pw.rdo(stead_spec) # overlap-add synthesis of steady states
34+ g(transients, read) # write transients to output
35+ h(steadstate, read) # write steady states to output
36+
37+ del f, g, h # finish writing the files now
38+
39+ from demo_spectrogram import get_spectrogram
40+ from pylab import subplot, show
41+ subplot(311)
42+ get_spectrogram(sys.argv[1])
43+ subplot(312)
44+ get_spectrogram(sys.argv[2])
45+ subplot(313)
46+ get_spectrogram(sys.argv[3])
47+ show()
python/gen_pyobject.py+526−0
@@ -0,0 +1,526 @@
1+#! /usr/bin/python
2+
3+""" This madness of code is used to generate the C code of the python interface
4+to aubio. Don't try this at home.
5+
6+The list of typedefs and functions is obtained from the command line 'cpp
7+aubio.h'. This list is then used to parse all the functions about this object.
8+
9+I hear the ones asking "why not use swig, or cython, or something like that?"
10+
11+The requirements for this extension are the following:
12+
13+ - aubio vectors can be viewed as numpy arrays, and vice versa
14+ - aubio 'object' should be python classes, not just a bunch of functions
15+
16+I haven't met any python interface generator that can meet both these
17+requirements. If you know of one, please let me know, it will spare me
18+maintaining this bizarre file.
19+"""
20+
21+param_numbers = {
22+ 'source': [0, 2],
23+ 'sink': [2, 0],
24+}
25+
26+# TODO
27+# do function: for now, only the following pattern is supported:
28+# void aubio_<foo>_do (aubio_foo_t * o,
29+# [input1_t * input, [output1_t * output, ..., output3_t * output]]);
30+# There is no way of knowing that output1 is actually input2. In the future,
31+# const could be used for the inputs in the C prototypes.
32+
33+def write_msg(*args):
34+ pass
35+ # uncomment out for debugging
36+ #print args
37+
38+def split_type(arg):
39+ """ arg = 'foo *name'
40+ return ['foo*', 'name'] """
41+ l = arg.split()
42+ type_arg = {'type': l[0], 'name': l[1]}
43+ # ['foo', '*name'] -> ['foo*', 'name']
44+ if l[-1].startswith('*'):
45+ #return [l[0]+'*', l[1][1:]]
46+ type_arg['type'] = l[0] + '*'
47+ type_arg['name'] = l[1][1:]
48+ # ['foo', '*', 'name'] -> ['foo*', 'name']
49+ if len(l) == 3:
50+ #return [l[0]+l[1], l[2]]
51+ type_arg['type'] = l[0]+l[1]
52+ type_arg['name'] = l[2]
53+ else:
54+ #return l
55+ pass
56+ return type_arg
57+
58+def get_params(proto):
59+ """ get the list of parameters from a function prototype
60+ example: proto = "int main (int argc, char ** argv)"
61+ returns: ['int argc', 'char ** argv']
62+ """
63+ import re
64+ paramregex = re.compile('[\(, ](\w+ \*?\*? ?\w+)[, \)]')
65+ return paramregex.findall(proto)
66+
67+def get_params_types_names(proto):
68+ """ get the list of parameters from a function prototype
69+ example: proto = "int main (int argc, char ** argv)"
70+ returns: [['int', 'argc'], ['char **','argv']]
71+ """
72+ return map(split_type, get_params(proto))
73+
74+def get_return_type(proto):
75+ import re
76+ paramregex = re.compile('(\w+ ?\*?).*')
77+ outputs = paramregex.findall(proto)
78+ assert len(outputs) == 1
79+ return outputs[0].replace(' ', '')
80+
81+def get_name(proto):
82+ name = proto.split()[1].split('(')[0]
83+ return name.replace('*','')
84+
85+# the important bits: the size of the output for each objects. this data should
86+# move into the C library at some point.
87+defaultsizes = {
88+ 'resampler': ['input->length * self->ratio'],
89+ 'specdesc': ['1'],
90+ 'onset': ['1'],
91+ 'pitchyin': ['1'],
92+ 'pitchyinfft': ['1'],
93+ 'pitchschmitt': ['1'],
94+ 'pitchmcomb': ['1'],
95+ 'pitchfcomb': ['1'],
96+ 'pitch': ['1'],
97+ 'tss': ['self->buf_size', 'self->buf_size'],
98+ 'mfcc': ['self->n_coeffs'],
99+ 'beattracking': ['self->hop_size'],
100+ 'tempo': ['1'],
101+ 'peakpicker': ['1'],
102+ 'source': ['self->hop_size', '1'],
103+}
104+
105+# default value for variables
106+aubioinitvalue = {
107+ 'uint_t': 0,
108+ 'smpl_t': 0,
109+ 'lsmp_t': 0.,
110+ 'char_t*': 'NULL',
111+ }
112+
113+aubiodefvalue = {
114+ # we have some clean up to do
115+ 'buf_size': 'Py_default_vector_length',
116+ # and here too
117+ 'hop_size': 'Py_default_vector_length / 2',
118+ # these should be alright
119+ 'samplerate': 'Py_aubio_default_samplerate',
120+ # now for the non obvious ones
121+ 'n_filters': '40',
122+ 'n_coeffs': '13',
123+ 'nelems': '10',
124+ 'flow': '0.',
125+ 'fhig': '1.',
126+ 'ilow': '0.',
127+ 'ihig': '1.',
128+ 'thrs': '0.5',
129+ 'ratio': '0.5',
130+ 'method': '"default"',
131+ 'uri': '"none"',
132+ }
133+
134+# aubio to python
135+aubio2pytypes = {
136+ 'uint_t': 'I',
137+ 'smpl_t': 'f',
138+ 'lsmp_t': 'd',
139+ 'fvec_t*': 'O',
140+ 'cvec_t*': 'O',
141+ 'char_t*': 's',
142+}
143+
144+# python to aubio
145+aubiovecfrompyobj = {
146+ 'fvec_t*': 'PyAubio_ArrayToCFvec',
147+ 'cvec_t*': 'PyAubio_ArrayToCCvec',
148+ 'uint_t': '(uint_t)PyInt_AsLong',
149+}
150+
151+# aubio to python
152+aubiovectopyobj = {
153+ 'fvec_t*': 'PyAubio_CFvecToArray',
154+ 'cvec_t*': 'PyAubio_CCvecToPyCvec',
155+ 'smpl_t': 'PyFloat_FromDouble',
156+ 'uint_t*': 'PyInt_FromLong',
157+ 'uint_t': 'PyInt_FromLong',
158+}
159+
160+def gen_new_init(newfunc, name):
161+ newparams = get_params_types_names(newfunc)
162+ # self->param1, self->param2, self->param3
163+ if len(newparams):
164+ selfparams = ', self->'+', self->'.join([p['name'] for p in newparams])
165+ else:
166+ selfparams = ''
167+ # "param1", "param2", "param3"
168+ paramnames = ", ".join(["\""+p['name']+"\"" for p in newparams])
169+ pyparams = "".join(map(lambda p: aubio2pytypes[p['type']], newparams))
170+ paramrefs = ", ".join(["&" + p['name'] for p in newparams])
171+ s = """\
172+// WARNING: this file is generated, DO NOT EDIT
173+
174+// WARNING: if you haven't read the first line yet, please do so
175+#include "aubiowraphell.h"
176+
177+typedef struct
178+{
179+ PyObject_HEAD
180+ aubio_%(name)s_t * o;
181+""" % locals()
182+ for p in newparams:
183+ ptype = p['type']
184+ pname = p['name']
185+ s += """\
186+ %(ptype)s %(pname)s;
187+""" % locals()
188+ s += """\
189+} Py_%(name)s;
190+
191+static char Py_%(name)s_doc[] = "%(name)s object";
192+
193+static PyObject *
194+Py_%(name)s_new (PyTypeObject * pytype, PyObject * args, PyObject * kwds)
195+{
196+ Py_%(name)s *self;
197+""" % locals()
198+ for p in newparams:
199+ ptype = p['type']
200+ pname = p['name']
201+ initval = aubioinitvalue[ptype]
202+ s += """\
203+ %(ptype)s %(pname)s = %(initval)s;
204+""" % locals()
205+ # now the actual PyArg_Parse
206+ if len(paramnames):
207+ s += """\
208+ static char *kwlist[] = { %(paramnames)s, NULL };
209+
210+ if (!PyArg_ParseTupleAndKeywords (args, kwds, "|%(pyparams)s", kwlist,
211+ %(paramrefs)s)) {
212+ return NULL;
213+ }
214+""" % locals()
215+ s += """\
216+
217+ self = (Py_%(name)s *) pytype->tp_alloc (pytype, 0);
218+
219+ if (self == NULL) {
220+ return NULL;
221+ }
222+""" % locals()
223+ for p in newparams:
224+ ptype = p['type']
225+ pname = p['name']
226+ defval = aubiodefvalue[pname]
227+ if ptype == 'char_t*':
228+ s += """\
229+
230+ self->%(pname)s = %(defval)s;
231+ if (%(pname)s != NULL) {
232+ self->%(pname)s = %(pname)s;
233+ }
234+""" % locals()
235+ elif ptype == 'uint_t':
236+ s += """\
237+
238+ self->%(pname)s = %(defval)s;
239+ if (%(pname)s > 0) {
240+ self->%(pname)s = %(pname)s;
241+ } else if (%(pname)s < 0) {
242+ PyErr_SetString (PyExc_ValueError,
243+ "can not use negative value for %(pname)s");
244+ return NULL;
245+ }
246+""" % locals()
247+ elif ptype == 'smpl_t':
248+ s += """\
249+
250+ self->%(pname)s = %(defval)s;
251+ if (%(pname)s != %(defval)s) {
252+ self->%(pname)s = %(pname)s;
253+ }
254+""" % locals()
255+ else:
256+ write_msg ("ERROR, unknown type of parameter %s %s" % (ptype, pname) )
257+ s += """\
258+
259+ return (PyObject *) self;
260+}
261+
262+AUBIO_INIT(%(name)s %(selfparams)s)
263+
264+AUBIO_DEL(%(name)s)
265+
266+""" % locals()
267+ return s
268+
269+def gen_do_input_params(inputparams):
270+ inputdefs = ''
271+ parseinput = ''
272+ inputrefs = ''
273+ inputvecs = ''
274+ pytypes = ''
275+
276+ if len(inputparams):
277+ # build the parsing string for PyArg_ParseTuple
278+ pytypes = "".join([aubio2pytypes[p['type']] for p in inputparams])
279+
280+ inputdefs = " /* input vectors python prototypes */\n"
281+ for p in inputparams:
282+ if p['type'] != 'uint_t':
283+ inputdefs += " PyObject * " + p['name'] + "_obj;\n"
284+
285+ inputvecs = " /* input vectors prototypes */\n "
286+ inputvecs += "\n ".join(map(lambda p: p['type'] + ' ' + p['name'] + ";", inputparams))
287+
288+ parseinput = " /* input vectors parsing */\n "
289+ for p in inputparams:
290+ inputvec = p['name']
291+ if p['type'] != 'uint_t':
292+ inputdef = p['name'] + "_obj"
293+ else:
294+ inputdef = p['name']
295+ converter = aubiovecfrompyobj[p['type']]
296+ if p['type'] != 'uint_t':
297+ parseinput += """%(inputvec)s = %(converter)s (%(inputdef)s);
298+
299+ if (%(inputvec)s == NULL) {
300+ return NULL;
301+ }
302+
303+ """ % locals()
304+
305+ # build the string for the input objects references
306+ inputreflist = []
307+ for p in inputparams:
308+ if p['type'] != 'uint_t':
309+ inputreflist += [ "&" + p['name'] + "_obj" ]
310+ else:
311+ inputreflist += [ "&" + p['name'] ]
312+ inputrefs = ", ".join(inputreflist)
313+ # end of inputs strings
314+ return inputdefs, parseinput, inputrefs, inputvecs, pytypes
315+
316+def gen_do_output_params(outputparams, name):
317+ outputvecs = ""
318+ outputcreate = ""
319+ if len(outputparams):
320+ outputvecs = " /* output vectors prototypes */\n"
321+ for p in outputparams:
322+ params = {
323+ 'name': p['name'], 'pytype': p['type'], 'autype': p['type'][:-3],
324+ 'length': defaultsizes[name].pop(0) }
325+ if (p['type'] == 'uint_t*'):
326+ outputvecs += ' uint_t' + ' ' + p['name'] + ";\n"
327+ outputcreate += " %(name)s = 0;\n" % params
328+ else:
329+ outputvecs += " " + p['type'] + ' ' + p['name'] + ";\n"
330+ outputcreate += " /* creating output %(name)s as a new_%(autype)s of length %(length)s */\n" % params
331+ outputcreate += " %(name)s = new_%(autype)s (%(length)s);\n" % params
332+
333+ returnval = "";
334+ if len(outputparams) > 1:
335+ returnval += " PyObject *outputs = PyList_New(0);\n"
336+ for p in outputparams:
337+ returnval += " PyList_Append( outputs, (PyObject *)" + aubiovectopyobj[p['type']] + " (" + p['name'] + ")" +");\n"
338+ returnval += " return outputs;"
339+ elif len(outputparams) == 1:
340+ if defaultsizes[name] == '1':
341+ returnval += " return (PyObject *)PyFloat_FromDouble(" + p['name'] + "->data[0])"
342+ else:
343+ returnval += " return (PyObject *)" + aubiovectopyobj[p['type']] + " (" + p['name'] + ")"
344+ else:
345+ returnval = " return Py_None;";
346+ # end of output strings
347+ return outputvecs, outputcreate, returnval
348+
349+def gen_do(dofunc, name):
350+ funcname = dofunc.split()[1].split('(')[0]
351+ doparams = get_params_types_names(dofunc)
352+ # make sure the first parameter is the object
353+ assert doparams[0]['type'] == "aubio_"+name+"_t*", \
354+ "method is not in 'aubio_<name>_t"
355+ # and remove it
356+ doparams = doparams[1:]
357+
358+ n_param = len(doparams)
359+
360+ if name in param_numbers.keys():
361+ n_input_param, n_output_param = param_numbers[name]
362+ else:
363+ n_input_param, n_output_param = 1, n_param - 1
364+
365+ assert n_output_param + n_input_param == n_param, "n_output_param + n_input_param != n_param for %s" % name
366+
367+ inputparams = doparams[:n_input_param]
368+ outputparams = doparams[n_input_param:n_input_param + n_output_param]
369+
370+ inputdefs, parseinput, inputrefs, inputvecs, pytypes = gen_do_input_params(inputparams);
371+ outputvecs, outputcreate, returnval = gen_do_output_params(outputparams, name)
372+
373+ # build strings for outputs
374+ # build the parameters for the _do() call
375+ doparams_string = "self->o"
376+ for p in doparams:
377+ if p['type'] == 'uint_t*':
378+ doparams_string += ", &" + p['name']
379+ else:
380+ doparams_string += ", " + p['name']
381+
382+ if n_input_param:
383+ arg_parse_tuple = """\
384+ if (!PyArg_ParseTuple (args, "%(pytypes)s", %(inputrefs)s)) {
385+ return NULL;
386+ }
387+""" % locals()
388+ else:
389+ arg_parse_tuple = ""
390+ # put it all together
391+ s = """\
392+/* function Py_%(name)s_do */
393+static PyObject *
394+Py_%(name)s_do(Py_%(name)s * self, PyObject * args)
395+{
396+%(inputdefs)s
397+%(inputvecs)s
398+%(outputvecs)s
399+
400+%(arg_parse_tuple)s
401+
402+%(parseinput)s
403+
404+%(outputcreate)s
405+
406+ /* compute _do function */
407+ %(funcname)s (%(doparams_string)s);
408+
409+%(returnval)s;
410+}
411+""" % locals()
412+ return s
413+
414+def gen_members(new_method, name):
415+ newparams = get_params_types_names(new_method)
416+ s = """
417+AUBIO_MEMBERS_START(%(name)s)""" % locals()
418+ for param in newparams:
419+ if param['type'] == 'char_t*':
420+ s += """
421+ {"%(pname)s", T_STRING, offsetof (Py_%(name)s, %(pname)s), READONLY, ""},""" \
422+ % { 'pname': param['name'], 'ptype': param['type'], 'name': name}
423+ elif param['type'] == 'uint_t':
424+ s += """
425+ {"%(pname)s", T_INT, offsetof (Py_%(name)s, %(pname)s), READONLY, ""},""" \
426+ % { 'pname': param['name'], 'ptype': param['type'], 'name': name}
427+ elif param['type'] == 'smpl_t':
428+ s += """
429+ {"%(pname)s", T_FLOAT, offsetof (Py_%(name)s, %(pname)s), READONLY, ""},""" \
430+ % { 'pname': param['name'], 'ptype': param['type'], 'name': name}
431+ else:
432+ write_msg ("-- ERROR, unknown member type ", param )
433+ s += """
434+AUBIO_MEMBERS_STOP(%(name)s)
435+
436+""" % locals()
437+ return s
438+
439+
440+def gen_methods(get_methods, set_methods, name):
441+ s = ""
442+ method_defs = ""
443+ for method in set_methods:
444+ method_name = get_name(method)
445+ params = get_params_types_names(method)
446+ out_type = get_return_type(method)
447+ assert params[0]['type'] == "aubio_"+name+"_t*", \
448+ "get method is not in 'aubio_<name>_t"
449+ write_msg (method )
450+ write_msg (params[1:])
451+ setter_args = "self->o, " +",".join([p['name'] for p in params[1:]])
452+ parse_args = ""
453+ for p in params[1:]:
454+ parse_args += p['type'] + " " + p['name'] + ";\n"
455+ argmap = "".join([aubio2pytypes[p['type']] for p in params[1:]])
456+ arglist = ", ".join(["&"+p['name'] for p in params[1:]])
457+ parse_args += """
458+ if (!PyArg_ParseTuple (args, "%(argmap)s", %(arglist)s)) {
459+ return NULL;
460+ } """ % locals()
461+ s += """
462+static PyObject *
463+Py%(funcname)s (Py_%(objname)s *self, PyObject *args)
464+{
465+ uint_t err = 0;
466+
467+ %(parse_args)s
468+
469+ err = %(funcname)s (%(setter_args)s);
470+
471+ if (err > 0) {
472+ PyErr_SetString (PyExc_ValueError,
473+ "error running %(funcname)s");
474+ return NULL;
475+ }
476+ return Py_None;
477+}
478+""" % {'funcname': method_name, 'objname': name,
479+ 'out_type': out_type, 'setter_args': setter_args, 'parse_args': parse_args }
480+ shortname = method_name.split(name+'_')[-1]
481+ method_defs += """\
482+ {"%(shortname)s", (PyCFunction) Py%(method_name)s,
483+ METH_VARARGS, ""},
484+""" % locals()
485+
486+ for method in get_methods:
487+ method_name = get_name(method)
488+ params = get_params_types_names(method)
489+ out_type = get_return_type(method)
490+ assert params[0]['type'] == "aubio_"+name+"_t*", \
491+ "get method is not in 'aubio_<name>_t %s" % params[0]['type']
492+ assert len(params) == 1, \
493+ "get method has more than one parameter %s" % params
494+ getter_args = "self->o"
495+ returnval = "(PyObject *)" + aubiovectopyobj[out_type] + " (tmp)"
496+ shortname = method_name.split(name+'_')[-1]
497+ method_defs += """\
498+ {"%(shortname)s", (PyCFunction) Py%(method_name)s,
499+ METH_NOARGS, ""},
500+""" % locals()
501+ s += """
502+static PyObject *
503+Py%(funcname)s (Py_%(objname)s *self, PyObject *unused)
504+{
505+ %(out_type)s tmp = %(funcname)s (%(getter_args)s);
506+ return %(returnval)s;
507+}
508+""" % {'funcname': method_name, 'objname': name,
509+ 'out_type': out_type, 'getter_args': getter_args, 'returnval': returnval }
510+
511+ s += """
512+static PyMethodDef Py_%(name)s_methods[] = {
513+""" % locals()
514+ s += method_defs
515+ s += """\
516+ {NULL} /* sentinel */
517+};
518+""" % locals()
519+ return s
520+
521+def gen_finish(name):
522+ s = """\
523+
524+AUBIO_TYPEOBJECT(%(name)s, "aubio.%(name)s")
525+""" % locals()
526+ return s
python/generator.py+187−0
@@ -0,0 +1,187 @@
1+#! /usr/bin/python
2+
3+""" This file generates a c file from a list of cpp prototypes. """
4+
5+import os, sys, shutil
6+from gen_pyobject import write_msg, gen_new_init, gen_do, gen_members, gen_methods, gen_finish
7+
8+def get_cpp_objects():
9+
10+ cpp_output = [l.strip() for l in os.popen('cpp -DAUBIO_UNSTABLE=1 -I../build/src ../src/aubio.h').readlines()]
11+
12+ cpp_output = filter(lambda y: len(y) > 1, cpp_output)
13+ cpp_output = filter(lambda y: not y.startswith('#'), cpp_output)
14+
15+ i = 1
16+ while 1:
17+ if i >= len(cpp_output): break
18+ if cpp_output[i-1].endswith(',') or cpp_output[i-1].endswith('{') or cpp_output[i].startswith('}'):
19+ cpp_output[i] = cpp_output[i-1] + ' ' + cpp_output[i]
20+ cpp_output.pop(i-1)
21+ else:
22+ i += 1
23+
24+ typedefs = filter(lambda y: y.startswith ('typedef struct _aubio'), cpp_output)
25+
26+ cpp_objects = [a.split()[3][:-1] for a in typedefs]
27+
28+ return cpp_output, cpp_objects
29+
30+def generate_object_files():
31+ if os.path.isdir('generated'): shutil.rmtree('generated')
32+ os.mkdir('generated')
33+
34+ generated_objects = []
35+ cpp_output, cpp_objects = get_cpp_objects()
36+ skip_objects = ['fft',
37+ 'pvoc',
38+ 'filter',
39+ 'filterbank',
40+ 'resampler',
41+ 'sndfile',
42+ 'sink_apple_audio',
43+ 'sink_sndfile',
44+ 'source_apple_audio',
45+ 'source_sndfile']
46+
47+ write_msg("-- INFO: %d objects in total" % len(cpp_objects))
48+
49+ for this_object in cpp_objects:
50+ lint = 0
51+
52+ if this_object[-2:] == '_t':
53+ object_name = this_object[:-2]
54+ else:
55+ object_name = this_object
56+ write_msg("-- WARNING: %s does not end in _t" % this_object)
57+
58+ if object_name[:len('aubio_')] != 'aubio_':
59+ write_msg("-- WARNING: %s does not start n aubio_" % this_object)
60+
61+ write_msg("-- INFO: looking at", object_name)
62+ object_methods = filter(lambda x: this_object in x, cpp_output)
63+ object_methods = [a.strip() for a in object_methods]
64+ object_methods = filter(lambda x: not x.startswith('typedef'), object_methods)
65+ #for method in object_methods:
66+ # write_msg(method)
67+ new_methods = filter(lambda x: 'new_'+object_name in x, object_methods)
68+ if len(new_methods) > 1:
69+ write_msg("-- WARNING: more than one new method for", object_name)
70+ for method in new_methods:
71+ write_msg(method)
72+ elif len(new_methods) < 1:
73+ write_msg("-- WARNING: no new method for", object_name)
74+ elif 0:
75+ for method in new_methods:
76+ write_msg(method)
77+
78+ del_methods = filter(lambda x: 'del_'+object_name in x, object_methods)
79+ if len(del_methods) > 1:
80+ write_msg("-- WARNING: more than one del method for", object_name)
81+ for method in del_methods:
82+ write_msg(method)
83+ elif len(del_methods) < 1:
84+ write_msg("-- WARNING: no del method for", object_name)
85+
86+ do_methods = filter(lambda x: object_name+'_do' in x, object_methods)
87+ if len(do_methods) > 1:
88+ pass
89+ #write_msg("-- WARNING: more than one do method for", object_name)
90+ #for method in do_methods:
91+ # write_msg(method)
92+ elif len(do_methods) < 1:
93+ write_msg("-- WARNING: no do method for", object_name)
94+ elif 0:
95+ for method in do_methods:
96+ write_msg(method)
97+
98+ # check do methods return void
99+ for method in do_methods:
100+ if (method.split()[0] != 'void'):
101+ write_msg("-- ERROR: _do method does not return void:", method )
102+
103+ get_methods = filter(lambda x: object_name+'_get_' in x, object_methods)
104+
105+ set_methods = filter(lambda x: object_name+'_set_' in x, object_methods)
106+ for method in set_methods:
107+ if (method.split()[0] != 'uint_t'):
108+ write_msg("-- ERROR: _set method does not return uint_t:", method )
109+
110+ other_methods = filter(lambda x: x not in new_methods, object_methods)
111+ other_methods = filter(lambda x: x not in del_methods, other_methods)
112+ other_methods = filter(lambda x: x not in do_methods, other_methods)
113+ other_methods = filter(lambda x: x not in get_methods, other_methods)
114+ other_methods = filter(lambda x: x not in set_methods, other_methods)
115+
116+ if len(other_methods) > 0:
117+ write_msg("-- WARNING: some methods for", object_name, "were unidentified")
118+ for method in other_methods:
119+ write_msg(method)
120+
121+
122+ # generate this_object
123+ short_name = object_name[len('aubio_'):]
124+ if short_name in skip_objects:
125+ write_msg("-- INFO: skipping object", short_name )
126+ continue
127+ if 1: #try:
128+ s = gen_new_init(new_methods[0], short_name)
129+ s += gen_do(do_methods[0], short_name)
130+ s += gen_members(new_methods[0], short_name)
131+ s += gen_methods(get_methods, set_methods, short_name)
132+ s += gen_finish(short_name)
133+ generated_filepath = 'generated/gen-'+short_name+'.c'
134+ fd = open(generated_filepath, 'w')
135+ fd.write(s)
136+ #except Exception, e:
137+ # write_msg("-- ERROR:", type(e), str(e), "in", short_name)
138+ # continue
139+ generated_objects += [this_object]
140+
141+ s = """// generated list of objects created with generator.py
142+
143+"""
144+
145+ for each in generated_objects:
146+ s += "extern PyTypeObject Py_%sType;\n" % \
147+ each.replace('aubio_','').replace('_t','')
148+
149+ types_ready = []
150+ for each in generated_objects:
151+ types_ready.append(" PyType_Ready (&Py_%sType) < 0" % \
152+ each.replace('aubio_','').replace('_t','') )
153+
154+ s += """
155+ int
156+ generated_types_ready (void)
157+ {
158+ return (
159+ """
160+ s += ('\n ||').join(types_ready)
161+ s += """);
162+ }
163+ """
164+
165+ s += """
166+ void
167+ add_generated_objects ( PyObject *m )
168+ {"""
169+ for each in generated_objects:
170+ s += """ Py_INCREF (&Py_%(name)sType);
171+ PyModule_AddObject (m, "%(name)s", (PyObject *) & Py_%(name)sType);""" % \
172+ { 'name': ( each.replace('aubio_','').replace('_t','') ) }
173+
174+ s += """
175+ }"""
176+
177+ fd = open('generated/aubio-generated.h', 'w')
178+ fd.write(s)
179+
180+ from os import listdir
181+ generated_files = listdir('generated')
182+ generated_files = filter(lambda x: x.endswith('.c'), generated_files)
183+ generated_files = ['generated/'+f for f in generated_files]
184+ return generated_files
185+
186+if __name__ == '__main__':
187+ generate_object_files()
python/py-cvec.c+302−0
@@ -0,0 +1,302 @@
1+#include "aubio-types.h"
2+
3+/* cvec type definition
4+
5+class cvec():
6+ def __init__(self, length = 1024):
7+ self.length = length
8+ self.norm = array(length)
9+ self.phas = array(length)
10+
11+*/
12+
13+static char Py_cvec_doc[] = "cvec object";
14+
15+static PyObject *
16+Py_cvec_new (PyTypeObject * type, PyObject * args, PyObject * kwds)
17+{
18+ int length= 0;
19+ Py_cvec *self;
20+ static char *kwlist[] = { "length", NULL };
21+
22+ if (!PyArg_ParseTupleAndKeywords (args, kwds, "|I", kwlist,
23+ &length)) {
24+ return NULL;
25+ }
26+
27+
28+ self = (Py_cvec *) type->tp_alloc (type, 0);
29+
30+ self->length = Py_default_vector_length / 2 + 1;
31+
32+ if (self == NULL) {
33+ return NULL;
34+ }
35+
36+ if (length > 0) {
37+ self->length = length / 2 + 1;
38+ } else if (length < 0) {
39+ PyErr_SetString (PyExc_ValueError,
40+ "can not use negative number of elements");
41+ return NULL;
42+ }
43+
44+ return (PyObject *) self;
45+}
46+
47+static int
48+Py_cvec_init (Py_cvec * self, PyObject * args, PyObject * kwds)
49+{
50+ self->o = new_cvec ((self->length - 1) * 2);
51+ if (self->o == NULL) {
52+ return -1;
53+ }
54+
55+ return 0;
56+}
57+
58+static void
59+Py_cvec_del (Py_cvec * self)
60+{
61+ del_cvec (self->o);
62+ self->ob_type->tp_free ((PyObject *) self);
63+}
64+
65+static PyObject *
66+Py_cvec_repr (Py_cvec * self, PyObject * unused)
67+{
68+ PyObject *format = NULL;
69+ PyObject *args = NULL;
70+ PyObject *result = NULL;
71+
72+ format = PyString_FromString ("aubio cvec of %d elements");
73+ if (format == NULL) {
74+ goto fail;
75+ }
76+
77+ args = Py_BuildValue ("I", self->length);
78+ if (args == NULL) {
79+ goto fail;
80+ }
81+ cvec_print ( self->o );
82+
83+ result = PyString_Format (format, args);
84+
85+fail:
86+ Py_XDECREF (format);
87+ Py_XDECREF (args);
88+
89+ return result;
90+}
91+
92+PyObject *
93+PyAubio_CvecNormToArray (Py_cvec * self)
94+{
95+ npy_intp dims[] = { self->o->length, 1 };
96+ return PyArray_SimpleNewFromData (1, dims, NPY_FLOAT, self->o->norm);
97+}
98+
99+
100+PyObject *
101+PyAubio_CvecPhasToArray (Py_cvec * self)
102+{
103+ npy_intp dims[] = { self->o->length, 1 };
104+ return PyArray_SimpleNewFromData (1, dims, NPY_FLOAT, self->o->phas);
105+}
106+
107+PyObject *
108+PyAubio_ArrayToCvecPhas (PyObject * self)
109+{
110+ return NULL;
111+}
112+
113+PyObject *
114+Py_cvec_get_norm (Py_cvec * self, void *closure)
115+{
116+ return PyAubio_CvecNormToArray(self);
117+}
118+
119+PyObject *
120+Py_cvec_get_phas (Py_cvec * self, void *closure)
121+{
122+ return PyAubio_CvecPhasToArray(self);
123+}
124+
125+static int
126+Py_cvec_set_norm (Py_cvec * vec, PyObject *input, void * closure)
127+{
128+ PyArrayObject * array;
129+ if (input == NULL) {
130+ PyErr_SetString (PyExc_ValueError, "input array is not a python object");
131+ goto fail;
132+ }
133+ if (PyArray_Check(input)) {
134+
135+ // we got an array, convert it to a cvec.norm
136+ if (PyArray_NDIM ((PyArrayObject *)input) == 0) {
137+ PyErr_SetString (PyExc_ValueError, "input array is a scalar");
138+ goto fail;
139+ } else if (PyArray_NDIM ((PyArrayObject *)input) > 2) {
140+ PyErr_SetString (PyExc_ValueError,
141+ "input array has more than two dimensions");
142+ goto fail;
143+ }
144+
145+ if (!PyArray_ISFLOAT ((PyArrayObject *)input)) {
146+ PyErr_SetString (PyExc_ValueError, "input array should be float");
147+ goto fail;
148+ } else if (PyArray_TYPE ((PyArrayObject *)input) != AUBIO_NPY_SMPL) {
149+ PyErr_SetString (PyExc_ValueError, "input array should be float32");
150+ goto fail;
151+ }
152+ array = (PyArrayObject *)input;
153+
154+ // check input array dimensions
155+ if (PyArray_NDIM (array) != 1) {
156+ PyErr_Format (PyExc_ValueError,
157+ "input array has %d dimensions, not 1",
158+ PyArray_NDIM (array));
159+ goto fail;
160+ } else {
161+ if (vec->o->length != PyArray_SIZE (array)) {
162+ PyErr_Format (PyExc_ValueError,
163+ "input array has length %d, but cvec has length %d",
164+ (int)PyArray_SIZE (array), vec->o->length);
165+ goto fail;
166+ }
167+ }
168+
169+ vec->o->norm = (smpl_t *) PyArray_GETPTR1 (array, 0);
170+
171+ } else {
172+ PyErr_SetString (PyExc_ValueError, "can only accept array as input");
173+ return 1;
174+ }
175+
176+ Py_INCREF(array);
177+ return 0;
178+
179+fail:
180+ return 1;
181+}
182+
183+static int
184+Py_cvec_set_phas (Py_cvec * vec, PyObject *input, void * closure)
185+{
186+ PyArrayObject * array;
187+ if (input == NULL) {
188+ PyErr_SetString (PyExc_ValueError, "input array is not a python object");
189+ goto fail;
190+ }
191+ if (PyArray_Check(input)) {
192+
193+ // we got an array, convert it to a cvec.phas
194+ if (PyArray_NDIM ((PyArrayObject *)input) == 0) {
195+ PyErr_SetString (PyExc_ValueError, "input array is a scalar");
196+ goto fail;
197+ } else if (PyArray_NDIM ((PyArrayObject *)input) > 2) {
198+ PyErr_SetString (PyExc_ValueError,
199+ "input array has more than two dimensions");
200+ goto fail;
201+ }
202+
203+ if (!PyArray_ISFLOAT ((PyArrayObject *)input)) {
204+ PyErr_SetString (PyExc_ValueError, "input array should be float");
205+ goto fail;
206+ } else if (PyArray_TYPE ((PyArrayObject *)input) != AUBIO_NPY_SMPL) {
207+ PyErr_SetString (PyExc_ValueError, "input array should be float32");
208+ goto fail;
209+ }
210+ array = (PyArrayObject *)input;
211+
212+ // check input array dimensions
213+ if (PyArray_NDIM (array) != 1) {
214+ PyErr_Format (PyExc_ValueError,
215+ "input array has %d dimensions, not 1",
216+ PyArray_NDIM (array));
217+ goto fail;
218+ } else {
219+ if (vec->o->length != PyArray_SIZE (array)) {
220+ PyErr_Format (PyExc_ValueError,
221+ "input array has length %d, but cvec has length %d",
222+ (int)PyArray_SIZE (array), vec->o->length);
223+ goto fail;
224+ }
225+ }
226+
227+ vec->o->phas = (smpl_t *) PyArray_GETPTR1 (array, 0);
228+
229+ } else {
230+ PyErr_SetString (PyExc_ValueError, "can only accept array as input");
231+ return 1;
232+ }
233+
234+ Py_INCREF(array);
235+ return 0;
236+
237+fail:
238+ return 1;
239+}
240+
241+static PyMemberDef Py_cvec_members[] = {
242+ // TODO remove READONLY flag and define getter/setter
243+ {"length", T_INT, offsetof (Py_cvec, length), READONLY,
244+ "length attribute"},
245+ {NULL} /* Sentinel */
246+};
247+
248+static PyMethodDef Py_cvec_methods[] = {
249+ {NULL}
250+};
251+
252+static PyGetSetDef Py_cvec_getseters[] = {
253+ {"norm", (getter)Py_cvec_get_norm, (setter)Py_cvec_set_norm,
254+ "Numpy vector of shape (length,) containing the magnitude",
255+ NULL},
256+ {"phas", (getter)Py_cvec_get_phas, (setter)Py_cvec_set_phas,
257+ "Numpy vector of shape (length,) containing the phase",
258+ NULL},
259+ {NULL} /* sentinel */
260+};
261+
262+PyTypeObject Py_cvecType = {
263+ PyObject_HEAD_INIT (NULL)
264+ 0, /* ob_size */
265+ "aubio.cvec", /* tp_name */
266+ sizeof (Py_cvec), /* tp_basicsize */
267+ 0, /* tp_itemsize */
268+ (destructor) Py_cvec_del, /* tp_dealloc */
269+ 0, /* tp_print */
270+ 0, /* tp_getattr */
271+ 0, /* tp_setattr */
272+ 0, /* tp_compare */
273+ (reprfunc) Py_cvec_repr, /* tp_repr */
274+ 0, /* tp_as_number */
275+ 0, //&Py_cvec_tp_as_sequence, /* tp_as_sequence */
276+ 0, /* tp_as_mapping */
277+ 0, /* tp_hash */
278+ 0, /* tp_call */
279+ 0, /* tp_str */
280+ 0, /* tp_getattro */
281+ 0, /* tp_setattro */
282+ 0, /* tp_as_buffer */
283+ Py_TPFLAGS_DEFAULT, /* tp_flags */
284+ Py_cvec_doc, /* tp_doc */
285+ 0, /* tp_traverse */
286+ 0, /* tp_clear */
287+ 0, /* tp_richcompare */
288+ 0, /* tp_weaklistoffset */
289+ 0, /* tp_iter */
290+ 0, /* tp_iternext */
291+ Py_cvec_methods, /* tp_methods */
292+ Py_cvec_members, /* tp_members */
293+ Py_cvec_getseters, /* tp_getset */
294+ 0, /* tp_base */
295+ 0, /* tp_dict */
296+ 0, /* tp_descr_get */
297+ 0, /* tp_descr_set */
298+ 0, /* tp_dictoffset */
299+ (initproc) Py_cvec_init, /* tp_init */
300+ 0, /* tp_alloc */
301+ Py_cvec_new, /* tp_new */
302+};
python/py-fft.c+107−0
@@ -0,0 +1,107 @@
1+#include "aubiowraphell.h"
2+
3+static char Py_fft_doc[] = "fft object";
4+
5+AUBIO_DECLARE(fft, uint_t win_s)
6+
7+//AUBIO_NEW(fft)
8+static PyObject *
9+Py_fft_new (PyTypeObject * type, PyObject * args, PyObject * kwds)
10+{
11+ int win_s = 0;
12+ Py_fft *self;
13+ static char *kwlist[] = { "win_s", NULL };
14+
15+ if (!PyArg_ParseTupleAndKeywords (args, kwds, "|I", kwlist,
16+ &win_s)) {
17+ return NULL;
18+ }
19+
20+ self = (Py_fft *) type->tp_alloc (type, 0);
21+
22+ if (self == NULL) {
23+ return NULL;
24+ }
25+
26+ self->win_s = Py_default_vector_length;
27+
28+ if (self == NULL) {
29+ return NULL;
30+ }
31+
32+ if (win_s > 0) {
33+ self->win_s = win_s;
34+ } else if (win_s < 0) {
35+ PyErr_SetString (PyExc_ValueError,
36+ "can not use negative window size");
37+ return NULL;
38+ }
39+
40+ return (PyObject *) self;
41+}
42+
43+
44+AUBIO_INIT(fft, self->win_s)
45+
46+AUBIO_DEL(fft)
47+
48+static PyObject *
49+Py_fft_do(PyObject * self, PyObject * args)
50+{
51+ PyObject *input;
52+ fvec_t *vec;
53+ cvec_t *output;
54+
55+ if (!PyArg_ParseTuple (args, "O", &input)) {
56+ return NULL;
57+ }
58+
59+ vec = PyAubio_ArrayToCFvec (input);
60+
61+ if (vec == NULL) {
62+ return NULL;
63+ }
64+
65+ output = new_cvec(((Py_fft *) self)->win_s);
66+
67+ // compute the function
68+ aubio_fft_do (((Py_fft *)self)->o, vec, output);
69+ return (PyObject *)PyAubio_CCvecToPyCvec(output);
70+}
71+
72+AUBIO_MEMBERS_START(fft)
73+ {"win_s", T_INT, offsetof (Py_fft, win_s), READONLY,
74+ "size of the window"},
75+AUBIO_MEMBERS_STOP(fft)
76+
77+static PyObject *
78+Py_fft_rdo(Py_fft * self, PyObject * args)
79+{
80+ PyObject *input;
81+ cvec_t *vec;
82+ fvec_t *output;
83+
84+ if (!PyArg_ParseTuple (args, "O", &input)) {
85+ return NULL;
86+ }
87+
88+ vec = PyAubio_ArrayToCCvec (input);
89+
90+ if (vec == NULL) {
91+ return NULL;
92+ }
93+
94+ output = new_fvec(self->win_s);
95+
96+ // compute the function
97+ aubio_fft_rdo (((Py_fft *)self)->o, vec, output);
98+ return (PyObject *)PyAubio_CFvecToArray(output);
99+}
100+
101+static PyMethodDef Py_fft_methods[] = {
102+ {"rdo", (PyCFunction) Py_fft_rdo, METH_VARARGS,
103+ "synthesis of spectral grain"},
104+ {NULL}
105+};
106+
107+AUBIO_TYPEOBJECT(fft, "aubio.fft")
python/py-filter.c+198−0
@@ -0,0 +1,198 @@
1+#include "aubio-types.h"
2+
3+typedef struct
4+{
5+ PyObject_HEAD
6+ aubio_filter_t * o;
7+ uint_t order;
8+} Py_filter;
9+
10+static char Py_filter_doc[] = "filter object";
11+
12+static PyObject *
13+Py_filter_new (PyTypeObject * type, PyObject * args, PyObject * kwds)
14+{
15+ int order= 0;
16+ Py_filter *self;
17+ static char *kwlist[] = { "order", NULL };
18+
19+ if (!PyArg_ParseTupleAndKeywords (args, kwds, "|I", kwlist,
20+ &order)) {
21+ return NULL;
22+ }
23+
24+ self = (Py_filter *) type->tp_alloc (type, 0);
25+
26+ if (self == NULL) {
27+ return NULL;
28+ }
29+
30+ self->order = 7;
31+
32+ if (order > 0) {
33+ self->order = order;
34+ } else if (order < 0) {
35+ PyErr_SetString (PyExc_ValueError,
36+ "can not use negative order");
37+ return NULL;
38+ }
39+
40+ return (PyObject *) self;
41+}
42+
43+static int
44+Py_filter_init (Py_filter * self, PyObject * args, PyObject * kwds)
45+{
46+ self->o = new_aubio_filter (self->order);
47+ if (self->o == NULL) {
48+ return -1;
49+ }
50+
51+ return 0;
52+}
53+
54+static void
55+Py_filter_del (Py_filter * self)
56+{
57+ del_aubio_filter (self->o);
58+ self->ob_type->tp_free ((PyObject *) self);
59+}
60+
61+static PyObject *
62+Py_filter_do(Py_filter * self, PyObject * args)
63+{
64+ PyObject *input;
65+ fvec_t *vec;
66+
67+ if (!PyArg_ParseTuple (args, "O:digital_filter.do", &input)) {
68+ return NULL;
69+ }
70+
71+ if (input == NULL) {
72+ return NULL;
73+ }
74+
75+ vec = PyAubio_ArrayToCFvec (input);
76+
77+ if (vec == NULL) {
78+ return NULL;
79+ }
80+
81+ // compute the function
82+ fvec_t * out = new_fvec(vec->length);
83+ aubio_filter_do_outplace (self->o, vec, out);
84+ return PyAubio_CFvecToArray(out);
85+}
86+
87+static PyObject *
88+Py_filter_set_c_weighting (Py_filter * self, PyObject *args)
89+{
90+ uint_t err = 0;
91+ uint_t samplerate;
92+ if (!PyArg_ParseTuple (args, "I", &samplerate)) {
93+ return NULL;
94+ }
95+
96+ err = aubio_filter_set_c_weighting (self->o, samplerate);
97+ if (err > 0) {
98+ PyErr_SetString (PyExc_ValueError,
99+ "error when setting filter to C-weighting");
100+ return NULL;
101+ }
102+ return Py_None;
103+}
104+
105+static PyObject *
106+Py_filter_set_a_weighting (Py_filter * self, PyObject *args)
107+{
108+ uint_t err = 0;
109+ uint_t samplerate;
110+ if (!PyArg_ParseTuple (args, "I", &samplerate)) {
111+ return NULL;
112+ }
113+
114+ err = aubio_filter_set_a_weighting (self->o, samplerate);
115+ if (err > 0) {
116+ PyErr_SetString (PyExc_ValueError,
117+ "error when setting filter to A-weighting");
118+ return NULL;
119+ }
120+ return Py_None;
121+}
122+
123+static PyObject *
124+Py_filter_set_biquad(Py_filter * self, PyObject *args)
125+{
126+ uint_t err = 0;
127+ lsmp_t b0, b1, b2, a1, a2;
128+ if (!PyArg_ParseTuple (args, "ddddd", &b0, &b1, &b2, &a1, &a2)) {
129+ return NULL;
130+ }
131+
132+ err = aubio_filter_set_biquad (self->o, b0, b1, b2, a1, a2);
133+ if (err > 0) {
134+ PyErr_SetString (PyExc_ValueError,
135+ "error when setting filter with biquad coefficients");
136+ return NULL;
137+ }
138+ return Py_None;
139+}
140+
141+static PyMemberDef Py_filter_members[] = {
142+ // TODO remove READONLY flag and define getter/setter
143+ {"order", T_INT, offsetof (Py_filter, order), READONLY,
144+ "order of the filter"},
145+ {NULL} /* Sentinel */
146+};
147+
148+static PyMethodDef Py_filter_methods[] = {
149+ {"set_c_weighting", (PyCFunction) Py_filter_set_c_weighting, METH_VARARGS,
150+ "set filter coefficients to C-weighting"},
151+ {"set_a_weighting", (PyCFunction) Py_filter_set_a_weighting, METH_VARARGS,
152+ "set filter coefficients to A-weighting"},
153+ {"set_biquad", (PyCFunction) Py_filter_set_biquad, METH_VARARGS,
154+ "set b0, b1, b2, a1, a2 biquad coefficients"},
155+ {NULL}
156+};
157+
158+PyTypeObject Py_filterType = {
159+ PyObject_HEAD_INIT (NULL)
160+ 0, /* ob_size */
161+ "aubio.digital_filter", /* tp_name */
162+ sizeof (Py_filter), /* tp_basicsize */
163+ 0, /* tp_itemsize */
164+ (destructor) Py_filter_del, /* tp_dealloc */
165+ 0, /* tp_print */
166+ 0, /* tp_getattr */
167+ 0, /* tp_setattr */
168+ 0, /* tp_compare */
169+ 0, //(reprfunc) Py_filter_repr, /* tp_repr */
170+ 0, /* tp_as_number */
171+ 0, /* tp_as_sequence */
172+ 0, /* tp_as_mapping */
173+ 0, /* tp_hash */
174+ (ternaryfunc)Py_filter_do, /* tp_call */
175+ 0, /* tp_str */
176+ 0, /* tp_getattro */
177+ 0, /* tp_setattro */
178+ 0, /* tp_as_buffer */
179+ Py_TPFLAGS_DEFAULT, /* tp_flags */
180+ Py_filter_doc, /* tp_doc */
181+ 0, /* tp_traverse */
182+ 0, /* tp_clear */
183+ 0, /* tp_richcompare */
184+ 0, /* tp_weaklistoffset */
185+ 0, /* tp_iter */
186+ 0, /* tp_iternext */
187+ Py_filter_methods, /* tp_methods */
188+ Py_filter_members, /* tp_members */
189+ 0, /* tp_getset */
190+ 0, /* tp_base */
191+ 0, /* tp_dict */
192+ 0, /* tp_descr_get */
193+ 0, /* tp_descr_set */
194+ 0, /* tp_dictoffset */
195+ (initproc) Py_filter_init, /* tp_init */
196+ 0, /* tp_alloc */
197+ Py_filter_new, /* tp_new */
198+};
python/py-filterbank.c+183−0
@@ -0,0 +1,183 @@
1+#include "aubiowraphell.h"
2+
3+static char Py_filterbank_doc[] = "filterbank object";
4+
5+AUBIO_DECLARE(filterbank, uint_t n_filters; uint_t win_s)
6+
7+//AUBIO_NEW(filterbank)
8+static PyObject *
9+Py_filterbank_new (PyTypeObject * type, PyObject * args, PyObject * kwds)
10+{
11+ int win_s = 0, n_filters = 0;
12+ Py_filterbank *self;
13+ static char *kwlist[] = { "n_filters", "win_s", NULL };
14+
15+ if (!PyArg_ParseTupleAndKeywords (args, kwds, "|II", kwlist,
16+ &n_filters, &win_s)) {
17+ return NULL;
18+ }
19+
20+ self = (Py_filterbank *) type->tp_alloc (type, 0);
21+
22+ if (self == NULL) {
23+ return NULL;
24+ }
25+
26+ self->win_s = Py_default_vector_length;
27+ if (win_s > 0) {
28+ self->win_s = win_s;
29+ } else if (win_s < 0) {
30+ PyErr_SetString (PyExc_ValueError,
31+ "can not use negative window size");
32+ return NULL;
33+ }
34+
35+ self->n_filters = 40;
36+ if (n_filters > 0) {
37+ self->n_filters = n_filters;
38+ } else if (n_filters < 0) {
39+ PyErr_SetString (PyExc_ValueError,
40+ "can not use negative number of filters");
41+ return NULL;
42+ }
43+
44+ return (PyObject *) self;
45+}
46+
47+
48+AUBIO_INIT(filterbank, self->n_filters, self->win_s)
49+
50+AUBIO_DEL(filterbank)
51+
52+static PyObject *
53+Py_filterbank_do(Py_filterbank * self, PyObject * args)
54+{
55+ PyObject *input;
56+ cvec_t *vec;
57+ fvec_t *out;
58+
59+ if (!PyArg_ParseTuple (args, "O", &input)) {
60+ return NULL;
61+ }
62+
63+ vec = PyAubio_ArrayToCCvec (input);
64+
65+ if (vec == NULL) {
66+ return NULL;
67+ }
68+
69+ out = new_fvec (self->n_filters);
70+
71+ // compute the function
72+ aubio_filterbank_do (self->o, vec, out);
73+ return (PyObject *)PyAubio_CFvecToArray(out);
74+}
75+
76+AUBIO_MEMBERS_START(filterbank)
77+ {"win_s", T_INT, offsetof (Py_filterbank, win_s), READONLY,
78+ "size of the window"},
79+ {"n_filters", T_INT, offsetof (Py_filterbank, n_filters), READONLY,
80+ "number of filters"},
81+AUBIO_MEMBERS_STOP(filterbank)
82+
83+static PyObject *
84+Py_filterbank_set_triangle_bands (Py_filterbank * self, PyObject *args)
85+{
86+ uint_t err = 0;
87+
88+ PyObject *input;
89+ uint_t samplerate;
90+ fvec_t *freqs;
91+ if (!PyArg_ParseTuple (args, "OI", &input, &samplerate)) {
92+ return NULL;
93+ }
94+
95+ if (input == NULL) {
96+ return NULL;
97+ }
98+
99+ freqs = PyAubio_ArrayToCFvec (input);
100+
101+ if (freqs == NULL) {
102+ return NULL;
103+ }
104+
105+ err = aubio_filterbank_set_triangle_bands (self->o,
106+ freqs, samplerate);
107+ if (err > 0) {
108+ PyErr_SetString (PyExc_ValueError,
109+ "error when setting filter to A-weighting");
110+ return NULL;
111+ }
112+ return Py_None;
113+}
114+
115+static PyObject *
116+Py_filterbank_set_mel_coeffs_slaney (Py_filterbank * self, PyObject *args)
117+{
118+ uint_t err = 0;
119+
120+ uint_t samplerate;
121+ if (!PyArg_ParseTuple (args, "I", &samplerate)) {
122+ return NULL;
123+ }
124+
125+ err = aubio_filterbank_set_mel_coeffs_slaney (self->o, samplerate);
126+ if (err > 0) {
127+ PyErr_SetString (PyExc_ValueError,
128+ "error when setting filter to A-weighting");
129+ return NULL;
130+ }
131+ return Py_None;
132+}
133+
134+static PyObject *
135+Py_filterbank_set_coeffs (Py_filterbank * self, PyObject *args)
136+{
137+ uint_t err = 0;
138+
139+ PyObject *input;
140+ fmat_t *coeffs;
141+
142+ if (!PyArg_ParseTuple (args, "O", &input)) {
143+ return NULL;
144+ }
145+
146+ coeffs = PyAubio_ArrayToCFmat (input);
147+
148+ if (coeffs == NULL) {
149+ PyErr_SetString (PyExc_ValueError,
150+ "unable to parse input array");
151+ return NULL;
152+ }
153+
154+ err = aubio_filterbank_set_coeffs (self->o, coeffs);
155+
156+ if (err > 0) {
157+ PyErr_SetString (PyExc_ValueError,
158+ "error when setting filter coefficients");
159+ return NULL;
160+ }
161+ return Py_None;
162+}
163+
164+static PyObject *
165+Py_filterbank_get_coeffs (Py_filterbank * self, PyObject *unused)
166+{
167+ return (PyObject *)PyAubio_CFmatToArray(
168+ aubio_filterbank_get_coeffs (self->o) );
169+}
170+
171+static PyMethodDef Py_filterbank_methods[] = {
172+ {"set_triangle_bands", (PyCFunction) Py_filterbank_set_triangle_bands,
173+ METH_VARARGS, "set coefficients of filterbanks"},
174+ {"set_mel_coeffs_slaney", (PyCFunction) Py_filterbank_set_mel_coeffs_slaney,
175+ METH_VARARGS, "set coefficients of filterbank as in Auditory Toolbox"},
176+ {"get_coeffs", (PyCFunction) Py_filterbank_get_coeffs,
177+ METH_NOARGS, "get coefficients of filterbank"},
178+ {"set_coeffs", (PyCFunction) Py_filterbank_set_coeffs,
179+ METH_VARARGS, "set coefficients of filterbank"},
180+ {NULL}
181+};
182+
183+AUBIO_TYPEOBJECT(filterbank, "aubio.filterbank")
python/py-phasevoc.c+118−0
@@ -0,0 +1,118 @@
1+#include "aubiowraphell.h"
2+
3+static char Py_pvoc_doc[] = "pvoc object";
4+
5+AUBIO_DECLARE(pvoc, uint_t win_s; uint_t hop_s)
6+
7+//AUBIO_NEW(pvoc)
8+static PyObject *
9+Py_pvoc_new (PyTypeObject * type, PyObject * args, PyObject * kwds)
10+{
11+ int win_s = 0, hop_s = 0;
12+ Py_pvoc *self;
13+ static char *kwlist[] = { "win_s", "hop_s", NULL };
14+
15+ if (!PyArg_ParseTupleAndKeywords (args, kwds, "|II", kwlist,
16+ &win_s, &hop_s)) {
17+ return NULL;
18+ }
19+
20+ self = (Py_pvoc *) type->tp_alloc (type, 0);
21+
22+ if (self == NULL) {
23+ return NULL;
24+ }
25+
26+ self->win_s = Py_default_vector_length;
27+ self->hop_s = Py_default_vector_length/2;
28+
29+ if (self == NULL) {
30+ return NULL;
31+ }
32+
33+ if (win_s > 0) {
34+ self->win_s = win_s;
35+ } else if (win_s < 0) {
36+ PyErr_SetString (PyExc_ValueError,
37+ "can not use negative window size");
38+ return NULL;
39+ }
40+
41+ if (hop_s > 0) {
42+ self->hop_s = hop_s;
43+ } else if (hop_s < 0) {
44+ PyErr_SetString (PyExc_ValueError,
45+ "can not use negative hop size");
46+ return NULL;
47+ }
48+
49+ return (PyObject *) self;
50+}
51+
52+
53+AUBIO_INIT(pvoc, self->win_s, self->hop_s)
54+
55+AUBIO_DEL(pvoc)
56+
57+static PyObject *
58+Py_pvoc_do(Py_pvoc * self, PyObject * args)
59+{
60+ PyObject *input;
61+ fvec_t *vec;
62+ cvec_t *output;
63+
64+ if (!PyArg_ParseTuple (args, "O", &input)) {
65+ return NULL;
66+ }
67+
68+ vec = PyAubio_ArrayToCFvec (input);
69+
70+ if (vec == NULL) {
71+ return NULL;
72+ }
73+
74+ output = new_cvec(self->win_s);
75+
76+ // compute the function
77+ aubio_pvoc_do (self->o, vec, output);
78+ return (PyObject *)PyAubio_CCvecToPyCvec(output);
79+}
80+
81+AUBIO_MEMBERS_START(pvoc)
82+ {"win_s", T_INT, offsetof (Py_pvoc, win_s), READONLY,
83+ "size of the window"},
84+ {"hop_s", T_INT, offsetof (Py_pvoc, hop_s), READONLY,
85+ "size of the hop"},
86+AUBIO_MEMBERS_STOP(pvoc)
87+
88+static PyObject *
89+Py_pvoc_rdo(Py_pvoc * self, PyObject * args)
90+{
91+ PyObject *input;
92+ cvec_t *vec;
93+ fvec_t *output;
94+
95+ if (!PyArg_ParseTuple (args, "O", &input)) {
96+ return NULL;
97+ }
98+
99+ vec = PyAubio_ArrayToCCvec (input);
100+
101+ if (vec == NULL) {
102+ return NULL;
103+ }
104+
105+ output = new_fvec(self->hop_s);
106+
107+ // compute the function
108+ aubio_pvoc_rdo (self->o, vec, output);
109+ return (PyObject *)PyAubio_CFvecToArray(output);
110+}
111+
112+static PyMethodDef Py_pvoc_methods[] = {
113+ {"rdo", (PyCFunction) Py_pvoc_rdo, METH_VARARGS,
114+ "synthesis of spectral grain"},
115+ {NULL}
116+};
117+
118+AUBIO_TYPEOBJECT(pvoc, "aubio.pvoc")
python/run_all_tests+20−0
@@ -0,0 +1,20 @@
1+#! /usr/bin/env python
2+
3+if __name__ == '__main__':
4+ import os, sys, unittest
5+ def load_test():
6+ # get relevant files
7+ curdir = os.path.dirname(sys.argv[0])
8+ if curdir == '': curdir = '.'
9+ files = os.listdir(os.path.join(curdir, 'tests'))
10+ modfiles = filter (lambda y: y.endswith('.py'), files)
11+ modfiles = filter (lambda f: f.startswith('test_'), modfiles)
12+ # get module names
13+ modnames = map (lambda x: os.path.splitext(x)[0], modfiles)
14+ # import them
15+ modules = map (__import__, modnames)
16+ # create a test suites from the imported module
17+ load_from_module = unittest.defaultTestLoader.loadTestsFromModule
18+ tests = map(load_from_module, modules)
19+ return unittest.TestSuite(tests)
20+ unittest.main(defaultTest = 'load_test')
python/setup.py+41−0
@@ -0,0 +1,41 @@
1+#! /usr/bin/python
2+
3+from distutils.core import setup, Extension
4+from generator import generate_object_files
5+import os.path
6+import numpy
7+
8+library_dirs = ['../build/src', '../src/.libs']
9+include_dirs = ['../build/src', '../src', '.' ]
10+library_dirs = filter (lambda x: os.path.isdir(x), library_dirs)
11+include_dirs = filter (lambda x: os.path.isdir(x), include_dirs)
12+
13+aubio_extension = Extension("_aubio",
14+ ["aubiomodule.c",
15+ "aubioproxy.c",
16+ "py-cvec.c",
17+ # example without macro
18+ "py-filter.c",
19+ # macroised
20+ "py-filterbank.c",
21+ "py-fft.c",
22+ "py-phasevoc.c",
23+ # generated files
24+ ] + generate_object_files(),
25+ include_dirs = include_dirs + [ numpy.get_include() ],
26+ library_dirs = library_dirs,
27+ libraries=['aubio'])
28+
29+setup(name='aubio',
30+ version = '0.4.0alpha',
31+ packages = ['aubio'],
32+ description = 'interface to the aubio library',
33+ long_description = 'interface to the aubio library',
34+ license = 'GNU/GPL version 3',
35+ author = 'Paul Brossier',
36+ author_email = 'piem@aubio.org',
37+ maintainer = 'Paul Brossier',
38+ maintainer_email = 'piem@aubio.org',
39+ url = 'http://aubio.org/',
40+ ext_modules = [aubio_extension])
41+
python/tests/test_aubio.py+14−0
@@ -0,0 +1,14 @@
1+#! /usr/bin/env python
2+
3+from numpy.testing import TestCase, run_module_suite
4+
5+class aubiomodule_test_case(TestCase):
6+
7+ def test_import(self):
8+ """ try importing aubio """
9+ import aubio
10+
11+if __name__ == '__main__':
12+ from unittest import main
13+ main()
14+
python/tests/test_cvec.py+50−0
@@ -0,0 +1,50 @@
1+from numpy.testing import TestCase, run_module_suite
2+from numpy.testing import assert_equal, assert_almost_equal
3+from aubio import cvec
4+from numpy import array, shape, pi
5+
6+class aubio_cvec_test_case(TestCase):
7+
8+ def test_vector_created_with_zeroes(self):
9+ a = cvec(10)
10+ a
11+ shape(a.norm)
12+ shape(a.phas)
13+ a.norm[0]
14+ assert_equal(a.norm, 0.)
15+ assert_equal(a.phas, 0.)
16+
17+ def test_vector_assign_element(self):
18+ a = cvec()
19+ a.norm[0] = 1
20+ assert_equal(a.norm[0], 1)
21+ a.phas[0] = 1
22+ assert_equal(a.phas[0], 1)
23+
24+ def test_vector_assign_element_end(self):
25+ a = cvec()
26+ a.norm[-1] = 1
27+ assert_equal(a.norm[-1], 1)
28+ assert_equal(a.norm[len(a.norm)-1], 1)
29+ a.phas[-1] = 1
30+ assert_equal(a.phas[-1], 1)
31+ assert_equal(a.phas[len(a.phas)-1], 1)
32+
33+ def test_assign_cvec_norm_slice(self):
34+ spec = cvec(1024)
35+ spec.norm[40:100] = 100
36+ assert_equal (spec.norm[0:40], 0)
37+ assert_equal (spec.norm[40:100], 100)
38+ assert_equal (spec.norm[100:-1], 0)
39+ assert_equal (spec.phas, 0)
40+
41+ def test_assign_cvec_phas_slice(self):
42+ spec = cvec(1024)
43+ spec.phas[39:-1] = -pi
44+ assert_equal (spec.phas[0:39], 0)
45+ assert_equal (spec.phas[39:-1], -pi)
46+ assert_equal (spec.norm, 0)
47+
48+if __name__ == '__main__':
49+ from unittest import main
50+ main()
python/tests/test_fft.py+113−0
@@ -0,0 +1,113 @@
1+#! /usr/bin/env python
2+
3+from numpy.testing import TestCase, run_module_suite
4+from numpy.testing import assert_equal, assert_almost_equal
5+# WARNING: numpy also has an fft object
6+from aubio import fvec, fft, cvec
7+from numpy import array, shape
8+from math import pi
9+
10+class aubio_fft_test_case(TestCase):
11+
12+ def test_members(self):
13+ f = fft()
14+ assert_equal (f.win_s, 1024)
15+
16+ def test_output_dimensions(self):
17+ """ check the dimensions of output """
18+ win_s = 1024
19+ timegrain = fvec(win_s)
20+ f = fft(win_s)
21+ fftgrain = f (timegrain)
22+ assert_equal (fftgrain.norm, 0)
23+ assert_equal (shape(fftgrain.norm), (win_s/2+1,))
24+ assert_equal (fftgrain.phas, 0)
25+ assert_equal (shape(fftgrain.phas), (win_s/2+1,))
26+
27+ def test_zeros(self):
28+ """ check the transform of zeros """
29+ win_s = 512
30+ timegrain = fvec(win_s)
31+ f = fft(win_s)
32+ fftgrain = f(timegrain)
33+ assert_equal ( fftgrain.norm == 0, True )
34+ assert_equal ( fftgrain.phas == 0, True )
35+
36+ def test_impulse(self):
37+ """ check the transform of one impulse at a random place """
38+ from random import random
39+ from math import floor
40+ win_s = 256
41+ i = floor(random()*win_s)
42+ impulse = pi * random()
43+ f = fft(win_s)
44+ timegrain = fvec(win_s)
45+ timegrain[i] = impulse
46+ fftgrain = f ( timegrain )
47+ #self.plot_this ( fftgrain.phas )
48+ assert_almost_equal ( fftgrain.norm, impulse, decimal = 6 )
49+ assert_equal ( fftgrain.phas <= pi, True)
50+ assert_equal ( fftgrain.phas >= -pi, True)
51+
52+ def test_impulse_negative(self):
53+ """ check the transform of one impulse at a random place """
54+ from random import random
55+ from math import floor
56+ win_s = 256
57+ i = 0
58+ impulse = -10.
59+ f = fft(win_s)
60+ timegrain = fvec(win_s)
61+ timegrain[i] = impulse
62+ fftgrain = f ( timegrain )
63+ #self.plot_this ( fftgrain.phas )
64+ assert_almost_equal ( fftgrain.norm, abs(impulse), decimal = 6 )
65+ if impulse < 0:
66+ # phase can be pi or -pi, as it is not unwrapped
67+ assert_almost_equal ( abs(fftgrain.phas[1:-1]) , pi, decimal = 6 )
68+ assert_almost_equal ( fftgrain.phas[0], pi, decimal = 6)
69+ assert_almost_equal ( fftgrain.phas[-1], pi, decimal = 6)
70+ else:
71+ assert_equal ( fftgrain.phas[1:-1] == 0, True)
72+ assert_equal ( fftgrain.phas[0] == 0, True)
73+ assert_equal ( fftgrain.phas[-1] == 0, True)
74+ # now check the resynthesis
75+ synthgrain = f.rdo ( fftgrain )
76+ #self.plot_this ( fftgrain.phas.T )
77+ assert_equal ( fftgrain.phas <= pi, True)
78+ assert_equal ( fftgrain.phas >= -pi, True)
79+ #self.plot_this ( synthgrain - timegrain )
80+ assert_almost_equal ( synthgrain, timegrain, decimal = 6 )
81+
82+ def test_impulse_at_zero(self):
83+ """ check the transform of one impulse at a index 0 """
84+ win_s = 1024
85+ impulse = pi
86+ f = fft(win_s)
87+ timegrain = fvec(win_s)
88+ timegrain[0] = impulse
89+ fftgrain = f ( timegrain )
90+ #self.plot_this ( fftgrain.phas )
91+ assert_equal ( fftgrain.phas[0], 0)
92+ # could be 0 or -0 depending on fft implementation (0 for fftw3, -0 for ooura)
93+ assert_almost_equal ( fftgrain.phas[1], 0)
94+ assert_almost_equal ( fftgrain.norm[0], impulse, decimal = 6 )
95+
96+ def test_rdo_before_do(self):
97+ """ check running fft.rdo before fft.do works """
98+ win_s = 1024
99+ impulse = pi
100+ f = fft(win_s)
101+ fftgrain = cvec(win_s)
102+ t = f.rdo( fftgrain )
103+ assert_equal ( t, 0 )
104+
105+ def plot_this(self, this):
106+ from pylab import plot, show
107+ plot ( this )
108+ show ()
109+
110+if __name__ == '__main__':
111+ from unittest import main
112+ main()
113+
python/tests/test_filter.py+68−0
@@ -0,0 +1,68 @@
1+#! /usr/bin/env python
2+
3+from numpy.testing import TestCase, assert_equal, assert_almost_equal
4+from aubio import fvec, digital_filter
5+from numpy import array
6+
7+def array_from_text_file(filename, dtype = 'float'):
8+ return array([line.split() for line in open(filename).readlines()],
9+ dtype = dtype)
10+
11+class aubio_filter_test_case(TestCase):
12+
13+ def test_members(self):
14+ f = digital_filter()
15+ assert_equal (f.order, 7)
16+ f = digital_filter(5)
17+ assert_equal (f.order, 5)
18+ f(fvec())
19+
20+ def test_cweighting_error(self):
21+ f = digital_filter (2)
22+ self.assertRaises ( ValueError, f.set_c_weighting, 44100 )
23+ f = digital_filter (8)
24+ self.assertRaises ( ValueError, f.set_c_weighting, 44100 )
25+ f = digital_filter (5)
26+ self.assertRaises ( ValueError, f.set_c_weighting, 4000 )
27+ f = digital_filter (5)
28+ self.assertRaises ( ValueError, f.set_c_weighting, 193000 )
29+ f = digital_filter (7)
30+ self.assertRaises ( ValueError, f.set_a_weighting, 193000 )
31+ f = digital_filter (5)
32+ self.assertRaises ( ValueError, f.set_a_weighting, 192000 )
33+
34+ def test_c_weighting(self):
35+ expected = array_from_text_file('c_weighting_test_simple.expected')
36+ f = digital_filter(5)
37+ f.set_c_weighting(44100)
38+ v = fvec(32)
39+ v[12] = .5
40+ u = f(v)
41+ assert_almost_equal (expected[1], u)
42+
43+ def test_a_weighting(self):
44+ expected = array_from_text_file('a_weighting_test_simple.expected')
45+ f = digital_filter(7)
46+ f.set_a_weighting(44100)
47+ v = fvec(32)
48+ v[12] = .5
49+ u = f(v)
50+ assert_almost_equal (expected[1], u)
51+
52+ def test_a_weighting_parted(self):
53+ expected = array_from_text_file('a_weighting_test_simple.expected')
54+ f = digital_filter(7)
55+ f.set_a_weighting(44100)
56+ v = fvec(16)
57+ v[12] = .5
58+ u = f(v)
59+ assert_almost_equal (expected[1][:16], u)
60+ # one more time
61+ v = fvec(16)
62+ u = f(v)
63+ assert_almost_equal (expected[1][16:], u)
64+
65+if __name__ == '__main__':
66+ from unittest import main
67+ main()
68+
python/tests/test_filterbank.py+23−0
@@ -0,0 +1,23 @@
1+#! /usr/bin/env python
2+
3+from numpy.testing import TestCase, run_module_suite
4+from numpy.testing import assert_equal, assert_almost_equal
5+from numpy import random
6+from aubio import cvec, filterbank
7+
8+class aubio_filterbank_test_case(TestCase):
9+
10+ def test_members(self):
11+ f = filterbank(40, 512)
12+ assert_equal ([f.n_filters, f.win_s], [40, 512])
13+
14+ def test_set_coeffs(self):
15+ f = filterbank(40, 512)
16+ r = random.random([40, 512 / 2 + 1]).astype('float32')
17+ f.set_coeffs(r)
18+ assert_equal (r, f.get_coeffs())
19+
20+if __name__ == '__main__':
21+ from unittest import main
22+ main()
23+
python/tests/test_filterbank_mel.py+51−0
@@ -0,0 +1,51 @@
1+#! /usr/bin/env python
2+
3+from numpy.testing import TestCase, run_module_suite
4+from numpy.testing import assert_equal, assert_almost_equal
5+from numpy import array, shape
6+from aubio import cvec, filterbank
7+
8+class aubio_filterbank_mel_test_case(TestCase):
9+
10+ def test_slaney(self):
11+ f = filterbank(40, 512)
12+ f.set_mel_coeffs_slaney(16000)
13+ a = f.get_coeffs()
14+ assert_equal(shape (a), (40, 512/2 + 1) )
15+
16+ def test_other_slaney(self):
17+ f = filterbank(40, 512*2)
18+ f.set_mel_coeffs_slaney(44100)
19+ a = f.get_coeffs()
20+ #print "sum is", sum(sum(a))
21+ for win_s in [256, 512, 1024, 2048, 4096]:
22+ f = filterbank(40, win_s)
23+ f.set_mel_coeffs_slaney(320000)
24+ a = f.get_coeffs()
25+ #print "sum is", sum(sum(a))
26+
27+ def test_triangle_freqs_zeros(self):
28+ f = filterbank(9, 1024)
29+ freq_list = [40, 80, 200, 400, 800, 1600, 3200, 6400, 12800, 15000, 24000]
30+ freqs = array(freq_list, dtype = 'float32')
31+ f.set_triangle_bands(freqs, 48000)
32+ f.get_coeffs().T
33+ assert_equal ( f(cvec(1024)), 0)
34+
35+ def test_triangle_freqs_ones(self):
36+ f = filterbank(9, 1024)
37+ freq_list = [40, 80, 200, 400, 800, 1600, 3200, 6400, 12800, 15000, 24000]
38+ freqs = array(freq_list, dtype = 'float32')
39+ f.set_triangle_bands(freqs, 48000)
40+ f.get_coeffs().T
41+ spec = cvec(1024)
42+ spec.norm[:] = 1
43+ assert_almost_equal ( f(spec),
44+ [ 0.02070313, 0.02138672, 0.02127604, 0.02135417,
45+ 0.02133301, 0.02133301, 0.02133311, 0.02133334, 0.02133345])
46+
47+if __name__ == '__main__':
48+ from unittest import main
49+ main()
50+
51+
python/tests/test_fvec.py+135−0
@@ -0,0 +1,135 @@
1+#! /usr/bin/env python
2+
3+from numpy.testing import TestCase, run_module_suite
4+from numpy.testing import assert_equal, assert_almost_equal
5+from aubio import fvec, zero_crossing_rate, alpha_norm, min_removal
6+from numpy import array, shape
7+
8+class aubio_fvec_test_case(TestCase):
9+
10+ def test_vector_created_with_zeroes(self):
11+ a = fvec(10)
12+ a
13+ shape(a)
14+ a[0]
15+ #del a
16+ assert_equal(array(a), 0.)
17+
18+ def test_vector_create_with_list(self):
19+ a = fvec([0,1,2,3])
20+ assert_equal (range(4), a)
21+
22+ def test_vector_assign_element(self):
23+ a = fvec()
24+ a[0] = 1
25+ assert_equal(a[0], 1)
26+
27+ def test_vector_assign_element_end(self):
28+ a = fvec()
29+ a[-1] = 1
30+ assert_equal(a[-1], 1)
31+ assert_equal(a[len(a)-1], 1)
32+
33+ def test_vector(self):
34+ a = fvec()
35+ a, len(a) #a.length
36+ a[0]
37+ array(a)
38+ a = fvec(10)
39+ a = fvec(1)
40+ a.T
41+ array(a).T
42+ a = range(len(a))
43+
44+ def test_wrong_values(self):
45+ self.assertRaises (ValueError, fvec, -10)
46+
47+ a = fvec(2)
48+ self.assertRaises (IndexError, a.__getitem__, 3)
49+ self.assertRaises (IndexError, a.__getitem__, 2)
50+
51+ def test_alpha_norm_of_fvec(self):
52+ a = fvec(2)
53+ self.assertEquals (alpha_norm(a, 1), 0)
54+ a[0] = 1
55+ self.assertEquals (alpha_norm(a, 1), 0.5)
56+ a[1] = 1
57+ self.assertEquals (alpha_norm(a, 1), 1)
58+ a = array([0, 1], dtype='float32')
59+ from math import sqrt
60+ assert_almost_equal (alpha_norm(a, 2), sqrt(2)/2.)
61+
62+ def test_alpha_norm_of_none(self):
63+ self.assertRaises (ValueError, alpha_norm, None, 1)
64+
65+ def test_alpha_norm_of_array_of_float32(self):
66+ # check scalar fails
67+ a = array(1, dtype = 'float32')
68+ self.assertRaises (ValueError, alpha_norm, a, 1)
69+ # check 2d array fails
70+ a = array([[2],[4]], dtype = 'float32')
71+ self.assertRaises (ValueError, alpha_norm, a, 1)
72+ # check 1d array
73+ a = array(range(10), dtype = 'float32')
74+ self.assertEquals (alpha_norm(a, 1), 4.5)
75+
76+ def test_alpha_norm_of_array_of_int(self):
77+ a = array(1, dtype = 'int')
78+ self.assertRaises (ValueError, alpha_norm, a, 1)
79+ a = array([[[1,2],[3,4]]], dtype = 'int')
80+ self.assertRaises (ValueError, alpha_norm, a, 1)
81+ a = array(range(10), dtype = 'int')
82+ self.assertRaises (ValueError, alpha_norm, a, 1)
83+
84+ def test_alpha_norm_of_array_of_string (self):
85+ a = "hello"
86+ self.assertRaises (ValueError, alpha_norm, a, 1)
87+
88+ def test_zero_crossing_rate(self):
89+ a = array([0,1,-1], dtype='float32')
90+ assert_almost_equal (zero_crossing_rate(a), 1./3. )
91+ a = array([0.]*100, dtype='float32')
92+ self.assertEquals (zero_crossing_rate(a), 0 )
93+ a = array([-1.]*100, dtype='float32')
94+ self.assertEquals (zero_crossing_rate(a), 0 )
95+ a = array([1.]*100, dtype='float32')
96+ self.assertEquals (zero_crossing_rate(a), 0 )
97+
98+ def test_alpha_norm_of_array_of_float64(self):
99+ # check scalar fail
100+ a = array(1, dtype = 'float64')
101+ self.assertRaises (ValueError, alpha_norm, a, 1)
102+ # check 3d array fail
103+ a = array([[[1,2],[3,4]]], dtype = 'float64')
104+ self.assertRaises (ValueError, alpha_norm, a, 1)
105+ # check float64 1d array fail
106+ a = array(range(10), dtype = 'float64')
107+ self.assertRaises (ValueError, alpha_norm, a, 1)
108+ # check float64 2d array fail
109+ a = array([range(10), range(10)], dtype = 'float64')
110+ self.assertRaises (ValueError, alpha_norm, a, 1)
111+
112+ def test_fvec_min_removal_of_array(self):
113+ a = array([20,1,19], dtype='float32')
114+ b = min_removal(a)
115+ assert_equal (array(b), [19, 0, 18])
116+ assert_equal (b, [19, 0, 18])
117+ assert_equal (a, b)
118+ a[0] = 0
119+ assert_equal (a, b)
120+
121+ def test_fvec_min_removal_of_array_float64(self):
122+ a = array([20,1,19], dtype='float64')
123+ self.assertRaises (ValueError, min_removal, a)
124+
125+ def test_fvec_min_removal_of_fvec(self):
126+ a = fvec(3)
127+ a = array([20, 1, 19], dtype = 'float32')
128+ b = min_removal(a)
129+ assert_equal (array(b), [19, 0, 18])
130+ assert_equal (b, [19, 0, 18])
131+ assert_equal (a, b)
132+
133+if __name__ == '__main__':
134+ from unittest import main
135+ main()
python/tests/test_onset.py+20−0
@@ -0,0 +1,20 @@
1+#! /usr/bin/env python
2+
3+from numpy.testing import TestCase, run_module_suite
4+from numpy.testing import assert_equal, assert_almost_equal
5+# WARNING: numpy also has an fft object
6+from aubio import onset, cvec
7+from numpy import array, shape, arange, zeros, log
8+from math import pi
9+
10+class aubio_onset(TestCase):
11+
12+ def test_members(self):
13+ o = onset()
14+ assert_equal ([o.buf_size, o.hop_size, o.method, o.samplerate],
15+ [1024,512,'default',44100])
16+
17+
18+if __name__ == '__main__':
19+ from unittest import main
20+ main()
python/tests/test_peakpicker.py+115−0
@@ -0,0 +1,115 @@
1+#! /usr/bin/env python
2+
3+from numpy.testing import TestCase, assert_equal, assert_almost_equal
4+from aubio import peakpicker, fvec
5+
6+class aubio_peakpicker(TestCase):
7+
8+ def test_members(self):
9+ o = peakpicker()
10+
11+ def test_peakpicker_zeroes(self):
12+ o = peakpicker()
13+ assert_equal(o.get_thresholded_input(), 0.)
14+
15+ def test_peakpick_set_threshold(self):
16+ o = peakpicker()
17+ new_threshold = threshold
18+ o.set_threshold(new_threshold)
19+ assert_almost_equal(new_threshold, o.get_threshold())
20+
21+ def test_peakpicker_get_threshold(self):
22+ o = peakpicker()
23+ new_threshold = o.get_threshold()
24+ o.set_threshold(new_threshold)
25+ assert_equal(new_threshold, o.get_threshold())
26+
27+buf_size = 1024
28+slice_size = 5
29+delay = 1
30+threshold = .9
31+
32+class aubio_peakpicker_peaks(TestCase):
33+
34+ def setUp(self):
35+ self.o = peakpicker()
36+ self.o.set_threshold (threshold)
37+ self.vec = fvec(buf_size)
38+
39+ def test_peakpicker_impulse(self):
40+ vec = self.vec; o = self.o
41+ a = 345
42+ vec[a] = 1000.
43+ self.peaks = [a]
44+
45+ def test_peakpicker_ramp_up(self):
46+ vec = self.vec; o = self.o
47+ a = 345
48+ vec[a] = 1000. / 4. * 1.
49+ vec[a+1] = 1000. / 4. * 2.
50+ vec[a+2] = 1000. / 4. * 3.
51+ vec[a+3] = 1000.
52+ self.peaks = [a+1]
53+
54+ def test_peakpicker_ramp_down(self):
55+ vec = self.vec; o = self.o
56+ a = 345
57+ vec[a] = 1000.
58+ vec[a+1] = 1000. / 4. * 3.
59+ vec[a+2] = 1000. / 4. * 2.
60+ vec[a+3] = 1000. / 4. * 1.
61+ self.peaks = [a]
62+
63+ def test_peakpicker_plateau(self):
64+ vec = self.vec; o = self.o
65+ a = 345
66+ vec[a] = 1000. / 2
67+ vec[a+1] = 1000.
68+ vec[a+2] = 1000.
69+ vec[a+3] = 1000.
70+ vec[a+4] = 1000. / 2
71+ self.peaks = [a+1]
72+
73+ def test_peakpicker_consecutive_peaks(self):
74+ vec = self.vec; o = self.o
75+ a = 345
76+ vec[a] = 1000. / 2
77+ vec[a+1] = 1000.
78+ vec[a+3] = 1000.
79+ vec[a+4] = 1000. / 2
80+ self.peaks = [a]
81+
82+ def test_peakpicker_distant_peaks(self):
83+ vec = self.vec; o = self.o
84+ a = 345
85+ vec[a] = 1000.
86+ vec[a+7] = 1000.
87+ self.peaks = [a, a+7]
88+
89+ def test_peakpicker_very_distant_peaks(self):
90+ vec = self.vec; o = self.o
91+ a = 345
92+ vec[a] = 1000.
93+ vec[a+67] = 1000.
94+ self.peaks = [a, a+67]
95+
96+ def tearDown(self):
97+ fpeaks = []
98+ for index in range(0,buf_size-slice_size):
99+ sliced = self.vec[index:index+slice_size]
100+ findex = self.o(sliced)
101+ if findex:
102+ # we found a peak
103+ fpeak = index - findex - delay
104+ #print self.peaks, index, '-', findex, '-', delay, '=', fpeak
105+ if not round(index - findex - delay) in self.peaks:
106+ self.fail('missing peak ' + str(fpeak))
107+ fpeaks.append(fpeak)
108+ if len(fpeaks) != len(self.peaks):
109+ self.fail('some peaks of ' + str(self.peaks) + 'were not found, got only ' + str(fpeaks))
110+ #print
111+ #print fpeaks, self.peaks
112+
113+if __name__ == '__main__':
114+ from unittest import main
115+ main()
python/tests/test_phasevoc.py+65−0
@@ -0,0 +1,65 @@
1+#! /usr/bin/env python
2+
3+from numpy.testing import TestCase, run_module_suite
4+from numpy.testing import assert_equal, assert_almost_equal
5+from aubio import fvec, cvec, pvoc
6+from numpy import array, shape
7+
8+class aubio_pvoc_test_case(TestCase):
9+
10+ def test_members(self):
11+ f = pvoc()
12+ assert_equal ([f.win_s, f.hop_s], [1024, 512])
13+ f = pvoc(2048, 128)
14+ assert_equal ([f.win_s, f.hop_s], [2048, 128])
15+
16+ def test_zeros(self):
17+ win_s, hop_s = 1024, 256
18+ f = pvoc (win_s, hop_s)
19+ t = fvec (hop_s)
20+ for time in range( 4 * win_s / hop_s ):
21+ s = f(t)
22+ r = f.rdo(s)
23+ assert_equal ( array(t), 0)
24+ assert_equal ( s.norm, 0)
25+ assert_equal ( s.phas, 0)
26+ assert_equal ( r, 0)
27+
28+ def test_steps_two_channels(self):
29+ """ check the resynthesis of steps is correct """
30+ f = pvoc(1024, 512)
31+ t1 = fvec(512)
32+ t2 = fvec(512)
33+ # positive step in first channel
34+ t1[100:200] = .1
35+ # positive step in second channel
36+ t1[20:50] = -.1
37+ s1 = f(t1)
38+ r1 = f.rdo(s1)
39+ s2 = f(t2)
40+ r2 = f.rdo(s2)
41+ #self.plot_this ( s1.norm.T )
42+ assert_almost_equal ( t1, r2, decimal = 6 )
43+
44+ def test_steps_three_random_channels(self):
45+ from random import random
46+ f = pvoc(64, 16)
47+ t0 = fvec(16)
48+ t1 = fvec(16)
49+ for i in xrange(16):
50+ t1[i] = random() * 2. - 1.
51+ t2 = f.rdo(f(t1))
52+ t2 = f.rdo(f(t0))
53+ t2 = f.rdo(f(t0))
54+ t2 = f.rdo(f(t0))
55+ assert_almost_equal( t1, t2, decimal = 6 )
56+
57+ def plot_this( self, this ):
58+ from pylab import semilogy, show
59+ semilogy ( this )
60+ show ()
61+
62+if __name__ == '__main__':
63+ from unittest import main
64+ main()
65+
python/tests/test_pitch.py+101−0
@@ -0,0 +1,101 @@
1+#! /usr/bin/env python
2+
3+from numpy.testing import TestCase
4+from numpy.testing import assert_equal, assert_almost_equal
5+from numpy import random, sin, arange, mean, median
6+from math import pi
7+from aubio import fvec, pitch
8+
9+class aubio_mathutils_test_case(TestCase):
10+
11+ def test_members(self):
12+ p = pitch()
13+ assert_equal ( [p.method, p.buf_size, p.hop_size, p.samplerate],
14+ ['default', 1024, 512, 44100])
15+
16+ def test_members_not_default(self):
17+ p = pitch('mcomb', 2048, 512, 32000)
18+ assert_equal ( [p.method, p.buf_size, p.hop_size, p.samplerate],
19+ ['mcomb', 2048, 512, 32000])
20+
21+ def test_run_on_zeros(self):
22+ p = pitch('mcomb', 2048, 512, 32000)
23+ f = fvec (512)
24+ assert_equal ( p(f), 0. )
25+
26+ def test_run_on_ones(self):
27+ p = pitch('mcomb', 2048, 512, 32000)
28+ f = fvec (512)
29+ f[:] = 1
30+ assert( p(f) != 0. )
31+
32+ def test_run_default_on_sinusoid(self):
33+ method = 'default'
34+ buf_size = 2048
35+ hop_size = 512
36+ samplerate = 32000
37+ freq = 450.
38+ self.run_pitch_on_sinusoid(method, buf_size, hop_size, samplerate, freq)
39+
40+ def test_run_schmitt_on_sinusoid(self):
41+ method = 'schmitt'
42+ buf_size = 4096
43+ hop_size = 512
44+ samplerate = 44100
45+ freq = 800.
46+ self.run_pitch_on_sinusoid(method, buf_size, hop_size, samplerate, freq)
47+
48+ def test_run_mcomb_on_sinusoid(self):
49+ method = 'mcomb'
50+ buf_size = 2048
51+ hop_size = 512
52+ samplerate = 44100
53+ freq = 10000.
54+ self.run_pitch_on_sinusoid(method, buf_size, hop_size, samplerate, freq)
55+
56+ def test_run_fcomb_on_sinusoid(self):
57+ method = 'fcomb'
58+ buf_size = 2048
59+ hop_size = 512
60+ samplerate = 32000
61+ freq = 440.
62+ self.run_pitch_on_sinusoid(method, buf_size, hop_size, samplerate, freq)
63+
64+ def test_run_yin_on_sinusoid(self):
65+ method = 'yin'
66+ buf_size = 4096
67+ hop_size = 512
68+ samplerate = 32000
69+ freq = 880.
70+ self.run_pitch_on_sinusoid(method, buf_size, hop_size, samplerate, freq)
71+
72+ def test_run_yinfft_on_sinusoid(self):
73+ method = 'yinfft'
74+ buf_size = 2048
75+ hop_size = 512
76+ samplerate = 32000
77+ freq = 640.
78+ self.run_pitch_on_sinusoid(method, buf_size, hop_size, samplerate, freq)
79+
80+ def run_pitch_on_sinusoid(self, method, buf_size, hop_size, samplerate, freq):
81+ p = pitch(method, buf_size, hop_size, samplerate)
82+ sinvec = self.build_sinusoid(hop_size * 100, freq, samplerate)
83+ self.run_pitch(p, sinvec, freq)
84+
85+ def build_sinusoid(self, length, freq, samplerate):
86+ return sin( 2. * pi * arange(length).astype('float32') * freq / samplerate)
87+
88+ def run_pitch(self, p, input_vec, freq):
89+ count = 0
90+ pitches, errors = [], []
91+ for vec_slice in input_vec.reshape((-1, p.hop_size)):
92+ pitch = p(vec_slice)
93+ pitches.append(pitch)
94+ errors.append(1. - pitch / freq)
95+ # check that the mean of all relative errors is less than 10%
96+ assert_almost_equal (mean(errors), 0., decimal = 2)
97+
98+if __name__ == '__main__':
99+ from unittest import main
100+ main()
101+
python/tests/test_source.py+27−0
@@ -0,0 +1,27 @@
1+#! /usr/bin/env python
2+
3+from numpy.testing import TestCase, assert_equal, assert_almost_equal
4+from aubio import fvec, source
5+from numpy import array
6+
7+path = "/Users/piem/archives/sounds/loops/drum_Chocolate_Milk_-_Ation_Speaks_Louder_Than_Words.wav"
8+
9+class aubio_filter_test_case(TestCase):
10+
11+ def test_members(self):
12+ f = source(path)
13+ print dir(f)
14+
15+ def test_read(self):
16+ f = source(path)
17+ total_frames = 0
18+ while True:
19+ vec, read = f()
20+ total_frames += read
21+ if read < f.hop_size: break
22+ print "read", total_frames / float(f.samplerate), " seconds from", path
23+
24+if __name__ == '__main__':
25+ from unittest import main
26+ main()
27+
python/tests/test_specdesc.py+238−0
@@ -0,0 +1,238 @@
1+#! /usr/bin/env python
2+
3+from numpy.testing import TestCase, assert_equal, assert_almost_equal
4+from numpy import random, arange, log, zeros
5+from aubio import specdesc, cvec
6+from math import pi
7+
8+methods = ["default",
9+ "energy",
10+ "hfc",
11+ "complex",
12+ "phase",
13+ "specdiff",
14+ "kl",
15+ "mkl",
16+ "specflux",
17+ "centroid",
18+ "spread",
19+ "skewness",
20+ "kurtosis",
21+ "slope",
22+ "decrease",
23+ "rolloff"]
24+buf_size = 2048
25+
26+class aubio_specdesc(TestCase):
27+
28+ def test_members(self):
29+ o = specdesc()
30+
31+ for method in methods:
32+ o = specdesc(method, buf_size)
33+ assert_equal ([o.buf_size, o.method], [buf_size, method])
34+
35+ spec = cvec(buf_size)
36+ spec.norm[0] = 1
37+ spec.norm[1] = 1./2.
38+ #print "%20s" % method, str(o(spec))
39+ o(spec)
40+ spec.norm = random.random_sample((len(spec.norm),)).astype('float32')
41+ spec.phas = random.random_sample((len(spec.phas),)).astype('float32')
42+ #print "%20s" % method, str(o(spec))
43+ assert (o(spec) != 0.)
44+
45+ def test_hfc(self):
46+ o = specdesc("hfc", buf_size)
47+ spec = cvec(buf_size)
48+ # hfc of zeros is zero
49+ assert_equal (o(spec), 0.)
50+ # hfc of ones is sum of all bin numbers
51+ spec.norm[:] = 1
52+ expected = sum(range(buf_size/2 + 2))
53+ assert_equal (o(spec), expected)
54+ # changing phase doesn't change anything
55+ spec.phas[:] = 1
56+ assert_equal (o(spec), sum(range(buf_size/2 + 2)))
57+
58+ def test_phase(self):
59+ o = specdesc("phase", buf_size)
60+ spec = cvec(buf_size)
61+ # phase of zeros is zero
62+ assert_equal (o(spec), 0.)
63+ spec.phas = random.random_sample((len(spec.phas),)).astype('float32')
64+ # phase of random is not zero
65+ spec.norm[:] = 1
66+ assert (o(spec) != 0.)
67+
68+ def test_specdiff(self):
69+ o = specdesc("phase", buf_size)
70+ spec = cvec(buf_size)
71+ # specdiff of zeros is zero
72+ assert_equal (o(spec), 0.)
73+ spec.phas = random.random_sample((len(spec.phas),)).astype('float32')
74+ # phase of random is not zero
75+ spec.norm[:] = 1
76+ assert (o(spec) != 0.)
77+
78+ def test_hfc(self):
79+ o = specdesc("hfc")
80+ c = cvec()
81+ assert_equal( 0., o(c))
82+ a = arange(c.length, dtype='float32')
83+ c.norm = a
84+ assert_equal (a, c.norm)
85+ assert_equal ( sum(a*(a+1)), o(c))
86+
87+ def test_complex(self):
88+ o = specdesc("complex")
89+ c = cvec()
90+ assert_equal( 0., o(c))
91+ a = arange(c.length, dtype='float32')
92+ c.norm = a
93+ assert_equal (a, c.norm)
94+ # the previous run was on zeros, so previous frames are still 0
95+ # so we have sqrt ( abs ( r2 ^ 2) ) == r2
96+ assert_equal ( sum(a), o(c))
97+ # second time. c.norm = a, so, r1 = r2, and the euclidian distance is 0
98+ assert_equal ( 0, o(c))
99+
100+ def test_kl(self):
101+ o = specdesc("kl")
102+ c = cvec()
103+ assert_equal( 0., o(c))
104+ a = arange(c.length, dtype='float32')
105+ c.norm = a
106+ assert_almost_equal( sum(a * log(1.+ a/1.e-10 ) ) / o(c), 1., decimal=6)
107+
108+ def test_mkl(self):
109+ o = specdesc("mkl")
110+ c = cvec()
111+ assert_equal( 0., o(c))
112+ a = arange(c.length, dtype='float32')
113+ c.norm = a
114+ assert_almost_equal( sum(log(1.+ a/1.e-10 ) ) / o(c), 1, decimal=6)
115+
116+ def test_specflux(self):
117+ o = specdesc("specflux")
118+ c = cvec()
119+ assert_equal( 0., o(c))
120+ a = arange(c.length, dtype='float32')
121+ c.norm = a
122+ assert_equal( sum(a), o(c))
123+ assert_equal( 0, o(c))
124+ c.norm = zeros(c.length, dtype='float32')
125+ assert_equal( 0, o(c))
126+
127+ def test_centroid(self):
128+ o = specdesc("centroid")
129+ c = cvec()
130+ # make sure centroid of zeros is zero
131+ assert_equal( 0., o(c))
132+ a = arange(c.length, dtype='float32')
133+ c.norm = a
134+ centroid = sum(a*a) / sum(a)
135+ assert_almost_equal (centroid, o(c), decimal = 2)
136+
137+ c.norm = a * .5
138+ assert_almost_equal (centroid, o(c), decimal = 2)
139+
140+ def test_spread(self):
141+ o = specdesc("spread")
142+ c = cvec(2048)
143+ ramp = arange(c.length, dtype='float32')
144+ assert_equal( 0., o(c))
145+
146+ a = ramp
147+ c.norm = a
148+ centroid = sum(a*a) / sum(a)
149+ spread = sum( a * pow(ramp - centroid, 2.) ) / sum(a)
150+ assert_almost_equal (o(c), spread, decimal = 1)
151+
152+ def test_skewness(self):
153+ o = specdesc("skewness")
154+ c = cvec()
155+ assert_equal( 0., o(c))
156+ a = arange(c.length, dtype='float32')
157+ c.norm = a
158+ centroid = sum(a*a) / sum(a)
159+ spread = sum( (a - centroid)**2 *a) / sum(a)
160+ skewness = sum( (a - centroid)**3 *a) / sum(a) / spread **1.5
161+ assert_almost_equal (skewness, o(c), decimal = 2)
162+
163+ c.norm = a * 3
164+ assert_almost_equal (skewness, o(c), decimal = 2)
165+
166+ def test_kurtosis(self):
167+ o = specdesc("kurtosis")
168+ c = cvec()
169+ assert_equal( 0., o(c))
170+ a = arange(c.length, dtype='float32')
171+ c.norm = a
172+ centroid = sum(a*a) / sum(a)
173+ spread = sum( (a - centroid)**2 *a) / sum(a)
174+ kurtosis = sum( (a - centroid)**4 *a) / sum(a) / spread **2
175+ assert_almost_equal (kurtosis, o(c), decimal = 2)
176+
177+ def test_slope(self):
178+ o = specdesc("slope")
179+ c = cvec()
180+ assert_equal( 0., o(c))
181+ a = arange(c.length * 2, 0, -2, dtype='float32')
182+ k = arange(c.length, dtype='float32')
183+ c.norm = a
184+ num = len(a) * sum(k*a) - sum(k)*sum(a)
185+ den = (len(a) * sum(k**2) - sum(k)**2)
186+ slope = num/den/sum(a)
187+ assert_almost_equal (slope, o(c), decimal = 5)
188+
189+ a = arange(0, c.length * 2, +2, dtype='float32')
190+ c.norm = a
191+ num = len(a) * sum(k*a) - sum(k)*sum(a)
192+ den = (len(a) * sum(k**2) - sum(k)**2)
193+ slope = num/den/sum(a)
194+ assert_almost_equal (slope, o(c), decimal = 5)
195+
196+ a = arange(0, c.length * 2, +2, dtype='float32')
197+ c.norm = a * 2
198+ assert_almost_equal (slope, o(c), decimal = 5)
199+
200+ def test_decrease(self):
201+ o = specdesc("decrease")
202+ c = cvec()
203+ assert_equal( 0., o(c))
204+ a = arange(c.length * 2, 0, -2, dtype='float32')
205+ k = arange(c.length, dtype='float32')
206+ c.norm = a
207+ decrease = sum((a[1:] - a [0]) / k[1:]) / sum(a[1:])
208+ assert_almost_equal (decrease, o(c), decimal = 5)
209+
210+ a = arange(0, c.length * 2, +2, dtype='float32')
211+ c.norm = a
212+ decrease = sum((a[1:] - a [0]) / k[1:]) / sum(a[1:])
213+ assert_almost_equal (decrease, o(c), decimal = 5)
214+
215+ a = arange(0, c.length * 2, +2, dtype='float32')
216+ c.norm = a * 2
217+ decrease = sum((a[1:] - a [0]) / k[1:]) / sum(a[1:])
218+ assert_almost_equal (decrease, o(c), decimal = 5)
219+
220+ def test_rolloff(self):
221+ o = specdesc("rolloff")
222+ c = cvec()
223+ assert_equal( 0., o(c))
224+ a = arange(c.length * 2, 0, -2, dtype='float32')
225+ k = arange(c.length, dtype='float32')
226+ c.norm = a
227+ cumsum = .95*sum(a*a)
228+ i = 0; rollsum = 0
229+ while rollsum < cumsum:
230+ rollsum += a[i]*a[i]
231+ i+=1
232+ rolloff = i
233+ assert_equal (rolloff, o(c))
234+
235+
236+if __name__ == '__main__':
237+ from unittest import main
238+ main()
python/wscript_build+0−6
@@ -1,6 +0,0 @@
1−# vim:set syntax=python:
2−
3−ctx.add_subdirs('aubio')
4−# install headers
5−for file in ['aubiocut', 'aubiopitch']:
6− ctx.install_as('${PREFIX}/bin/' + file, file, chmod = 0755)

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t