ref: 1cf031a3a5b869368562b1251419fd45191eaa53
parent: bcc53876548334b4c5f1ebd47a5bd5f151974e8b
parent: ef0a430fdb65d2f8eaf3b92e47eaece4255497d8
author: Paul Brossier <piem@piem.org>
date: Mon Nov 26 06:34:45 EST 2018
Merge branch 'fix/bufoverflow_tempo' (thanks to @niugx)
--- /dev/null
+++ b/python/tests/test_tempo.py
@@ -1,0 +1,91 @@
+#! /usr/bin/env python
+
+from unittest import main
+from numpy.testing import TestCase, assert_equal, assert_almost_equal
+import aubio
+
+class aubio_tempo_default(TestCase):
+
+ def test_members(self):
+ o = aubio.tempo()
+ assert_equal ([o.buf_size, o.hop_size, o.method, o.samplerate],
+ [1024,512,'default',44100])
+
+class aubio_tempo_params(TestCase):
+
+ samplerate = 44100
+
+ def setUp(self):
+ self.o = aubio.tempo(samplerate = self.samplerate)
+
+ def test_get_delay(self):
+ self.assertEqual(self.o.get_delay(), 0)
+
+ def test_set_delay(self):
+ val = 256
+ self.o.set_delay(val)
+ assert_equal (self.o.get_delay(), val)
+
+ def test_get_delay_s(self):
+ self.assertEqual(self.o.get_delay_s(), 0.)
+
+ def test_set_delay_s(self):
+ val = .05
+ self.o.set_delay_s(val)
+ assert_almost_equal (self.o.get_delay_s(), val)
+
+ def test_get_delay_ms(self):
+ self.assertEqual(self.o.get_delay_ms(), 0.)
+
+ def test_set_delay_ms(self):
+ val = 50.
+ self.o.set_delay_ms(val)
+ assert_almost_equal (self.o.get_delay_ms(), val)
+
+ def test_get_threshold(self):
+ assert_almost_equal(self.o.get_threshold(), 0.3)
+
+ def test_set_threshold(self):
+ val = .1
+ self.o.set_threshold(val)
+ assert_almost_equal (self.o.get_threshold(), val)
+
+ def test_get_silence(self):
+ self.assertEqual(self.o.get_silence(), -90.)
+
+ def test_set_silence(self):
+ val = -50.
+ self.o.set_silence(val)
+ assert_almost_equal (self.o.get_silence(), val)
+
+ def test_get_last(self):
+ self.assertEqual(self.o.get_last(), 0.)
+
+ def test_get_last_s(self):
+ self.assertEqual(self.o.get_last_s(), 0.)
+
+ def test_get_last_ms(self):
+ self.assertEqual(self.o.get_last_ms(), 0.)
+
+ def test_get_period(self):
+ self.assertEqual(self.o.get_period(), 0.)
+
+ def test_get_period_s(self):
+ self.assertEqual(self.o.get_period_s(), 0.)
+
+ def test_get_last_tatum(self):
+ self.assertEqual(self.o.get_last_tatum(), 0.)
+
+ def test_set_tatum_signature(self):
+ self.o.set_tatum_signature(8)
+ self.o.set_tatum_signature(64)
+ self.o.set_tatum_signature(1)
+
+ def test_set_wrong_tatum_signature(self):
+ with self.assertRaises(ValueError):
+ self.o.set_tatum_signature(101)
+ with self.assertRaises(ValueError):
+ self.o.set_tatum_signature(0)
+
+if __name__ == '__main__':
+ main()
--- a/src/tempo/tempo.c
+++ b/src/tempo/tempo.c
@@ -128,8 +128,7 @@
}
uint_t aubio_tempo_set_delay_ms(aubio_tempo_t * o, smpl_t delay) {
- o->delay = 1000. * delay * o->samplerate;
- return AUBIO_OK;
+ return aubio_tempo_set_delay_s(o, delay / 1000.);
}
uint_t aubio_tempo_get_delay(aubio_tempo_t * o) {
@@ -141,7 +140,7 @@
}
smpl_t aubio_tempo_get_delay_ms(aubio_tempo_t * o) {
- return o->delay / (smpl_t)(o->samplerate) / 1000.;
+ return aubio_tempo_get_delay_s(o) * 1000.;
}
uint_t aubio_tempo_set_silence(aubio_tempo_t * o, smpl_t silence) {
@@ -168,7 +167,7 @@
uint_t buf_size, uint_t hop_size, uint_t samplerate)
{
aubio_tempo_t * o = AUBIO_NEW(aubio_tempo_t);
- char_t specdesc_func[20];
+ char_t specdesc_func[PATH_MAX];
o->samplerate = samplerate;
// check parameters are valid
if ((sint_t)hop_size < 1) {
@@ -203,9 +202,10 @@
o->pp = new_aubio_peakpicker();
aubio_peakpicker_set_threshold (o->pp, o->threshold);
if ( strcmp(tempo_mode, "default") == 0 ) {
- strcpy(specdesc_func, "specflux");
+ strncpy(specdesc_func, "specflux", PATH_MAX - 1);
} else {
- strcpy(specdesc_func, tempo_mode);
+ strncpy(specdesc_func, tempo_mode, PATH_MAX - 1);
+ specdesc_func[PATH_MAX - 1] = '\0';
}
o->od = new_aubio_specdesc(specdesc_func,buf_size);
o->of = new_fvec(1);
@@ -215,12 +215,17 @@
o2 = new_aubio_specdesc(type_onset2,buffer_size);
onset2 = new_fvec(1);
}*/
+ if (!o->dfframe || !o->fftgrain || !o->out || !o->pv ||
+ !o->pp || !o->od || !o->of || !o->bt || !o->onset) {
+ AUBIO_ERR("tempo: failed creating tempo object\n");
+ goto beach;
+ }
o->last_tatum = 0;
o->tatum_signature = 4;
return o;
beach:
- AUBIO_FREE(o);
+ del_aubio_tempo(o);
return NULL;
}
@@ -277,15 +282,23 @@
void del_aubio_tempo (aubio_tempo_t *o)
{
- del_aubio_specdesc(o->od);
- del_aubio_beattracking(o->bt);
- del_aubio_peakpicker(o->pp);
- del_aubio_pvoc(o->pv);
- del_fvec(o->out);
- del_fvec(o->of);
- del_cvec(o->fftgrain);
- del_fvec(o->dfframe);
- del_fvec(o->onset);
+ if (o->od)
+ del_aubio_specdesc(o->od);
+ if (o->bt)
+ del_aubio_beattracking(o->bt);
+ if (o->pp)
+ del_aubio_peakpicker(o->pp);
+ if (o->pv)
+ del_aubio_pvoc(o->pv);
+ if (o->out)
+ del_fvec(o->out);
+ if (o->of)
+ del_fvec(o->of);
+ if (o->fftgrain)
+ del_cvec(o->fftgrain);
+ if (o->dfframe)
+ del_fvec(o->dfframe);
+ if (o->onset)
+ del_fvec(o->onset);
AUBIO_FREE(o);
- return;
}
--- a/tests/src/tempo/test-tempo.c
+++ b/tests/src/tempo/test-tempo.c
@@ -1,14 +1,22 @@
#include <aubio.h>
#include "utils_tests.h"
+int test_wrong_params(void);
+
int main (int argc, char **argv)
{
uint_t err = 0;
if (argc < 2) {
err = 2;
- PRINT_ERR("not enough arguments\n");
- PRINT_MSG("read a wave file as a mono vector\n");
- PRINT_MSG("usage: %s <source_path> [samplerate] [win_size] [hop_size]\n", argv[0]);
+ PRINT_WRN("no arguments, running tests\n");
+ if (test_wrong_params() != 0) {
+ PRINT_ERR("tests failed!\n");
+ err = 1;
+ } else {
+ err = 0;
+ }
+ PRINT_MSG("usage: %s <source_path> [samplerate] [win_size] [hop_size]\n",
+ argv[0]);
return err;
}
uint_t samplerate = 0;
@@ -20,7 +28,8 @@
uint_t n_frames = 0, read = 0;
char_t *source_path = argv[1];
- aubio_source_t * source = new_aubio_source(source_path, samplerate, hop_size);
+ aubio_source_t * source = new_aubio_source(source_path, samplerate,
+ hop_size);
if (!source) { err = 1; goto beach; }
if (samplerate == 0 ) samplerate = aubio_source_get_samplerate(source);
@@ -30,8 +39,11 @@
fvec_t * out = new_fvec (1); // output position
// create tempo object
- aubio_tempo_t * o = new_aubio_tempo("default", win_size, hop_size, samplerate);
+ aubio_tempo_t * o = new_aubio_tempo("default", win_size, hop_size,
+ samplerate);
+ if (!o) { err = 1; goto beach_tempo; }
+
do {
// put some fresh data in input vector
aubio_source_do(source, in, &read);
@@ -39,9 +51,11 @@
aubio_tempo_do(o,in,out);
// do something with the beats
if (out->data[0] != 0) {
- PRINT_MSG("beat at %.3fms, %.3fs, frame %d, %.2fbpm with confidence %.2f\n",
+ PRINT_MSG("beat at %.3fms, %.3fs, frame %d, %.2f bpm "
+ "with confidence %.2f\n",
aubio_tempo_get_last_ms(o), aubio_tempo_get_last_s(o),
- aubio_tempo_get_last(o), aubio_tempo_get_bpm(o), aubio_tempo_get_confidence(o));
+ aubio_tempo_get_last(o), aubio_tempo_get_bpm(o),
+ aubio_tempo_get_confidence(o));
}
n_frames += read;
} while ( read == hop_size );
@@ -53,6 +67,7 @@
// clean up memory
del_aubio_tempo(o);
+beach_tempo:
del_fvec(in);
del_fvec(out);
del_aubio_source(source);
@@ -60,4 +75,65 @@
aubio_cleanup();
return err;
+}
+
+int test_wrong_params(void)
+{
+ uint_t win_size = 1024;
+ uint_t hop_size = 256;
+ uint_t samplerate = 44100;
+ aubio_tempo_t *t;
+ fvec_t* in, *out;
+ uint_t i;
+
+ // test wrong method fails
+ if (new_aubio_tempo("unexisting_method", win_size, hop_size, samplerate))
+ return 1;
+
+ // test hop > win fails
+ if (new_aubio_tempo("default", hop_size, win_size, samplerate))
+ return 1;
+
+ // test null hop_size fails
+ if (new_aubio_tempo("default", win_size, 0, samplerate))
+ return 1;
+
+ // test 1 buf_size fails
+ if (new_aubio_tempo("default", 1, 1, samplerate))
+ return 1;
+
+ // test null samplerate fails
+ if (new_aubio_tempo("default", win_size, hop_size, 0))
+ return 1;
+
+ // test short sizes workaround
+ t = new_aubio_tempo("default", 2048, 2048, 500);
+ if (!t)
+ return 1;
+
+ del_aubio_tempo(t);
+
+ t = new_aubio_tempo("default", win_size, hop_size, samplerate);
+ if (!t)
+ return 1;
+
+ in = new_fvec(hop_size);
+ out = new_fvec(1);
+
+ // up to step = (next_power_of_two(5.8 * samplerate / hop_size ) / 4 )
+ for (i = 0; i < 256 + 1; i++)
+ {
+ aubio_tempo_do(t,in,out);
+ PRINT_MSG("beat at %.3fms, %.3fs, frame %d, %.2f bpm "
+ "with confidence %.2f, was tatum %d\n",
+ aubio_tempo_get_last_ms(t), aubio_tempo_get_last_s(t),
+ aubio_tempo_get_last(t), aubio_tempo_get_bpm(t),
+ aubio_tempo_get_confidence(t), aubio_tempo_was_tatum(t));
+ }
+
+ del_aubio_tempo(t);
+ del_fvec(in);
+ del_fvec(out);
+
+ return 0;
}