History

Merge branch 'master' into feature/pitchshift

Paul Brossier committed 7 years ago

Commit d0f19a72 parents 34d4232 0045668101 files · +1797 −1448Browse files

Unified · Split

101 files
  1. .appveyor.yml +1 −1
  2. .circleci/config.yml +8 −8
  3. .gitignore +2 −0
  4. .travis.yml +1 −0
  5. MANIFEST.in +1 −3
  6. Makefile +4 −6
  7. doc/py_analysis.rst +15 −0
  8. doc/py_spectral.rst +34 −0
  9. doc/py_synth.rst +9 −0
  10. doc/py_temporal.rst +8 −0
  11. doc/python.rst +4 −0
  12. doc/python_module.rst +8 −7
  13. examples/aubiomfcc.c +1 −1
  14. examples/aubionotes.c +1 −1
  15. examples/aubioonset.c +1 −1
  16. examples/aubiopitch.c +1 −1
  17. examples/aubioquiet.c +1 −1
  18. examples/aubiotrack.c +1 −1
  19. nose2.cfg +0 −6
  20. python/README.md +1 −1
  21. python/ext/aubio-docstrings.h +143 −0
  22. python/ext/aubio-types.h +1 −0
  23. python/ext/aubiomodule.c +2 −2
  24. python/ext/py-cvec.c +1 −1
  25. python/ext/py-fft.c +19 −1
  26. python/ext/py-filter.c +55 −4
  27. python/ext/py-filterbank.c +209 −9
  28. python/ext/py-musicutils.c +10 −10
  29. python/lib/gen_code.py +13 −3
  30. python/tests/__init__.py +0 −1
  31. python/tests/_tools.py +41 −0
  32. python/tests/run_all_tests +0 −5
  33. python/tests/test_aubio.py +1 −2
  34. python/tests/test_aubio_cmd.py +2 −2
  35. python/tests/test_aubio_cut.py +1 −1
  36. python/tests/test_cvec.py +1 −1
  37. python/tests/test_dct.py +4 −0
  38. python/tests/test_fft.py +1 −1
  39. python/tests/test_filter.py +2 −2
  40. python/tests/test_filterbank.py +3 −3
  41. python/tests/test_filterbank_mel.py +14 −15
  42. python/tests/test_fvec.py +1 −1
  43. python/tests/test_fvec_shift.py +1 −1
  44. python/tests/test_hztomel.py +11 −8
  45. python/tests/test_mathutils.py +1 −1
  46. python/tests/test_mfcc.py +17 −21
  47. python/tests/test_midi2note.py +11 −12
  48. python/tests/test_musicutils.py +2 −2
  49. python/tests/test_note2midi.py +24 −19
  50. python/tests/test_notes.py +6 −7
  51. python/tests/test_onset.py +1 −1
  52. python/tests/test_phasevoc.py +13 −8
  53. python/tests/test_pitch.py +5 −5
  54. python/tests/test_sink.py +16 −22
  55. python/tests/test_slicing.py +3 −3
  56. python/tests/test_source.py +56 −53
  57. python/tests/test_source_channels.py +1 −1
  58. python/tests/test_specdesc.py +1 −1
  59. python/tests/test_zero_crossing_rate.py +1 −1
  60. python/tests/utils.py +6 −12
  61. requirements.txt +1 −1
  62. scripts/get_waf.sh +1 −1
  63. setup.py +0 −4
  64. src/aubio_priv.h +7 −0
  65. src/io/ioutils.c +36 −0
  66. src/io/ioutils.h +27 −0
  67. src/io/sink.c +4 −4
  68. src/io/sink_apple_audio.c +62 −42
  69. src/io/sink_sndfile.c +27 −39
  70. src/io/sink_wavwrite.c +24 −29
  71. src/io/source.c +4 −3
  72. src/io/source.h +0 −1
  73. src/io/source_apple_audio.c +30 −45
  74. src/io/source_avcodec.c +10 −2
  75. src/io/source_sndfile.c +1 −2
  76. src/io/source_wavread.c +1 −2
  77. src/io/utils_apple_audio.c +4 −3
  78. tests/src/io/base-sink_custom.h +167 −0
  79. tests/src/io/base-source_custom.h +125 −0
  80. tests/src/io/test-sink-multi.c +0 −72
  81. tests/src/io/test-sink.c +121 −28
  82. tests/src/io/test-sink_apple_audio-multi.c +0 −78
  83. tests/src/io/test-sink_apple_audio.c +19 −57
  84. tests/src/io/test-sink_sndfile-multi.c +0 −78
  85. tests/src/io/test-sink_sndfile.c +19 −57
  86. tests/src/io/test-sink_wavwrite-multi.c +0 −78
  87. tests/src/io/test-sink_wavwrite.c +19 −57
  88. tests/src/io/test-source.c +58 −8
  89. tests/src/io/test-source_apple_audio.c +20 −53
  90. tests/src/io/test-source_avcodec.c +20 −53
  91. tests/src/io/test-source_multi.c +0 −57
  92. tests/src/io/test-source_seek.c +0 −92
  93. tests/src/io/test-source_sndfile.c +20 −53
  94. tests/src/io/test-source_wavread.c +20 −53
  95. tests/src/onset/test-onset.c +9 −12
  96. tests/src/spectral/test-mfcc.c +80 −21
  97. tests/src/tempo/test-tempo.c +7 −14
  98. tests/src/temporal/test-filter.c +7 −12
  99. tests/src/test-delnull.c +0 −24
  100. tests/utils_tests.h +11 −12
  101. wscript +34 −21
.appveyor.yml+1−1
@@ -75,4 +75,4 @@ build_script: · 74 unmodified lines
7575
7676 test_script:
7777 - "python python\\demos\\demo_create_test_sounds.py"
78− - "nose2 --verbose"
78+ - "pytest --verbose"
.circleci/config.yml+8−8
@@ -19,16 +19,16 @@ install-wheel: &install-wheel · 18 unmodified lines
1919 command: |
2020 pip install --user dist/aubio*.whl
2121
22−test-nose2: &test-nose2
22+test-pytest: &test-pytest
2323 name: Test python wheel
2424 command: |
2525 make create_test_sounds
26− PATH=/home/circleci/.local/bin:$PATH nose2 -v
26+ PATH=/home/circleci/.local/bin:$PATH pytest -v
2727
28−test-nose2-nosounds: &test-nose2-nosounds
28+test-pytest-nosounds: &test-pytest-nosounds
2929 name: Test python wheel
3030 command: |
31− PATH=/home/circleci/.local/bin:$PATH nose2 -v
31+ PATH=/home/circleci/.local/bin:$PATH pytest -v
3232
3333 uninstall-wheel: &uninstall-wheel
3434 name: Uninstall python wheel
@@ -47,7 +47,7 @@ jobs: · 12 unmodified lines
4747 - run: *pip-install
4848 - run: *build-wheel
4949 - run: *install-wheel
50− - run: *test-nose2
50+ - run: *test-pytest
5151 - run: *uninstall-wheel
5252 - store_artifacts:
5353 path: dist/
@@ -61,7 +61,7 @@ jobs: · 7 unmodified lines
6161 - run: *pip-install
6262 - run: *build-wheel
6363 - run: *install-wheel
64− - run: *test-nose2
64+ - run: *test-pytest
6565 - run: *uninstall-wheel
6666 - store_artifacts:
6767 path: dist/
@@ -75,7 +75,7 @@ jobs: · 7 unmodified lines
7575 - run: *pip-install
7676 - run: *build-wheel
7777 - run: *install-wheel
78− - run: *test-nose2
78+ - run: *test-pytest
7979 - run: *uninstall-wheel
8080 - store_artifacts:
8181 path: dist/
@@ -88,7 +88,7 @@ jobs: · 6 unmodified lines
8888 - run: *pip-install
8989 - run: *build-wheel
9090 - run: *install-wheel
91− - run: *test-nose2-nosounds
91+ - run: *test-pytest-nosounds
9292 - run: *uninstall-wheel
9393 - store_artifacts:
9494 path: dist/
.gitignore+2−0
@@ -5,6 +5,8 @@ · 4 unmodified lines
55 # gcov generated files
66 *.gcno
77 *.gcda
8+python/lib/aubio/_aubio.*.so
9+.coverage
810
911 # ignore compiled examples
1012 RE:examples/[a-z]*
.travis.yml+1−0
@@ -88,6 +88,7 @@ install: · 87 unmodified lines
8888 - travis_retry make getwaf expandwaf deps_python
8989 - which pip
9090 - pip --version
91+ - pip install coverage
9192
9293 script:
9394 - make create_test_sounds
MANIFEST.in+1−3
@@ -6,16 +6,14 @@ include waf · 5 unmodified lines
66 recursive-include waflib *.py
77 include Makefile wscript */wscript_build
88 include aubio.pc.in
9−include nose2.cfg
109 include requirements.txt
1110 include src/*.c src/*.h
1211 include src/*/*.c src/*/*.h
1312 include examples/*.c examples/*.h
14−include tests/*.h tests/*/*.c tests/*/*/*.c
13+recursive-include tests *.h *.c *.py
1514 include python/ext/*.h
1615 recursive-include python *.py
1716 include python/README.md
18−include python/tests/run_all_tests
1917 include python/tests/eval_pitch
2018 include python/tests/*.expected
2119 include doc/*.txt doc/*.rst doc/*.cfg doc/Makefile doc/make.bat doc/conf.py
Makefile+4−6
@@ -35,8 +35,8 @@ INCLUDEDIR?=$(PREFIX)/include · 34 unmodified lines
3535 DATAROOTDIR?=$(PREFIX)/share
3636 MANDIR?=$(DATAROOTDIR)/man
3737
38−# default nose2 command
39−NOSE2?=nose2 -N 4 --verbose
38+# default python test command
39+PYTEST?=pytest --verbose
4040
4141 SOX=sox
4242
@@ -140,9 +140,7 @@ test_python: export LD_LIBRARY_PATH=$(DESTDIR)/$(LIBDIR) · 97 unmodified lines
140140 test_python: export PYTHONPATH=$(PYDESTDIR)/$(LIBDIR)
141141 test_python: local_dylib
142142 # run test with installed package
143− # ./python/tests/run_all_tests --verbose
144− # run with nose2, multiple processes
145− $(NOSE2)
143+ $(PYTEST)
146144
147145 clean_python:
148146 ./setup.py clean
@@ -253,7 +251,7 @@ coverage: force_uninstall_python deps_python \ · 104 unmodified lines
253251 # build and test python
254252 pip install -v -e .
255253 # run tests, with python coverage
256− coverage run `which nose2`
254+ coverage run `which pytest`
257255 # capture coverage again
258256 lcov $(LCOVOPTS) --capture --no-external --directory . \
259257 --output-file build/coverage_python.info
doc/py_analysis.rst+15−0
@@ -0,0 +1,15 @@
1+.. currentmodule:: aubio
2+.. default-domain:: py
3+
4+Analysis
5+--------
6+
7+.. members of generated classes are not shown
8+
9+.. autoclass:: onset
10+
11+.. autoclass:: pitch
12+
13+.. autoclass:: tempo
14+
15+.. autoclass:: notes
doc/py_spectral.rst+34−0
@@ -0,0 +1,34 @@
1+.. currentmodule:: aubio
2+.. default-domain:: py
3+
4+.. members of generated classes are not yet documented
5+
6+Spectral features
7+-----------------
8+
9+This section contains the documentation for:
10+
11+- :class:`dct`
12+- :class:`fft`
13+- :class:`filterbank`
14+- :class:`mfcc`
15+- :class:`pvoc`
16+- :class:`specdesc`
17+- :class:`tss`
18+
19+.. autoclass:: dct
20+
21+.. autoclass:: fft
22+ :members:
23+
24+.. autoclass:: filterbank
25+ :members:
26+
27+.. autoclass:: mfcc
28+
29+.. autoclass:: pvoc
30+ :members:
31+
32+.. autoclass:: specdesc
33+
34+.. autoclass:: tss
doc/py_synth.rst+9−0
@@ -0,0 +1,9 @@
1+.. currentmodule:: aubio
2+.. default-domain:: py
3+
4+Synthesis
5+---------
6+
7+.. autoclass:: sampler
8+
9+.. autoclass:: wavetable
doc/py_temporal.rst+8−0
@@ -0,0 +1,8 @@
1+.. currentmodule:: aubio
2+.. default-domain:: py
3+
4+Digital filters
5+---------------
6+
7+.. autoclass:: digital_filter
8+ :members:
doc/python.rst+4−0
@@ -30,6 +30,10 @@ Contents · 29 unmodified lines
3030
3131 py_datatypes
3232 py_io
33+ py_temporal
34+ py_spectral
35+ py_analysis
36+ py_synth
3337 py_utils
3438 py_examples
3539
doc/python_module.rst+8−7
@@ -89,14 +89,15 @@ The command line `aubio` is also installed: · 88 unmodified lines
8989 Python tests
9090 ------------
9191
92−A number of Python tests are provided in the `python tests`_. To run them,
93−install `nose2`_ and run the script ``python/tests/run_all_tests``:
92+A number of Python tests are provided in the `python/tests`_ folder. To run
93+them, install `pytest`_ and run it from the aubio source directory:
9494
9595 .. code-block:: console
9696
97− $ pip install nose2
98− $ ./python/tests/run_all_tests
97+ $ pip install pytest
98+ $ git clone https://git.aubio.org/aubio/aubio
99+ $ cd aubio
100+ $ pytest
99101
100−.. _demo_filter.py: https://github.com/aubio/aubio/blob/master/python/demos/demo_filter.py
101−.. _python tests: https://github.com/aubio/aubio/blob/master/python/tests
102−.. _nose2: https://github.com/nose-devs/nose2
102+.. _python/tests: https://github.com/aubio/aubio/blob/master/python/tests
103+.. _pytest: https://pytest.org
examples/aubiomfcc.c+1−1
@@ -68,7 +68,7 @@ int main(int argc, char **argv) { · 67 unmodified lines
6868 goto beach;
6969 }
7070
71− examples_common_process((aubio_process_func_t)process_block, process_print);
71+ examples_common_process(process_block, process_print);
7272
7373 del_aubio_pvoc (pv);
7474 del_cvec (fftgrain);
examples/aubionotes.c+1−1
@@ -90,7 +90,7 @@ int main(int argc, char **argv) { · 89 unmodified lines
9090 }
9191 }
9292
93− examples_common_process((aubio_process_func_t)process_block, process_print);
93+ examples_common_process(process_block, process_print);
9494
9595 // send a last note off if required
9696 if (lastmidi) {
examples/aubioonset.c+1−1
@@ -86,7 +86,7 @@ int main(int argc, char **argv) { · 85 unmodified lines
8686 aubio_wavetable_set_freq ( wavetable, 2450.);
8787 //aubio_sampler_load (sampler, "/archives/sounds/woodblock.aiff");
8888
89− examples_common_process((aubio_process_func_t)process_block, process_print);
89+ examples_common_process(process_block, process_print);
9090
9191 // send a last note off
9292 if (usejack) {
examples/aubiopitch.c+1−1
@@ -79,7 +79,7 @@ int main(int argc, char **argv) { · 78 unmodified lines
7979 wavetable = new_aubio_wavetable (samplerate, hop_size);
8080 aubio_wavetable_play ( wavetable );
8181
82− examples_common_process((aubio_process_func_t)process_block,process_print);
82+ examples_common_process(process_block, process_print);
8383
8484 del_aubio_pitch (o);
8585 del_aubio_wavetable (wavetable);
examples/aubioquiet.c+1−1
@@ -55,7 +55,7 @@ int main(int argc, char **argv) { · 54 unmodified lines
5555 verbmsg ("using source: %s at %dHz\n", source_uri, samplerate);
5656 verbmsg ("buffer_size: %d, ", buffer_size);
5757 verbmsg ("hop_size: %d\n", hop_size);
58− examples_common_process((aubio_process_func_t)process_block,process_print);
58+ examples_common_process(process_block, process_print);
5959 examples_common_del();
6060 return 0;
6161 }
examples/aubiotrack.c+1−1
@@ -87,7 +87,7 @@ int main(int argc, char **argv) { · 86 unmodified lines
8787 aubio_wavetable_set_freq ( wavetable, 2450.);
8888 //aubio_sampler_load (sampler, "/archives/sounds/woodblock.aiff");
8989
90− examples_common_process((aubio_process_func_t)process_block,process_print);
90+ examples_common_process(process_block, process_print);
9191
9292 // send a last note off
9393 if (usejack) {
nose2.cfg+0−6
@@ -1,6 +0,0 @@
1−[unittest]
2−start-dir = python/tests/
3−plugins = nose2.plugins.mp
4−
5−[multiprocess]
6−always-on = false
python/README.md+1−1
@@ -27,7 +27,7 @@ Links · 26 unmodified lines
2727 Demos
2828 -----
2929
30−Some examples are available in the [`python/demos`][demos_dir] folder. Each
30+Some examples are available in the [`python/demos` folder][demos_dir]. Each
3131 script is a command line program which accepts one ore more argument.
3232
3333 **Notes**: installing additional modules is required to run some of the demos.
python/ext/aubio-docstrings.h+143−0
@@ -0,0 +1,143 @@
1+#define PYAUBIO_dct_doc \
2+ "dct(size=1024)\n"\
3+ "\n"\
4+ "Compute Discrete Fourier Transorms of Type-II.\n"\
5+ "\n"\
6+ "Parameters\n"\
7+ "----------\n"\
8+ "size : int\n"\
9+ " size of the DCT to compute\n"\
10+ "\n"\
11+ "Example\n"\
12+ "-------\n"\
13+ ">>> d = aubio.dct(16)\n"\
14+ ">>> d.size\n"\
15+ "16\n"\
16+ ">>> x = aubio.fvec(np.ones(d.size))\n"\
17+ ">>> d(x)\n"\
18+ "array([4., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],\n"\
19+ " dtype=float32)\n"\
20+ ">>> d.rdo(d(x))\n"\
21+ "array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],\n"\
22+ " dtype=float32)\n"\
23+ "\n"\
24+ "References\n"\
25+ "----------\n"\
26+ "`DCT-II in Discrete Cosine Transform\n"\
27+ "<https://en.wikipedia.org/wiki/Discrete_cosine_transform#DCT-II>`_\n"\
28+ "on Wikipedia.\n"
29+
30+#define PYAUBIO_mfcc_doc \
31+ "mfcc(buf_size=1024, n_filters=40, n_coeffs=13, samplerate=44100)\n"\
32+ "\n"\
33+ "Compute Mel Frequency Cepstrum Coefficients (MFCC).\n"\
34+ "\n"\
35+ "`mfcc` creates a callable which takes a `cvec` as input.\n"\
36+ "\n"\
37+ "If `n_filters = 40`, the filterbank will be initialized with\n"\
38+ ":meth:`filterbank.set_mel_coeffs_slaney`. Otherwise, if `n_filters`\n"\
39+ "is greater than `0`, it will be initialized with\n"\
40+ ":meth:`filterbank.set_mel_coeffs` using `fmin = 0`,\n"\
41+ "`fmax = samplerate/`.\n"\
42+ "\n"\
43+ "Example\n"\
44+ "-------\n"\
45+ ">>> buf_size = 2048; n_filters = 128; n_coeffs = 13; samplerate = 44100\n"\
46+ ">>> mf = aubio.mfcc(buf_size, n_filters, n_coeffs, samplerate)\n"\
47+ ">>> fftgrain = aubio.cvec(buf_size)\n"\
48+ ">>> mf(fftgrain).shape\n"\
49+ "(13,)\n"\
50+ ""
51+
52+#define PYAUBIO_notes_doc \
53+ "notes(method=\"default\", buf_size=1024, hop_size=512, samplerate=44100)\n"\
54+ "\n"\
55+ "Note detection\n"
56+
57+#define PYAUBIO_onset_doc \
58+ "onset(method=\"default\", buf_size=1024, hop_size=512, samplerate=44100)\n"\
59+ "\n"\
60+ "Onset detection object. `method` should be one of method supported by\n"\
61+ ":class:`specdesc`.\n"
62+
63+#define PYAUBIO_pitch_doc \
64+ "pitch(method=\"default\", buf_size=1024, hop_size=512, samplerate=44100)\n"\
65+ "\n"\
66+ "Pitch detection.\n"\
67+ "\n"\
68+ "Supported methods: `yinfft`, `yin`, `yinfast`, `fcomb`, `mcomb`,\n"\
69+ "`schmitt`, `specacf`, `default` (`yinfft`).\n"
70+
71+#define PYAUBIO_sampler_doc \
72+ "sampler(hop_size=512, samplerate=44100)\n"\
73+ "\n"\
74+ "Sampler.\n"
75+
76+#define PYAUBIO_specdesc_doc \
77+ "specdesc(method=\"default\", buf_size=1024)\n"\
78+ "\n"\
79+ "Spectral description functions. Creates a callable that takes a\n"\
80+ ":class:`cvec` as input, typically created by :class:`pvoc` for\n"\
81+ "overlap and windowing, and returns a single float.\n"\
82+ "\n"\
83+ "`method` can be any of the values listed below. If `default` is used\n"\
84+ "the `hfc` function will be selected.\n"\
85+ "\n"\
86+ "Onset novelty functions:\n"\
87+ "\n"\
88+ "- `energy`: local energy,\n"\
89+ "- `hfc`: high frequency content,\n"\
90+ "- `complex`: complex domain,\n"\
91+ "- `phase`: phase-based method,\n"\
92+ "- `wphase`: weighted phase deviation,\n"\
93+ "- `specdiff`: spectral difference,\n"\
94+ "- `kl`: Kullback-Liebler,\n"\
95+ "- `mkl`: modified Kullback-Liebler,\n"\
96+ "- `specflux`: spectral flux.\n"\
97+ "\n"\
98+ "Spectral shape functions:\n"\
99+ "\n"\
100+ "- `centroid`: spectral centroid (barycenter of the norm vector),\n"\
101+ "- `spread`: variance around centroid,\n"\
102+ "- `skewness`: third order moment,\n"\
103+ "- `kurtosis`: a measure of the flatness of the spectrum,\n"\
104+ "- `slope`: decreasing rate of the amplitude,\n"\
105+ "- `decrease`: perceptual based measurement of the decreasing rate,\n"\
106+ "- `rolloff`: 95th energy percentile.\n"\
107+ "\n"\
108+ "Parameters\n"\
109+ "----------\n"\
110+ "method : str\n"\
111+ " Onset novelty or spectral shape function.\n"\
112+ "buf_size : int\n"\
113+ " Length of the input frame.\n"\
114+ "\n"\
115+ "Example\n"\
116+ "-------\n"\
117+ ">>> win_s = 1024; hop_s = win_s // 2\n"\
118+ ">>> pv = aubio.pvoc(win_s, hop_s)\n"\
119+ ">>> sd = aubio.specdesc(\"mkl\", win_s)\n"\
120+ ">>> sd(pv(aubio.fvec(hop_s))).shape\n"\
121+ "(1,)\n"\
122+ "\n"\
123+ "References\n"\
124+ "----------\n"\
125+ "`Detailed description "\
126+ "<https://aubio.org/doc/latest/specdesc_8h.html#details>`_ in\n"\
127+ "`aubio API documentation <https://aubio.org/doc/latest/index.html>`_.\n"\
128+ ""
129+
130+#define PYAUBIO_tempo_doc \
131+ "tempo(method=\"default\", buf_size=1024, hop_size=512, samplerate=44100)\n"\
132+ "\n"\
133+ "Tempo detection and beat tracking.\n"
134+
135+#define PYAUBIO_tss_doc \
136+ "tss(buf_size=1024, hop_size=512)\n"\
137+ "\n"\
138+ "Transient/Steady-state separation.\n"
139+
140+#define PYAUBIO_wavetable_doc \
141+ "wavetable(samplerate=44100, hop_size=512)\n"\
142+ "\n"\
143+ "Wavetable synthesis.\n"
python/ext/aubio-types.h+1−0
@@ -1,6 +1,7 @@
11 #include <Python.h>
22 #include <structmember.h>
33
4+#include "aubio-docstrings.h"
45 #include "aubio-generated.h"
56
67 #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
python/ext/aubiomodule.c+2−2
@@ -223,7 +223,7 @@ Py_alpha_norm (PyObject * self, PyObject * args) · 222 unmodified lines
223223 }
224224
225225 // compute the function
226− result = Py_BuildValue (AUBIO_NPY_SMPL_CHR, fvec_alpha_norm (&vec, alpha));
226+ result = PyFloat_FromDouble(fvec_alpha_norm (&vec, alpha));
227227 if (result == NULL) {
228228 return NULL;
229229 }
@@ -319,7 +319,7 @@ Py_zero_crossing_rate (PyObject * self, PyObject * args) · 89 unmodified lines
319319 }
320320
321321 // compute the function
322− result = Py_BuildValue (AUBIO_NPY_SMPL_CHR, aubio_zero_crossing_rate (&vec));
322+ result = PyFloat_FromDouble(aubio_zero_crossing_rate (&vec));
323323 if (result == NULL) {
324324 return NULL;
325325 }
python/ext/py-cvec.c+1−1
@@ -136,7 +136,7 @@ Py_cvec_repr (Py_cvec * self, PyObject * unused) · 135 unmodified lines
136136 goto fail;
137137 }
138138
139− args = Py_BuildValue ("I", self->length);
139+ args = PyLong_FromLong(self->length);
140140 if (args == NULL) {
141141 goto fail;
142142 }
python/ext/py-fft.c+19−1
@@ -1,6 +1,24 @@
11 #include "aubio-types.h"
22
3−static char Py_fft_doc[] = "fft object";
3+static char Py_fft_doc[] = ""
4+"fft(size=1024)\n"
5+"\n"
6+"Compute Fast Fourier Transorms.\n"
7+"\n"
8+"Parameters\n"
9+"----------\n"
10+"size : int\n"
11+" size of the FFT to compute\n"
12+"\n"
13+"Example\n"
14+"-------\n"
15+">>> x = aubio.fvec(512)\n"
16+">>> f = aubio.fft(512)\n"
17+">>> c = f(x); c\n"
18+"aubio cvec of 257 elements\n"
19+">>> x2 = f.rdo(c); x2.shape\n"
20+"(512,)\n"
21+"";
422
523 typedef struct
624 {
python/ext/py-filter.c+55−4
@@ -10,7 +10,58 @@ typedef struct · 9 unmodified lines
1010 fvec_t c_out;
1111 } Py_filter;
1212
13−static char Py_filter_doc[] = "filter object";
13+static char Py_filter_doc[] = ""
14+"digital_filter(order=7)\n"
15+"\n"
16+"Create a digital filter.\n"
17+"";
18+
19+static char Py_filter_set_c_weighting_doc[] = ""
20+"set_c_weighting(samplerate)\n"
21+"\n"
22+"Set filter coefficients to C-weighting.\n"
23+"\n"
24+"`samplerate` should be one of 8000, 11025, 16000, 22050, 24000, 32000,\n"
25+"44100, 48000, 88200, 96000, or 192000. `order` of the filter should be 5.\n"
26+"\n"
27+"Parameters\n"
28+"----------\n"
29+"samplerate : int\n"
30+" Sampling-rate of the input signal, in Hz.\n"
31+"";
32+
33+static char Py_filter_set_a_weighting_doc[] = ""
34+"set_a_weighting(samplerate)\n"
35+"\n"
36+"Set filter coefficients to A-weighting.\n"
37+"\n"
38+"`samplerate` should be one of 8000, 11025, 16000, 22050, 24000, 32000,\n"
39+"44100, 48000, 88200, 96000, or 192000. `order` of the filter should be 7.\n"
40+"\n"
41+"Parameters\n"
42+"----------\n"
43+"samplerate : int\n"
44+" Sampling-rate of the input signal.\n"
45+"";
46+
47+static char Py_filter_set_biquad_doc[] = ""
48+"set_biquad(b0, b1, b2, a1, a2)\n"
49+"\n"
50+"Set biquad coefficients. `order` of the filter should be 3.\n"
51+"\n"
52+"Parameters\n"
53+"----------\n"
54+"b0 : float\n"
55+" Forward filter coefficient.\n"
56+"b1 : float\n"
57+" Forward filter coefficient.\n"
58+"b2 : float\n"
59+" Forward filter coefficient.\n"
60+"a1 : float\n"
61+" Feedback filter coefficient.\n"
62+"a2 : float\n"
63+" Feedback filter coefficient.\n"
64+"";
1465
1566 static PyObject *
1667 Py_filter_new (PyTypeObject * type, PyObject * args, PyObject * kwds)
@@ -156,11 +207,11 @@ static PyMemberDef Py_filter_members[] = { · 139 unmodified lines
156207
157208 static PyMethodDef Py_filter_methods[] = {
158209 {"set_c_weighting", (PyCFunction) Py_filter_set_c_weighting, METH_VARARGS,
159− "set filter coefficients to C-weighting"},
210+ Py_filter_set_c_weighting_doc},
160211 {"set_a_weighting", (PyCFunction) Py_filter_set_a_weighting, METH_VARARGS,
161− "set filter coefficients to A-weighting"},
212+ Py_filter_set_a_weighting_doc},
162213 {"set_biquad", (PyCFunction) Py_filter_set_biquad, METH_VARARGS,
163− "set b0, b1, b2, a1, a2 biquad coefficients"},
214+ Py_filter_set_biquad_doc},
164215 {NULL}
165216 };
166217
python/ext/py-filterbank.c+209−9
@@ -1,6 +1,188 @@
11 #include "aubio-types.h"
22
3−static char Py_filterbank_doc[] = "filterbank object";
3+static char Py_filterbank_doc[] = ""
4+"filterbank(n_filters=40, win_s=1024)\n"
5+"\n"
6+"Create a bank of spectral filters. Each instance is a callable\n"
7+"that holds a matrix of coefficients.\n"
8+"\n"
9+"See also :meth:`set_mel_coeffs`, :meth:`set_mel_coeffs_htk`,\n"
10+":meth:`set_mel_coeffs_slaney`, :meth:`set_triangle_bands`, and\n"
11+":meth:`set_coeffs`.\n"
12+"\n"
13+"Parameters\n"
14+"----------\n"
15+"n_filters : int\n"
16+" Number of filters to create.\n"
17+"win_s : int\n"
18+" Size of the input spectrum to process.\n"
19+"\n"
20+"Examples\n"
21+"--------\n"
22+">>> f = aubio.filterbank(128, 1024)\n"
23+">>> f.set_mel_coeffs(44100, 0, 10000)\n"
24+">>> c = aubio.cvec(1024)\n"
25+">>> f(c).shape\n"
26+"(128, )\n"
27+"";
28+
29+static char Py_filterbank_set_triangle_bands_doc[] =""
30+"set_triangle_bands(freqs, samplerate)\n"
31+"\n"
32+"Set triangular bands. The coefficients will be set to triangular\n"
33+"overlapping windows using the boundaries specified by `freqs`.\n"
34+"\n"
35+"`freqs` should contain `n_filters + 2` frequencies in Hz, ordered\n"
36+"by value, from smallest to largest. The first element should be greater\n"
37+"or equal to zero; the last element should be smaller or equal to\n"
38+"`samplerate / 2`.\n"
39+"\n"
40+"Parameters\n"
41+"----------\n"
42+"freqs: fvec\n"
43+" List of frequencies, in Hz.\n"
44+"samplerate : float\n"
45+" Sampling-rate of the expected input.\n"
46+"\n"
47+"Example\n"
48+"-------\n"
49+">>> fb = aubio.filterbank(n_filters=100, win_s=2048)\n"
50+">>> samplerate = 44100; freqs = np.linspace(0, 20200, 102)\n"
51+">>> fb.set_triangle_bands(aubio.fvec(freqs), samplerate)\n"
52+"";
53+
54+static char Py_filterbank_set_mel_coeffs_slaney_doc[] = ""
55+"set_mel_coeffs_slaney(samplerate)\n"
56+"\n"
57+"Set coefficients of filterbank to match Slaney's Auditory Toolbox.\n"
58+"\n"
59+"The filter coefficients will be set as in Malcolm Slaney's\n"
60+"implementation. The filterbank should have been created with\n"
61+"`n_filters = 40`.\n"
62+"\n"
63+"This is approximately equivalent to using :meth:`set_mel_coeffs` with\n"
64+"`fmin = 400./3., fmax = 6853.84`.\n"
65+"\n"
66+"Parameters\n"
67+"----------\n"
68+"samplerate : float\n"
69+" Sampling-rate of the expected input.\n"
70+"\n"
71+"References\n"
72+"----------\n"
73+"\n"
74+"Malcolm Slaney, `Auditory Toolbox Version 2, Technical Report #1998-010\n"
75+"<https://engineering.purdue.edu/~malcolm/interval/1998-010/>`_\n"
76+"";
77+
78+static char Py_filterbank_set_mel_coeffs_doc[] = ""
79+"set_mel_coeffs(samplerate, fmin, fmax)\n"
80+"\n"
81+"Set coefficients of filterbank to linearly spaced mel scale.\n"
82+"\n"
83+"Parameters\n"
84+"----------\n"
85+"samplerate : float\n"
86+" Sampling-rate of the expected input.\n"
87+"fmin : float\n"
88+" Lower frequency boundary of the first filter.\n"
89+"fmax : float\n"
90+" Upper frequency boundary of the last filter.\n"
91+"\n"
92+"See also\n"
93+"--------\n"
94+"hztomel\n"
95+"";
96+
97+static char Py_filterbank_set_mel_coeffs_htk_doc[] = ""
98+"set_mel_coeffs_htk(samplerate, fmin, fmax)\n"
99+"\n"
100+"Set coefficients of the filters to be linearly spaced in the HTK mel scale.\n"
101+"\n"
102+"Parameters\n"
103+"----------\n"
104+"samplerate : float\n"
105+" Sampling-rate of the expected input.\n"
106+"fmin : float\n"
107+" Lower frequency boundary of the first filter.\n"
108+"fmax : float\n"
109+" Upper frequency boundary of the last filter.\n"
110+"\n"
111+"See also\n"
112+"--------\n"
113+"hztomel with `htk=True`\n"
114+"";
115+
116+static char Py_filterbank_get_coeffs_doc[] = ""
117+"get_coeffs()\n"
118+"\n"
119+"Get coefficients matrix of filterbank.\n"
120+"\n"
121+"Returns\n"
122+"-------\n"
123+"array_like\n"
124+" Array of shape (n_filters, win_s/2+1) containing the coefficients.\n"
125+"";
126+
127+static char Py_filterbank_set_coeffs_doc[] = ""
128+"set_coeffs(coeffs)\n"
129+"\n"
130+"Set coefficients of filterbank.\n"
131+"\n"
132+"Parameters\n"
133+"----------\n"
134+"coeffs : fmat\n"
135+" Array of shape (n_filters, win_s/2+1) containing the coefficients.\n"
136+"";
137+
138+static char Py_filterbank_set_power_doc[] = ""
139+"set_power(power)\n"
140+"\n"
141+"Set power applied to input spectrum of filterbank.\n"
142+"\n"
143+"Parameters\n"
144+"----------\n"
145+"power : float\n"
146+" Power to raise input spectrum to before computing the filters.\n"
147+"";
148+
149+static char Py_filterbank_get_power_doc[] = ""
150+"get_power()\n"
151+"\n"
152+"Get power applied to filterbank.\n"
153+"\n"
154+"Returns\n"
155+"-------\n"
156+"float\n"
157+" Power parameter.\n"
158+"";
159+
160+static char Py_filterbank_set_norm_doc[] = ""
161+"set_norm(norm)\n"
162+"\n"
163+"Set norm parameter. If set to `0`, the filters will not be normalized.\n"
164+"If set to `1`, the filters will be normalized to one. Default to `1`.\n"
165+"\n"
166+"This function should be called *before* :meth:`set_triangle_bands`,\n"
167+":meth:`set_mel_coeffs`, :meth:`set_mel_coeffs_htk`, or\n"
168+":meth:`set_mel_coeffs_slaney`.\n"
169+"\n"
170+"Parameters\n"
171+"----------\n"
172+"norm : int\n"
173+" `0` to disable, `1` to enable\n"
174+"";
175+
176+static char Py_filterbank_get_norm_doc[] = ""
177+"get_norm()\n"
178+"\n"
179+"Get norm parameter of filterbank.\n"
180+"\n"
181+"Returns\n"
182+"-------\n"
183+"float\n"
184+" Norm parameter.\n"
185+"";
4186
5187 typedef struct
6188 {
@@ -288,6 +470,13 @@ Py_filterbank_set_power(Py_filterbank *self, PyObject *args) · 281 unmodified lines
288470 Py_RETURN_NONE;
289471 }
290472
473+static PyObject *
474+Py_filterbank_get_power (Py_filterbank * self, PyObject *unused)
475+{
476+ smpl_t power = aubio_filterbank_get_power(self->o);
477+ return (PyObject *)PyFloat_FromDouble (power);
478+}
479+
291480 static PyObject *
292481 Py_filterbank_set_norm(Py_filterbank *self, PyObject *args)
293482 {
@@ -311,23 +500,34 @@ Py_filterbank_set_norm(Py_filterbank *self, PyObject *args) · 17 unmodified lines
311500 Py_RETURN_NONE;
312501 }
313502
503+static PyObject *
504+Py_filterbank_get_norm (Py_filterbank * self, PyObject *unused)
505+{
506+ smpl_t norm = aubio_filterbank_get_norm(self->o);
507+ return (PyObject *)PyFloat_FromDouble (norm);
508+}
509+
314510 static PyMethodDef Py_filterbank_methods[] = {
315511 {"set_triangle_bands", (PyCFunction) Py_filterbank_set_triangle_bands,
316− METH_VARARGS, "set coefficients of filterbanks"},
512+ METH_VARARGS, Py_filterbank_set_triangle_bands_doc},
317513 {"set_mel_coeffs_slaney", (PyCFunction) Py_filterbank_set_mel_coeffs_slaney,
318− METH_VARARGS, "set coefficients of filterbank as in Auditory Toolbox"},
514+ METH_VARARGS, Py_filterbank_set_mel_coeffs_slaney_doc},
319515 {"set_mel_coeffs", (PyCFunction) Py_filterbank_set_mel_coeffs,
320− METH_VARARGS, "set coefficients of filterbank to linearly spaced mel scale"},
516+ METH_VARARGS, Py_filterbank_set_mel_coeffs_doc},
321517 {"set_mel_coeffs_htk", (PyCFunction) Py_filterbank_set_mel_coeffs_htk,
322− METH_VARARGS, "set coefficients of filterbank to linearly spaced mel scale"},
518+ METH_VARARGS, Py_filterbank_set_mel_coeffs_htk_doc},
323519 {"get_coeffs", (PyCFunction) Py_filterbank_get_coeffs,
324− METH_NOARGS, "get coefficients of filterbank"},
520+ METH_NOARGS, Py_filterbank_get_coeffs_doc},
325521 {"set_coeffs", (PyCFunction) Py_filterbank_set_coeffs,
326− METH_VARARGS, "set coefficients of filterbank"},
522+ METH_VARARGS, Py_filterbank_set_coeffs_doc},
327523 {"set_power", (PyCFunction) Py_filterbank_set_power,
328− METH_VARARGS, "set power applied to filterbank input spectrum"},
524+ METH_VARARGS, Py_filterbank_set_power_doc},
525+ {"get_power", (PyCFunction) Py_filterbank_get_power,
526+ METH_NOARGS, Py_filterbank_get_power_doc},
329527 {"set_norm", (PyCFunction) Py_filterbank_set_norm,
330− METH_VARARGS, "set norm applied to filterbank input spectrum"},
528+ METH_VARARGS, Py_filterbank_set_norm_doc},
529+ {"get_norm", (PyCFunction) Py_filterbank_get_norm,
530+ METH_NOARGS, Py_filterbank_get_norm_doc},
331531 {NULL}
332532 };
333533
python/ext/py-musicutils.c+10−10
@@ -39,7 +39,7 @@ Py_aubio_level_lin(PyObject *self, PyObject *args) · 38 unmodified lines
3939 return NULL;
4040 }
4141
42− level_lin = Py_BuildValue(AUBIO_NPY_SMPL_CHR, aubio_level_lin(&vec));
42+ level_lin = PyFloat_FromDouble(aubio_level_lin(&vec));
4343 if (level_lin == NULL) {
4444 PyErr_SetString (PyExc_ValueError, "failed computing level_lin");
4545 return NULL;
@@ -67,7 +67,7 @@ Py_aubio_db_spl(PyObject *self, PyObject *args) · 21 unmodified lines
6767 return NULL;
6868 }
6969
70− db_spl = Py_BuildValue(AUBIO_NPY_SMPL_CHR, aubio_db_spl(&vec));
70+ db_spl = PyFloat_FromDouble(aubio_db_spl(&vec));
7171 if (db_spl == NULL) {
7272 PyErr_SetString (PyExc_ValueError, "failed computing db_spl");
7373 return NULL;
@@ -96,7 +96,7 @@ Py_aubio_silence_detection(PyObject *self, PyObject *args) · 22 unmodified lines
9696 return NULL;
9797 }
9898
99− silence_detection = Py_BuildValue("I", aubio_silence_detection(&vec, threshold));
99+ silence_detection = PyLong_FromLong(aubio_silence_detection(&vec, threshold));
100100 if (silence_detection == NULL) {
101101 PyErr_SetString (PyExc_ValueError, "failed computing silence_detection");
102102 return NULL;
@@ -125,7 +125,7 @@ Py_aubio_level_detection(PyObject *self, PyObject *args) · 22 unmodified lines
125125 return NULL;
126126 }
127127
128− level_detection = Py_BuildValue(AUBIO_NPY_SMPL_CHR, aubio_level_detection(&vec, threshold));
128+ level_detection = PyFloat_FromDouble(aubio_level_detection(&vec, threshold));
129129 if (level_detection == NULL) {
130130 PyErr_SetString (PyExc_ValueError, "failed computing level_detection");
131131 return NULL;
@@ -194,9 +194,9 @@ Py_aubio_hztomel(PyObject *self, PyObject *args, PyObject *kwds) · 62 unmodified lines
194194 return NULL;
195195 }
196196 if (htk != NULL && PyObject_IsTrue(htk) == 1)
197− return Py_BuildValue(AUBIO_NPY_SMPL_CHR, aubio_hztomel_htk(v));
197+ return PyFloat_FromDouble(aubio_hztomel_htk(v));
198198 else
199− return Py_BuildValue(AUBIO_NPY_SMPL_CHR, aubio_hztomel(v));
199+ return PyFloat_FromDouble(aubio_hztomel(v));
200200 }
201201
202202 PyObject*
@@ -211,9 +211,9 @@ Py_aubio_meltohz(PyObject *self, PyObject *args, PyObject *kwds) · 8 unmodified lines
211211 return NULL;
212212 }
213213 if (htk != NULL && PyObject_IsTrue(htk) == 1)
214− return Py_BuildValue(AUBIO_NPY_SMPL_CHR, aubio_meltohz_htk(v));
214+ return PyFloat_FromDouble(aubio_meltohz_htk(v));
215215 else
216− return Py_BuildValue(AUBIO_NPY_SMPL_CHR, aubio_meltohz(v));
216+ return PyFloat_FromDouble(aubio_meltohz(v));
217217 }
218218
219219 PyObject*
@@ -223,7 +223,7 @@ Py_aubio_hztomel_htk(PyObject *self, PyObject *args) · 3 unmodified lines
223223 if (!PyArg_ParseTuple(args, AUBIO_NPY_SMPL_CHR, &v)) {
224224 return NULL;
225225 }
226− return Py_BuildValue(AUBIO_NPY_SMPL_CHR, aubio_hztomel_htk(v));
226+ return PyFloat_FromDouble(aubio_hztomel_htk(v));
227227 }
228228
229229 PyObject*
@@ -233,5 +233,5 @@ Py_aubio_meltohz_htk(PyObject *self, PyObject *args) · 3 unmodified lines
233233 if (!PyArg_ParseTuple(args, AUBIO_NPY_SMPL_CHR, &v)) {
234234 return NULL;
235235 }
236− return Py_BuildValue(AUBIO_NPY_SMPL_CHR, aubio_meltohz_htk(v));
236+ return PyFloat_FromDouble(aubio_meltohz_htk(v));
237237 }
python/lib/gen_code.py+13−3
@@ -234,11 +234,21 @@ typedef struct{{ · 233 unmodified lines
234234 return out.format(do_inputs_list = do_inputs_list, **self.__dict__)
235235
236236 def gen_doc(self):
237+ sig = []
238+ for p in self.input_params:
239+ name = p['name']
240+ defval = aubiodefvalue[name].replace('"','\\\"')
241+ sig.append("{name}={defval}".format(defval=defval, name=name))
237242 out = """
238−// TODO: add documentation
239−static char Py_{shortname}_doc[] = \"undefined\";
243+#ifndef PYAUBIO_{shortname}_doc
244+#define PYAUBIO_{shortname}_doc "{shortname}({sig})"
245+#endif /* PYAUBIO_{shortname}_doc */
246+
247+static char Py_{shortname}_doc[] = ""
248+PYAUBIO_{shortname}_doc
249+"";
240250 """
241− return out.format(**self.__dict__)
251+ return out.format(sig=', '.join(sig), **self.__dict__)
242252
243253 def gen_new(self):
244254 out = """
python/tests/__init__.py+0−1
@@ -1 +0,0 @@
1−
python/tests/_tools.py+41−0
@@ -0,0 +1,41 @@
1+"""
2+This file imports test methods from different testing modules, in this
3+order:
4+
5+ - try importing 'pytest'
6+ - if it fails, fallback to 'numpy.testing'
7+
8+Nose2 support was removed because of lacking assertWarns on py2.7.
9+
10+"""
11+
12+import sys
13+
14+_has_pytest = False
15+
16+# check if we have pytest
17+try:
18+ import pytest
19+ parametrize = pytest.mark.parametrize
20+ assert_raises = pytest.raises
21+ assert_warns = pytest.warns
22+ skipTest = pytest.skip
23+ _has_pytest = True
24+ def run_module_suite():
25+ import sys, pytest
26+ pytest.main(sys.argv)
27+except:
28+ pass
29+
30+# otherwise fallback on numpy.testing
31+if not _has_pytest:
32+ from numpy.testing import dec, assert_raises, assert_warns
33+ from numpy.testing import SkipTest
34+ parametrize = dec.parametrize
35+ def skipTest(msg):
36+ raise SkipTest(msg)
37+ from numpy.testing import run_module_suite
38+
39+# always use numpy's assert_equal
40+import numpy
41+assert_equal = numpy.testing.assert_equal
python/tests/run_all_tests+0−5
@@ -1,5 +0,0 @@
1−#! /usr/bin/env python
2−
3−if __name__ == '__main__':
4− import nose2.main
5− nose2.discover()
python/tests/test_aubio.py+1−2
@@ -1,6 +1,5 @@
11 #! /usr/bin/env python
22
3−from unittest import main
43 from numpy.testing import TestCase
54
65 class aubiomodule_test_case(TestCase):
@@ -15,5 +14,5 @@ class aubiomodule_test_case(TestCase): · 8 unmodified lines
1514 self.assertEqual('0', aubio.version[0])
1615
1716 if __name__ == '__main__':
17+ from unittest import main
1818 main()
19−
python/tests/test_aubio_cmd.py+2−2
@@ -1,8 +1,7 @@
11 #! /usr/bin/env python
22
3−import aubio.cmd
4−from nose2 import main
53 from numpy.testing import TestCase
4+import aubio.cmd
65
76 class aubio_cmd(TestCase):
87
@@ -31,4 +30,5 @@ class aubio_cmd_utils(TestCase): · 22 unmodified lines
3130 "3200\t")
3231
3332 if __name__ == '__main__':
33+ from unittest import main
3434 main()
python/tests/test_aubio_cut.py+1−1
@@ -1,7 +1,6 @@
11 #! /usr/bin/env python
22
33 import aubio.cut
4−from nose2 import main
54 from numpy.testing import TestCase
65
76 class aubio_cut(TestCase):
@@ -13,4 +12,5 @@ class aubio_cut(TestCase): · 5 unmodified lines
1312 assert self.a_parser.parse_args(['-v']).verbose
1413
1514 if __name__ == '__main__':
15+ from unittest import main
1616 main()
python/tests/test_cvec.py+1−1
@@ -1,6 +1,5 @@
11 #! /usr/bin/env python
22
3−from unittest import main
43 import numpy as np
54 from numpy.testing import TestCase, assert_equal
65 from aubio import cvec, fvec, float_type
@@ -141,4 +140,5 @@ class aubio_cvec_wrong_norm_input(TestCase): · 134 unmodified lines
141140 a.norm = np.zeros((512//2+1, 2), dtype = float_type)
142141
143142 if __name__ == '__main__':
143+ from unittest import main
144144 main()
python/tests/test_dct.py+4−0
@@ -66,3 +66,7 @@ class aubio_dct(TestCase): · 65 unmodified lines
6666 aubio.dct(size)
6767 except AssertionError:
6868 self.skipTest('creating aubio.dct with size %d did not fail' % size)
69+
70+if __name__ == '__main__':
71+ from unittest import main
72+ main()
python/tests/test_fft.py+1−1
@@ -1,6 +1,5 @@
11 #! /usr/bin/env python
22
3−from unittest import main
43 from numpy.testing import TestCase
54 from numpy.testing import assert_equal, assert_almost_equal
65 import numpy as np
@@ -212,4 +211,5 @@ class aubio_fft_wrong_params(TestCase): · 205 unmodified lines
212211 fft(win_s)
213212
214213 if __name__ == '__main__':
214+ from unittest import main
215215 main()
python/tests/test_filter.py+2−2
@@ -1,9 +1,8 @@
11 #! /usr/bin/env python
22
3−from unittest import main
43 from numpy.testing import TestCase, assert_equal, assert_almost_equal
54 from aubio import fvec, digital_filter
6−from .utils import array_from_text_file
5+from utils import array_from_text_file
76
87 class aubio_filter_test_case(TestCase):
98
@@ -94,4 +93,5 @@ class aubio_filter_wrong_params(TestCase): · 84 unmodified lines
9493 digital_filter(-1)
9594
9695 if __name__ == '__main__':
96+ from unittest import main
9797 main()
python/tests/test_filterbank.py+3−3
@@ -4,7 +4,7 @@ import numpy as np · 3 unmodified lines
44 from numpy.testing import TestCase, assert_equal, assert_almost_equal
55
66 from aubio import cvec, filterbank, float_type
7−from .utils import array_from_text_file
7+from utils import array_from_text_file
88
99 class aubio_filterbank_test_case(TestCase):
1010
@@ -87,5 +87,5 @@ class aubio_filterbank_wrong_values(TestCase): · 76 unmodified lines
8787 f(cvec(256))
8888
8989 if __name__ == '__main__':
90− import nose2
91− nose2.main()
90+ from unittest import main
91+ main()
python/tests/test_filterbank_mel.py+14−15
@@ -2,12 +2,10 @@ · 1 unmodified line
22
33 import numpy as np
44 from numpy.testing import TestCase, assert_equal, assert_almost_equal
5+from _tools import assert_warns
56
67 from aubio import fvec, cvec, filterbank, float_type
78
8−import warnings
9−warnings.filterwarnings('ignore', category=UserWarning, append=True)
10−
119 class aubio_filterbank_mel_test_case(TestCase):
1210
1311 def test_slaney(self):
@@ -75,40 +73,41 @@ class aubio_filterbank_mel_test_case(TestCase): · 61 unmodified lines
7573 samplerate = 22050
7674 freq_list = [0, samplerate//4, samplerate // 2 + 1]
7775 f = filterbank(len(freq_list)-2, 1024)
78− # TODO add assert_warns
79− f.set_triangle_bands(fvec(freq_list), samplerate)
76+ with assert_warns(UserWarning):
77+ f.set_triangle_bands(fvec(freq_list), samplerate)
8078
8179 def test_triangle_freqs_with_not_enough_filters(self):
8280 """make sure set_triangle_bands warns when not enough filters"""
8381 samplerate = 22050
8482 freq_list = [0, 100, 1000, 4000, 8000, 10000]
8583 f = filterbank(len(freq_list)-3, 1024)
86− # TODO add assert_warns
87− f.set_triangle_bands(fvec(freq_list), samplerate)
84+ with assert_warns(UserWarning):
85+ f.set_triangle_bands(fvec(freq_list), samplerate)
8886
8987 def test_triangle_freqs_with_too_many_filters(self):
9088 """make sure set_triangle_bands warns when too many filters"""
9189 samplerate = 22050
9290 freq_list = [0, 100, 1000, 4000, 8000, 10000]
9391 f = filterbank(len(freq_list)-1, 1024)
94− # TODO add assert_warns
95− f.set_triangle_bands(fvec(freq_list), samplerate)
92+ with assert_warns(UserWarning):
93+ f.set_triangle_bands(fvec(freq_list), samplerate)
9694
9795 def test_triangle_freqs_with_double_value(self):
9896 """make sure set_triangle_bands works with 2 duplicate freqs"""
9997 samplerate = 22050
10098 freq_list = [0, 100, 1000, 4000, 4000, 4000, 10000]
10199 f = filterbank(len(freq_list)-2, 1024)
102− # TODO add assert_warns
103− f.set_triangle_bands(fvec(freq_list), samplerate)
100+ with assert_warns(UserWarning):
101+ f.set_triangle_bands(fvec(freq_list), samplerate)
104102
105103 def test_triangle_freqs_with_triple(self):
106104 """make sure set_triangle_bands works with 3 duplicate freqs"""
107105 samplerate = 22050
108106 freq_list = [0, 100, 1000, 4000, 4000, 4000, 10000]
109107 f = filterbank(len(freq_list)-2, 1024)
110− # TODO add assert_warns
111− f.set_triangle_bands(fvec(freq_list), samplerate)
108+ with assert_warns(UserWarning):
109+ f.set_triangle_bands(fvec(freq_list), samplerate)
110+
112111
113112 def test_triangle_freqs_without_norm(self):
114113 """make sure set_triangle_bands works without """
@@ -168,5 +167,5 @@ class aubio_filterbank_mel_test_case(TestCase): · 53 unmodified lines
168167
169168
170169 if __name__ == '__main__':
171− import nose2
172− nose2.main()
170+ from unittest import main
171+ main()
python/tests/test_fvec.py+1−1
@@ -1,6 +1,5 @@
11 #! /usr/bin/env python
22
3−from unittest import main
43 import numpy as np
54 from numpy.testing import TestCase, assert_equal, assert_almost_equal
65 from aubio import fvec, zero_crossing_rate, alpha_norm, min_removal
@@ -148,4 +147,5 @@ class aubio_fvec_test_memory(TestCase): · 141 unmodified lines
148147 del c
149148
150149 if __name__ == '__main__':
150+ from unittest import main
151151 main()
python/tests/test_fvec_shift.py+1−1
@@ -30,6 +30,6 @@ class aubio_shift_test_case(TestCase): · 29 unmodified lines
3030 def test_can_shift_fvec_odd(self):
3131 self.run_shift_ishift(7)
3232
33−from unittest import main
3433 if __name__ == '__main__':
34+ from unittest import main
3535 main()
python/tests/test_hztomel.py+11−8
@@ -3,6 +3,7 @@ · 2 unmodified lines
33 from unittest import main
44 from numpy.testing import TestCase
55 from numpy.testing import assert_equal, assert_almost_equal
6+from _tools import assert_warns
67 import numpy as np
78 import aubio
89
@@ -37,12 +38,12 @@ class aubio_hztomel_test_case(TestCase): · 28 unmodified lines
3738 assert_almost_equal(meltohz(hztomel(f)) - f, 0, decimal=1)
3839
3940 def test_meltohz_negative(self):
40− # TODO add assert_warns
41− assert_equal(meltohz(-1), 0)
41+ with assert_warns(UserWarning):
42+ assert_equal(meltohz(-1), 0)
4243
4344 def test_hztomel_negative(self):
44− # TODO add assert_warns
45− assert_equal(hztomel(-1), 0)
45+ with assert_warns(UserWarning):
46+ assert_equal(hztomel(-1), 0)
4647
4748
4849 class aubio_hztomel_htk_test_case(TestCase):
@@ -57,14 +58,16 @@ class aubio_hztomel_htk_test_case(TestCase): · 8 unmodified lines
5758 assert_almost_equal(hztomel(6300, htk=True), 2595., decimal=1)
5859
5960 def test_meltohz_negative(self):
60− # TODO add assert_warns
61− assert_equal(meltohz(-1, htk=True), 0)
61+ with assert_warns(UserWarning):
62+ assert_equal(meltohz(-1, htk=True), 0)
6263 assert_almost_equal(meltohz(2000, htk=True), 3428.7, decimal=1)
6364 assert_almost_equal(meltohz(1000, htk=True), 1000., decimal=1)
6465
6566 def test_hztomel_negative(self):
66− # TODO add assert_warns
67− assert_equal(hztomel(-1, htk=True), 0)
67+ with assert_warns(UserWarning):
68+ assert_equal(meltohz(-1, htk=True), 0)
69+ with assert_warns(UserWarning):
70+ assert_equal(hztomel(-1, htk=True), 0)
6871 assert_almost_equal(hztomel(1000, htk=True), 1000., decimal=1)
6972
7073 def test_hztomel_htk(self):
python/tests/test_mathutils.py+1−1
@@ -1,6 +1,5 @@
11 #! /usr/bin/env python
22
3−from unittest import main
43 from numpy.testing import TestCase, assert_equal
54 from numpy import array, arange, isnan, isinf
65 from aubio import bintomidi, miditobin, freqtobin, bintofreq, freqtomidi, miditofreq
@@ -101,4 +100,5 @@ class aubio_mathutils(TestCase): · 94 unmodified lines
101100 assert_equal ( array(b) < 0, False )
102101
103102 if __name__ == '__main__':
103+ from unittest import main
104104 main()
python/tests/test_mfcc.py+17−21
@@ -1,7 +1,6 @@
11 #! /usr/bin/env python
22
3−from nose2 import main
4−from nose2.tools import params
3+from _tools import parametrize, assert_raises
54 from numpy import random, count_nonzero
65 from numpy.testing import TestCase
76 from aubio import mfcc, cvec, float_type
@@ -15,28 +14,21 @@ samplerate = 44100 · 7 unmodified lines
1514 new_params = ['buf_size', 'n_filters', 'n_coeffs', 'samplerate']
1615 new_deflts = [1024, 40, 13, 44100]
1716
18−class aubio_mfcc(TestCase):
17+class Test_aubio_mfcc(object):
1918
20− def setUp(self):
21− self.o = mfcc()
19+ members_args = 'name'
2220
23− def test_default_creation(self):
24− pass
25−
26− def test_delete(self):
27− del self.o
28−
29− @params(*new_params)
21+ @parametrize(members_args, new_params)
3022 def test_read_only_member(self, name):
31− o = self.o
32− with self.assertRaises((TypeError, AttributeError)):
23+ o = mfcc()
24+ with assert_raises((TypeError, AttributeError)):
3325 setattr(o, name, 0)
3426
35− @params(*zip(new_params, new_deflts))
27+ @parametrize('name, expected', zip(new_params, new_deflts))
3628 def test_default_param(self, name, expected):
3729 """ test mfcc.{:s} = {:d} """.format(name, expected)
38− o = self.o
39− self.assertEqual( getattr(o, name), expected)
30+ o = mfcc()
31+ assert getattr(o, name) == expected
4032
4133 class aubio_mfcc_wrong_params(TestCase):
4234
@@ -82,9 +74,9 @@ class aubio_mfcc_compute(TestCase): · 39 unmodified lines
8274 #print coeffs
8375
8476
85−class aubio_mfcc_all_parameters(TestCase):
77+class Test_aubio_mfcc_all_parameters(object):
8678
87− @params(
79+ run_values = [
8880 (2048, 40, 13, 44100),
8981 (1024, 40, 13, 44100),
9082 (512, 40, 13, 44100),
@@ -100,7 +92,10 @@ class aubio_mfcc_all_parameters(TestCase): · 9 unmodified lines
10092 #(1024, 30, 20, 44100),
10193 (1024, 40, 40, 44100),
10294 (1024, 40, 3, 44100),
103− )
95+ ]
96+ run_args = ['buf_size', 'n_filters', 'n_coeffs', 'samplerate']
97+
98+ @parametrize(run_args, run_values)
10499 def test_run_with_params(self, buf_size, n_filters, n_coeffs, samplerate):
105100 " check mfcc can run with reasonable parameters "
106101 o = mfcc(buf_size, n_filters, n_coeffs, samplerate)
@@ -148,4 +143,5 @@ class aubio_mfcc_fb_params(TestCase): · 41 unmodified lines
148143 assert m.get_scale() == 1
149144
150145 if __name__ == '__main__':
151− main()
146+ from _tools import run_module_suite
147+ run_module_suite()
python/tests/test_midi2note.py+11−12
@@ -2,8 +2,7 @@ · 1 unmodified line
22 # -*- coding: utf-8 -*-
33
44 from aubio import midi2note
5−from nose2.tools import params
6−import unittest
5+from _tools import parametrize, assert_raises
76
87 list_of_known_midis = (
98 ( 0, 'C-1' ),
@@ -15,31 +14,31 @@ list_of_known_midis = ( · 5 unmodified lines
1514 ( 127, 'G9' ),
1615 )
1716
18−class midi2note_good_values(unittest.TestCase):
17+class Test_midi2note_good_values(object):
1918
20− @params(*list_of_known_midis)
19+ @parametrize('midi, note', list_of_known_midis)
2120 def test_midi2note_known_values(self, midi, note):
2221 " known values are correctly converted "
23− self.assertEqual ( midi2note(midi), note )
22+ assert midi2note(midi) == (note)
2423
25−class midi2note_wrong_values(unittest.TestCase):
24+class Test_midi2note_wrong_values(object):
2625
2726 def test_midi2note_negative_value(self):
2827 " fails when passed a negative value "
29− self.assertRaises(ValueError, midi2note, -2)
28+ assert_raises(ValueError, midi2note, -2)
3029
3130 def test_midi2note_large(self):
3231 " fails when passed a value greater than 127 "
33− self.assertRaises(ValueError, midi2note, 128)
32+ assert_raises(ValueError, midi2note, 128)
3433
3534 def test_midi2note_floating_value(self):
3635 " fails when passed a floating point "
37− self.assertRaises(TypeError, midi2note, 69.2)
36+ assert_raises(TypeError, midi2note, 69.2)
3837
3938 def test_midi2note_character_value(self):
4039 " fails when passed a value that can not be transformed to integer "
41− self.assertRaises(TypeError, midi2note, "a")
40+ assert_raises(TypeError, midi2note, "a")
4241
4342 if __name__ == '__main__':
44− import nose2
45− nose2.main()
43+ from _tools import run_module_suite
44+ run_module_suite()
python/tests/test_musicutils.py+2−2
@@ -1,9 +1,8 @@
11 #! /usr/bin/env python
22
3−from unittest import main
43 import numpy as np
54 from numpy.testing import TestCase
6−from numpy.testing.utils import assert_equal, assert_almost_equal
5+from numpy.testing import assert_equal, assert_almost_equal
76 from aubio import window, level_lin, db_spl, silence_detection, level_detection
87 from aubio import fvec, float_type
98
@@ -85,4 +84,5 @@ class aubio_level_detection(TestCase): · 75 unmodified lines
8584 assert level_detection(ones(1024, dtype = float_type), -70) == 0
8685
8786 if __name__ == '__main__':
87+ from unittest import main
8888 main()
python/tests/test_note2midi.py+24−19
@@ -4,8 +4,8 @@ · 3 unmodified lines
44 from __future__ import unicode_literals
55
66 from aubio import note2midi, freq2note, note2freq, float_type
7−from nose2.tools import params
8−import unittest
7+from numpy.testing import TestCase
8+from _tools import parametrize, assert_raises, skipTest
99
1010 list_of_known_notes = (
1111 ( 'C-1', 0 ),
@@ -44,29 +44,32 @@ list_of_unknown_notes = ( · 32 unmodified lines
4444 ( '2' ),
4545 )
4646
47−class note2midi_good_values(unittest.TestCase):
47+class Test_note2midi_good_values(object):
4848
49− @params(*list_of_known_notes)
49+ @parametrize('note, midi', list_of_known_notes)
5050 def test_note2midi_known_values(self, note, midi):
5151 " known values are correctly converted "
52− self.assertEqual ( note2midi(note), midi )
52+ assert note2midi(note) == midi
5353
54− @params(*list_of_known_notes_with_unicode_issues)
54+ @parametrize('note, midi', list_of_known_notes_with_unicode_issues)
5555 def test_note2midi_known_values_with_unicode_issues(self, note, midi):
56− " known values are correctly converted, unless decoding is expected to fail"
56+ " difficult values are correctly converted unless expected failure "
5757 try:
58− self.assertEqual ( note2midi(note), midi )
58+ assert note2midi(note) == midi
5959 except UnicodeEncodeError as e:
60+ # platforms with decoding failures include:
61+ # - osx: python <= 2.7.10
62+ # - win: python <= 2.7.12
6063 import sys
61− strfmt = "len(u'\\U0001D12A') != 1, excpected decoding failure | {:s} | {:s} {:s}"
62− strres = strfmt.format(e, sys.platform, sys.version)
63− # happens with: darwin 2.7.10, windows 2.7.12
64+ strmsg = "len(u'\\U0001D12A') != 1, expected decoding failure"
65+ strmsg += " | upgrade to Python 3 to fix"
66+ strmsg += " | {:s} | {:s} {:s}"
6467 if len('\U0001D12A') != 1 and sys.version[0] == '2':
65− self.skipTest(strres + " | upgrade to Python 3 to fix")
68+ skipTest(strmsg.format(repr(e), sys.platform, sys.version))
6669 else:
6770 raise
6871
69−class note2midi_wrong_values(unittest.TestCase):
72+class note2midi_wrong_values(TestCase):
7073
7174 def test_note2midi_missing_octave(self):
7275 " fails when passed only one character"
@@ -104,12 +107,14 @@ class note2midi_wrong_values(unittest.TestCase): · 31 unmodified lines
104107 " fails when passed a note with a note name longer than expected"
105108 self.assertRaises(ValueError, note2midi, 'CB+-3')
106109
107− @params(*list_of_unknown_notes)
110+class Test_note2midi_unknown_values(object):
111+
112+ @parametrize('note', list_of_unknown_notes)
108113 def test_note2midi_unknown_values(self, note):
109114 " unknown values throw out an error "
110− self.assertRaises(ValueError, note2midi, note)
115+ assert_raises(ValueError, note2midi, note)
111116
112−class freq2note_simple_test(unittest.TestCase):
117+class freq2note_simple_test(TestCase):
113118
114119 def test_freq2note_above(self):
115120 " make sure freq2note(441) == A4 "
@@ -119,7 +124,7 @@ class freq2note_simple_test(unittest.TestCase): · 3 unmodified lines
119124 " make sure freq2note(439) == A4 "
120125 self.assertEqual("A4", freq2note(439))
121126
122−class note2freq_simple_test(unittest.TestCase):
127+class note2freq_simple_test(TestCase):
123128
124129 def test_note2freq(self):
125130 " make sure note2freq('A3') == 220"
@@ -133,5 +138,5 @@ class note2freq_simple_test(unittest.TestCase): · 7 unmodified lines
133138 self.assertLess(abs(note2freq("A4")-440), 1.e-12)
134139
135140 if __name__ == '__main__':
136− import nose2
137− nose2.main()
141+ from _tools import run_module_suite
142+ run_module_suite()
python/tests/test_notes.py+6−7
@@ -1,8 +1,11 @@
11 #! /usr/bin/env python
22
3−from unittest import main
43 from numpy.testing import TestCase, assert_equal, assert_almost_equal
5−from aubio import notes
4+from aubio import notes, source
5+import numpy as np
6+from utils import list_all_sounds
7+
8+list_of_sounds = list_all_sounds('sounds')
69
710 AUBIO_DEFAULT_NOTES_SILENCE = -70.
811 AUBIO_DEFAULT_NOTES_RELEASE_DROP = 10.
@@ -52,14 +55,9 @@ class aubio_notes_params(TestCase): · 43 unmodified lines
5255 with self.assertRaises(ValueError):
5356 self.o.set_release_drop(val)
5457
55−from .utils import list_all_sounds
56−list_of_sounds = list_all_sounds('sounds')
57−
5858 class aubio_notes_sinewave(TestCase):
5959
6060 def analyze_file(self, filepath, samplerate=0):
61− from aubio import source
62− import numpy as np
6361 win_s = 512 # fft size
6462 hop_s = 256 # hop size
6563
@@ -92,4 +90,5 @@ class aubio_notes_sinewave(TestCase): · 26 unmodified lines
9290 assert_equal (results[0][1], [69, 123, -1])
9391
9492 if __name__ == '__main__':
93+ from unittest import main
9594 main()
python/tests/test_onset.py+1−1
@@ -1,6 +1,5 @@
11 #! /usr/bin/env python
22
3−from unittest import main
43 from numpy.testing import TestCase, assert_equal, assert_almost_equal
54 from aubio import onset, fvec
65
@@ -116,4 +115,5 @@ class aubio_onset_coverate(TestCase): · 109 unmodified lines
116115
117116
118117 if __name__ == '__main__':
118+ from unittest import main
119119 main()
python/tests/test_phasevoc.py+13−8
@@ -1,9 +1,8 @@
11 #! /usr/bin/env python
22
33 from numpy.testing import TestCase, assert_equal, assert_array_less
4+from _tools import parametrize
45 from aubio import fvec, cvec, pvoc, float_type
5−from nose2 import main
6−from nose2.tools import params
76 import numpy as np
87
98 if float_type == 'float32':
@@ -18,7 +17,7 @@ def create_sine(hop_s, freq, samplerate): · 8 unmodified lines
1817 def create_noise(hop_s):
1918 return np.random.rand(hop_s).astype(float_type) * 2. - 1.
2019
21−class aubio_pvoc_test_case(TestCase):
20+class Test_aubio_pvoc_test_case(object):
2221 """ pvoc object test case """
2322
2423 def test_members_automatic_sizes_default(self):
@@ -65,7 +64,8 @@ class aubio_pvoc_test_case(TestCase): · 40 unmodified lines
6564 r = f.rdo(s)
6665 assert_equal ( t, 0.)
6766
68− @params(
67+ resynth_noise_args = "hop_s, ratio"
68+ resynth_noise_values = [
6969 ( 256, 8),
7070 ( 256, 4),
7171 ( 256, 2),
@@ -87,13 +87,16 @@ class aubio_pvoc_test_case(TestCase): · 15 unmodified lines
8787 (8192, 8),
8888 (8192, 4),
8989 (8192, 2),
90− )
90+ ]
91+
92+ @parametrize(resynth_noise_args, resynth_noise_values)
9193 def test_resynth_steps_noise(self, hop_s, ratio):
9294 """ check the resynthesis of a random signal is correct """
9395 sigin = create_noise(hop_s)
9496 self.reconstruction(sigin, hop_s, ratio)
9597
96− @params(
98+ resynth_sine_args = "samplerate, hop_s, ratio, freq"
99+ resynth_sine_values = [
97100 (44100, 256, 8, 441),
98101 (44100, 256, 4, 1203),
99102 (44100, 256, 2, 3045),
@@ -108,7 +111,9 @@ class aubio_pvoc_test_case(TestCase): · 8 unmodified lines
108111 (22050, 256, 8, 445),
109112 (96000, 1024, 8, 47000),
110113 (96000, 1024, 8, 20),
111− )
114+ ]
115+
116+ @parametrize(resynth_sine_args, resynth_sine_values)
112117 def test_resynth_steps_sine(self, samplerate, hop_s, ratio, freq):
113118 """ check the resynthesis of a sine is correct """
114119 sigin = create_sine(hop_s, freq, samplerate)
@@ -199,5 +204,5 @@ class aubio_pvoc_wrong_params(TestCase): · 84 unmodified lines
199204 self.skipTest('creating aubio.pvoc with size %d did not fail' % win_s)
200205
201206 if __name__ == '__main__':
207+ from unittest import main
202208 main()
203−
python/tests/test_pitch.py+5−5
@@ -1,7 +1,6 @@
11 #! /usr/bin/env python
22
3−from unittest import TestCase, main
4−from numpy.testing import assert_equal
3+from numpy.testing import TestCase, assert_equal
54 from numpy import sin, arange, mean, median, isnan, pi
65 from aubio import fvec, pitch, freqtomidi, float_type
76
@@ -116,10 +115,11 @@ def create_test (algo, mode): · 108 unmodified lines
116115
117116 for algo in pitch_algorithms:
118117 for mode in signal_modes:
119− test_method = create_test (algo, mode)
120− test_method.__name__ = 'test_pitch_%s_%d_%d_%dHz_sin_%.0f' % ( algo,
118+ _test_method = create_test (algo, mode)
119+ _test_method.__name__ = 'test_pitch_%s_%d_%d_%dHz_sin_%.0f' % ( algo,
121120 mode[0], mode[1], mode[2], mode[3] )
122− setattr (aubio_pitch_Sinusoid, test_method.__name__, test_method)
121+ setattr (aubio_pitch_Sinusoid, _test_method.__name__, _test_method)
123122
124123 if __name__ == '__main__':
124+ from unittest import main
125125 main()
python/tests/test_sink.py+16−22
@@ -1,13 +1,9 @@
11 #! /usr/bin/env python
22
3−from nose2 import main
4−from nose2.tools import params
53 from numpy.testing import TestCase
64 from aubio import fvec, source, sink
7−from .utils import list_all_sounds, get_tmp_sink_path, del_tmp_sink_path
8−
9−import warnings
10−warnings.filterwarnings('ignore', category=UserWarning, append=True)
5+from utils import list_all_sounds, get_tmp_sink_path, del_tmp_sink_path
6+from _tools import parametrize, skipTest, assert_raises
117
128 list_of_sounds = list_all_sounds('sounds')
139 samplerates = [0, 44100, 8000, 32000]
@@ -23,30 +19,26 @@ for soundfile in list_of_sounds: · 9 unmodified lines
2319 for samplerate in samplerates:
2420 all_params.append((hop_size, samplerate, soundfile))
2521
26−class aubio_sink_test_case(TestCase):
27−
28− def setUp(self):
29− if not len(list_of_sounds):
30− self.skipTest('add some sound files in \'python/tests/sounds\'')
22+class Test_aubio_sink(object):
3123
3224 def test_wrong_filename(self):
33− with self.assertRaises(RuntimeError):
25+ with assert_raises(RuntimeError):
3426 sink('')
3527
3628 def test_wrong_samplerate(self):
37− with self.assertRaises(RuntimeError):
29+ with assert_raises(RuntimeError):
3830 sink(get_tmp_sink_path(), -1)
3931
4032 def test_wrong_samplerate_too_large(self):
41− with self.assertRaises(RuntimeError):
33+ with assert_raises(RuntimeError):
4234 sink(get_tmp_sink_path(), 1536001, 2)
4335
4436 def test_wrong_channels(self):
45− with self.assertRaises(RuntimeError):
37+ with assert_raises(RuntimeError):
4638 sink(get_tmp_sink_path(), 44100, -1)
4739
4840 def test_wrong_channels_too_large(self):
49− with self.assertRaises(RuntimeError):
41+ with assert_raises(RuntimeError):
5042 sink(get_tmp_sink_path(), 44100, 202020)
5143
5244 def test_many_sinks(self):
@@ -66,13 +58,13 @@ class aubio_sink_test_case(TestCase): · 13 unmodified lines
6658 g.close()
6759 shutil.rmtree(tmpdir)
6860
69− @params(*all_params)
61+ @parametrize('hop_size, samplerate, path', all_params)
7062 def test_read_and_write(self, hop_size, samplerate, path):
71−
7263 try:
7364 f = source(path, samplerate, hop_size)
7465 except RuntimeError as e:
75− self.skipTest('failed opening with hop_s = {:d}, samplerate = {:d} ({:s})'.format(hop_size, samplerate, str(e)))
66+ err_msg = '{:s} (hop_s = {:d}, samplerate = {:d})'
67+ skipTest(err_msg.format(str(e), hop_size, samplerate))
7668 if samplerate == 0: samplerate = f.samplerate
7769 sink_path = get_tmp_sink_path()
7870 g = sink(sink_path, samplerate)
@@ -84,12 +76,13 @@ class aubio_sink_test_case(TestCase): · 5 unmodified lines
8476 if read < f.hop_size: break
8577 del_tmp_sink_path(sink_path)
8678
87− @params(*all_params)
79+ @parametrize('hop_size, samplerate, path', all_params)
8880 def test_read_and_write_multi(self, hop_size, samplerate, path):
8981 try:
9082 f = source(path, samplerate, hop_size)
9183 except RuntimeError as e:
92− self.skipTest('failed opening with hop_s = {:d}, samplerate = {:d} ({:s})'.format(hop_size, samplerate, str(e)))
84+ err_msg = '{:s} (hop_s = {:d}, samplerate = {:d})'
85+ skipTest(err_msg.format(str(e), hop_size, samplerate))
9386 if samplerate == 0: samplerate = f.samplerate
9487 sink_path = get_tmp_sink_path()
9588 g = sink(sink_path, samplerate, channels = f.channels)
@@ -125,4 +118,5 @@ class aubio_sink_test_case(TestCase): · 29 unmodified lines
125118 g(vec, 128)
126119
127120 if __name__ == '__main__':
128− main()
121+ from _tools import run_module_suite
122+ run_module_suite()
python/tests/test_slicing.py+3−3
@@ -1,10 +1,9 @@
11 #! /usr/bin/env python
22
3−from unittest import main
43 from numpy.testing import TestCase, assert_equal
54 from aubio import slice_source_at_stamps
6−from .utils import count_files_in_directory, get_default_test_sound
7−from .utils import count_samples_in_directory, count_samples_in_file
5+from utils import count_files_in_directory, get_default_test_sound
6+from utils import count_samples_in_directory, count_samples_in_file
87
98 import tempfile
109 import shutil
@@ -167,4 +166,5 @@ class aubio_slicing_wrong_ends_test_case(TestCase): · 156 unmodified lines
167166 shutil.rmtree(self.output_dir)
168167
169168 if __name__ == '__main__':
169+ from unittest import main
170170 main()
python/tests/test_source.py+56−53
@@ -1,19 +1,17 @@
11 #! /usr/bin/env python
22
3−from nose2 import main
4−from nose2.tools import params
3+
54 from numpy.testing import TestCase, assert_equal
65 from aubio import source
7−from .utils import list_all_sounds
8−
9−import warnings
10−warnings.filterwarnings('ignore', category=UserWarning, append=True)
6+from utils import list_all_sounds
7+import unittest
8+from _tools import parametrize, assert_raises, assert_equal, skipTest
119
1210 list_of_sounds = list_all_sounds('sounds')
1311 samplerates = [0, 44100, 8000, 32000]
1412 hop_sizes = [512, 1024, 64]
1513
16−path = None
14+default_test_sound = len(list_of_sounds) and list_of_sounds[0] or None
1715
1816 all_params = []
1917 for soundfile in list_of_sounds:
@@ -21,24 +19,20 @@ for soundfile in list_of_sounds: · 1 unmodified line
2119 for samplerate in samplerates:
2220 all_params.append((hop_size, samplerate, soundfile))
2321
22+no_sounds_msg = "no test sounds, add some in 'python/tests/sounds/'!"
2423
25−class aubio_source_test_case_base(TestCase):
26−
27− def setUp(self):
28− if not len(list_of_sounds):
29− self.skipTest('add some sound files in \'python/tests/sounds\'')
30− self.default_test_sound = list_of_sounds[0]
24+_debug = False
3125
32−class aubio_source_test_case(aubio_source_test_case_base):
26+class Test_aubio_source_test_case(object):
3327
34− @params(*list_of_sounds)
28+ @parametrize('filename', list_of_sounds)
3529 def test_close_file(self, filename):
3630 samplerate = 0 # use native samplerate
3731 hop_size = 256
3832 f = source(filename, samplerate, hop_size)
3933 f.close()
4034
41− @params(*list_of_sounds)
35+ @parametrize('filename', list_of_sounds)
4236 def test_close_file_twice(self, filename):
4337 samplerate = 0 # use native samplerate
4438 hop_size = 256
@@ -46,7 +40,7 @@ class aubio_source_test_case(aubio_source_test_case_base): · 1 unmodified line
4640 f.close()
4741 f.close()
4842
49−class aubio_source_read_test_case(aubio_source_test_case_base):
43+class Test_aubio_source_read(object):
5044
5145 def read_from_source(self, f):
5246 total_frames = 0
@@ -56,47 +50,51 @@ class aubio_source_read_test_case(aubio_source_test_case_base): · 3 unmodified lines
5650 if read < f.hop_size:
5751 assert_equal(samples[read:], 0)
5852 break
59− #result_str = "read {:.2f}s ({:d} frames in {:d} blocks at {:d}Hz) from {:s}"
60− #result_params = total_frames / float(f.samplerate), total_frames, total_frames//f.hop_size, f.samplerate, f.uri
61− #print (result_str.format(*result_params))
53+ if _debug:
54+ result_str = "read {:.2f}s ({:d} frames"
55+ result_str += " in {:d} blocks at {:d}Hz) from {:s}"
56+ result_params = total_frames / float(f.samplerate), total_frames, \
57+ total_frames//f.hop_size, f.samplerate, f.uri
58+ print (result_str.format(*result_params))
6259 return total_frames
6360
64− @params(*all_params)
61+ @parametrize('hop_size, samplerate, soundfile', all_params)
6562 def test_samplerate_hopsize(self, hop_size, samplerate, soundfile):
6663 try:
6764 f = source(soundfile, samplerate, hop_size)
6865 except RuntimeError as e:
69− self.skipTest('failed opening with hop_s = {:d}, samplerate = {:d} ({:s})'.format(hop_size, samplerate, str(e)))
66+ err_msg = 'failed opening with hop_s={:d}, samplerate={:d} ({:s})'
67+ skipTest(err_msg.format(hop_size, samplerate, str(e)))
7068 assert f.samplerate != 0
7169 read_frames = self.read_from_source(f)
7270 if 'f_' in soundfile and samplerate == 0:
7371 import re
74− f = re.compile('.*_\([0:9]*f\)_.*')
72+ f = re.compile(r'.*_\([0:9]*f\)_.*')
7573 match_f = re.findall('([0-9]*)f_', soundfile)
7674 if len(match_f) == 1:
7775 expected_frames = int(match_f[0])
78− self.assertEqual(expected_frames, read_frames)
76+ assert_equal(expected_frames, read_frames)
7977
80− @params(*list_of_sounds)
78+ @parametrize('p', list_of_sounds)
8179 def test_samplerate_none(self, p):
8280 f = source(p)
8381 assert f.samplerate != 0
8482 self.read_from_source(f)
8583
86− @params(*list_of_sounds)
84+ @parametrize('p', list_of_sounds)
8785 def test_samplerate_0(self, p):
8886 f = source(p, 0)
8987 assert f.samplerate != 0
9088 self.read_from_source(f)
9189
92− @params(*list_of_sounds)
90+ @parametrize('p', list_of_sounds)
9391 def test_zero_hop_size(self, p):
9492 f = source(p, 0, 0)
9593 assert f.samplerate != 0
9694 assert f.hop_size != 0
9795 self.read_from_source(f)
9896
99− @params(*list_of_sounds)
97+ @parametrize('p', list_of_sounds)
10098 def test_seek_to_half(self, p):
10199 from random import randint
102100 f = source(p, 0, 0)
@@ -108,7 +106,7 @@ class aubio_source_read_test_case(aubio_source_test_case_base): · 5 unmodified lines
108106 b = self.read_from_source(f)
109107 assert a == b + c
110108
111− @params(*list_of_sounds)
109+ @parametrize('p', list_of_sounds)
112110 def test_duration(self, p):
113111 total_frames = 0
114112 f = source(p)
@@ -117,43 +115,44 @@ class aubio_source_read_test_case(aubio_source_test_case_base): · 2 unmodified lines
117115 _, read = f()
118116 total_frames += read
119117 if read < f.hop_size: break
120− self.assertEqual(duration, total_frames)
118+ assert_equal (duration, total_frames)
121119
122120
123−class aubio_source_test_wrong_params(TestCase):
121+class Test_aubio_source_wrong_params(object):
124122
125123 def test_wrong_file(self):
126− with self.assertRaises(RuntimeError):
124+ with assert_raises(RuntimeError):
127125 source('path_to/unexisting file.mp3')
128126
129−class aubio_source_test_wrong_params_with_file(aubio_source_test_case_base):
127+@unittest.skipIf(default_test_sound is None, no_sounds_msg)
128+class Test_aubio_source_wrong_params_with_file(TestCase):
130129
131130 def test_wrong_samplerate(self):
132− with self.assertRaises(ValueError):
133− source(self.default_test_sound, -1)
131+ with assert_raises(ValueError):
132+ source(default_test_sound, -1)
134133
135134 def test_wrong_hop_size(self):
136− with self.assertRaises(ValueError):
137− source(self.default_test_sound, 0, -1)
135+ with assert_raises(ValueError):
136+ source(default_test_sound, 0, -1)
138137
139138 def test_wrong_channels(self):
140− with self.assertRaises(ValueError):
141− source(self.default_test_sound, 0, 0, -1)
139+ with assert_raises(ValueError):
140+ source(default_test_sound, 0, 0, -1)
142141
143142 def test_wrong_seek(self):
144− f = source(self.default_test_sound)
145− with self.assertRaises(ValueError):
143+ f = source(default_test_sound)
144+ with assert_raises(ValueError):
146145 f.seek(-1)
147146
148147 def test_wrong_seek_too_large(self):
149− f = source(self.default_test_sound)
148+ f = source(default_test_sound)
150149 try:
151− with self.assertRaises(ValueError):
150+ with assert_raises(ValueError):
152151 f.seek(f.duration + f.samplerate * 10)
153− except AssertionError:
154− self.skipTest('seeking after end of stream failed raising ValueError')
152+ except:
153+ skipTest('seeking after end of stream failed raising ValueError')
155154
156−class aubio_source_readmulti_test_case(aubio_source_read_test_case):
155+class Test_aubio_source_readmulti(Test_aubio_source_read):
157156
158157 def read_from_source(self, f):
159158 total_frames = 0
@@ -163,15 +162,18 @@ class aubio_source_readmulti_test_case(aubio_source_read_test_case): · 3 unmodified lines
163162 if read < f.hop_size:
164163 assert_equal(samples[:,read:], 0)
165164 break
166− #result_str = "read {:.2f}s ({:d} frames in {:d} channels and {:d} blocks at {:d}Hz) from {:s}"
167− #result_params = total_frames / float(f.samplerate), total_frames, f.channels, int(total_frames/f.hop_size), f.samplerate, f.uri
168− #print (result_str.format(*result_params))
165+ if _debug:
166+ result_str = "read {:.2f}s ({:d} frames in {:d} channels"
167+ result_str += " and {:d} blocks at {:d}Hz) from {:s}"
168+ result_params = total_frames / float(f.samplerate), total_frames, \
169+ f.channels, int(total_frames/f.hop_size), \
170+ f.samplerate, f.uri
171+ print (result_str.format(*result_params))
169172 return total_frames
170173
171−class aubio_source_with(aubio_source_test_case_base):
174+class Test_aubio_source_with(object):
172175
173− #@params(*list_of_sounds)
174− @params(*list_of_sounds)
176+ @parametrize('filename', list_of_sounds)
175177 def test_read_from_mono(self, filename):
176178 total_frames = 0
177179 hop_size = 2048
@@ -185,4 +187,5 @@ class aubio_source_with(aubio_source_test_case_base): · 7 unmodified lines
185187 assert_equal(total_frames, input_source.duration)
186188
187189 if __name__ == '__main__':
188− main()
190+ from _tools import run_module_suite
191+ run_module_suite()
python/tests/test_source_channels.py+1−1
@@ -8,7 +8,7 @@ import unittest · 7 unmodified lines
88 import aubio
99 import numpy as np
1010 from numpy.testing import assert_equal
11−from .utils import get_tmp_sink_path
11+from utils import get_tmp_sink_path
1212
1313 class aubio_source_test_case(unittest.TestCase):
1414
python/tests/test_specdesc.py+1−1
@@ -1,6 +1,5 @@
11 #! /usr/bin/env python
22
3−from unittest import main
43 from numpy.testing import TestCase, assert_equal, assert_almost_equal
54 from numpy import random, arange, log, zeros
65 from aubio import specdesc, cvec, float_type
@@ -229,4 +228,5 @@ class aubio_specdesc_wrong(TestCase): · 222 unmodified lines
229228 specdesc("unknown", 512)
230229
231230 if __name__ == '__main__':
231+ from unittest import main
232232 main()
python/tests/test_zero_crossing_rate.py+1−1
@@ -1,6 +1,5 @@
11 #! /usr/bin/env python
22
3−from unittest import main
43 from numpy.testing import TestCase
54 from aubio import fvec, zero_crossing_rate
65
@@ -43,4 +42,5 @@ class zero_crossing_rate_test_case(TestCase): · 36 unmodified lines
4342 self.assertEqual(2./buf_size, zero_crossing_rate(self.vector))
4443
4544 if __name__ == '__main__':
45+ from unittest import main
4646 main()
python/tests/utils.py+6−12
@@ -8,11 +8,8 @@ from tempfile import mkstemp · 7 unmodified lines
88 DEFAULT_SOUND = '22050Hz_5s_brownnoise.wav'
99
1010 def array_from_text_file(filename, dtype = 'float'):
11− filename = os.path.join(os.path.dirname(__file__), filename)
12− with open(filename) as f:
13− lines = f.readlines()
14− return np.array([line.split() for line in lines],
15− dtype = dtype)
11+ realpathname = os.path.join(os.path.dirname(__file__), filename)
12+ return np.loadtxt(realpathname, dtype = dtype)
1613
1714 def list_all_sounds(rel_dir):
1815 datadir = os.path.join(os.path.dirname(__file__), rel_dir)
@@ -38,13 +35,10 @@ def del_tmp_sink_path(path): · 19 unmodified lines
3835 try:
3936 os.unlink(path)
4037 except WindowsError as e:
41− print("deleting {:s} failed ({:s}), reopening".format(path, repr(e)))
42− with open(path, 'wb') as f:
43− f.close()
44− try:
45− os.unlink(path)
46− except WindowsError as f:
47− print("deleting {:s} failed ({:s}), aborting".format(path, repr(e)))
38+ # removing the temporary directory sometimes fails on windows
39+ import warnings
40+ errmsg = "failed deleting temporary file {:s} ({:s})"
41+ warnings.warn(UserWarning(errmsg.format(path, repr(e))))
4842
4943 def array_from_yaml_file(filename):
5044 import yaml
requirements.txt+1−1
@@ -1,2 +1,2 @@
11 numpy
2−nose2
2+pytest
scripts/get_waf.sh+1−1
@@ -3,7 +3,7 @@ · 2 unmodified lines
33 set -e
44 #set -x
55
6−WAFVERSION=2.0.12
6+WAFVERSION=2.0.13
77 WAFTARBALL=waf-$WAFVERSION.tar.bz2
88 WAFURL=https://waf.io/$WAFTARBALL
99 WAFUPSTREAMKEY=https://gitlab.com/ita1024/waf/raw/master/utils/pubkey.asc
setup.py+0−4
@@ -95,8 +95,4 @@ distrib = setup(name='aubio', · 94 unmodified lines
9595 'aubiocut = aubio.cut:main',
9696 ],
9797 },
98− test_suite = 'nose2.collector.collector',
99− extras_require = {
100− 'tests': ['numpy'],
101− },
10298 )
src/aubio_priv.h+7−0
@@ -367,4 +367,11 @@ uint_t aubio_log(sint_t level, const char_t *fmt, ...); · 366 unmodified lines
367367 #endif
368368 #endif /* __STRICT_ANSI__ */
369369
370+#if defined(DEBUG)
371+#include <assert.h>
372+#define AUBIO_ASSERT(x) assert(x)
373+#else
374+#define AUBIO_ASSERT(x)
375+#endif /* DEBUG */
376+
370377 #endif /* AUBIO_PRIV_H */
src/io/ioutils.c+36−0
@@ -51,3 +51,39 @@ aubio_io_validate_channels(const char_t *kind, const char_t *path, uint_t channe · 50 unmodified lines
5151 }
5252 return AUBIO_OK;
5353 }
54+
55+uint_t
56+aubio_sink_validate_input_length(const char_t *kind, const char_t *path,
57+ uint_t max_size, uint_t write_data_length, uint_t write)
58+{
59+ uint_t can_write = write;
60+
61+ if (write > max_size) {
62+ AUBIO_WRN("%s: partial write to %s, trying to write %d frames,"
63+ " at most %d can be written at once\n", kind, path, write, max_size);
64+ can_write = max_size;
65+ }
66+
67+ if (can_write > write_data_length) {
68+ AUBIO_WRN("%s: partial write to %s, trying to write %d frames,"
69+ " but found input of length %d\n", kind, path, write,
70+ write_data_length);
71+ can_write = write_data_length;
72+ }
73+
74+ return can_write;
75+}
76+
77+uint_t
78+aubio_sink_validate_input_channels(const char_t *kind, const char_t *path,
79+ uint_t sink_channels, uint_t write_data_height)
80+{
81+ uint_t channels = sink_channels;
82+ if (write_data_height < sink_channels) {
83+ AUBIO_WRN("%s: partial write to %s, trying to write %d channels,"
84+ " but found input of height %d\n", kind, path, sink_channels,
85+ write_data_height);
86+ channels = write_data_height;
87+ }
88+ return channels;
89+}
src/io/ioutils.h+27−0
@@ -53,6 +53,33 @@ uint_t aubio_io_validate_samplerate(const char_t *kind, const char_t *path, · 52 unmodified lines
5353 uint_t aubio_io_validate_channels(const char_t *kind, const char_t *path,
5454 uint_t channels);
5555
56+/** validate length of input
57+
58+ \param kind the object kind to report on
59+ \param path the path to report on
60+ \param max_size maximum number of frames that can be written
61+ \param write_data_length actual length of input vector/matrix
62+ \param write number of samples asked
63+
64+ \return write or the maximum number of frames that can be written
65+*/
66+uint_t
67+aubio_sink_validate_input_length(const char_t *kind, const char_t *path,
68+ uint_t max_size, uint_t write_data_length, uint_t write);
69+
70+/** validate height of input
71+
72+ \param kind the object kind to report on
73+ \param path the path to report on
74+ \param max_size maximum number of channels that can be written
75+ \param write_data_height actual height of input matrix
76+
77+ \return write_data_height or the maximum number of channels
78+*/
79+uint_t
80+aubio_sink_validate_input_channels(const char_t *kind, const char_t *path,
81+ uint_t sink_channels, uint_t write_data_height);
82+
5683 #ifdef __cplusplus
5784 }
5885 #endif
src/io/sink.c+4−4
@@ -102,7 +102,7 @@ aubio_sink_t * new_aubio_sink(const char_t * uri, uint_t samplerate) { · 101 unmodified lines
102102 !defined(HAVE_SINK_APPLE_AUDIO)
103103 AUBIO_ERROR("sink: failed creating '%s' at %dHz (no sink built-in)\n", uri, samplerate);
104104 #endif
105− AUBIO_FREE(s);
105+ del_aubio_sink(s);
106106 return NULL;
107107 }
108108
@@ -135,8 +135,8 @@ uint_t aubio_sink_close(aubio_sink_t *s) { · 26 unmodified lines
135135 }
136136
137137 void del_aubio_sink(aubio_sink_t * s) {
138− if (!s) return;
139− s->s_del((void *)s->sink);
138+ AUBIO_ASSERT(s);
139+ if (s->s_del && s->sink)
140+ s->s_del((void *)s->sink);
140141 AUBIO_FREE(s);
141− return;
142142 }
src/io/sink_apple_audio.c+62−42
@@ -31,9 +31,7 @@ · 30 unmodified lines
3131 // ExtAudioFileRef, AudioStreamBasicDescription, AudioBufferList, ...
3232 #include <AudioToolbox/AudioToolbox.h>
3333
34−#define FLOAT_TO_SHORT(x) (short)(x * 32768)
35−
36−extern int createAubioBufferList(AudioBufferList *bufferList, int channels, int segmentSize);
34+extern int createAudioBufferList(AudioBufferList *bufferList, int channels, int segmentSize);
3735 extern void freeAudioBufferList(AudioBufferList *bufferList);
3836 extern CFURLRef createURLFromPath(const char * path);
3937 char_t *getPrintableOSStatusError(char_t *str, OSStatus error);
@@ -61,11 +59,11 @@ aubio_sink_apple_audio_t * new_aubio_sink_apple_audio(const char_t * uri, uint_t · 21 unmodified lines
6159 s->max_frames = MAX_SIZE;
6260 s->async = false;
6361
64− if ( (uri == NULL) || (strlen(uri) < 1) ) {
62+ if ( (uri == NULL) || (strnlen(uri, PATH_MAX) < 1) ) {
6563 AUBIO_ERROR("sink_apple_audio: Aborted opening null path\n");
6664 goto beach;
6765 }
68− if (s->path != NULL) AUBIO_FREE(s->path);
66+
6967 s->path = AUBIO_ARRAY(char_t, strnlen(uri, PATH_MAX) + 1);
7068 strncpy(s->path, uri, strnlen(uri, PATH_MAX) + 1);
7169
@@ -76,6 +74,7 @@ aubio_sink_apple_audio_t * new_aubio_sink_apple_audio(const char_t * uri, uint_t · 4 unmodified lines
7674 if ((sint_t)samplerate == 0) {
7775 return s;
7876 }
77+
7978 // invalid samplerate given, abort
8079 if (aubio_io_validate_samplerate("sink_apple_audio", s->path, samplerate)) {
8180 goto beach;
@@ -91,7 +90,7 @@ aubio_sink_apple_audio_t * new_aubio_sink_apple_audio(const char_t * uri, uint_t · 9 unmodified lines
9190
9291 return s;
9392 beach:
94− AUBIO_FREE(s);
93+ del_aubio_sink_apple_audio(s);
9594 return NULL;
9695 }
9796
@@ -102,7 +101,7 @@ uint_t aubio_sink_apple_audio_preset_samplerate(aubio_sink_apple_audio_t *s, uin · 4 unmodified lines
102101 }
103102 s->samplerate = samplerate;
104103 // automatically open when both samplerate and channels have been set
105− if (s->samplerate != 0 && s->channels != 0) {
104+ if (/* s->samplerate != 0 && */ s->channels != 0) {
106105 return aubio_sink_apple_audio_open(s);
107106 }
108107 return AUBIO_OK;
@@ -115,7 +114,7 @@ uint_t aubio_sink_apple_audio_preset_channels(aubio_sink_apple_audio_t *s, uint_ · 6 unmodified lines
115114 }
116115 s->channels = channels;
117116 // automatically open when both samplerate and channels have been set
118− if (s->samplerate != 0 && s->channels != 0) {
117+ if (s->samplerate != 0 /* && s->channels != 0 */) {
119118 return aubio_sink_apple_audio_open(s);
120119 }
121120 return AUBIO_OK;
@@ -150,6 +149,18 @@ uint_t aubio_sink_apple_audio_open(aubio_sink_apple_audio_t *s) { · 28 unmodified lines
150149 AudioFileTypeID fileType = kAudioFileWAVEType;
151150 CFURLRef fileURL = createURLFromPath(s->path);
152151 bool overwrite = true;
152+
153+ // set the in-memory format
154+ AudioStreamBasicDescription inputFormat;
155+ memset(&inputFormat, 0, sizeof(AudioStreamBasicDescription));
156+ inputFormat.mFormatID = kAudioFormatLinearPCM;
157+ inputFormat.mSampleRate = (Float64)(s->samplerate);
158+ inputFormat.mFormatFlags = kAudioFormatFlagIsFloat | kAudioFormatFlagIsPacked;
159+ inputFormat.mChannelsPerFrame = s->channels;
160+ inputFormat.mBitsPerChannel = sizeof(smpl_t) * 8;
161+ inputFormat.mFramesPerPacket = 1;
162+ inputFormat.mBytesPerFrame = inputFormat.mBitsPerChannel * inputFormat.mChannelsPerFrame / 8;
163+ inputFormat.mBytesPerPacket = inputFormat.mFramesPerPacket * inputFormat.mBytesPerFrame;
153164 OSStatus err = noErr;
154165 err = ExtAudioFileCreateWithURL(fileURL, fileType, &clientFormat, NULL,
155166 overwrite ? kAudioFileFlags_EraseFile : 0, &s->audioFile);
@@ -161,7 +172,18 @@ uint_t aubio_sink_apple_audio_open(aubio_sink_apple_audio_t *s) { · 5 unmodified lines
161172 getPrintableOSStatusError(errorstr, err));
162173 goto beach;
163174 }
164− if (createAubioBufferList(&s->bufferList, s->channels, s->max_frames * s->channels)) {
175+
176+ err = ExtAudioFileSetProperty(s->audioFile,
177+ kExtAudioFileProperty_ClientDataFormat,
178+ sizeof(AudioStreamBasicDescription), &inputFormat);
179+ if (err) {
180+ char_t errorstr[20];
181+ AUBIO_ERR("sink_apple_audio: error when trying to set output format on %s "
182+ "(%s)\n", s->path, getPrintableOSStatusError(errorstr, err));
183+ goto beach;
184+ }
185+
186+ if (createAudioBufferList(&s->bufferList, s->channels, s->max_frames * s->channels)) {
165187 AUBIO_ERR("sink_apple_audio: error when creating buffer list for %s, "
166188 "out of memory? \n", s->path);
167189 goto beach;
@@ -174,46 +196,42 @@ beach: · 6 unmodified lines
174196
175197 void aubio_sink_apple_audio_do(aubio_sink_apple_audio_t * s, fvec_t * write_data, uint_t write) {
176198 UInt32 c, v;
177− short *data = (short*)s->bufferList.mBuffers[0].mData;
178− if (write > s->max_frames) {
179− AUBIO_WRN("sink_apple_audio: trying to write %d frames, max %d\n", write, s->max_frames);
180− write = s->max_frames;
181− }
182− smpl_t *buf = write_data->data;
183−
184− if (buf) {
185− for (c = 0; c < s->channels; c++) {
186− for (v = 0; v < write; v++) {
187− data[v * s->channels + c] =
188− FLOAT_TO_SHORT(buf[ v * s->channels + c]);
189− }
190− }
199+ smpl_t *data = (smpl_t*)s->bufferList.mBuffers[0].mData;
200+ uint_t length = aubio_sink_validate_input_length("sink_apple_audio", s->path,
201+ s->max_frames, write_data->length, write);
202+
203+ for (c = 0; c < s->channels; c++) {
204+ for (v = 0; v < length; v++) {
205+ data[v * s->channels + c] = write_data->data[v];
206+ }
191207 }
192− aubio_sink_apple_audio_write(s, write);
208+
209+ aubio_sink_apple_audio_write(s, length);
193210 }
194211
195212 void aubio_sink_apple_audio_do_multi(aubio_sink_apple_audio_t * s, fmat_t * write_data, uint_t write) {
196213 UInt32 c, v;
197− short *data = (short*)s->bufferList.mBuffers[0].mData;
198− if (write > s->max_frames) {
199− AUBIO_WRN("sink_apple_audio: trying to write %d frames, max %d\n", write, s->max_frames);
200− write = s->max_frames;
201− }
202− smpl_t **buf = write_data->data;
203−
204− if (buf) {
205− for (c = 0; c < s->channels; c++) {
206− for (v = 0; v < write; v++) {
207− data[v * s->channels + c] =
208− FLOAT_TO_SHORT(buf[c][v]);
209− }
210− }
214+ smpl_t *data = (smpl_t*)s->bufferList.mBuffers[0].mData;
215+ uint_t channels = aubio_sink_validate_input_channels("sink_apple_audio",
216+ s->path, s->channels, write_data->height);
217+ uint_t length = aubio_sink_validate_input_length("sink_apple_audio", s->path,
218+ s->max_frames, write_data->length, write);
219+
220+ for (c = 0; c < channels; c++) {
221+ for (v = 0; v < length; v++) {
222+ data[v * s->channels + c] = write_data->data[c][v];
223+ }
211224 }
212− aubio_sink_apple_audio_write(s, write);
225+
226+ aubio_sink_apple_audio_write(s, length);
213227 }
214228
215229 void aubio_sink_apple_audio_write(aubio_sink_apple_audio_t *s, uint_t write) {
216230 OSStatus err = noErr;
231+ // set mDataByteSize to match the number of frames to be written
232+ // see https://www.mail-archive.com/coreaudio-api@lists.apple.com/msg01109.html
233+ s->bufferList.mBuffers[0].mDataByteSize = write * s->channels
234+ * sizeof(smpl_t);
217235 if (s->async) {
218236 err = ExtAudioFileWriteAsync(s->audioFile, write, &s->bufferList);
219237 if (err) {
@@ -257,11 +275,13 @@ uint_t aubio_sink_apple_audio_close(aubio_sink_apple_audio_t * s) { · 37 unmodified lines
257275 }
258276
259277 void del_aubio_sink_apple_audio(aubio_sink_apple_audio_t * s) {
260− if (s->audioFile) aubio_sink_apple_audio_close (s);
261− if (s->path) AUBIO_FREE(s->path);
278+ AUBIO_ASSERT(s);
279+ if (s->audioFile)
280+ aubio_sink_apple_audio_close (s);
281+ if (s->path)
282+ AUBIO_FREE(s->path);
262283 freeAudioBufferList(&s->bufferList);
263284 AUBIO_FREE(s);
264− return;
265285 }
266286
267287 #endif /* HAVE_SINK_APPLE_AUDIO */
src/io/sink_sndfile.c+27−39
@@ -58,10 +58,9 @@ aubio_sink_sndfile_t * new_aubio_sink_sndfile(const char_t * path, uint_t sample · 57 unmodified lines
5858
5959 if (path == NULL) {
6060 AUBIO_ERR("sink_sndfile: Aborted opening null path\n");
61− return NULL;
61+ goto beach;
6262 }
6363
64− if (s->path) AUBIO_FREE(s->path);
6564 s->path = AUBIO_ARRAY(char_t, strnlen(path, PATH_MAX) + 1);
6665 strncpy(s->path, path, strnlen(path, PATH_MAX) + 1);
6766
@@ -97,7 +96,7 @@ uint_t aubio_sink_sndfile_preset_samplerate(aubio_sink_sndfile_t *s, uint_t samp · 29 unmodified lines
9796 }
9897 s->samplerate = samplerate;
9998 // automatically open when both samplerate and channels have been set
100− if (s->samplerate != 0 && s->channels != 0) {
99+ if (/* s->samplerate != 0 && */ s->channels != 0) {
101100 return aubio_sink_sndfile_open(s);
102101 }
103102 return AUBIO_OK;
@@ -110,7 +109,7 @@ uint_t aubio_sink_sndfile_preset_channels(aubio_sink_sndfile_t *s, uint_t channe · 6 unmodified lines
110109 }
111110 s->channels = channels;
112111 // automatically open when both samplerate and channels have been set
113− if (s->samplerate != 0 && s->channels != 0) {
112+ if (s->samplerate != 0 /* && s->channels != 0 */) {
114113 return aubio_sink_sndfile_open(s);
115114 }
116115 return AUBIO_OK;
@@ -147,8 +146,7 @@ uint_t aubio_sink_sndfile_open(aubio_sink_sndfile_t *s) { · 30 unmodified lines
147146 s->scratch_size = s->max_size*s->channels;
148147 /* allocate data for de/interleaving reallocated when needed. */
149148 if (s->scratch_size >= MAX_SIZE * AUBIO_MAX_CHANNELS) {
150− abort();
151− AUBIO_ERR("sink_sndfile: %d x %d exceeds maximum aubio_sink_sndfile buffer size %d\n",
149+ AUBIO_ERR("sink_sndfile: %d x %d exceeds maximum buffer size %d\n",
152150 s->max_size, s->channels, MAX_SIZE * AUBIO_MAX_CHANNELS);
153151 return AUBIO_FAIL;
154152 }
@@ -158,24 +156,17 @@ uint_t aubio_sink_sndfile_open(aubio_sink_sndfile_t *s) { · 3 unmodified lines
158156 }
159157
160158 void aubio_sink_sndfile_do(aubio_sink_sndfile_t *s, fvec_t * write_data, uint_t write){
161− uint_t i, j, channels = s->channels;
162− int nsamples = 0;
163− smpl_t *pwrite;
159+ uint_t i, j;
164160 sf_count_t written_frames;
165−
166− if (write > s->max_size) {
167− AUBIO_WRN("sink_sndfile: trying to write %d frames, but only %d can be written at a time\n",
168− write, s->max_size);
169− write = s->max_size;
170− }
171−
172− nsamples = channels * write;
161+ uint_t channels = s->channels;
162+ uint_t length = aubio_sink_validate_input_length("sink_sndfile", s->path,
163+ s->max_size, write_data->length, write);
164+ int nsamples = channels * length;
173165
174166 /* interleaving data */
175167 for ( i = 0; i < channels; i++) {
176− pwrite = (smpl_t *)write_data->data;
177− for (j = 0; j < write; j++) {
178− s->scratch_data[channels*j+i] = pwrite[j];
168+ for (j = 0; j < length; j++) {
169+ s->scratch_data[channels*j+i] = write_data->data[j];
179170 }
180171 }
181172
@@ -188,24 +179,18 @@ void aubio_sink_sndfile_do(aubio_sink_sndfile_t *s, fvec_t * write_data, uint_t · 6 unmodified lines
188179 }
189180
190181 void aubio_sink_sndfile_do_multi(aubio_sink_sndfile_t *s, fmat_t * write_data, uint_t write){
191− uint_t i, j, channels = s->channels;
192− int nsamples = 0;
193− smpl_t *pwrite;
182+ uint_t i, j;
194183 sf_count_t written_frames;
195−
196− if (write > s->max_size) {
197− AUBIO_WRN("sink_sndfile: trying to write %d frames, but only %d can be written at a time\n",
198− write, s->max_size);
199− write = s->max_size;
200− }
201−
202− nsamples = channels * write;
184+ uint_t channels = aubio_sink_validate_input_channels("sink_sndfile", s->path,
185+ s->channels, write_data->height);
186+ uint_t length = aubio_sink_validate_input_length("sink_sndfile", s->path,
187+ s->max_size, write_data->length, write);
188+ int nsamples = channels * length;
203189
204190 /* interleaving data */
205− for ( i = 0; i < write_data->height; i++) {
206− pwrite = (smpl_t *)write_data->data[i];
207− for (j = 0; j < write; j++) {
208− s->scratch_data[channels*j+i] = pwrite[j];
191+ for ( i = 0; i < channels; i++) {
192+ for (j = 0; j < length; j++) {
193+ s->scratch_data[channels*j+i] = write_data->data[i][j];
209194 }
210195 }
211196
@@ -230,10 +215,13 @@ uint_t aubio_sink_sndfile_close (aubio_sink_sndfile_t *s) { · 18 unmodified lines
230215 }
231216
232217 void del_aubio_sink_sndfile(aubio_sink_sndfile_t * s){
233− if (!s) return;
234− if (s->path) AUBIO_FREE(s->path);
235− aubio_sink_sndfile_close(s);
236− AUBIO_FREE(s->scratch_data);
218+ AUBIO_ASSERT(s);
219+ if (s->handle)
220+ aubio_sink_sndfile_close(s);
221+ if (s->path)
222+ AUBIO_FREE(s->path);
223+ if (s->scratch_data)
224+ AUBIO_FREE(s->scratch_data);
237225 AUBIO_FREE(s);
238226 }
239227
src/io/sink_wavwrite.c+24−29
@@ -87,12 +87,7 @@ aubio_sink_wavwrite_t * new_aubio_sink_wavwrite(const char_t * path, uint_t samp · 86 unmodified lines
8787 AUBIO_ERR("sink_wavwrite: Aborted opening null path\n");
8888 goto beach;
8989 }
90− if ((sint_t)samplerate < 0) {
91− AUBIO_ERR("sink_wavwrite: Can not create %s with samplerate %d\n", path, samplerate);
92− goto beach;
93− }
9490
95− if (s->path) AUBIO_FREE(s->path);
9691 s->path = AUBIO_ARRAY(char_t, strnlen(path, PATH_MAX) + 1);
9792 strncpy(s->path, path, strnlen(path, PATH_MAX) + 1);
9893
@@ -135,7 +130,7 @@ uint_t aubio_sink_wavwrite_preset_samplerate(aubio_sink_wavwrite_t *s, uint_t sa · 36 unmodified lines
135130 }
136131 s->samplerate = samplerate;
137132 // automatically open when both samplerate and channels have been set
138− if (s->samplerate != 0 && s->channels != 0) {
133+ if (/* s->samplerate != 0 && */ s->channels != 0) {
139134 return aubio_sink_wavwrite_open(s);
140135 }
141136 return AUBIO_OK;
@@ -148,7 +143,7 @@ uint_t aubio_sink_wavwrite_preset_channels(aubio_sink_wavwrite_t *s, uint_t chan · 6 unmodified lines
148143 }
149144 s->channels = channels;
150145 // automatically open when both samplerate and channels have been set
151− if (s->samplerate != 0 && s->channels != 0) {
146+ if (s->samplerate != 0 /* && s->channels != 0 */) {
152147 return aubio_sink_wavwrite_open(s);
153148 }
154149 return AUBIO_OK;
@@ -233,18 +228,16 @@ beach: · 78 unmodified lines
233228
234229
235230 void aubio_sink_wavwrite_do(aubio_sink_wavwrite_t *s, fvec_t * write_data, uint_t write){
236− uint_t i = 0, written_frames = 0;
237−
238− if (write > s->max_size) {
239− AUBIO_WRN("sink_wavwrite: trying to write %d frames to %s, "
240− "but only %d can be written at a time\n", write, s->path, s->max_size);
241− write = s->max_size;
242− }
231+ uint_t c = 0, i = 0, written_frames = 0;
232+ uint_t length = aubio_sink_validate_input_length("sink_wavwrite", s->path,
233+ s->max_size, write_data->length, write);
243234
244− for (i = 0; i < write; i++) {
245− s->scratch_data[i] = HTOLES(FLOAT_TO_SHORT(write_data->data[i]));
235+ for (c = 0; c < s->channels; c++) {
236+ for (i = 0; i < length; i++) {
237+ s->scratch_data[i * s->channels + c] = HTOLES(FLOAT_TO_SHORT(write_data->data[i]));
238+ }
246239 }
247− written_frames = fwrite(s->scratch_data, 2, write, s->fid);
240+ written_frames = fwrite(s->scratch_data, 2, length * s->channels, s->fid);
248241
249242 if (written_frames != write) {
250243 AUBIO_WRN("sink_wavwrite: trying to write %d frames to %s, "
@@ -257,18 +250,17 @@ void aubio_sink_wavwrite_do(aubio_sink_wavwrite_t *s, fvec_t * write_data, uint_ · 6 unmodified lines
257250 void aubio_sink_wavwrite_do_multi(aubio_sink_wavwrite_t *s, fmat_t * write_data, uint_t write){
258251 uint_t c = 0, i = 0, written_frames = 0;
259252
260− if (write > s->max_size) {
261− AUBIO_WRN("sink_wavwrite: trying to write %d frames to %s, "
262− "but only %d can be written at a time\n", write, s->path, s->max_size);
263− write = s->max_size;
264− }
253+ uint_t channels = aubio_sink_validate_input_channels("sink_wavwrite", s->path,
254+ s->channels, write_data->height);
255+ uint_t length = aubio_sink_validate_input_length("sink_wavwrite", s->path,
256+ s->max_size, write_data->length, write);
265257
266− for (c = 0; c < s->channels; c++) {
267− for (i = 0; i < write; i++) {
258+ for (c = 0; c < channels; c++) {
259+ for (i = 0; i < length; i++) {
268260 s->scratch_data[i * s->channels + c] = HTOLES(FLOAT_TO_SHORT(write_data->data[c][i]));
269261 }
270262 }
271− written_frames = fwrite(s->scratch_data, 2, write * s->channels, s->fid);
263+ written_frames = fwrite(s->scratch_data, 2, length * s->channels, s->fid);
272264
273265 if (written_frames != write * s->channels) {
274266 AUBIO_WRN("sink_wavwrite: trying to write %d frames to %s, "
@@ -297,10 +289,13 @@ uint_t aubio_sink_wavwrite_close(aubio_sink_wavwrite_t * s) { · 22 unmodified lines
297289 }
298290
299291 void del_aubio_sink_wavwrite(aubio_sink_wavwrite_t * s){
300− if (!s) return;
301− aubio_sink_wavwrite_close(s);
302− if (s->path) AUBIO_FREE(s->path);
303− AUBIO_FREE(s->scratch_data);
292+ AUBIO_ASSERT(s);
293+ if (s->fid)
294+ aubio_sink_wavwrite_close(s);
295+ if (s->path)
296+ AUBIO_FREE(s->path);
297+ if (s->scratch_data)
298+ AUBIO_FREE(s->scratch_data);
304299 AUBIO_FREE(s);
305300 }
306301
src/io/source.c+4−3
@@ -121,7 +121,7 @@ aubio_source_t * new_aubio_source(const char_t * uri, uint_t samplerate, uint_t · 120 unmodified lines
121121 AUBIO_ERROR("source: failed creating with %s at %dHz with hop size %d"
122122 " (no source built-in)\n", uri, samplerate, hop_size);
123123 #endif
124− AUBIO_FREE(s);
124+ del_aubio_source(s);
125125 return NULL;
126126 }
127127
@@ -138,8 +138,9 @@ uint_t aubio_source_close(aubio_source_t * s) { · 10 unmodified lines
138138 }
139139
140140 void del_aubio_source(aubio_source_t * s) {
141− if (!s) return;
142− s->s_del((void *)s->source);
141+ AUBIO_ASSERT(s);
142+ if (s->s_del && s->source)
143+ s->s_del((void *)s->source);
143144 AUBIO_FREE(s);
144145 }
145146
src/io/source.h+0−1
@@ -59,7 +59,6 @@ · 58 unmodified lines
5959 A simple source to read from 16-bits PCM RIFF encoded WAV files.
6060
6161 \example io/test-source.c
62− \example io/test-source_multi.c
6362
6463 */
6564
src/io/source_apple_audio.c+30−45
@@ -34,8 +34,6 @@ · 33 unmodified lines
3434 #define RT_BYTE3( a ) ( ((a) >> 16) & 0xff )
3535 #define RT_BYTE4( a ) ( ((a) >> 24) & 0xff )
3636
37−#define SHORT_TO_FLOAT(x) (smpl_t)(x * 3.0517578125e-05)
38−
3937 struct _aubio_source_apple_audio_t {
4038 uint_t channels;
4139 uint_t samplerate; //< requested samplerate
@@ -48,7 +46,7 @@ struct _aubio_source_apple_audio_t { · 6 unmodified lines
4846 AudioBufferList bufferList;
4947 };
5048
51−extern int createAubioBufferList(AudioBufferList *bufferList, int channels, int max_source_samples);
49+extern int createAudioBufferList(AudioBufferList *bufferList, int channels, int max_source_samples);
5250 extern void freeAudioBufferList(AudioBufferList *bufferList);
5351 extern CFURLRef createURLFromPath(const char * path);
5452 char_t *getPrintableOSStatusError(char_t *str, OSStatus error);
@@ -59,7 +57,7 @@ aubio_source_apple_audio_t * new_aubio_source_apple_audio(const char_t * path, u · 4 unmodified lines
5957 {
6058 aubio_source_apple_audio_t * s = AUBIO_NEW(aubio_source_apple_audio_t);
6159
62− if (path == NULL) {
60+ if (path == NULL || strnlen(path, PATH_MAX) < 1) {
6361 AUBIO_ERROR("source_apple_audio: Aborted opening null path\n");
6462 goto beach;
6563 }
@@ -85,7 +83,7 @@ aubio_source_apple_audio_t * new_aubio_source_apple_audio(const char_t * path, u · 19 unmodified lines
8583 return s;
8684
8785 beach:
88− AUBIO_FREE(s);
86+ del_aubio_source_apple_audio(s);
8987 return NULL;
9088 }
9189
@@ -94,7 +92,6 @@ uint_t aubio_source_apple_audio_open (aubio_source_apple_audio_t *s, const char_ · 2 unmodified lines
9492 OSStatus err = noErr;
9593 UInt32 propSize;
9694
97− if (s->path) AUBIO_FREE(s->path);
9895 s->path = AUBIO_ARRAY(char_t, strnlen(path, PATH_MAX) + 1);
9996 strncpy(s->path, path, strnlen(path, PATH_MAX) + 1);
10097
@@ -139,17 +136,16 @@ uint_t aubio_source_apple_audio_open (aubio_source_apple_audio_t *s, const char_ · 38 unmodified lines
139136 s->channels = fileFormat.mChannelsPerFrame;
140137
141138 AudioStreamBasicDescription clientFormat;
142− propSize = sizeof(clientFormat);
139+ propSize = sizeof(AudioStreamBasicDescription);
143140 memset(&clientFormat, 0, sizeof(AudioStreamBasicDescription));
144141 clientFormat.mFormatID = kAudioFormatLinearPCM;
145142 clientFormat.mSampleRate = (Float64)(s->samplerate);
146− clientFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
143+ clientFormat.mFormatFlags = kAudioFormatFlagIsFloat;
147144 clientFormat.mChannelsPerFrame = s->channels;
148− clientFormat.mBitsPerChannel = sizeof(short) * 8;
145+ clientFormat.mBitsPerChannel = sizeof(smpl_t) * 8;
149146 clientFormat.mFramesPerPacket = 1;
150147 clientFormat.mBytesPerFrame = clientFormat.mBitsPerChannel * clientFormat.mChannelsPerFrame / 8;
151148 clientFormat.mBytesPerPacket = clientFormat.mFramesPerPacket * clientFormat.mBytesPerFrame;
152− clientFormat.mReserved = 0;
153149
154150 // set the client format description
155151 err = ExtAudioFileSetProperty(s->audioFile, kExtAudioFileProperty_ClientDataFormat,
@@ -187,7 +183,7 @@ uint_t aubio_source_apple_audio_open (aubio_source_apple_audio_t *s, const char_ · 31 unmodified lines
187183
188184 // allocate the AudioBufferList
189185 freeAudioBufferList(&s->bufferList);
190− if (createAubioBufferList(&s->bufferList, s->channels, s->block_size * s->channels)) {
186+ if (createAudioBufferList(&s->bufferList, s->channels, s->block_size * s->channels)) {
191187 AUBIO_ERR("source_apple_audio: failed creating bufferList\n");
192188 goto beach;
193189 }
@@ -196,60 +192,51 @@ beach: · 2 unmodified lines
196192 return err;
197193 }
198194
199−void aubio_source_apple_audio_do(aubio_source_apple_audio_t *s, fvec_t * read_to, uint_t * read) {
200− UInt32 c, v, loadedPackets = s->block_size;
195+static UInt32 aubio_source_apple_audio_read_frame(aubio_source_apple_audio_t *s)
196+{
197+ UInt32 loadedPackets = s->block_size;
201198 OSStatus err = ExtAudioFileRead(s->audioFile, &loadedPackets, &s->bufferList);
202199 if (err) {
203200 char_t errorstr[20];
204201 AUBIO_ERROR("source_apple_audio: error while reading %s "
205202 "with ExtAudioFileRead (%s)\n", s->path,
206203 getPrintableOSStatusError(errorstr, err));
207− goto beach;
208204 }
205+ return loadedPackets;
206+}
209207
210− short *data = (short*)s->bufferList.mBuffers[0].mData;
211−
212− smpl_t *buf = read_to->data;
208+void aubio_source_apple_audio_do(aubio_source_apple_audio_t *s, fvec_t * read_to,
209+ uint_t * read) {
210+ uint_t c, v;
211+ UInt32 loadedPackets = aubio_source_apple_audio_read_frame(s);
212+ smpl_t *data = (smpl_t*)s->bufferList.mBuffers[0].mData;
213213
214214 for (v = 0; v < loadedPackets; v++) {
215− buf[v] = 0.;
215+ read_to->data[v] = 0.;
216216 for (c = 0; c < s->channels; c++) {
217− buf[v] += SHORT_TO_FLOAT(data[ v * s->channels + c]);
217+ read_to->data[v] += data[ v * s->channels + c];
218218 }
219− buf[v] /= (smpl_t)s->channels;
219+ read_to->data[v] /= (smpl_t)s->channels;
220220 }
221221 // short read, fill with zeros
222222 if (loadedPackets < s->block_size) {
223223 for (v = loadedPackets; v < s->block_size; v++) {
224− buf[v] = 0.;
224+ read_to->data[v] = 0.;
225225 }
226226 }
227227
228228 *read = (uint_t)loadedPackets;
229229 return;
230−beach:
231− *read = 0;
232− return;
233230 }
234231
235232 void aubio_source_apple_audio_do_multi(aubio_source_apple_audio_t *s, fmat_t * read_to, uint_t * read) {
236− UInt32 c, v, loadedPackets = s->block_size;
237− OSStatus err = ExtAudioFileRead(s->audioFile, &loadedPackets, &s->bufferList);
238− if (err) {
239− char_t errorstr[20];
240− AUBIO_ERROR("source_apple_audio: error while reading %s "
241− "with ExtAudioFileRead (%s)\n", s->path,
242− getPrintableOSStatusError(errorstr, err));
243− goto beach;
244− }
245−
246− short *data = (short*)s->bufferList.mBuffers[0].mData;
247−
248− smpl_t **buf = read_to->data;
233+ uint_t c, v;
234+ UInt32 loadedPackets = aubio_source_apple_audio_read_frame(s);
235+ smpl_t *data = (smpl_t*)s->bufferList.mBuffers[0].mData;
249236
250237 for (v = 0; v < loadedPackets; v++) {
251238 for (c = 0; c < read_to->height; c++) {
252− buf[c][v] = SHORT_TO_FLOAT(data[ v * s->channels + c]);
239+ read_to->data[c][v] = data[ v * s->channels + c];
253240 }
254241 }
255242 // if read_data has more channels than the file
@@ -257,7 +244,7 @@ void aubio_source_apple_audio_do_multi(aubio_source_apple_audio_t *s, fmat_t * r · 1 unmodified line
257244 // copy last channel to all additional channels
258245 for (v = 0; v < loadedPackets; v++) {
259246 for (c = s->channels; c < read_to->height; c++) {
260− buf[c][v] = SHORT_TO_FLOAT(data[ v * s->channels + (s->channels - 1)]);
247+ read_to->data[c][v] = data[ v * s->channels + (s->channels - 1)];
261248 }
262249 }
263250 }
@@ -265,15 +252,13 @@ void aubio_source_apple_audio_do_multi(aubio_source_apple_audio_t *s, fmat_t * r · 1 unmodified line
265252 if (loadedPackets < s->block_size) {
266253 for (v = loadedPackets; v < s->block_size; v++) {
267254 for (c = 0; c < read_to->height; c++) {
268− buf[c][v] = 0.;
255+ read_to->data[c][v] = 0.;
269256 }
270257 }
271258 }
259+
272260 *read = (uint_t)loadedPackets;
273261 return;
274−beach:
275− *read = 0;
276− return;
277262 }
278263
279264 uint_t aubio_source_apple_audio_close (aubio_source_apple_audio_t *s)
@@ -293,11 +278,11 @@ uint_t aubio_source_apple_audio_close (aubio_source_apple_audio_t *s) · 13 unmodified lines
293278 }
294279
295280 void del_aubio_source_apple_audio(aubio_source_apple_audio_t * s){
281+ AUBIO_ASSERT(s);
296282 aubio_source_apple_audio_close (s);
297283 if (s->path) AUBIO_FREE(s->path);
298284 freeAudioBufferList(&s->bufferList);
299285 AUBIO_FREE(s);
300− return;
301286 }
302287
303288 uint_t aubio_source_apple_audio_seek (aubio_source_apple_audio_t * s, uint_t pos) {
@@ -323,7 +308,7 @@ uint_t aubio_source_apple_audio_seek (aubio_source_apple_audio_t * s, uint_t pos · 19 unmodified lines
323308 }
324309 // after a short read, the bufferList size needs to resetted to prepare for a full read
325310 AudioBufferList *bufferList = &s->bufferList;
326− bufferList->mBuffers[0].mDataByteSize = s->block_size * s->channels * sizeof (short);
311+ bufferList->mBuffers[0].mDataByteSize = s->block_size * s->channels * sizeof (smpl_t);
327312 // do the actual seek
328313 err = ExtAudioFileSeek(s->audioFile, resampled_pos);
329314 if (err) {
src/io/source_avcodec.c+10−2
@@ -46,6 +46,10 @@ · 45 unmodified lines
4646 #define HAVE_AUBIO_LIBAVCODEC_DEPRECATED 1
4747 #endif
4848
49+#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58,3,102)
50+#define HAVE_AUBIO_LIBAVCODEC_TIMEBASE_FIX 1
51+#endif
52+
4953 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55,28,1)
5054 #warning "libavcodec < 56 is deprecated"
5155 #define av_frame_alloc avcodec_alloc_frame
@@ -143,7 +147,6 @@ aubio_source_avcodec_t * new_aubio_source_avcodec(const char_t * path, · 91 unmodified lines
143147 s->hop_size = hop_size;
144148 s->channels = 1;
145149
146− if (s->path) AUBIO_FREE(s->path);
147150 s->path = AUBIO_ARRAY(char_t, strnlen(path, PATH_MAX) + 1);
148151 strncpy(s->path, path, strnlen(path, PATH_MAX) + 1);
149152
@@ -239,6 +242,11 @@ aubio_source_avcodec_t * new_aubio_source_avcodec(const char_t * path, · 89 unmodified lines
239242 av_get_media_type_string(AVMEDIA_TYPE_AUDIO), s->path);
240243 goto beach;
241244 }
245+#if HAVE_AUBIO_LIBAVCODEC_TIMEBASE_FIX
246+ // avoids 'skipped frames warning' with avecodec < 58, deprecated after
247+ av_codec_set_pkt_timebase(avCodecCtx,
248+ avFormatCtx->streams[selected_stream]->time_base);
249+#endif
242250 #endif
243251
244252 if ( ( err = avcodec_open2(avCodecCtx, codec, NULL) ) < 0) {
@@ -630,7 +638,7 @@ uint_t aubio_source_avcodec_close(aubio_source_avcodec_t * s) { · 385 unmodified lines
630638 }
631639
632640 void del_aubio_source_avcodec(aubio_source_avcodec_t * s){
633− if (!s) return;
641+ AUBIO_ASSERT(s);
634642 aubio_source_avcodec_close(s);
635643 if (s->output != NULL) {
636644 av_free(s->output);
src/io/source_sndfile.c+1−2
@@ -86,7 +86,6 @@ aubio_source_sndfile_t * new_aubio_source_sndfile(const char_t * path, uint_t sa · 85 unmodified lines
8686 s->hop_size = hop_size;
8787 s->channels = 1;
8888
89− if (s->path) AUBIO_FREE(s->path);
9089 s->path = AUBIO_ARRAY(char_t, strnlen(path, PATH_MAX) + 1);
9190 strncpy(s->path, path, strnlen(path, PATH_MAX) + 1);
9291
@@ -331,7 +330,7 @@ uint_t aubio_source_sndfile_close (aubio_source_sndfile_t *s) { · 238 unmodified lines
331330 }
332331
333332 void del_aubio_source_sndfile(aubio_source_sndfile_t * s){
334− if (!s) return;
333+ AUBIO_ASSERT(s);
335334 aubio_source_sndfile_close(s);
336335 #ifdef HAVE_SAMPLERATE
337336 if (s->resamplers != NULL) {
src/io/source_wavread.c+1−2
@@ -91,7 +91,6 @@ aubio_source_wavread_t * new_aubio_source_wavread(const char_t * path, uint_t sa · 90 unmodified lines
9191 goto beach;
9292 }
9393
94− if (s->path) AUBIO_FREE(s->path);
9594 s->path = AUBIO_ARRAY(char_t, strnlen(path, PATH_MAX) + 1);
9695 strncpy(s->path, path, strnlen(path, PATH_MAX) + 1);
9796
@@ -471,7 +470,7 @@ uint_t aubio_source_wavread_close (aubio_source_wavread_t * s) { · 373 unmodified lines
471470 }
472471
473472 void del_aubio_source_wavread(aubio_source_wavread_t * s) {
474− if (!s) return;
473+ AUBIO_ASSERT(s);
475474 aubio_source_wavread_close(s);
476475 if (s->short_output) AUBIO_FREE(s->short_output);
477476 if (s->output) del_fmat(s->output);
src/io/utils_apple_audio.c+4−3
@@ -12,11 +12,12 @@ void freeAudioBufferList(AudioBufferList *bufferList); · 11 unmodified lines
1212 CFURLRef getURLFromPath(const char * path);
1313 char_t *getPrintableOSStatusError(char_t *str, OSStatus error);
1414
15−int createAubioBufferList(AudioBufferList * bufferList, int channels, int max_source_samples) {
15+int createAudioBufferList(AudioBufferList * bufferList, int channels,
16+ int max_source_samples) {
1617 bufferList->mNumberBuffers = 1;
1718 bufferList->mBuffers[0].mNumberChannels = channels;
18− bufferList->mBuffers[0].mData = AUBIO_ARRAY(short, max_source_samples);
19− bufferList->mBuffers[0].mDataByteSize = max_source_samples * sizeof(short);
19+ bufferList->mBuffers[0].mData = AUBIO_ARRAY(smpl_t, max_source_samples);
20+ bufferList->mBuffers[0].mDataByteSize = max_source_samples * sizeof(smpl_t);
2021 return 0;
2122 }
2223
tests/src/io/base-sink_custom.h+167−0
@@ -0,0 +1,167 @@
1+// this should be included *after* custom functions have been defined
2+
3+#ifndef aubio_sink_custom
4+#define aubio_sink_custom "undefined"
5+#endif /* aubio_sink_custom */
6+
7+#ifdef HAVE_AUBIO_SINK_CUSTOM
8+int test_wrong_params(void);
9+
10+int base_main(int argc, char **argv)
11+{
12+ uint_t err = 0;
13+ if (argc < 3 || argc >= 6) {
14+ PRINT_ERR("wrong number of arguments, running tests\n");
15+ err = test_wrong_params();
16+ PRINT_MSG("usage: %s <input_path> <output_path> [samplerate] [hop_size]\n",
17+ argv[0]);
18+ return err;
19+ }
20+
21+ uint_t samplerate = 0;
22+ uint_t hop_size = 512;
23+ uint_t n_frames = 0, read = 0;
24+
25+ char_t *source_path = argv[1];
26+ char_t *sink_path = argv[2];
27+
28+ aubio_source_t *src = NULL;
29+ aubio_sink_custom_t *snk = NULL;
30+
31+ if ( argc >= 4 ) samplerate = atoi(argv[3]);
32+ if ( argc >= 5 ) hop_size = atoi(argv[4]);
33+
34+ fvec_t *vec = new_fvec(hop_size);
35+ if (!vec) { err = 1; goto failure; }
36+
37+ src = new_aubio_source(source_path, samplerate, hop_size);
38+ if (!src) { err = 1; goto failure; }
39+ if (samplerate == 0 ) samplerate = aubio_source_get_samplerate(src);
40+
41+ snk = new_aubio_sink_custom(sink_path, samplerate);
42+ if (!snk) { err = 1; goto failure; }
43+
44+ do {
45+ aubio_source_do(src, vec, &read);
46+ aubio_sink_custom_do(snk, vec, read);
47+ n_frames += read;
48+ } while ( read == hop_size );
49+
50+ PRINT_MSG("%d frames at %dHz (%d blocks) read from %s, wrote to %s\n",
51+ n_frames, samplerate, n_frames / hop_size,
52+ source_path, sink_path);
53+
54+ // close sink now (optional)
55+ aubio_sink_custom_close(snk);
56+
57+failure:
58+ if (snk)
59+ del_aubio_sink_custom(snk);
60+ if (src)
61+ del_aubio_source(src);
62+ if (vec)
63+ del_fvec(vec);
64+
65+ return err;
66+}
67+
68+int test_wrong_params(void)
69+{
70+ fvec_t *vec;
71+ fmat_t *mat;
72+ aubio_sink_custom_t *s;
73+ char_t sink_path[PATH_MAX] = "tmp_aubio_XXXXXX";
74+ uint_t samplerate = 44100;
75+ uint_t hop_size = 256;
76+ uint_t oversized_hop_size = 4097;
77+ uint_t oversized_samplerate = 192000 * 8 + 1;
78+ uint_t channels = 3;
79+ uint_t oversized_channels = 1025;
80+ // create temp file
81+ int fd = create_temp_sink(sink_path);
82+
83+ if (!fd) return 1;
84+
85+ if (new_aubio_sink_custom( 0, samplerate)) return 1;
86+ if (new_aubio_sink_custom("\0", samplerate)) return 1;
87+ if (new_aubio_sink_custom(sink_path, -1)) return 1;
88+
89+ s = new_aubio_sink_custom(sink_path, 0);
90+
91+ // check setting wrong parameters fails
92+ if (!aubio_sink_custom_preset_samplerate(s, oversized_samplerate)) return 1;
93+ if (!aubio_sink_custom_preset_channels(s, oversized_channels)) return 1;
94+ if (!aubio_sink_custom_preset_channels(s, -1)) return 1;
95+
96+ // check setting valid parameters passes
97+ if (aubio_sink_custom_preset_samplerate(s, samplerate)) return 1;
98+ if (aubio_sink_custom_preset_channels(s, 1)) return 1;
99+
100+ // check writing a vector with valid length
101+ vec = new_fvec(hop_size);
102+ aubio_sink_custom_do(s, vec, hop_size);
103+ // check writing more than in the input
104+ aubio_sink_custom_do(s, vec, hop_size+1);
105+ // check write 0 frames
106+ aubio_sink_custom_do(s, vec, 0);
107+ del_fvec(vec);
108+
109+ // check writing an oversized vector
110+ vec = new_fvec(oversized_hop_size);
111+ aubio_sink_custom_do(s, vec, oversized_hop_size);
112+ del_fvec(vec);
113+
114+ // test delete without closing
115+ del_aubio_sink_custom(s);
116+
117+ s = new_aubio_sink_custom(sink_path, 0);
118+
119+ // preset channels first
120+ if (aubio_sink_custom_preset_channels(s, channels)) return 1;
121+ if (aubio_sink_custom_preset_samplerate(s, samplerate)) return 1;
122+
123+ if (aubio_sink_custom_get_samplerate(s) != samplerate) return 1;
124+ if (aubio_sink_custom_get_channels(s) != channels) return 1;
125+
126+ mat = new_fmat(channels, hop_size);
127+ // check writing a vector with valid length
128+ aubio_sink_custom_do_multi(s, mat, hop_size);
129+ // check writing 0 frames
130+ aubio_sink_custom_do_multi(s, mat, 0);
131+ // check writing more than in the input
132+ aubio_sink_custom_do_multi(s, mat, hop_size+1);
133+ del_fmat(mat);
134+
135+ // check writing oversized input
136+ mat = new_fmat(channels, oversized_hop_size);
137+ aubio_sink_custom_do_multi(s, mat, oversized_hop_size);
138+ del_fmat(mat);
139+
140+ // check writing undersized input
141+ mat = new_fmat(channels - 1, hop_size);
142+ aubio_sink_custom_do_multi(s, mat, hop_size);
143+ del_fmat(mat);
144+
145+ aubio_sink_custom_close(s);
146+ // test closing twice
147+ aubio_sink_custom_close(s);
148+
149+ del_aubio_sink_custom(s);
150+
151+ // delete temp file
152+ close_temp_sink(sink_path, fd);
153+
154+ return run_on_default_source_and_sink(base_main);
155+}
156+
157+#else /* HAVE_AUBIO_SINK_CUSTOM */
158+
159+int base_main(int argc, char** argv)
160+{
161+ PRINT_ERR("aubio was not compiled with aubio_sink_"
162+ aubio_sink_custom ", failed running %s with %d args\n",
163+ argv[0], argc);
164+ return 0;
165+}
166+
167+#endif /* HAVE_AUBIO_SINK_CUSTOM */
tests/src/io/base-source_custom.h+125−0
@@ -0,0 +1,125 @@
1+// this should be included *after* custom functions have been defined
2+
3+#ifndef aubio_source_custom
4+#define aubio_source_custom "undefined"
5+#endif /* aubio_source_custom */
6+
7+#ifdef HAVE_AUBIO_SOURCE_CUSTOM
8+int test_wrong_params(void);
9+
10+int base_main(int argc, char **argv)
11+{
12+ uint_t err = 0;
13+ if (argc < 2) {
14+ PRINT_ERR("not enough arguments, running tests\n");
15+ err = test_wrong_params();
16+ PRINT_MSG("read a wave file as a mono vector\n");
17+ PRINT_MSG("usage: %s <source_path> [samplerate] [hop_size]\n", argv[0]);
18+ PRINT_MSG("examples:\n");
19+ PRINT_MSG(" - read file.wav at original samplerate\n");
20+ PRINT_MSG(" %s file.wav\n", argv[0]);
21+ PRINT_MSG(" - read file.wav at 32000Hz\n");
22+ PRINT_MSG(" %s file.aif 32000\n", argv[0]);
23+ PRINT_MSG(" - read file.wav at original samplerate with 4096 blocks\n");
24+ PRINT_MSG(" %s file.wav 0 4096 \n", argv[0]);
25+ return err;
26+ }
27+
28+ uint_t samplerate = 0;
29+ uint_t hop_size = 256;
30+ uint_t n_frames = 0, read = 0;
31+ if ( argc >= 3 ) samplerate = atoi(argv[2]);
32+ if ( argc >= 4 ) hop_size = atoi(argv[3]);
33+
34+ char_t *source_path = argv[1];
35+
36+ aubio_source_custom_t * s =
37+ new_aubio_source_custom(source_path, samplerate, hop_size);
38+ fvec_t *vec = new_fvec(hop_size);
39+ if (!s || !vec) { err = 1; goto beach; }
40+
41+ uint_t n_frames_expected = aubio_source_custom_get_duration(s);
42+
43+ samplerate = aubio_source_custom_get_samplerate(s);
44+
45+ do {
46+ aubio_source_custom_do(s, vec, &read);
47+ fvec_print (vec);
48+ n_frames += read;
49+ } while ( read == hop_size );
50+
51+ PRINT_MSG("read %d frames (expected %d) at %dHz (%d blocks) from %s\n",
52+ n_frames, n_frames_expected, samplerate, n_frames / hop_size,
53+ source_path);
54+
55+ // close the file (optional)
56+ aubio_source_custom_close(s);
57+
58+beach:
59+ if (vec)
60+ del_fvec(vec);
61+ if (s)
62+ del_aubio_source_custom(s);
63+ return err;
64+}
65+
66+int test_wrong_params(void)
67+{
68+ char_t *uri = DEFINEDSTRING(AUBIO_TESTS_SOURCE);
69+ uint_t samplerate = 44100;
70+ uint_t hop_size = 512;
71+ uint_t channels, read = 0;
72+ fvec_t *vec;
73+ fmat_t *mat;
74+ aubio_source_custom_t *s;
75+
76+ if (new_aubio_source_custom(0, samplerate, hop_size)) return 1;
77+ if (new_aubio_source_custom("\0", samplerate, hop_size)) return 1;
78+ if (new_aubio_source_custom(uri, -1, hop_size)) return 1;
79+ if (new_aubio_source_custom(uri, 0, 0)) return 1;
80+
81+ s = new_aubio_source_custom(uri, samplerate, hop_size);
82+ if (!s) return 1;
83+ channels = aubio_source_custom_get_channels(s);
84+
85+ // vector to read downmixed samples
86+ vec = new_fvec(hop_size);
87+ // matrix to read individual channels
88+ mat = new_fmat(channels, hop_size);
89+
90+ if (aubio_source_custom_get_samplerate(s) != samplerate) return 1;
91+
92+ // read first hop_size frames
93+ aubio_source_custom_do(s, vec, &read);
94+ if (read != hop_size) return 1;
95+
96+ // seek to 0
97+ if(aubio_source_custom_seek(s, 0)) return 1;
98+
99+ // read again as multiple channels
100+ aubio_source_custom_do_multi(s, mat, &read);
101+ if (read != hop_size) return 1;
102+
103+ // close the file (optional)
104+ aubio_source_custom_close(s);
105+ // test closing the file a second time
106+ aubio_source_custom_close(s);
107+
108+ del_aubio_source_custom(s);
109+ del_fmat(mat);
110+ del_fvec(vec);
111+
112+ return run_on_default_source(base_main);
113+}
114+
115+#else /* HAVE_AUBIO_SOURCE_CUSTOM */
116+
117+int base_main(int argc, char** argv)
118+{
119+ PRINT_ERR("aubio was not compiled with aubio_source_"
120+ aubio_source_custom ", failed running %s with %d args\n",
121+ argv[0], argc);
122+ return 0;
123+}
124+
125+#endif /* HAVE_AUBIO_SOURCE_CUSTOM */
tests/src/io/test-sink-multi.c+0−72
@@ -1,72 +0,0 @@
1−#include <aubio.h>
2−#include "utils_tests.h"
3−
4−// same as test-sink.c, but uses aubio_source_do_multi to read multiple
5−// channels
6−
7−int main (int argc, char **argv)
8−{
9− sint_t err = 0;
10−
11− if (argc < 3) {
12− PRINT_ERR("not enough arguments, running tests\n");
13− err = run_on_default_source_and_sink(main);
14− PRINT_MSG("usage: %s <input_path> <output_path> [samplerate] [channels] [hop_size]\n", argv[0]);
15− return err;
16− }
17−
18− uint_t samplerate = 0;
19− uint_t channels = 0;
20− uint_t hop_size = 512;
21− uint_t n_frames = 0, read = 0;
22−
23− char_t *source_path = argv[1];
24− char_t *sink_path = argv[2];
25−
26− if ( argc >= 4 ) samplerate = atoi(argv[3]);
27− if ( argc >= 5 ) channels = atoi(argv[4]);
28− if ( argc >= 6 ) hop_size = atoi(argv[5]);
29− if ( argc >= 7 ) {
30− err = 2;
31− PRINT_ERR("too many arguments\n");
32− return err;
33− }
34−
35− aubio_source_t *i = new_aubio_source(source_path, samplerate, hop_size);
36− if (!i) { err = 1; goto beach_source; }
37−
38− if (samplerate == 0 ) samplerate = aubio_source_get_samplerate(i);
39− if (channels == 0 ) channels = aubio_source_get_channels(i);
40−
41− fmat_t *mat = new_fmat(channels, hop_size);
42− if (!mat) { err = 1; goto beach_fmat; }
43−
44− aubio_sink_t *o = new_aubio_sink(sink_path, 0);
45− if (!o) { err = 1; goto beach_sink; }
46− err = aubio_sink_preset_samplerate(o, samplerate);
47− if (err) { goto beach; }
48− err = aubio_sink_preset_channels(o, channels);
49− if (err) { goto beach; }
50−
51− do {
52− aubio_source_do_multi(i, mat, &read);
53− aubio_sink_do_multi(o, mat, read);
54− n_frames += read;
55− } while ( read == hop_size );
56−
57− PRINT_MSG("read %d frames at %dHz in %d channels (%d blocks) from %s written to %s\n",
58− n_frames, samplerate, channels, n_frames / hop_size,
59− source_path, sink_path);
60− PRINT_MSG("wrote %s with %dHz in %d channels\n", sink_path,
61− aubio_sink_get_samplerate(o),
62− aubio_sink_get_channels(o) );
63−
64−beach:
65− del_aubio_sink(o);
66−beach_sink:
67− del_fmat(mat);
68−beach_fmat:
69− del_aubio_source(i);
70−beach_source:
71− return err;
72−}
tests/src/io/test-sink.c+121−28
@@ -1,14 +1,16 @@
11 #include <aubio.h>
22 #include "utils_tests.h"
33
4−int main (int argc, char **argv)
5−{
6− sint_t err = 0;
4+int test_wrong_params(void);
75
8− if (argc < 3) {
9− PRINT_ERR("not enough arguments, running tests\n");
10− err = run_on_default_source_and_sink(main);
11− PRINT_MSG("usage: %s <input_path> <output_path> [samplerate] [hop_size]\n", argv[0]);
6+int main(int argc, char **argv)
7+{
8+ uint_t err = 0;
9+ if (argc < 3 || argc >= 6) {
10+ PRINT_ERR("wrong number of arguments, running tests\n");
11+ err = test_wrong_params();
12+ PRINT_MSG("usage: %s <input_path> <output_path> [samplerate] [hop_size]\n",
13+ argv[0]);
1214 return err;
1315 }
1416
@@ -19,40 +21,131 @@ int main (int argc, char **argv) · 4 unmodified lines
1921 char_t *source_path = argv[1];
2022 char_t *sink_path = argv[2];
2123
24+ aubio_source_t *src = NULL;
25+ aubio_sink_t *snk = NULL;
26+
2227 if ( argc >= 4 ) samplerate = atoi(argv[3]);
2328 if ( argc >= 5 ) hop_size = atoi(argv[4]);
24− if ( argc >= 6 ) {
25− err = 2;
26− PRINT_ERR("too many arguments\n");
27− return err;
28− }
2929
3030 fvec_t *vec = new_fvec(hop_size);
31− if (!vec) { err = 1; goto beach_fvec; }
32−
33− aubio_source_t *i = new_aubio_source(source_path, samplerate, hop_size);
34− if (!i) { err = 1; goto beach_source; }
31+ if (!vec) { err = 1; goto failure; }
3532
36− if (samplerate == 0 ) samplerate = aubio_source_get_samplerate(i);
33+ src = new_aubio_source(source_path, samplerate, hop_size);
34+ if (!src) { err = 1; goto failure; }
35+ if (samplerate == 0 ) samplerate = aubio_source_get_samplerate(src);
3736
38− aubio_sink_t *o = new_aubio_sink(sink_path, samplerate);
39− if (!o) { err = 1; goto beach_sink; }
37+ snk = new_aubio_sink(sink_path, samplerate);
38+ if (!snk) { err = 1; goto failure; }
4039
4140 do {
42− aubio_source_do(i, vec, &read);
43− aubio_sink_do(o, vec, read);
41+ aubio_source_do(src, vec, &read);
42+ aubio_sink_do(snk, vec, read);
4443 n_frames += read;
4544 } while ( read == hop_size );
4645
47− PRINT_MSG("read %d frames at %dHz (%d blocks) from %s written to %s\n",
46+ PRINT_MSG("%d frames read at %dHz (%d blocks) from %s and written to %s\n",
4847 n_frames, samplerate, n_frames / hop_size,
4948 source_path, sink_path);
5049
51− del_aubio_sink(o);
52−beach_sink:
53− del_aubio_source(i);
54−beach_source:
55− del_fvec(vec);
56−beach_fvec:
50+ // close sink now (optional)
51+ aubio_sink_close(snk);
52+
53+failure:
54+ if (snk)
55+ del_aubio_sink(snk);
56+ if (src)
57+ del_aubio_source(src);
58+ if (vec)
59+ del_fvec(vec);
60+
5761 return err;
5862 }
63+
64+int test_wrong_params(void)
65+{
66+ fvec_t *vec;
67+ fmat_t *mat;
68+ aubio_sink_t *s;
69+ char_t sink_path[PATH_MAX] = "tmp_aubio_XXXXXX";
70+ uint_t samplerate = 44100;
71+ uint_t hop_size = 256;
72+ uint_t oversized_hop_size = 4097;
73+ uint_t oversized_samplerate = 192000 * 8 + 1;
74+ uint_t channels = 3;
75+ uint_t oversized_channels = 1025;
76+ // create temp file
77+ int fd = create_temp_sink(sink_path);
78+
79+ if (!fd) return 1;
80+
81+ if (new_aubio_sink( 0, samplerate)) return 1;
82+ if (new_aubio_sink("\0", samplerate)) return 1;
83+ if (new_aubio_sink(sink_path, -1)) return 1;
84+
85+ s = new_aubio_sink(sink_path, 0);
86+
87+ // check setting wrong parameters fails
88+ if (!aubio_sink_preset_samplerate(s, oversized_samplerate)) return 1;
89+ if (!aubio_sink_preset_channels(s, oversized_channels)) return 1;
90+ if (!aubio_sink_preset_channels(s, -1)) return 1;
91+
92+ // check setting valid parameters passes
93+ if (aubio_sink_preset_samplerate(s, samplerate)) return 1;
94+ if (aubio_sink_preset_channels(s, 1)) return 1;
95+
96+ // check writing a vector with valid length
97+ vec = new_fvec(hop_size);
98+ aubio_sink_do(s, vec, hop_size);
99+ // check writing more than in the input
100+ aubio_sink_do(s, vec, hop_size+1);
101+ // check write 0 frames
102+ aubio_sink_do(s, vec, 0);
103+ del_fvec(vec);
104+
105+ // check writing an oversized vector
106+ vec = new_fvec(oversized_hop_size);
107+ aubio_sink_do(s, vec, oversized_hop_size);
108+ del_fvec(vec);
109+
110+ // test delete without closing
111+ del_aubio_sink(s);
112+
113+ s = new_aubio_sink(sink_path, 0);
114+
115+ // preset channels first
116+ if (aubio_sink_preset_channels(s, channels)) return 1;
117+ if (aubio_sink_preset_samplerate(s, samplerate)) return 1;
118+
119+ if (aubio_sink_get_samplerate(s) != samplerate) return 1;
120+ if (aubio_sink_get_channels(s) != channels) return 1;
121+
122+ mat = new_fmat(channels, hop_size);
123+ // check writing a vector with valid length
124+ aubio_sink_do_multi(s, mat, hop_size);
125+ // check writing 0 frames
126+ aubio_sink_do_multi(s, mat, 0);
127+ // check writing more than in the input
128+ aubio_sink_do_multi(s, mat, hop_size+1);
129+ del_fmat(mat);
130+
131+ // check writing oversized input
132+ mat = new_fmat(channels, oversized_hop_size);
133+ aubio_sink_do_multi(s, mat, oversized_hop_size);
134+ del_fmat(mat);
135+
136+ // check writing undersized input
137+ mat = new_fmat(channels - 1, hop_size);
138+ aubio_sink_do_multi(s, mat, hop_size);
139+ del_fmat(mat);
140+
141+ aubio_sink_close(s);
142+ // test closing twice
143+ aubio_sink_close(s);
144+
145+ del_aubio_sink(s);
146+
147+ // delete temp file
148+ close_temp_sink(sink_path, fd);
149+
150+ return run_on_default_source_and_sink(main);
151+}
tests/src/io/test-sink_apple_audio-multi.c+0−78
@@ -1,78 +0,0 @@
1−#define AUBIO_UNSTABLE 1
2−#include <aubio.h>
3−#include "utils_tests.h"
4−
5−// this file uses the unstable aubio api to test aubio_sink_apple_audio, please
6−// use aubio_sink instead see src/io/sink.h and tests/src/sink/test-sink.c
7−
8−int main (int argc, char **argv)
9−{
10− sint_t err = 0;
11−
12− if (argc < 3) {
13− PRINT_ERR("not enough arguments, running tests\n");
14− err = run_on_default_source_and_sink(main);
15− PRINT_MSG("usage: %s <input_path> <output_path> [samplerate] [channels] [hop_size]\n", argv[0]);
16− return err;
17− }
18−
19−#ifdef HAVE_SINK_APPLE_AUDIO
20− uint_t samplerate = 0;
21− uint_t channels = 0;
22− uint_t hop_size = 512;
23− uint_t n_frames = 0, read = 0;
24−
25− char_t *source_path = argv[1];
26− char_t *sink_path = argv[2];
27−
28− if ( argc >= 4 ) samplerate = atoi(argv[3]);
29− if ( argc >= 5 ) channels = atoi(argv[4]);
30− if ( argc >= 6 ) hop_size = atoi(argv[5]);
31− if ( argc >= 7 ) {
32− err = 2;
33− PRINT_ERR("too many arguments\n");
34− return err;
35− }
36−
37− aubio_source_t *i = new_aubio_source(source_path, samplerate, hop_size);
38− if (!i) { err = 1; goto beach_source; }
39−
40− if (samplerate == 0 ) samplerate = aubio_source_get_samplerate(i);
41− if (channels == 0 ) channels = aubio_source_get_channels(i);
42−
43− fmat_t *mat = new_fmat(channels, hop_size);
44− if (!mat) { err = 1; goto beach_fmat; }
45−
46− aubio_sink_apple_audio_t *o = new_aubio_sink_apple_audio(sink_path, 0);
47− if (!o) { err = 1; goto beach_sink; }
48− err = aubio_sink_apple_audio_preset_samplerate(o, samplerate);
49− if (err) { goto beach; }
50− err = aubio_sink_apple_audio_preset_channels(o, channels);
51− if (err) { goto beach; }
52−
53− do {
54− aubio_source_do_multi(i, mat, &read);
55− aubio_sink_apple_audio_do_multi(o, mat, read);
56− n_frames += read;
57− } while ( read == hop_size );
58−
59− PRINT_MSG("read %d frames at %dHz in %d channels (%d blocks) from %s written to %s\n",
60− n_frames, samplerate, channels, n_frames / hop_size,
61− source_path, sink_path);
62− PRINT_MSG("wrote %s with %dHz in %d channels\n", sink_path,
63− aubio_sink_apple_audio_get_samplerate(o),
64− aubio_sink_apple_audio_get_channels(o) );
65−
66−beach:
67− del_aubio_sink_apple_audio(o);
68−beach_sink:
69− del_fmat(mat);
70−beach_fmat:
71− del_aubio_source(i);
72−beach_source:
73−#else /* HAVE_SINK_APPLE_AUDIO */
74− err = 0;
75− PRINT_ERR("aubio was not compiled with aubio_sink_apple_audio\n");
76−#endif /* HAVE_SINK_APPLE_AUDIO */
77− return err;
78−}
tests/src/io/test-sink_apple_audio.c+19−57
@@ -2,66 +2,28 @@ · 1 unmodified line
22 #include <aubio.h>
33 #include "utils_tests.h"
44
5−// this file uses the unstable aubio api, please use aubio_sink instead
6−// see src/io/sink.h and tests/src/sink/test-sink.c
7−
8−int main (int argc, char **argv)
9−{
10− sint_t err = 0;
11−
12− if (argc < 3) {
13− PRINT_ERR("not enough arguments, running tests\n");
14− err = run_on_default_source_and_sink(main);
15− PRINT_MSG("usage: %s <input_path> <output_path> [samplerate] [hop_size]\n", argv[0]);
16− return err;
17− }
5+#define aubio_sink_custom "apple_audio"
186
197 #ifdef HAVE_SINK_APPLE_AUDIO
20− uint_t samplerate = 0;
21− uint_t hop_size = 512;
22− uint_t n_frames = 0, read = 0;
23−
24− char_t *source_path = argv[1];
25− char_t *sink_path = argv[2];
26−
27− if ( argc >= 4 ) samplerate = atoi(argv[3]);
28− if ( argc >= 5 ) hop_size = atoi(argv[4]);
29− if ( argc >= 6 ) {
30− err = 2;
31− PRINT_ERR("too many arguments\n");
32− return err;
33− }
34−
35− fvec_t *vec = new_fvec(hop_size);
36− if (!vec) { err = 1; goto beach_fvec; }
37−
38− aubio_source_t *i = new_aubio_source(source_path, samplerate, hop_size);
39− if (!i) { err = 1; goto beach_source; }
40−
41− if (samplerate == 0 ) samplerate = aubio_source_get_samplerate(i);
42−
43− aubio_sink_apple_audio_t *o = new_aubio_sink_apple_audio(sink_path, samplerate);
44− if (!o) { err = 1; goto beach_sink; }
8+#define HAVE_AUBIO_SINK_CUSTOM
9+#define aubio_sink_custom_t aubio_sink_apple_audio_t
10+#define new_aubio_sink_custom new_aubio_sink_apple_audio
11+#define del_aubio_sink_custom del_aubio_sink_apple_audio
12+#define aubio_sink_custom_do aubio_sink_apple_audio_do
13+#define aubio_sink_custom_do_multi aubio_sink_apple_audio_do_multi
14+#define aubio_sink_custom_close aubio_sink_apple_audio_close
15+#define aubio_sink_custom_preset_samplerate aubio_sink_apple_audio_preset_samplerate
16+#define aubio_sink_custom_preset_channels aubio_sink_apple_audio_preset_channels
17+#define aubio_sink_custom_get_samplerate aubio_sink_apple_audio_get_samplerate
18+#define aubio_sink_custom_get_channels aubio_sink_apple_audio_get_channels
19+#endif /* HAVE_SINK_APPLE_AUDIO */
4520
46− do {
47− aubio_source_do(i, vec, &read);
48− aubio_sink_apple_audio_do(o, vec, read);
49− n_frames += read;
50− } while ( read == hop_size );
21+#include "base-sink_custom.h"
5122
52− PRINT_MSG("read %d frames at %dHz (%d blocks) from %s written to %s\n",
53− n_frames, samplerate, n_frames / hop_size,
54− source_path, sink_path);
23+// this file uses the unstable aubio api, please use aubio_sink instead
24+// see src/io/sink.h and tests/src/sink/test-sink.c
5525
56− del_aubio_sink_apple_audio(o);
57−beach_sink:
58− del_aubio_source(i);
59−beach_source:
60− del_fvec(vec);
61−beach_fvec:
62−#else /* HAVE_SINK_APPLE_AUDIO */
63− err = 0;
64− PRINT_ERR("aubio was not compiled with aubio_source_apple_audio\n");
65−#endif /* HAVE_SINK_APPLE_AUDIO */
66− return err;
26+int main (int argc, char **argv)
27+{
28+ return base_main(argc, argv);
6729 }
tests/src/io/test-sink_sndfile-multi.c+0−78
@@ -1,78 +0,0 @@
1−#define AUBIO_UNSTABLE 1
2−#include <aubio.h>
3−#include "utils_tests.h"
4−
5−// this file uses the unstable aubio api to test aubio_sink_sndfile, please
6−// use aubio_sink instead see src/io/sink.h and tests/src/sink/test-sink.c
7−
8−int main (int argc, char **argv)
9−{
10− sint_t err = 0;
11−
12− if (argc < 3) {
13− PRINT_ERR("not enough arguments, running tests\n");
14− err = run_on_default_source_and_sink(main);
15− PRINT_MSG("usage: %s <input_path> <output_path> [samplerate] [channels] [hop_size]\n", argv[0]);
16− return err;
17− }
18−
19−#ifdef HAVE_SNDFILE
20− uint_t samplerate = 0;
21− uint_t channels = 0;
22− uint_t hop_size = 512;
23− uint_t n_frames = 0, read = 0;
24−
25− char_t *source_path = argv[1];
26− char_t *sink_path = argv[2];
27−
28− if ( argc >= 4 ) samplerate = atoi(argv[3]);
29− if ( argc >= 5 ) channels = atoi(argv[4]);
30− if ( argc >= 6 ) hop_size = atoi(argv[5]);
31− if ( argc >= 7 ) {
32− err = 2;
33− PRINT_ERR("too many arguments\n");
34− return err;
35− }
36−
37− aubio_source_t *i = new_aubio_source(source_path, samplerate, hop_size);
38− if (!i) { err = 1; goto beach_source; }
39−
40− if (samplerate == 0 ) samplerate = aubio_source_get_samplerate(i);
41− if (channels == 0 ) channels = aubio_source_get_channels(i);
42−
43− fmat_t *mat = new_fmat(channels, hop_size);
44− if (!mat) { err = 1; goto beach_fmat; }
45−
46− aubio_sink_sndfile_t *o = new_aubio_sink_sndfile(sink_path, 0);
47− if (!o) { err = 1; goto beach_sink; }
48− err = aubio_sink_sndfile_preset_samplerate(o, samplerate);
49− if (err) { goto beach; }
50− err = aubio_sink_sndfile_preset_channels(o, channels);
51− if (err) { goto beach; }
52−
53− do {
54− aubio_source_do_multi(i, mat, &read);
55− aubio_sink_sndfile_do_multi(o, mat, read);
56− n_frames += read;
57− } while ( read == hop_size );
58−
59− PRINT_MSG("read %d frames at %dHz in %d channels (%d blocks) from %s written to %s\n",
60− n_frames, samplerate, channels, n_frames / hop_size,
61− source_path, sink_path);
62− PRINT_MSG("wrote %s with %dHz in %d channels\n", sink_path,
63− aubio_sink_sndfile_get_samplerate(o),
64− aubio_sink_sndfile_get_channels(o) );
65−
66−beach:
67− del_aubio_sink_sndfile(o);
68−beach_sink:
69− del_fmat(mat);
70−beach_fmat:
71− del_aubio_source(i);
72−beach_source:
73−#else
74− err = 0;
75− PRINT_ERR("aubio was not compiled with aubio_sink_sndfile\n");
76−#endif /* HAVE_SNDFILE */
77− return err;
78−}
tests/src/io/test-sink_sndfile.c+19−57
@@ -2,66 +2,28 @@ · 1 unmodified line
22 #include <aubio.h>
33 #include "utils_tests.h"
44
5−// this file uses the unstable aubio api, please use aubio_sink instead
6−// see src/io/sink.h and tests/src/sink/test-sink.c
7−
8−int main (int argc, char **argv)
9−{
10− sint_t err = 0;
11−
12− if (argc < 3) {
13− PRINT_ERR("not enough arguments, running tests\n");
14− err = run_on_default_source_and_sink(main);
15− PRINT_MSG("usage: %s <input_path> <output_path> [samplerate] [hop_size]\n", argv[0]);
16− return err;
17− }
5+#define aubio_sink_custom "sndfile"
186
197 #ifdef HAVE_SNDFILE
20− uint_t samplerate = 0;
21− uint_t hop_size = 512;
22− uint_t n_frames = 0, read = 0;
23−
24− char_t *source_path = argv[1];
25− char_t *sink_path = argv[2];
26−
27− if ( argc >= 4 ) samplerate = atoi(argv[3]);
28− if ( argc >= 5 ) hop_size = atoi(argv[4]);
29− if ( argc >= 6 ) {
30− err = 2;
31− PRINT_ERR("too many arguments\n");
32− return err;
33− }
34−
35− fvec_t *vec = new_fvec(hop_size);
36− if (!vec) { err = 1; goto beach_fvec; }
37−
38− aubio_source_t *i = new_aubio_source(source_path, samplerate, hop_size);
39− if (!i) { err = 1; goto beach_source; }
40−
41− if (samplerate == 0 ) samplerate = aubio_source_get_samplerate(i);
42−
43− aubio_sink_sndfile_t *o = new_aubio_sink_sndfile(sink_path, samplerate);
44− if (!o) { err = 1; goto beach_sink; }
8+#define HAVE_AUBIO_SINK_CUSTOM
9+#define aubio_sink_custom_t aubio_sink_sndfile_t
10+#define new_aubio_sink_custom new_aubio_sink_sndfile
11+#define del_aubio_sink_custom del_aubio_sink_sndfile
12+#define aubio_sink_custom_do aubio_sink_sndfile_do
13+#define aubio_sink_custom_do_multi aubio_sink_sndfile_do_multi
14+#define aubio_sink_custom_close aubio_sink_sndfile_close
15+#define aubio_sink_custom_preset_samplerate aubio_sink_sndfile_preset_samplerate
16+#define aubio_sink_custom_preset_channels aubio_sink_sndfile_preset_channels
17+#define aubio_sink_custom_get_samplerate aubio_sink_sndfile_get_samplerate
18+#define aubio_sink_custom_get_channels aubio_sink_sndfile_get_channels
19+#endif /* HAVE_SNDFILE */
4520
46− do {
47− aubio_source_do(i, vec, &read);
48− aubio_sink_sndfile_do(o, vec, read);
49− n_frames += read;
50− } while ( read == hop_size );
21+#include "base-sink_custom.h"
5122
52− PRINT_MSG("read %d frames at %dHz (%d blocks) from %s written to %s\n",
53− n_frames, samplerate, n_frames / hop_size,
54− source_path, sink_path);
23+// this file uses the unstable aubio api, please use aubio_sink instead
24+// see src/io/sink.h and tests/src/sink/test-sink.c
5525
56− del_aubio_sink_sndfile(o);
57−beach_sink:
58− del_aubio_source(i);
59−beach_source:
60− del_fvec(vec);
61−beach_fvec:
62−#else
63− err = 0;
64− PRINT_ERR("aubio was not compiled with aubio_source_sndfile\n");
65−#endif /* HAVE_SNDFILE */
66− return err;
26+int main (int argc, char **argv)
27+{
28+ return base_main(argc, argv);
6729 }
tests/src/io/test-sink_wavwrite-multi.c+0−78
@@ -1,78 +0,0 @@
1−#define AUBIO_UNSTABLE 1
2−#include <aubio.h>
3−#include "utils_tests.h"
4−
5−// this file uses the unstable aubio api to test aubio_sink_wavwrite, please
6−// use aubio_sink instead see src/io/sink.h and tests/src/sink/test-sink.c
7−
8−int main (int argc, char **argv)
9−{
10− sint_t err = 0;
11−
12− if (argc < 3) {
13− PRINT_ERR("not enough arguments, running tests\n");
14− err = run_on_default_source_and_sink(main);
15− PRINT_MSG("usage: %s <input_path> <output_path> [samplerate] [channels] [hop_size]\n", argv[0]);
16− return err;
17− }
18−
19−#ifdef HAVE_WAVWRITE
20− uint_t samplerate = 0;
21− uint_t channels = 0;
22− uint_t hop_size = 512;
23− uint_t n_frames = 0, read = 0;
24−
25− char_t *source_path = argv[1];
26− char_t *sink_path = argv[2];
27−
28− if ( argc >= 4 ) samplerate = atoi(argv[3]);
29− if ( argc >= 5 ) channels = atoi(argv[4]);
30− if ( argc >= 6 ) hop_size = atoi(argv[5]);
31− if ( argc >= 7 ) {
32− err = 2;
33− PRINT_ERR("too many arguments\n");
34− return err;
35− }
36−
37− aubio_source_t *i = new_aubio_source(source_path, samplerate, hop_size);
38− if (!i) { err = 1; goto beach_source; }
39−
40− if (samplerate == 0 ) samplerate = aubio_source_get_samplerate(i);
41− if (channels == 0 ) channels = aubio_source_get_channels(i);
42−
43− fmat_t *mat = new_fmat(channels, hop_size);
44− if (!mat) { err = 1; goto beach_fmat; }
45−
46− aubio_sink_wavwrite_t *o = new_aubio_sink_wavwrite(sink_path, 0);
47− if (!o) { err = 1; goto beach_sink; }
48− err = aubio_sink_wavwrite_preset_samplerate(o, samplerate);
49− if (err) { goto beach; }
50− err = aubio_sink_wavwrite_preset_channels(o, channels);
51− if (err) { goto beach; }
52−
53− do {
54− aubio_source_do_multi(i, mat, &read);
55− aubio_sink_wavwrite_do_multi(o, mat, read);
56− n_frames += read;
57− } while ( read == hop_size );
58−
59− PRINT_MSG("read %d frames at %dHz in %d channels (%d blocks) from %s written to %s\n",
60− n_frames, samplerate, channels, n_frames / hop_size,
61− source_path, sink_path);
62− PRINT_MSG("wrote %s with %dHz in %d channels\n", sink_path,
63− aubio_sink_wavwrite_get_samplerate(o),
64− aubio_sink_wavwrite_get_channels(o) );
65−
66−beach:
67− del_aubio_sink_wavwrite(o);
68−beach_sink:
69− del_fmat(mat);
70−beach_fmat:
71− del_aubio_source(i);
72−beach_source:
73−#else
74− err = 0;
75− PRINT_ERR("aubio was not compiled with aubio_sink_wavwrite\n");
76−#endif /* HAVE_WAVWRITE */
77− return err;
78−}
tests/src/io/test-sink_wavwrite.c+19−57
@@ -2,66 +2,28 @@ · 1 unmodified line
22 #include <aubio.h>
33 #include "utils_tests.h"
44
5−// this file uses the unstable aubio api, please use aubio_sink instead
6−// see src/io/sink.h and tests/src/sink/test-sink.c
7−
8−int main (int argc, char **argv)
9−{
10− sint_t err = 0;
11−
12− if (argc < 3) {
13− PRINT_ERR("not enough arguments, running tests\n");
14− err = run_on_default_source_and_sink(main);
15− PRINT_MSG("usage: %s <input_path> <output_path> [samplerate] [hop_size]\n", argv[0]);
16− return err;
17− }
5+#define aubio_sink_custom "wavwrite"
186
197 #ifdef HAVE_WAVWRITE
20− uint_t samplerate = 0;
21− uint_t hop_size = 512;
22− uint_t n_frames = 0, read = 0;
23−
24− char_t *source_path = argv[1];
25− char_t *sink_path = argv[2];
26−
27− if ( argc >= 4 ) samplerate = atoi(argv[3]);
28− if ( argc >= 5 ) hop_size = atoi(argv[4]);
29− if ( argc >= 6 ) {
30− err = 2;
31− PRINT_ERR("too many arguments\n");
32− return err;
33− }
34−
35− fvec_t *vec = new_fvec(hop_size);
36− if (!vec) { err = 1; goto beach_fvec; }
37−
38− aubio_source_t *i = new_aubio_source(source_path, samplerate, hop_size);
39− if (!i) { err = 1; goto beach_source; }
40−
41− if (samplerate == 0 ) samplerate = aubio_source_get_samplerate(i);
42−
43− aubio_sink_wavwrite_t *o = new_aubio_sink_wavwrite(sink_path, samplerate);
44− if (!o) { err = 1; goto beach_sink; }
8+#define HAVE_AUBIO_SINK_CUSTOM
9+#define aubio_sink_custom_t aubio_sink_wavwrite_t
10+#define new_aubio_sink_custom new_aubio_sink_wavwrite
11+#define del_aubio_sink_custom del_aubio_sink_wavwrite
12+#define aubio_sink_custom_do aubio_sink_wavwrite_do
13+#define aubio_sink_custom_do_multi aubio_sink_wavwrite_do_multi
14+#define aubio_sink_custom_close aubio_sink_wavwrite_close
15+#define aubio_sink_custom_preset_samplerate aubio_sink_wavwrite_preset_samplerate
16+#define aubio_sink_custom_preset_channels aubio_sink_wavwrite_preset_channels
17+#define aubio_sink_custom_get_samplerate aubio_sink_wavwrite_get_samplerate
18+#define aubio_sink_custom_get_channels aubio_sink_wavwrite_get_channels
19+#endif /* HAVE_WAVWRITE */
4520
46− do {
47− aubio_source_do(i, vec, &read);
48− aubio_sink_wavwrite_do(o, vec, read);
49− n_frames += read;
50− } while ( read == hop_size );
21+#include "base-sink_custom.h"
5122
52− PRINT_MSG("read %d frames at %dHz (%d blocks) from %s written to %s\n",
53− n_frames, samplerate, n_frames / hop_size,
54− source_path, sink_path);
23+// this file uses the unstable aubio api, please use aubio_sink instead
24+// see src/io/sink.h and tests/src/sink/test-sink.c
5525
56− del_aubio_sink_wavwrite(o);
57−beach_sink:
58− del_aubio_source(i);
59−beach_source:
60− del_fvec(vec);
61−beach_fvec:
62−#else
63− err = 0;
64− PRINT_ERR("aubio was not compiled with aubio_sink_wavwrite\n");
65−#endif /* HAVE_WAVWRITE */
66− return err;
26+int main (int argc, char **argv)
27+{
28+ return base_main(argc, argv);
6729 }
tests/src/io/test-source.c+58−8
@@ -1,12 +1,14 @@
11 #include <aubio.h>
22 #include "utils_tests.h"
33
4−int main (int argc, char **argv)
4+int test_wrong_params(void);
5+
6+int main(int argc, char **argv)
57 {
68 uint_t err = 0;
79 if (argc < 2) {
810 PRINT_ERR("not enough arguments, running tests\n");
9− err = run_on_default_source(main);
11+ err = test_wrong_params();
1012 PRINT_MSG("read a wave file as a mono vector\n");
1113 PRINT_MSG("usage: %s <source_path> [samplerate] [hop_size]\n", argv[0]);
1214 PRINT_MSG("examples:\n");
@@ -27,11 +29,10 @@ int main (int argc, char **argv) · 14 unmodified lines
2729
2830 char_t *source_path = argv[1];
2931
30−
3132 aubio_source_t* s =
3233 new_aubio_source(source_path, samplerate, hop_size);
33− if (!s) { err = 1; goto beach; }
3434 fvec_t *vec = new_fvec(hop_size);
35+ if (!s || !vec) { err = 1; goto beach; }
3536
3637 uint_t n_frames_expected = aubio_source_get_duration(s);
3738
@@ -49,11 +50,60 @@ int main (int argc, char **argv) · 11 unmodified lines
4950
5051 // close the file (optional)
5152 aubio_source_close(s);
52− // test closing the file a second time
53− aubio_source_close(s);
5453
55− del_fvec (vec);
56− del_aubio_source (s);
5754 beach:
55+ if (vec)
56+ del_fvec(vec);
57+ if (s)
58+ del_aubio_source(s);
5859 return err;
5960 }
61+
62+int test_wrong_params(void)
63+{
64+ char_t *uri = DEFINEDSTRING(AUBIO_TESTS_SOURCE);
65+ uint_t samplerate = 44100;
66+ uint_t hop_size = 512;
67+ uint_t channels, read = 0;
68+ fvec_t *vec;
69+ fmat_t *mat;
70+ aubio_source_t *s;
71+
72+ if (new_aubio_source(0, samplerate, hop_size)) return 1;
73+ if (new_aubio_source("\0", samplerate, hop_size)) return 1;
74+ if (new_aubio_source(uri, -1, hop_size)) return 1;
75+ if (new_aubio_source(uri, 0, 0)) return 1;
76+
77+ s = new_aubio_source(uri, samplerate, hop_size);
78+ if (!s) return 1;
79+ channels = aubio_source_get_channels(s);
80+
81+ // vector to read downmixed samples
82+ vec = new_fvec(hop_size);
83+ // matrix to read individual channels
84+ mat = new_fmat(channels, hop_size);
85+
86+ if (aubio_source_get_samplerate(s) != samplerate) return 1;
87+
88+ // read first hop_size frames
89+ aubio_source_do(s, vec, &read);
90+ if (read != hop_size) return 1;
91+
92+ // seek to 0
93+ if(aubio_source_seek(s, 0)) return 1;
94+
95+ // read again as multiple channels
96+ aubio_source_do_multi(s, mat, &read);
97+ if (read != hop_size) return 1;
98+
99+ // close the file (optional)
100+ aubio_source_close(s);
101+ // test closing the file a second time
102+ aubio_source_close(s);
103+
104+ del_aubio_source(s);
105+ del_fmat(mat);
106+ del_fvec(vec);
107+
108+ return run_on_default_source(main);
109+}
tests/src/io/test-source_apple_audio.c+20−53
@@ -2,62 +2,29 @@ · 1 unmodified line
22 #include <aubio.h>
33 #include "utils_tests.h"
44
5+#define aubio_source_custom "apple_audio"
6+
7+#ifdef HAVE_SOURCE_APPLE_AUDIO
8+#define HAVE_AUBIO_SOURCE_CUSTOM
9+#define aubio_source_custom_t aubio_source_apple_audio_t
10+#define new_aubio_source_custom new_aubio_source_apple_audio
11+#define del_aubio_source_custom del_aubio_source_apple_audio
12+#define aubio_source_custom_get_samplerate aubio_source_apple_audio_get_samplerate
13+#define aubio_source_custom_get_duration aubio_source_apple_audio_get_duration
14+#define aubio_source_custom_do aubio_source_apple_audio_do
15+#define aubio_source_custom_do_multi aubio_source_apple_audio_do_multi
16+#define aubio_source_custom_seek aubio_source_apple_audio_seek
17+#define aubio_source_custom_close aubio_source_apple_audio_close
18+#define aubio_source_custom_get_channels aubio_source_apple_audio_get_channels
19+#define aubio_source_custom_get_samplerate aubio_source_apple_audio_get_samplerate
20+#endif /* HAVE_SOURCE_APPLE_AUDIO */
21+
22+#include "base-source_custom.h"
23+
524 // this file uses the unstable aubio api, please use aubio_source instead
625 // see src/io/source.h and tests/src/source/test-source.c
726
827 int main (int argc, char **argv)
928 {
10− uint_t err = 0;
11− if (argc < 2) {
12− PRINT_ERR("not enough arguments, running tests\n");
13− err = run_on_default_source(main);
14− PRINT_MSG("read a wave file as a mono vector\n");
15− PRINT_MSG("usage: %s <source_path> [samplerate] [hop_size]\n", argv[0]);
16− PRINT_MSG("examples:\n");
17− PRINT_MSG(" - read file.wav at original samplerate\n");
18− PRINT_MSG(" %s file.wav\n", argv[0]);
19− PRINT_MSG(" - read file.aif at 32000Hz\n");
20− PRINT_MSG(" %s file.aif 32000\n", argv[0]);
21− PRINT_MSG(" - read file.mp3 at original samplerate with 4096 blocks\n");
22− PRINT_MSG(" %s file.mp3 0 4096 \n", argv[0]);
23− return err;
24− }
25−
26−#if HAVE_SOURCE_APPLE_AUDIO
27− uint_t samplerate = 0;
28− uint_t hop_size = 256;
29− uint_t n_frames = 0, read = 0;
30− if ( argc >= 3 ) samplerate = atoi(argv[2]);
31− if ( argc >= 4 ) hop_size = atoi(argv[3]);
32−
33− char_t *source_path = argv[1];
34−
35−
36− aubio_source_apple_audio_t * s =
37− new_aubio_source_apple_audio(source_path, samplerate, hop_size);
38− if (!s) { err = 1; goto beach; }
39− fvec_t *vec = new_fvec(hop_size);
40−
41− uint_t n_frames_expected = aubio_source_apple_audio_get_duration(s);
42−
43− samplerate = aubio_source_apple_audio_get_samplerate(s);
44−
45− do {
46− aubio_source_apple_audio_do(s, vec, &read);
47− fvec_print (vec);
48− n_frames += read;
49− } while ( read == hop_size );
50−
51− PRINT_MSG("read %d frames (expected %d) at %dHz (%d blocks) from %s\n",
52− n_frames, n_frames_expected, samplerate, n_frames / hop_size,
53− source_path);
54−
55− del_fvec (vec);
56− del_aubio_source_apple_audio (s);
57−beach:
58−#else /* HAVE_SOURCE_APPLE_AUDIO */
59− err = 0;
60− PRINT_ERR("aubio was not compiled with aubio_source_apple_audio\n");
61−#endif /* HAVE_SOURCE_APPLE_AUDIO */
62− return err;
29+ return base_main(argc, argv);
6330 }
tests/src/io/test-source_avcodec.c+20−53
@@ -2,62 +2,29 @@ · 1 unmodified line
22 #include <aubio.h>
33 #include "utils_tests.h"
44
5−// this file uses the unstable aubio api, please use aubio_source instead
6−// see src/io/source.h and tests/src/source/test-source.c
7−
8−int main (int argc, char **argv)
9−{
10− uint_t err = 0;
11− if (argc < 2) {
12− PRINT_ERR("not enough arguments, running tests\n");
13− err = run_on_default_source(main);
14− PRINT_MSG("read a wave file as a mono vector\n");
15− PRINT_MSG("usage: %s <source_path> [samplerate] [hop_size]\n", argv[0]);
16− PRINT_MSG("examples:\n");
17− PRINT_MSG(" - read file.wav at original samplerate\n");
18− PRINT_MSG(" %s file.wav\n", argv[0]);
19− PRINT_MSG(" - read file.wav at 32000Hz\n");
20− PRINT_MSG(" %s file.aif 32000\n", argv[0]);
21− PRINT_MSG(" - read file.wav at original samplerate with 4096 blocks\n");
22− PRINT_MSG(" %s file.wav 0 4096 \n", argv[0]);
23− return err;
24− }
5+#define aubio_source_custom "avcodec"
256
267 #ifdef HAVE_LIBAV
27− uint_t samplerate = 0;
28− uint_t hop_size = 256;
29− uint_t n_frames = 0, read = 0;
30− if ( argc >= 3 ) samplerate = atoi(argv[2]);
31− if ( argc >= 4 ) hop_size = atoi(argv[3]);
32−
33− char_t *source_path = argv[1];
34−
35−
36− aubio_source_avcodec_t * s =
37− new_aubio_source_avcodec(source_path, samplerate, hop_size);
38− if (!s) { err = 1; goto beach; }
39− fvec_t *vec = new_fvec(hop_size);
40−
41− uint_t n_frames_expected = aubio_source_avcodec_get_duration(s);
42−
43− samplerate = aubio_source_avcodec_get_samplerate(s);
8+#define HAVE_AUBIO_SOURCE_CUSTOM
9+#define aubio_source_custom_t aubio_source_avcodec_t
10+#define new_aubio_source_custom new_aubio_source_avcodec
11+#define del_aubio_source_custom del_aubio_source_avcodec
12+#define aubio_source_custom_get_samplerate aubio_source_avcodec_get_samplerate
13+#define aubio_source_custom_get_duration aubio_source_avcodec_get_duration
14+#define aubio_source_custom_do aubio_source_avcodec_do
15+#define aubio_source_custom_do_multi aubio_source_avcodec_do_multi
16+#define aubio_source_custom_seek aubio_source_avcodec_seek
17+#define aubio_source_custom_close aubio_source_avcodec_close
18+#define aubio_source_custom_get_channels aubio_source_avcodec_get_channels
19+#define aubio_source_custom_get_samplerate aubio_source_avcodec_get_samplerate
20+#endif /* HAVE_LIBAV */
4421
45− do {
46− aubio_source_avcodec_do(s, vec, &read);
47− fvec_print (vec);
48− n_frames += read;
49− } while ( read == hop_size );
22+#include "base-source_custom.h"
5023
51− PRINT_MSG("read %d frames (expected %d) at %dHz (%d blocks) from %s\n",
52− n_frames, n_frames_expected, samplerate, n_frames / hop_size,
53− source_path);
24+// this file uses the unstable aubio api, please use aubio_source instead
25+// see src/io/source.h and tests/src/source/test-source.c
5426
55− del_fvec (vec);
56− del_aubio_source_avcodec (s);
57−beach:
58−#else /* HAVE_LIBAV */
59− err = 0;
60− PRINT_ERR("aubio was not compiled with aubio_source_avcodec\n");
61−#endif /* HAVE_LIBAV */
62− return err;
27+int main (int argc, char **argv)
28+{
29+ return base_main(argc, argv);
6330 }
tests/src/io/test-source_multi.c+0−57
@@ -1,57 +0,0 @@
1−#include <aubio.h>
2−#include "utils_tests.h"
3−
4−int main (int argc, char **argv)
5−{
6− sint_t err = 0;
7− if (argc < 2) {
8− PRINT_ERR("not enough arguments, running tests\n");
9− err = run_on_default_source(main);
10− PRINT_MSG("read a wave file as a mono vector\n");
11− PRINT_MSG("usage: %s <source_path> [samplerate] [hop_size]\n", argv[0]);
12− PRINT_MSG("examples:\n");
13− PRINT_MSG(" - read file.wav at original samplerate\n");
14− PRINT_MSG(" %s file.wav\n", argv[0]);
15− PRINT_MSG(" - read file.wav at 32000Hz\n");
16− PRINT_MSG(" %s file.aif 32000\n", argv[0]);
17− PRINT_MSG(" - read file.wav at original samplerate with 4096 blocks\n");
18− PRINT_MSG(" %s file.wav 0 4096 \n", argv[0]);
19− PRINT_MSG(" - read file.wav at original samplerate with 256 frames blocks, mono\n");
20− PRINT_MSG(" %s file.wav 0 4096 1\n", argv[0]);
21− return err;
22− }
23−
24− uint_t samplerate = 0;
25− uint_t hop_size = 256;
26− uint_t n_frames = 0, read = 0;
27− uint_t n_channels = 0;
28− if ( argc >= 3 ) samplerate = atoi(argv[2]);
29− if ( argc >= 4 ) hop_size = atoi(argv[3]);
30− if ( argc >= 5 ) n_channels = atoi(argv[4]);
31−
32− char_t *source_path = argv[1];
33−
34− aubio_source_t* s = new_aubio_source(source_path, samplerate, hop_size);
35− if (!s) { err = -1; goto beach; }
36−
37− if ( samplerate == 0 ) samplerate = aubio_source_get_samplerate(s);
38−
39− if ( n_channels == 0 ) n_channels = aubio_source_get_channels(s);
40−
41− fmat_t *mat = new_fmat(n_channels, hop_size);
42−
43− do {
44− aubio_source_do_multi (s, mat, &read);
45− fmat_print (mat);
46− n_frames += read;
47− } while ( read == hop_size );
48−
49− PRINT_MSG("read %d frames in %d channels at %dHz (%d blocks) from %s\n",
50− n_frames, n_channels, samplerate, n_frames / hop_size, source_path);
51−
52− del_fmat (mat);
53− del_aubio_source (s);
54−beach:
55−
56− return err;
57−}
tests/src/io/test-source_seek.c+0−92
@@ -1,92 +0,0 @@
1−#include <aubio.h>
2−#include "utils_tests.h"
3−
4−int main (int argc, char **argv)
5−{
6− uint_t err = 0;
7− if (argc < 2) {
8− PRINT_ERR("not enough arguments, running tests\n");
9− err = run_on_default_source(main);
10− PRINT_MSG("read a wave file as a mono vector\n");
11− PRINT_MSG("usage: %s <source_path> [samplerate] [hop_size]\n", argv[0]);
12− PRINT_MSG("examples:\n");
13− PRINT_MSG(" - read file.wav at original samplerate\n");
14− PRINT_MSG(" %s file.wav\n", argv[0]);
15− PRINT_MSG(" - read file.wav at 32000Hz\n");
16− PRINT_MSG(" %s file.aif 32000\n", argv[0]);
17− PRINT_MSG(" - read file.wav at original samplerate with 4096 blocks\n");
18− PRINT_MSG(" %s file.wav 0 4096 \n", argv[0]);
19− return err;
20− }
21−
22− uint_t samplerate = 0;
23− uint_t hop_size = 256;
24− uint_t n_frames = 0, read = 0;
25− uint_t old_n_frames_1 = 0, old_n_frames_2 = 0, old_n_frames_3 = 0;
26− if ( argc >= 3 ) samplerate = atoi(argv[2]);
27− if ( argc >= 4 ) hop_size = atoi(argv[3]);
28−
29− char_t *source_path = argv[1];
30−
31− fvec_t *vec = new_fvec(hop_size);
32−
33− aubio_source_t* s = new_aubio_source(source_path, samplerate, hop_size);
34− if (!s) { err = 1; goto beach; }
35−
36− if (samplerate == 0 ) samplerate = aubio_source_get_samplerate(s);
37−
38− do {
39− aubio_source_do(s, vec, &read);
40− //fvec_print (vec);
41− n_frames += read;
42− } while ( read == hop_size );
43−
44− PRINT_MSG("read %.2fs, %d frames at %dHz (%d blocks) from %s\n",
45− n_frames * 1. / samplerate,
46− n_frames, samplerate,
47− n_frames / hop_size, source_path);
48−
49− old_n_frames_1 = n_frames;
50−
51− aubio_source_seek (s, 0);
52−
53− n_frames = 0;
54− do {
55− aubio_source_do(s, vec, &read);
56− //fvec_print (vec);
57− n_frames += read;
58− } while ( read == hop_size );
59−
60− PRINT_MSG("read %.2fs, %d frames at %dHz (%d blocks) from %s\n",
61− n_frames * 1. / samplerate,
62− n_frames, samplerate,
63− n_frames / hop_size, source_path);
64−
65− old_n_frames_2 = n_frames;
66−
67− aubio_source_seek (s, old_n_frames_1 / 2);
68−
69− n_frames = 0;
70− do {
71− aubio_source_do(s, vec, &read);
72− //fvec_print (vec);
73− n_frames += read;
74− } while ( read == hop_size );
75−
76− PRINT_MSG("read %.2fs, %d frames at %dHz (%d blocks) from %s\n",
77− n_frames * 1. / samplerate,
78− n_frames, samplerate,
79− n_frames / hop_size, source_path);
80−
81− old_n_frames_3 = n_frames;
82−
83− del_aubio_source (s);
84−beach:
85− del_fvec (vec);
86−
87− // check that we got exactly the same number of frames
88− assert ( old_n_frames_2 == old_n_frames_1 );
89− // check that we got about half the frames, with 3 decimals
90− assert ( roundf(1.e3 * old_n_frames_1 / old_n_frames_3) / 1.e3 == 2.);
91− return err;
92−}
tests/src/io/test-source_sndfile.c+20−53
@@ -2,62 +2,29 @@ · 1 unmodified line
22 #include <aubio.h>
33 #include "utils_tests.h"
44
5+#define aubio_source_custom "sndfile"
6+
7+#ifdef HAVE_SNDFILE
8+#define HAVE_AUBIO_SOURCE_CUSTOM
9+#define aubio_source_custom_t aubio_source_sndfile_t
10+#define new_aubio_source_custom new_aubio_source_sndfile
11+#define del_aubio_source_custom del_aubio_source_sndfile
12+#define aubio_source_custom_get_samplerate aubio_source_sndfile_get_samplerate
13+#define aubio_source_custom_get_duration aubio_source_sndfile_get_duration
14+#define aubio_source_custom_do aubio_source_sndfile_do
15+#define aubio_source_custom_do_multi aubio_source_sndfile_do_multi
16+#define aubio_source_custom_seek aubio_source_sndfile_seek
17+#define aubio_source_custom_close aubio_source_sndfile_close
18+#define aubio_source_custom_get_channels aubio_source_sndfile_get_channels
19+#define aubio_source_custom_get_samplerate aubio_source_sndfile_get_samplerate
20+#endif /* HAVE_LIBAV */
21+
22+#include "base-source_custom.h"
23+
524 // this file uses the unstable aubio api, please use aubio_source instead
625 // see src/io/source.h and tests/src/source/test-source.c
726
827 int main (int argc, char **argv)
928 {
10− uint_t err = 0;
11− if (argc < 2) {
12− PRINT_ERR("not enough arguments, running tests\n");
13− err = run_on_default_source(main);
14− PRINT_MSG("read a wave file as a mono vector\n");
15− PRINT_MSG("usage: %s <source_path> [samplerate] [hop_size]\n", argv[0]);
16− PRINT_MSG("examples:\n");
17− PRINT_MSG(" - read file.wav at original samplerate\n");
18− PRINT_MSG(" %s file.wav\n", argv[0]);
19− PRINT_MSG(" - read file.wav at 32000Hz\n");
20− PRINT_MSG(" %s file.aif 32000\n", argv[0]);
21− PRINT_MSG(" - read file.wav at original samplerate with 4096 blocks\n");
22− PRINT_MSG(" %s file.wav 0 4096 \n", argv[0]);
23− return err;
24− }
25−
26−#ifdef HAVE_SNDFILE
27− uint_t samplerate = 0;
28− uint_t hop_size = 256;
29− uint_t n_frames = 0, read = 0;
30− if ( argc >= 3 ) samplerate = atoi(argv[2]);
31− if ( argc >= 4 ) hop_size = atoi(argv[3]);
32−
33− char_t *source_path = argv[1];
34−
35−
36− aubio_source_sndfile_t * s =
37− new_aubio_source_sndfile(source_path, samplerate, hop_size);
38− if (!s) { err = 1; goto beach; }
39− fvec_t *vec = new_fvec(hop_size);
40−
41− uint_t n_frames_expected = aubio_source_sndfile_get_duration(s);
42−
43− samplerate = aubio_source_sndfile_get_samplerate(s);
44−
45− do {
46− aubio_source_sndfile_do(s, vec, &read);
47− fvec_print (vec);
48− n_frames += read;
49− } while ( read == hop_size );
50−
51− PRINT_MSG("read %d frames (expected %d) at %dHz (%d blocks) from %s\n",
52− n_frames, n_frames_expected, samplerate, n_frames / hop_size,
53− source_path);
54−
55− del_fvec (vec);
56− del_aubio_source_sndfile (s);
57−beach:
58−#else
59− err = 0;
60− PRINT_ERR("aubio was not compiled with aubio_source_sndfile\n");
61−#endif /* HAVE_SNDFILE */
62− return err;
29+ return base_main(argc, argv);
6330 }
tests/src/io/test-source_wavread.c+20−53
@@ -2,62 +2,29 @@ · 1 unmodified line
22 #include <aubio.h>
33 #include "utils_tests.h"
44
5−// this file uses the unstable aubio api, please use aubio_source instead
6−// see src/io/source.h and tests/src/source/test-source.c
7−
8−int main (int argc, char **argv)
9−{
10− uint_t err = 0;
11− if (argc < 2) {
12− PRINT_ERR("not enough arguments, running tests\n");
13− err = run_on_default_source(main);
14− PRINT_MSG("read a wave file as a mono vector\n");
15− PRINT_MSG("usage: %s <source_path> [samplerate] [hop_size]\n", argv[0]);
16− PRINT_MSG("examples:\n");
17− PRINT_MSG(" - read file.wav at original samplerate\n");
18− PRINT_MSG(" %s file.wav\n", argv[0]);
19− PRINT_MSG(" - read file.wav at 32000Hz\n");
20− PRINT_MSG(" %s file.aif 32000\n", argv[0]);
21− PRINT_MSG(" - read file.wav at original samplerate with 4096 blocks\n");
22− PRINT_MSG(" %s file.wav 0 4096 \n", argv[0]);
23− return err;
24− }
5+#define aubio_source_custom "wavread"
256
267 #ifdef HAVE_WAVREAD
27− uint_t samplerate = 0;
28− uint_t hop_size = 256;
29− uint_t n_frames = 0, read = 0;
30− if ( argc >= 3 ) samplerate = atoi(argv[2]);
31− if ( argc >= 4 ) hop_size = atoi(argv[3]);
32−
33− char_t *source_path = argv[1];
34−
35−
36− aubio_source_wavread_t * s =
37− new_aubio_source_wavread(source_path, samplerate, hop_size);
38− if (!s) { err = 1; goto beach; }
39− fvec_t *vec = new_fvec(hop_size);
40−
41− uint_t n_frames_expected = aubio_source_wavread_get_duration(s);
42−
43− samplerate = aubio_source_wavread_get_samplerate(s);
8+#define HAVE_AUBIO_SOURCE_CUSTOM
9+#define aubio_source_custom_t aubio_source_wavread_t
10+#define new_aubio_source_custom new_aubio_source_wavread
11+#define del_aubio_source_custom del_aubio_source_wavread
12+#define aubio_source_custom_get_samplerate aubio_source_wavread_get_samplerate
13+#define aubio_source_custom_get_duration aubio_source_wavread_get_duration
14+#define aubio_source_custom_do aubio_source_wavread_do
15+#define aubio_source_custom_do_multi aubio_source_wavread_do_multi
16+#define aubio_source_custom_seek aubio_source_wavread_seek
17+#define aubio_source_custom_close aubio_source_wavread_close
18+#define aubio_source_custom_get_channels aubio_source_wavread_get_channels
19+#define aubio_source_custom_get_samplerate aubio_source_wavread_get_samplerate
20+#endif /* HAVE_WAVREAD */
4421
45− do {
46− aubio_source_wavread_do(s, vec, &read);
47− fvec_print (vec);
48− n_frames += read;
49− } while ( read == hop_size );
22+#include "base-source_custom.h"
5023
51− PRINT_MSG("read %d frames (expected %d) at %dHz (%d blocks) from %s\n",
52− n_frames, n_frames_expected, samplerate, n_frames / hop_size,
53− source_path);
24+// this file uses the unstable aubio api, please use aubio_source instead
25+// see src/io/source.h and tests/src/source/test-source.c
5426
55− del_fvec (vec);
56− del_aubio_source_wavread (s);
57−beach:
58−#else
59− err = 0;
60− PRINT_ERR("aubio was not compiled with aubio_source_wavread\n");
61−#endif /* HAVE_WAVREAD */
62− return err;
27+int main (int argc, char **argv)
28+{
29+ return base_main(argc, argv);
6330 }
tests/src/onset/test-onset.c+9−12
@@ -69,21 +69,19 @@ int test_wrong_params(void) · 68 unmodified lines
6969 uint_t hop_size = win_size / 2;
7070 uint_t samplerate = 44100;
7171 // hop_size < 1
72− if (new_aubio_onset("default", 5, 0, samplerate))
73− return 1;
72+ if (new_aubio_onset("default", 5, 0, samplerate)) return 1;
73+
7474 // buf_size < 2
75− if (new_aubio_onset("default", 1, 1, samplerate))
76− return 1;
75+ if (new_aubio_onset("default", 1, 1, samplerate)) return 1;
76+
7777 // buf_size < hop_size
78− if (new_aubio_onset("default", hop_size, win_size, samplerate))
79− return 1;
78+ if (new_aubio_onset("default", hop_size, win_size, samplerate)) return 1;
79+
8080 // samplerate < 1
81− if (new_aubio_onset("default", 1024, 512, 0))
82− return 1;
81+ if (new_aubio_onset("default", 1024, 512, 0)) return 1;
8382
8483 // specdesc creation failed
85− if (new_aubio_onset("abcd", win_size, win_size/2, samplerate))
86− return 1;
84+ if (new_aubio_onset("abcd", win_size, win_size/2, samplerate)) return 1;
8785
8886 aubio_onset_t *o;
8987
@@ -92,8 +90,7 @@ int test_wrong_params(void) · 2 unmodified lines
9290 if (o) del_aubio_onset(o);
9391
9492 o = new_aubio_onset("default", win_size, hop_size, samplerate);
95− if (!aubio_onset_set_default_parameters(o, "wrong_type"))
96− return 1;
93+ if (!aubio_onset_set_default_parameters(o, "wrong_type")) return 1;
9794 del_aubio_onset(o);
9895
9996 return run_on_default_source(main);
tests/src/spectral/test-mfcc.c+80−21
@@ -1,35 +1,94 @@
11 #include <aubio.h>
2+#include "utils_tests.h"
23
3−int main (void)
4+int test_wrong_params(void);
5+
6+int main (int argc, char** argv)
7+{
8+ sint_t err = 0;
9+
10+ if (argc < 2) {
11+ err = 2;
12+ PRINT_WRN("no arguments, running tests\n");
13+ err = test_wrong_params();
14+ PRINT_MSG("usage: %s <input_path> [samplerate] [hop_size]\n", argv[0]);
15+ return err;
16+ }
17+
18+ uint_t win_s; // fft size
19+ uint_t hop_s = 256; // block size
20+ uint_t samplerate = 0; // samplerate
21+ uint_t n_filters = 40; // number of filters
22+ uint_t n_coeffs = 13; // number of coefficients
23+ uint_t read = 0;
24+
25+ char_t *source_path = argv[1];
26+
27+ if ( argc >= 3 ) samplerate = atoi(argv[2]);
28+ if ( argc >= 4 ) hop_s = atoi(argv[3]);
29+
30+ win_s = 2 * hop_s;
31+
32+ aubio_source_t *source = 0;
33+ aubio_pvoc_t *pv = 0;
34+ aubio_mfcc_t *mfcc = 0;
35+
36+ fvec_t *in = new_fvec (win_s); // input buffer
37+ cvec_t *fftgrain = new_cvec (win_s); // input buffer
38+ fvec_t *out = new_fvec (n_coeffs); // output coefficients
39+
40+ if (!in || !fftgrain || !out) { err = 1; goto failure; }
41+
42+ // source
43+ source = new_aubio_source(source_path, samplerate, hop_s);
44+ if (!source) { err = 1; goto failure; }
45+ if (samplerate == 0) samplerate = aubio_source_get_samplerate(source);
46+
47+ // phase vocoder
48+ pv = new_aubio_pvoc(win_s, hop_s);
49+ if (!pv) { err = 1; goto failure; }
50+
51+ // mfcc object
52+ mfcc = new_aubio_mfcc (win_s, n_filters, n_coeffs, samplerate);
53+ if (!mfcc) { err = 1; goto failure; }
54+
55+ // processing loop
56+ do {
57+ aubio_source_do(source, in, &read);
58+ aubio_pvoc_do(pv, in, fftgrain);
59+ aubio_mfcc_do(mfcc, fftgrain, out);
60+ fvec_print(out);
61+ } while (read == hop_s);
62+
63+failure:
64+
65+ if (mfcc)
66+ del_aubio_mfcc(mfcc);
67+ if (pv)
68+ del_aubio_pvoc(pv);
69+ if (source)
70+ del_aubio_source(source);
71+ if (in)
72+ del_fvec(in);
73+ if (fftgrain)
74+ del_cvec(fftgrain);
75+ if (out)
76+ del_fvec(out);
77+ aubio_cleanup();
78+ return err;
79+}
80+
81+int test_wrong_params()
482 {
583 uint_t win_s = 512; // fft size
684 uint_t n_filters = 40; // number of filters
785 uint_t n_coeffs = 13; // number of coefficients
886 smpl_t samplerate = 16000.; // samplerate
9− cvec_t *in = new_cvec (win_s); // input buffer
10− fvec_t *out = new_fvec (n_coeffs); // output coefficients
1187
1288 if (new_aubio_mfcc( 0, n_filters, n_coeffs, samplerate)) return 1;
1389 if (new_aubio_mfcc(win_s, 0, n_coeffs, samplerate)) return 1;
1490 if (new_aubio_mfcc(win_s, n_filters, 0, samplerate)) return 1;
1591 if (new_aubio_mfcc(win_s, n_filters, n_coeffs, 0)) return 1;
1692
17− // create mfcc object
18− aubio_mfcc_t *o = new_aubio_mfcc (win_s, n_filters, n_coeffs, samplerate);
19−
20− cvec_norm_set_all (in, 1.);
21− aubio_mfcc_do (o, in, out);
22− fvec_print (out);
23−
24− cvec_norm_set_all (in, .5);
25− aubio_mfcc_do (o, in, out);
26− fvec_print (out);
27−
28− // clean up
29− del_aubio_mfcc (o);
30− del_cvec (in);
31− del_fvec (out);
32− aubio_cleanup ();
33−
34− return 0;
93+ return run_on_default_source(main);
3594 }
tests/src/tempo/test-tempo.c+7−14
@@ -81,35 +81,28 @@ int test_wrong_params(void) · 80 unmodified lines
8181 uint_t i;
8282
8383 // test wrong method fails
84− if (new_aubio_tempo("unexisting_method", win_size, hop_size, samplerate))
85− return 1;
84+ if (new_aubio_tempo("undefined", win_size, hop_size, samplerate)) return 1;
8685
8786 // test hop > win fails
88− if (new_aubio_tempo("default", hop_size, win_size, samplerate))
89− return 1;
87+ if (new_aubio_tempo("default", hop_size, win_size, samplerate)) return 1;
9088
9189 // test null hop_size fails
92− if (new_aubio_tempo("default", win_size, 0, samplerate))
93− return 1;
90+ if (new_aubio_tempo("default", win_size, 0, samplerate)) return 1;
9491
9592 // test 1 buf_size fails
96− if (new_aubio_tempo("default", 1, 1, samplerate))
97− return 1;
93+ if (new_aubio_tempo("default", 1, 1, samplerate)) return 1;
9894
9995 // test null samplerate fails
100− if (new_aubio_tempo("default", win_size, hop_size, 0))
101− return 1;
96+ if (new_aubio_tempo("default", win_size, hop_size, 0)) return 1;
10297
10398 // test short sizes workaround
10499 t = new_aubio_tempo("default", 2048, 2048, 500);
105− if (!t)
106− return 1;
100+ if (!t) return 1;
107101
108102 del_aubio_tempo(t);
109103
110104 t = new_aubio_tempo("default", win_size, hop_size, samplerate);
111− if (!t)
112− return 1;
105+ if (!t) return 1;
113106
114107 in = new_fvec(hop_size);
115108 out = new_fvec(1);
tests/src/temporal/test-filter.c+7−12
@@ -9,17 +9,13 @@ int main (void) · 8 unmodified lines
99
1010 aubio_filter_t *o = new_aubio_filter_c_weighting (44100);
1111
12− if (new_aubio_filter(0))
13− return 1;
12+ if (new_aubio_filter(0)) return 1;
1413
15− if (aubio_filter_get_samplerate(o) != 44100)
16− return 1;
14+ if (aubio_filter_get_samplerate(o) != 44100) return 1;
1715
18− if (aubio_filter_set_c_weighting (o, -1) == 0)
19− return 1;
16+ if (aubio_filter_set_c_weighting (o, -1) == 0) return 1;
2017
21− if (aubio_filter_set_c_weighting (0, 32000) == 0)
22− return 1;
18+ if (aubio_filter_set_c_weighting (0, 32000) == 0) return 1;
2319
2420 in->data[impulse_at] = 0.5;
2521 fvec_print (in);
@@ -29,10 +25,9 @@ int main (void) · 3 unmodified lines
2925
3026 o = new_aubio_filter_a_weighting (32000);
3127
32− if (aubio_filter_set_a_weighting (o, -1) == 0)
33− return 1;
34− if (aubio_filter_set_a_weighting (0, 32000) == 0)
35− return 1;
28+ if (aubio_filter_set_a_weighting (o, -1) == 0) return 1;
29+
30+ if (aubio_filter_set_a_weighting (0, 32000) == 0) return 1;
3631
3732 in->data[impulse_at] = 0.5;
3833 fvec_print (in);
tests/src/test-delnull.c+0−24
@@ -1,24 +0,0 @@
1−#include <stdlib.h>
2−#include "aubio.h"
3−
4−// When creating an aubio object, the user should check whether the object is
5−// set NULL, indicating the creation failed and the object was not allocated.
6−
7−int main (void)
8−{
9− uint_t return_code = 0;
10− fvec_t *f = new_fvec(-12);
11− cvec_t *c = new_cvec(-12);
12− lvec_t *l = new_lvec(-12);
13− aubio_fft_t *fft = new_aubio_fft(-12);
14− if (f != NULL) {
15− return_code = 1;
16− } else if (c != NULL) {
17− return_code = 2;
18− } else if (l != NULL) {
19− return_code = 3;
20− } else if (fft != NULL) {
21− return_code = 3;
22− }
23− return return_code;
24−}
tests/utils_tests.h+11−12
@@ -55,21 +55,20 @@ · 54 unmodified lines
5555 #define RAND_MAX 32767
5656 #endif
5757
58−// are we on windows ? or are we using -std=c99 ?
59−#if defined(HAVE_WIN_HACKS) || defined(__STRICT_ANSI__)
60−// http://en.wikipedia.org/wiki/Linear_congruential_generator
61−// no srandom/random on win32
58+#if defined(HAVE_WIN_HACKS)
6259
63−uint_t srandom_seed = 1029;
60+// use srand/rand on windows
61+#define srandom srand
62+#define random rand
6463
65−void srandom(uint_t new_seed) {
66− srandom_seed = new_seed;
67−}
64+#elif defined(__STRICT_ANSI__)
65+
66+// workaround to build with -std=c99 (for instance with older cygwin),
67+// assuming libbc is recent enough to supports these functions.
68+extern void srandom(unsigned);
69+extern int random(void);
70+extern char mkstemp(const char *pat);
6871
69−uint_t random(void) {
70− srandom_seed = 1664525 * srandom_seed + 1013904223;
71− return srandom_seed;
72−}
7372 #endif
7473
7574 void utils_init_random (void);
wscript+34−21
@@ -555,32 +555,45 @@ def doxygen(bld): · 554 unmodified lines
555555 # build documentation from source files using doxygen
556556 if bld.env['DOXYGEN']:
557557 bld.env.VERSION = VERSION
558− rule = '( cat ${SRC} && echo PROJECT_NUMBER=${VERSION}; )'
558+ rule = '( cat ${SRC[0]} && echo PROJECT_NUMBER=${VERSION}'
559+ rule += ' && echo OUTPUT_DIRECTORY=%s && echo HTML_OUTPUT=%s )'
559560 rule += ' | doxygen - > /dev/null'
561+ rule %= (os.path.abspath(out), 'api')
560562 bld( name = 'doxygen', rule = rule,
561− source = 'doc/web.cfg',
562− target = '../doc/web/html/index.html',
563− cwd = 'doc')
564− bld.install_files( '${DATAROOTDIR}' + '/doc/libaubio-doc',
565− bld.path.ant_glob('doc/web/html/**'),
566− cwd = bld.path.find_dir ('doc/web'),
567− relative_trick = True)
563+ source = ['doc/web.cfg']
564+ + bld.path.find_dir('src').ant_glob('**/*.h'),
565+ target = bld.path.find_or_declare('api/index.html'),
566+ cwd = bld.path.find_dir('doc'))
567+ # evaluate nodes lazily to prevent build directory traversal warnings
568+ bld.install_files('${DATAROOTDIR}/doc/libaubio-doc/api',
569+ bld.path.find_or_declare('api').ant_glob('**/*',
570+ generator=True), cwd=bld.path.find_or_declare('api'),
571+ relative_trick=True)
568572
569573 def sphinx(bld):
570− # build documentation from source files using sphinx-build note: build in
571− # ../doc/_build/html, otherwise waf wont install unsigned files
572− if bld.env['SPHINX']:
574+ # build documentation from source files using sphinx-build
575+ try:
576+ import aubio
577+ has_aubio = True
578+ except ImportError:
579+ from waflib import Logs
580+ Logs.pprint('YELLOW', "Sphinx manual: install aubio first")
581+ has_aubio = False
582+ if bld.env['SPHINX'] and has_aubio:
573583 bld.env.VERSION = VERSION
574− bld( name = 'sphinx',
575− rule = '${SPHINX} -b html -D release=${VERSION}' \
576− ' -D version=${VERSION} -a -q' \
577− ' `dirname ${SRC}` `dirname ${TGT}`',
578− source = 'doc/conf.py',
579− target = '../doc/_build/html/index.html')
580− bld.install_files( '${DATAROOTDIR}' + '/doc/libaubio-doc/sphinx',
581− bld.path.ant_glob('doc/_build/html/**'),
582− cwd = bld.path.find_dir('doc/_build/html'),
583− relative_trick = True)
584+ rule = '${SPHINX} -b html -D release=${VERSION}' \
585+ ' -D version=${VERSION} -W -a -q' \
586+ ' -d %s ' % os.path.join(os.path.abspath(out), 'doctrees')
587+ rule += ' . %s' % os.path.join(os.path.abspath(out), 'manual')
588+ bld( name = 'sphinx', rule = rule,
589+ cwd = bld.path.find_dir('doc'),
590+ source = bld.path.find_dir('doc').ant_glob('*.rst'),
591+ target = bld.path.find_or_declare('manual/index.html'))
592+ # evaluate nodes lazily to prevent build directory traversal warnings
593+ bld.install_files('${DATAROOTDIR}/doc/libaubio-doc/manual',
594+ bld.path.find_or_declare('manual').ant_glob('**/*',
595+ generator=True), cwd=bld.path.find_or_declare('manual'),
596+ relative_trick=True)
584597
585598 # register the previous rules as build rules
586599 from waflib.Build import BuildContext

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