From: Paul Brossier Date: Wed, 19 Dec 2018 16:50:42 +0000 (+0100) Subject: Merge branch 'master' into feature/pytest X-Git-Tag: 0.4.9~71^2 X-Git-Url: https://git.aubio.org/?p=aubio.git;a=commitdiff_plain;h=74c1fb9a63dfa46c0591816bd2f450c5f2dba751;hp=c1ba75b55fb6351ca1f2dcebf89b93aee72d2711 Merge branch 'master' into feature/pytest --- diff --git a/MANIFEST.in b/MANIFEST.in index 7bb30eb5..85edbdf1 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -10,7 +10,7 @@ include requirements.txt include src/*.c src/*.h include src/*/*.c src/*/*.h include examples/*.c examples/*.h -include tests/*.h tests/*/*.c tests/*/*/*.c +recursive-include tests *.h *.c *.py include python/ext/*.h recursive-include python *.py include python/README.md diff --git a/python/README.md b/python/README.md index 06c8bb61..0367adad 100644 --- a/python/README.md +++ b/python/README.md @@ -27,7 +27,7 @@ Links Demos ----- -Some examples are available in the [`python/demos`][demos_dir] folder. Each +Some examples are available in the [`python/demos` folder][demos_dir]. Each script is a command line program which accepts one ore more argument. **Notes**: installing additional modules is required to run some of the demos. diff --git a/python/ext/aubiomodule.c b/python/ext/aubiomodule.c index 03450647..d4ed0336 100644 --- a/python/ext/aubiomodule.c +++ b/python/ext/aubiomodule.c @@ -223,7 +223,7 @@ Py_alpha_norm (PyObject * self, PyObject * args) } // compute the function - result = Py_BuildValue (AUBIO_NPY_SMPL_CHR, fvec_alpha_norm (&vec, alpha)); + result = PyFloat_FromDouble(fvec_alpha_norm (&vec, alpha)); if (result == NULL) { return NULL; } @@ -319,7 +319,7 @@ Py_zero_crossing_rate (PyObject * self, PyObject * args) } // compute the function - result = Py_BuildValue (AUBIO_NPY_SMPL_CHR, aubio_zero_crossing_rate (&vec)); + result = PyFloat_FromDouble(aubio_zero_crossing_rate (&vec)); if (result == NULL) { return NULL; } diff --git a/python/ext/py-cvec.c b/python/ext/py-cvec.c index 9854b6d6..1c9316a0 100644 --- a/python/ext/py-cvec.c +++ b/python/ext/py-cvec.c @@ -136,7 +136,7 @@ Py_cvec_repr (Py_cvec * self, PyObject * unused) goto fail; } - args = Py_BuildValue ("I", self->length); + args = PyLong_FromLong(self->length); if (args == NULL) { goto fail; } diff --git a/python/ext/py-musicutils.c b/python/ext/py-musicutils.c index 32239456..0827ea24 100644 --- a/python/ext/py-musicutils.c +++ b/python/ext/py-musicutils.c @@ -39,7 +39,7 @@ Py_aubio_level_lin(PyObject *self, PyObject *args) return NULL; } - level_lin = Py_BuildValue(AUBIO_NPY_SMPL_CHR, aubio_level_lin(&vec)); + level_lin = PyFloat_FromDouble(aubio_level_lin(&vec)); if (level_lin == NULL) { PyErr_SetString (PyExc_ValueError, "failed computing level_lin"); return NULL; @@ -67,7 +67,7 @@ Py_aubio_db_spl(PyObject *self, PyObject *args) return NULL; } - db_spl = Py_BuildValue(AUBIO_NPY_SMPL_CHR, aubio_db_spl(&vec)); + db_spl = PyFloat_FromDouble(aubio_db_spl(&vec)); if (db_spl == NULL) { PyErr_SetString (PyExc_ValueError, "failed computing db_spl"); return NULL; @@ -96,7 +96,7 @@ Py_aubio_silence_detection(PyObject *self, PyObject *args) return NULL; } - silence_detection = Py_BuildValue("I", aubio_silence_detection(&vec, threshold)); + silence_detection = PyLong_FromLong(aubio_silence_detection(&vec, threshold)); if (silence_detection == NULL) { PyErr_SetString (PyExc_ValueError, "failed computing silence_detection"); return NULL; @@ -125,7 +125,7 @@ Py_aubio_level_detection(PyObject *self, PyObject *args) return NULL; } - level_detection = Py_BuildValue(AUBIO_NPY_SMPL_CHR, aubio_level_detection(&vec, threshold)); + level_detection = PyFloat_FromDouble(aubio_level_detection(&vec, threshold)); if (level_detection == NULL) { PyErr_SetString (PyExc_ValueError, "failed computing level_detection"); return NULL; @@ -194,9 +194,9 @@ Py_aubio_hztomel(PyObject *self, PyObject *args, PyObject *kwds) return NULL; } if (htk != NULL && PyObject_IsTrue(htk) == 1) - return Py_BuildValue(AUBIO_NPY_SMPL_CHR, aubio_hztomel_htk(v)); + return PyFloat_FromDouble(aubio_hztomel_htk(v)); else - return Py_BuildValue(AUBIO_NPY_SMPL_CHR, aubio_hztomel(v)); + return PyFloat_FromDouble(aubio_hztomel(v)); } PyObject* @@ -211,9 +211,9 @@ Py_aubio_meltohz(PyObject *self, PyObject *args, PyObject *kwds) return NULL; } if (htk != NULL && PyObject_IsTrue(htk) == 1) - return Py_BuildValue(AUBIO_NPY_SMPL_CHR, aubio_meltohz_htk(v)); + return PyFloat_FromDouble(aubio_meltohz_htk(v)); else - return Py_BuildValue(AUBIO_NPY_SMPL_CHR, aubio_meltohz(v)); + return PyFloat_FromDouble(aubio_meltohz(v)); } PyObject* @@ -223,7 +223,7 @@ Py_aubio_hztomel_htk(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, AUBIO_NPY_SMPL_CHR, &v)) { return NULL; } - return Py_BuildValue(AUBIO_NPY_SMPL_CHR, aubio_hztomel_htk(v)); + return PyFloat_FromDouble(aubio_hztomel_htk(v)); } PyObject* @@ -233,5 +233,5 @@ Py_aubio_meltohz_htk(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, AUBIO_NPY_SMPL_CHR, &v)) { return NULL; } - return Py_BuildValue(AUBIO_NPY_SMPL_CHR, aubio_meltohz_htk(v)); + return PyFloat_FromDouble(aubio_meltohz_htk(v)); } diff --git a/src/aubio_priv.h b/src/aubio_priv.h index 589c47af..c26b1f4a 100644 --- a/src/aubio_priv.h +++ b/src/aubio_priv.h @@ -367,4 +367,11 @@ uint_t aubio_log(sint_t level, const char_t *fmt, ...); #endif #endif /* __STRICT_ANSI__ */ +#if defined(DEBUG) +#include +#define AUBIO_ASSERT(x) assert(x) +#else +#define AUBIO_ASSERT(x) +#endif /* DEBUG */ + #endif /* AUBIO_PRIV_H */ diff --git a/src/io/ioutils.c b/src/io/ioutils.c index cce93c67..7828bebb 100644 --- a/src/io/ioutils.c +++ b/src/io/ioutils.c @@ -51,3 +51,39 @@ aubio_io_validate_channels(const char_t *kind, const char_t *path, uint_t channe } return AUBIO_OK; } + +uint_t +aubio_sink_validate_input_length(const char_t *kind, const char_t *path, + uint_t max_size, uint_t write_data_length, uint_t write) +{ + uint_t can_write = write; + + if (write > max_size) { + AUBIO_WRN("%s: partial write to %s, trying to write %d frames," + " at most %d can be written at once\n", kind, path, write, max_size); + can_write = max_size; + } + + if (can_write > write_data_length) { + AUBIO_WRN("%s: partial write to %s, trying to write %d frames," + " but found input of length %d\n", kind, path, write, + write_data_length); + can_write = write_data_length; + } + + return can_write; +} + +uint_t +aubio_sink_validate_input_channels(const char_t *kind, const char_t *path, + uint_t sink_channels, uint_t write_data_height) +{ + uint_t channels = sink_channels; + if (write_data_height < sink_channels) { + AUBIO_WRN("%s: partial write to %s, trying to write %d channels," + " but found input of height %d\n", kind, path, sink_channels, + write_data_height); + channels = write_data_height; + } + return channels; +} diff --git a/src/io/ioutils.h b/src/io/ioutils.h index 7eb65cbc..1db7b19b 100644 --- a/src/io/ioutils.h +++ b/src/io/ioutils.h @@ -53,6 +53,33 @@ uint_t aubio_io_validate_samplerate(const char_t *kind, const char_t *path, uint_t aubio_io_validate_channels(const char_t *kind, const char_t *path, uint_t channels); +/** validate length of input + + \param kind the object kind to report on + \param path the path to report on + \param max_size maximum number of frames that can be written + \param write_data_length actual length of input vector/matrix + \param write number of samples asked + + \return write or the maximum number of frames that can be written +*/ +uint_t +aubio_sink_validate_input_length(const char_t *kind, const char_t *path, + uint_t max_size, uint_t write_data_length, uint_t write); + +/** validate height of input + + \param kind the object kind to report on + \param path the path to report on + \param max_size maximum number of channels that can be written + \param write_data_height actual height of input matrix + + \return write_data_height or the maximum number of channels +*/ +uint_t +aubio_sink_validate_input_channels(const char_t *kind, const char_t *path, + uint_t sink_channels, uint_t write_data_height); + #ifdef __cplusplus } #endif diff --git a/src/io/sink.c b/src/io/sink.c index 70383cc7..f8ac5fdd 100644 --- a/src/io/sink.c +++ b/src/io/sink.c @@ -102,7 +102,7 @@ aubio_sink_t * new_aubio_sink(const char_t * uri, uint_t samplerate) { !defined(HAVE_SINK_APPLE_AUDIO) AUBIO_ERROR("sink: failed creating '%s' at %dHz (no sink built-in)\n", uri, samplerate); #endif - AUBIO_FREE(s); + del_aubio_sink(s); return NULL; } @@ -135,8 +135,8 @@ uint_t aubio_sink_close(aubio_sink_t *s) { } void del_aubio_sink(aubio_sink_t * s) { - if (!s) return; - s->s_del((void *)s->sink); + AUBIO_ASSERT(s); + if (s->s_del && s->sink) + s->s_del((void *)s->sink); AUBIO_FREE(s); - return; } diff --git a/src/io/sink_apple_audio.c b/src/io/sink_apple_audio.c index 32fbbf45..c58a52c6 100644 --- a/src/io/sink_apple_audio.c +++ b/src/io/sink_apple_audio.c @@ -31,9 +31,7 @@ // ExtAudioFileRef, AudioStreamBasicDescription, AudioBufferList, ... #include -#define FLOAT_TO_SHORT(x) (short)(x * 32768) - -extern int createAubioBufferList(AudioBufferList *bufferList, int channels, int segmentSize); +extern int createAudioBufferList(AudioBufferList *bufferList, int channels, int segmentSize); extern void freeAudioBufferList(AudioBufferList *bufferList); extern CFURLRef createURLFromPath(const char * path); 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 s->max_frames = MAX_SIZE; s->async = false; - if ( (uri == NULL) || (strlen(uri) < 1) ) { + if ( (uri == NULL) || (strnlen(uri, PATH_MAX) < 1) ) { AUBIO_ERROR("sink_apple_audio: Aborted opening null path\n"); goto beach; } - if (s->path != NULL) AUBIO_FREE(s->path); + s->path = AUBIO_ARRAY(char_t, strnlen(uri, PATH_MAX) + 1); strncpy(s->path, uri, strnlen(uri, PATH_MAX) + 1); @@ -76,6 +74,7 @@ aubio_sink_apple_audio_t * new_aubio_sink_apple_audio(const char_t * uri, uint_t if ((sint_t)samplerate == 0) { return s; } + // invalid samplerate given, abort if (aubio_io_validate_samplerate("sink_apple_audio", s->path, samplerate)) { goto beach; @@ -91,7 +90,7 @@ aubio_sink_apple_audio_t * new_aubio_sink_apple_audio(const char_t * uri, uint_t return s; beach: - AUBIO_FREE(s); + del_aubio_sink_apple_audio(s); return NULL; } @@ -102,7 +101,7 @@ uint_t aubio_sink_apple_audio_preset_samplerate(aubio_sink_apple_audio_t *s, uin } s->samplerate = samplerate; // automatically open when both samplerate and channels have been set - if (s->samplerate != 0 && s->channels != 0) { + if (/* s->samplerate != 0 && */ s->channels != 0) { return aubio_sink_apple_audio_open(s); } return AUBIO_OK; @@ -115,7 +114,7 @@ uint_t aubio_sink_apple_audio_preset_channels(aubio_sink_apple_audio_t *s, uint_ } s->channels = channels; // automatically open when both samplerate and channels have been set - if (s->samplerate != 0 && s->channels != 0) { + if (s->samplerate != 0 /* && s->channels != 0 */) { return aubio_sink_apple_audio_open(s); } return AUBIO_OK; @@ -150,6 +149,18 @@ uint_t aubio_sink_apple_audio_open(aubio_sink_apple_audio_t *s) { AudioFileTypeID fileType = kAudioFileWAVEType; CFURLRef fileURL = createURLFromPath(s->path); bool overwrite = true; + + // set the in-memory format + AudioStreamBasicDescription inputFormat; + memset(&inputFormat, 0, sizeof(AudioStreamBasicDescription)); + inputFormat.mFormatID = kAudioFormatLinearPCM; + inputFormat.mSampleRate = (Float64)(s->samplerate); + inputFormat.mFormatFlags = kAudioFormatFlagIsFloat | kAudioFormatFlagIsPacked; + inputFormat.mChannelsPerFrame = s->channels; + inputFormat.mBitsPerChannel = sizeof(smpl_t) * 8; + inputFormat.mFramesPerPacket = 1; + inputFormat.mBytesPerFrame = inputFormat.mBitsPerChannel * inputFormat.mChannelsPerFrame / 8; + inputFormat.mBytesPerPacket = inputFormat.mFramesPerPacket * inputFormat.mBytesPerFrame; OSStatus err = noErr; err = ExtAudioFileCreateWithURL(fileURL, fileType, &clientFormat, NULL, overwrite ? kAudioFileFlags_EraseFile : 0, &s->audioFile); @@ -161,7 +172,18 @@ uint_t aubio_sink_apple_audio_open(aubio_sink_apple_audio_t *s) { getPrintableOSStatusError(errorstr, err)); goto beach; } - if (createAubioBufferList(&s->bufferList, s->channels, s->max_frames * s->channels)) { + + err = ExtAudioFileSetProperty(s->audioFile, + kExtAudioFileProperty_ClientDataFormat, + sizeof(AudioStreamBasicDescription), &inputFormat); + if (err) { + char_t errorstr[20]; + AUBIO_ERR("sink_apple_audio: error when trying to set output format on %s " + "(%s)\n", s->path, getPrintableOSStatusError(errorstr, err)); + goto beach; + } + + if (createAudioBufferList(&s->bufferList, s->channels, s->max_frames * s->channels)) { AUBIO_ERR("sink_apple_audio: error when creating buffer list for %s, " "out of memory? \n", s->path); goto beach; @@ -174,46 +196,42 @@ beach: void aubio_sink_apple_audio_do(aubio_sink_apple_audio_t * s, fvec_t * write_data, uint_t write) { UInt32 c, v; - short *data = (short*)s->bufferList.mBuffers[0].mData; - if (write > s->max_frames) { - AUBIO_WRN("sink_apple_audio: trying to write %d frames, max %d\n", write, s->max_frames); - write = s->max_frames; - } - smpl_t *buf = write_data->data; - - if (buf) { - for (c = 0; c < s->channels; c++) { - for (v = 0; v < write; v++) { - data[v * s->channels + c] = - FLOAT_TO_SHORT(buf[ v * s->channels + c]); - } - } + smpl_t *data = (smpl_t*)s->bufferList.mBuffers[0].mData; + uint_t length = aubio_sink_validate_input_length("sink_apple_audio", s->path, + s->max_frames, write_data->length, write); + + for (c = 0; c < s->channels; c++) { + for (v = 0; v < length; v++) { + data[v * s->channels + c] = write_data->data[v]; + } } - aubio_sink_apple_audio_write(s, write); + + aubio_sink_apple_audio_write(s, length); } void aubio_sink_apple_audio_do_multi(aubio_sink_apple_audio_t * s, fmat_t * write_data, uint_t write) { UInt32 c, v; - short *data = (short*)s->bufferList.mBuffers[0].mData; - if (write > s->max_frames) { - AUBIO_WRN("sink_apple_audio: trying to write %d frames, max %d\n", write, s->max_frames); - write = s->max_frames; - } - smpl_t **buf = write_data->data; - - if (buf) { - for (c = 0; c < s->channels; c++) { - for (v = 0; v < write; v++) { - data[v * s->channels + c] = - FLOAT_TO_SHORT(buf[c][v]); - } - } + smpl_t *data = (smpl_t*)s->bufferList.mBuffers[0].mData; + uint_t channels = aubio_sink_validate_input_channels("sink_apple_audio", + s->path, s->channels, write_data->height); + uint_t length = aubio_sink_validate_input_length("sink_apple_audio", s->path, + s->max_frames, write_data->length, write); + + for (c = 0; c < channels; c++) { + for (v = 0; v < length; v++) { + data[v * s->channels + c] = write_data->data[c][v]; + } } - aubio_sink_apple_audio_write(s, write); + + aubio_sink_apple_audio_write(s, length); } void aubio_sink_apple_audio_write(aubio_sink_apple_audio_t *s, uint_t write) { OSStatus err = noErr; + // set mDataByteSize to match the number of frames to be written + // see https://www.mail-archive.com/coreaudio-api@lists.apple.com/msg01109.html + s->bufferList.mBuffers[0].mDataByteSize = write * s->channels + * sizeof(smpl_t); if (s->async) { err = ExtAudioFileWriteAsync(s->audioFile, write, &s->bufferList); if (err) { @@ -257,11 +275,13 @@ uint_t aubio_sink_apple_audio_close(aubio_sink_apple_audio_t * s) { } void del_aubio_sink_apple_audio(aubio_sink_apple_audio_t * s) { - if (s->audioFile) aubio_sink_apple_audio_close (s); - if (s->path) AUBIO_FREE(s->path); + AUBIO_ASSERT(s); + if (s->audioFile) + aubio_sink_apple_audio_close (s); + if (s->path) + AUBIO_FREE(s->path); freeAudioBufferList(&s->bufferList); AUBIO_FREE(s); - return; } #endif /* HAVE_SINK_APPLE_AUDIO */ diff --git a/src/io/sink_sndfile.c b/src/io/sink_sndfile.c index c105221e..35e2215c 100644 --- a/src/io/sink_sndfile.c +++ b/src/io/sink_sndfile.c @@ -58,10 +58,9 @@ aubio_sink_sndfile_t * new_aubio_sink_sndfile(const char_t * path, uint_t sample if (path == NULL) { AUBIO_ERR("sink_sndfile: Aborted opening null path\n"); - return NULL; + goto beach; } - if (s->path) AUBIO_FREE(s->path); s->path = AUBIO_ARRAY(char_t, strnlen(path, PATH_MAX) + 1); strncpy(s->path, path, strnlen(path, PATH_MAX) + 1); @@ -97,7 +96,7 @@ uint_t aubio_sink_sndfile_preset_samplerate(aubio_sink_sndfile_t *s, uint_t samp } s->samplerate = samplerate; // automatically open when both samplerate and channels have been set - if (s->samplerate != 0 && s->channels != 0) { + if (/* s->samplerate != 0 && */ s->channels != 0) { return aubio_sink_sndfile_open(s); } return AUBIO_OK; @@ -110,7 +109,7 @@ uint_t aubio_sink_sndfile_preset_channels(aubio_sink_sndfile_t *s, uint_t channe } s->channels = channels; // automatically open when both samplerate and channels have been set - if (s->samplerate != 0 && s->channels != 0) { + if (s->samplerate != 0 /* && s->channels != 0 */) { return aubio_sink_sndfile_open(s); } return AUBIO_OK; @@ -147,8 +146,7 @@ uint_t aubio_sink_sndfile_open(aubio_sink_sndfile_t *s) { s->scratch_size = s->max_size*s->channels; /* allocate data for de/interleaving reallocated when needed. */ if (s->scratch_size >= MAX_SIZE * AUBIO_MAX_CHANNELS) { - abort(); - AUBIO_ERR("sink_sndfile: %d x %d exceeds maximum aubio_sink_sndfile buffer size %d\n", + AUBIO_ERR("sink_sndfile: %d x %d exceeds maximum buffer size %d\n", s->max_size, s->channels, MAX_SIZE * AUBIO_MAX_CHANNELS); return AUBIO_FAIL; } @@ -158,24 +156,17 @@ uint_t aubio_sink_sndfile_open(aubio_sink_sndfile_t *s) { } void aubio_sink_sndfile_do(aubio_sink_sndfile_t *s, fvec_t * write_data, uint_t write){ - uint_t i, j, channels = s->channels; - int nsamples = 0; - smpl_t *pwrite; + uint_t i, j; sf_count_t written_frames; - - if (write > s->max_size) { - AUBIO_WRN("sink_sndfile: trying to write %d frames, but only %d can be written at a time\n", - write, s->max_size); - write = s->max_size; - } - - nsamples = channels * write; + uint_t channels = s->channels; + uint_t length = aubio_sink_validate_input_length("sink_sndfile", s->path, + s->max_size, write_data->length, write); + int nsamples = channels * length; /* interleaving data */ for ( i = 0; i < channels; i++) { - pwrite = (smpl_t *)write_data->data; - for (j = 0; j < write; j++) { - s->scratch_data[channels*j+i] = pwrite[j]; + for (j = 0; j < length; j++) { + s->scratch_data[channels*j+i] = write_data->data[j]; } } @@ -188,24 +179,18 @@ void aubio_sink_sndfile_do(aubio_sink_sndfile_t *s, fvec_t * write_data, uint_t } void aubio_sink_sndfile_do_multi(aubio_sink_sndfile_t *s, fmat_t * write_data, uint_t write){ - uint_t i, j, channels = s->channels; - int nsamples = 0; - smpl_t *pwrite; + uint_t i, j; sf_count_t written_frames; - - if (write > s->max_size) { - AUBIO_WRN("sink_sndfile: trying to write %d frames, but only %d can be written at a time\n", - write, s->max_size); - write = s->max_size; - } - - nsamples = channels * write; + uint_t channels = aubio_sink_validate_input_channels("sink_sndfile", s->path, + s->channels, write_data->height); + uint_t length = aubio_sink_validate_input_length("sink_sndfile", s->path, + s->max_size, write_data->length, write); + int nsamples = channels * length; /* interleaving data */ - for ( i = 0; i < write_data->height; i++) { - pwrite = (smpl_t *)write_data->data[i]; - for (j = 0; j < write; j++) { - s->scratch_data[channels*j+i] = pwrite[j]; + for ( i = 0; i < channels; i++) { + for (j = 0; j < length; j++) { + s->scratch_data[channels*j+i] = write_data->data[i][j]; } } @@ -230,10 +215,13 @@ uint_t aubio_sink_sndfile_close (aubio_sink_sndfile_t *s) { } void del_aubio_sink_sndfile(aubio_sink_sndfile_t * s){ - if (!s) return; - if (s->path) AUBIO_FREE(s->path); - aubio_sink_sndfile_close(s); - AUBIO_FREE(s->scratch_data); + AUBIO_ASSERT(s); + if (s->handle) + aubio_sink_sndfile_close(s); + if (s->path) + AUBIO_FREE(s->path); + if (s->scratch_data) + AUBIO_FREE(s->scratch_data); AUBIO_FREE(s); } diff --git a/src/io/sink_wavwrite.c b/src/io/sink_wavwrite.c index 2e456ea7..d13c4702 100644 --- a/src/io/sink_wavwrite.c +++ b/src/io/sink_wavwrite.c @@ -87,12 +87,7 @@ aubio_sink_wavwrite_t * new_aubio_sink_wavwrite(const char_t * path, uint_t samp AUBIO_ERR("sink_wavwrite: Aborted opening null path\n"); goto beach; } - if ((sint_t)samplerate < 0) { - AUBIO_ERR("sink_wavwrite: Can not create %s with samplerate %d\n", path, samplerate); - goto beach; - } - if (s->path) AUBIO_FREE(s->path); s->path = AUBIO_ARRAY(char_t, strnlen(path, PATH_MAX) + 1); strncpy(s->path, path, strnlen(path, PATH_MAX) + 1); @@ -135,7 +130,7 @@ uint_t aubio_sink_wavwrite_preset_samplerate(aubio_sink_wavwrite_t *s, uint_t sa } s->samplerate = samplerate; // automatically open when both samplerate and channels have been set - if (s->samplerate != 0 && s->channels != 0) { + if (/* s->samplerate != 0 && */ s->channels != 0) { return aubio_sink_wavwrite_open(s); } return AUBIO_OK; @@ -148,7 +143,7 @@ uint_t aubio_sink_wavwrite_preset_channels(aubio_sink_wavwrite_t *s, uint_t chan } s->channels = channels; // automatically open when both samplerate and channels have been set - if (s->samplerate != 0 && s->channels != 0) { + if (s->samplerate != 0 /* && s->channels != 0 */) { return aubio_sink_wavwrite_open(s); } return AUBIO_OK; @@ -233,18 +228,16 @@ beach: void aubio_sink_wavwrite_do(aubio_sink_wavwrite_t *s, fvec_t * write_data, uint_t write){ - uint_t i = 0, written_frames = 0; - - if (write > s->max_size) { - AUBIO_WRN("sink_wavwrite: trying to write %d frames to %s, " - "but only %d can be written at a time\n", write, s->path, s->max_size); - write = s->max_size; - } + uint_t c = 0, i = 0, written_frames = 0; + uint_t length = aubio_sink_validate_input_length("sink_wavwrite", s->path, + s->max_size, write_data->length, write); - for (i = 0; i < write; i++) { - s->scratch_data[i] = HTOLES(FLOAT_TO_SHORT(write_data->data[i])); + for (c = 0; c < s->channels; c++) { + for (i = 0; i < length; i++) { + s->scratch_data[i * s->channels + c] = HTOLES(FLOAT_TO_SHORT(write_data->data[i])); + } } - written_frames = fwrite(s->scratch_data, 2, write, s->fid); + written_frames = fwrite(s->scratch_data, 2, length * s->channels, s->fid); if (written_frames != write) { 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_ void aubio_sink_wavwrite_do_multi(aubio_sink_wavwrite_t *s, fmat_t * write_data, uint_t write){ uint_t c = 0, i = 0, written_frames = 0; - if (write > s->max_size) { - AUBIO_WRN("sink_wavwrite: trying to write %d frames to %s, " - "but only %d can be written at a time\n", write, s->path, s->max_size); - write = s->max_size; - } + uint_t channels = aubio_sink_validate_input_channels("sink_wavwrite", s->path, + s->channels, write_data->height); + uint_t length = aubio_sink_validate_input_length("sink_wavwrite", s->path, + s->max_size, write_data->length, write); - for (c = 0; c < s->channels; c++) { - for (i = 0; i < write; i++) { + for (c = 0; c < channels; c++) { + for (i = 0; i < length; i++) { s->scratch_data[i * s->channels + c] = HTOLES(FLOAT_TO_SHORT(write_data->data[c][i])); } } - written_frames = fwrite(s->scratch_data, 2, write * s->channels, s->fid); + written_frames = fwrite(s->scratch_data, 2, length * s->channels, s->fid); if (written_frames != write * s->channels) { 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) { } void del_aubio_sink_wavwrite(aubio_sink_wavwrite_t * s){ - if (!s) return; - aubio_sink_wavwrite_close(s); - if (s->path) AUBIO_FREE(s->path); - AUBIO_FREE(s->scratch_data); + AUBIO_ASSERT(s); + if (s->fid) + aubio_sink_wavwrite_close(s); + if (s->path) + AUBIO_FREE(s->path); + if (s->scratch_data) + AUBIO_FREE(s->scratch_data); AUBIO_FREE(s); } diff --git a/src/io/source.c b/src/io/source.c index 41581bf5..5a2e4938 100644 --- a/src/io/source.c +++ b/src/io/source.c @@ -121,7 +121,7 @@ aubio_source_t * new_aubio_source(const char_t * uri, uint_t samplerate, uint_t AUBIO_ERROR("source: failed creating with %s at %dHz with hop size %d" " (no source built-in)\n", uri, samplerate, hop_size); #endif - AUBIO_FREE(s); + del_aubio_source(s); return NULL; } @@ -138,8 +138,9 @@ uint_t aubio_source_close(aubio_source_t * s) { } void del_aubio_source(aubio_source_t * s) { - if (!s) return; - s->s_del((void *)s->source); + AUBIO_ASSERT(s); + if (s->s_del && s->source) + s->s_del((void *)s->source); AUBIO_FREE(s); } diff --git a/src/io/source.h b/src/io/source.h index 2df25843..ff9b8be9 100644 --- a/src/io/source.h +++ b/src/io/source.h @@ -59,7 +59,6 @@ A simple source to read from 16-bits PCM RIFF encoded WAV files. \example io/test-source.c - \example io/test-source_multi.c */ diff --git a/src/io/source_apple_audio.c b/src/io/source_apple_audio.c index db7ff54c..0ef60cd4 100644 --- a/src/io/source_apple_audio.c +++ b/src/io/source_apple_audio.c @@ -34,8 +34,6 @@ #define RT_BYTE3( a ) ( ((a) >> 16) & 0xff ) #define RT_BYTE4( a ) ( ((a) >> 24) & 0xff ) -#define SHORT_TO_FLOAT(x) (smpl_t)(x * 3.0517578125e-05) - struct _aubio_source_apple_audio_t { uint_t channels; uint_t samplerate; //< requested samplerate @@ -48,7 +46,7 @@ struct _aubio_source_apple_audio_t { AudioBufferList bufferList; }; -extern int createAubioBufferList(AudioBufferList *bufferList, int channels, int max_source_samples); +extern int createAudioBufferList(AudioBufferList *bufferList, int channels, int max_source_samples); extern void freeAudioBufferList(AudioBufferList *bufferList); extern CFURLRef createURLFromPath(const char * path); 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 { aubio_source_apple_audio_t * s = AUBIO_NEW(aubio_source_apple_audio_t); - if (path == NULL) { + if (path == NULL || strnlen(path, PATH_MAX) < 1) { AUBIO_ERROR("source_apple_audio: Aborted opening null path\n"); goto beach; } @@ -85,7 +83,7 @@ aubio_source_apple_audio_t * new_aubio_source_apple_audio(const char_t * path, u return s; beach: - AUBIO_FREE(s); + del_aubio_source_apple_audio(s); return NULL; } @@ -94,7 +92,6 @@ uint_t aubio_source_apple_audio_open (aubio_source_apple_audio_t *s, const char_ OSStatus err = noErr; UInt32 propSize; - if (s->path) AUBIO_FREE(s->path); s->path = AUBIO_ARRAY(char_t, strnlen(path, PATH_MAX) + 1); strncpy(s->path, path, strnlen(path, PATH_MAX) + 1); @@ -139,17 +136,16 @@ uint_t aubio_source_apple_audio_open (aubio_source_apple_audio_t *s, const char_ s->channels = fileFormat.mChannelsPerFrame; AudioStreamBasicDescription clientFormat; - propSize = sizeof(clientFormat); + propSize = sizeof(AudioStreamBasicDescription); memset(&clientFormat, 0, sizeof(AudioStreamBasicDescription)); clientFormat.mFormatID = kAudioFormatLinearPCM; clientFormat.mSampleRate = (Float64)(s->samplerate); - clientFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; + clientFormat.mFormatFlags = kAudioFormatFlagIsFloat; clientFormat.mChannelsPerFrame = s->channels; - clientFormat.mBitsPerChannel = sizeof(short) * 8; + clientFormat.mBitsPerChannel = sizeof(smpl_t) * 8; clientFormat.mFramesPerPacket = 1; clientFormat.mBytesPerFrame = clientFormat.mBitsPerChannel * clientFormat.mChannelsPerFrame / 8; clientFormat.mBytesPerPacket = clientFormat.mFramesPerPacket * clientFormat.mBytesPerFrame; - clientFormat.mReserved = 0; // set the client format description 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_ // allocate the AudioBufferList freeAudioBufferList(&s->bufferList); - if (createAubioBufferList(&s->bufferList, s->channels, s->block_size * s->channels)) { + if (createAudioBufferList(&s->bufferList, s->channels, s->block_size * s->channels)) { AUBIO_ERR("source_apple_audio: failed creating bufferList\n"); goto beach; } @@ -196,60 +192,51 @@ beach: return err; } -void aubio_source_apple_audio_do(aubio_source_apple_audio_t *s, fvec_t * read_to, uint_t * read) { - UInt32 c, v, loadedPackets = s->block_size; +static UInt32 aubio_source_apple_audio_read_frame(aubio_source_apple_audio_t *s) +{ + UInt32 loadedPackets = s->block_size; OSStatus err = ExtAudioFileRead(s->audioFile, &loadedPackets, &s->bufferList); if (err) { char_t errorstr[20]; AUBIO_ERROR("source_apple_audio: error while reading %s " "with ExtAudioFileRead (%s)\n", s->path, getPrintableOSStatusError(errorstr, err)); - goto beach; } + return loadedPackets; +} - short *data = (short*)s->bufferList.mBuffers[0].mData; - - smpl_t *buf = read_to->data; +void aubio_source_apple_audio_do(aubio_source_apple_audio_t *s, fvec_t * read_to, + uint_t * read) { + uint_t c, v; + UInt32 loadedPackets = aubio_source_apple_audio_read_frame(s); + smpl_t *data = (smpl_t*)s->bufferList.mBuffers[0].mData; for (v = 0; v < loadedPackets; v++) { - buf[v] = 0.; + read_to->data[v] = 0.; for (c = 0; c < s->channels; c++) { - buf[v] += SHORT_TO_FLOAT(data[ v * s->channels + c]); + read_to->data[v] += data[ v * s->channels + c]; } - buf[v] /= (smpl_t)s->channels; + read_to->data[v] /= (smpl_t)s->channels; } // short read, fill with zeros if (loadedPackets < s->block_size) { for (v = loadedPackets; v < s->block_size; v++) { - buf[v] = 0.; + read_to->data[v] = 0.; } } *read = (uint_t)loadedPackets; return; -beach: - *read = 0; - return; } void aubio_source_apple_audio_do_multi(aubio_source_apple_audio_t *s, fmat_t * read_to, uint_t * read) { - UInt32 c, v, loadedPackets = s->block_size; - OSStatus err = ExtAudioFileRead(s->audioFile, &loadedPackets, &s->bufferList); - if (err) { - char_t errorstr[20]; - AUBIO_ERROR("source_apple_audio: error while reading %s " - "with ExtAudioFileRead (%s)\n", s->path, - getPrintableOSStatusError(errorstr, err)); - goto beach; - } - - short *data = (short*)s->bufferList.mBuffers[0].mData; - - smpl_t **buf = read_to->data; + uint_t c, v; + UInt32 loadedPackets = aubio_source_apple_audio_read_frame(s); + smpl_t *data = (smpl_t*)s->bufferList.mBuffers[0].mData; for (v = 0; v < loadedPackets; v++) { for (c = 0; c < read_to->height; c++) { - buf[c][v] = SHORT_TO_FLOAT(data[ v * s->channels + c]); + read_to->data[c][v] = data[ v * s->channels + c]; } } // 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 // copy last channel to all additional channels for (v = 0; v < loadedPackets; v++) { for (c = s->channels; c < read_to->height; c++) { - buf[c][v] = SHORT_TO_FLOAT(data[ v * s->channels + (s->channels - 1)]); + read_to->data[c][v] = data[ v * s->channels + (s->channels - 1)]; } } } @@ -265,15 +252,13 @@ void aubio_source_apple_audio_do_multi(aubio_source_apple_audio_t *s, fmat_t * r if (loadedPackets < s->block_size) { for (v = loadedPackets; v < s->block_size; v++) { for (c = 0; c < read_to->height; c++) { - buf[c][v] = 0.; + read_to->data[c][v] = 0.; } } } + *read = (uint_t)loadedPackets; return; -beach: - *read = 0; - return; } 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) } void del_aubio_source_apple_audio(aubio_source_apple_audio_t * s){ + AUBIO_ASSERT(s); aubio_source_apple_audio_close (s); if (s->path) AUBIO_FREE(s->path); freeAudioBufferList(&s->bufferList); AUBIO_FREE(s); - return; } 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 } // after a short read, the bufferList size needs to resetted to prepare for a full read AudioBufferList *bufferList = &s->bufferList; - bufferList->mBuffers[0].mDataByteSize = s->block_size * s->channels * sizeof (short); + bufferList->mBuffers[0].mDataByteSize = s->block_size * s->channels * sizeof (smpl_t); // do the actual seek err = ExtAudioFileSeek(s->audioFile, resampled_pos); if (err) { diff --git a/src/io/source_avcodec.c b/src/io/source_avcodec.c index 3b358bc5..4df2f9d0 100644 --- a/src/io/source_avcodec.c +++ b/src/io/source_avcodec.c @@ -46,6 +46,10 @@ #define HAVE_AUBIO_LIBAVCODEC_DEPRECATED 1 #endif +#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58,3,102) +#define HAVE_AUBIO_LIBAVCODEC_TIMEBASE_FIX 1 +#endif + #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55,28,1) #warning "libavcodec < 56 is deprecated" #define av_frame_alloc avcodec_alloc_frame @@ -143,7 +147,6 @@ aubio_source_avcodec_t * new_aubio_source_avcodec(const char_t * path, s->hop_size = hop_size; s->channels = 1; - if (s->path) AUBIO_FREE(s->path); s->path = AUBIO_ARRAY(char_t, strnlen(path, PATH_MAX) + 1); strncpy(s->path, path, strnlen(path, PATH_MAX) + 1); @@ -239,6 +242,11 @@ aubio_source_avcodec_t * new_aubio_source_avcodec(const char_t * path, av_get_media_type_string(AVMEDIA_TYPE_AUDIO), s->path); goto beach; } +#if HAVE_AUBIO_LIBAVCODEC_TIMEBASE_FIX + // avoids 'skipped frames warning' with avecodec < 58, deprecated after + av_codec_set_pkt_timebase(avCodecCtx, + avFormatCtx->streams[selected_stream]->time_base); +#endif #endif if ( ( err = avcodec_open2(avCodecCtx, codec, NULL) ) < 0) { @@ -630,7 +638,7 @@ uint_t aubio_source_avcodec_close(aubio_source_avcodec_t * s) { } void del_aubio_source_avcodec(aubio_source_avcodec_t * s){ - if (!s) return; + AUBIO_ASSERT(s); aubio_source_avcodec_close(s); if (s->output != NULL) { av_free(s->output); diff --git a/src/io/source_sndfile.c b/src/io/source_sndfile.c index eea2ffce..23cd73cb 100644 --- a/src/io/source_sndfile.c +++ b/src/io/source_sndfile.c @@ -86,7 +86,6 @@ aubio_source_sndfile_t * new_aubio_source_sndfile(const char_t * path, uint_t sa s->hop_size = hop_size; s->channels = 1; - if (s->path) AUBIO_FREE(s->path); s->path = AUBIO_ARRAY(char_t, strnlen(path, PATH_MAX) + 1); strncpy(s->path, path, strnlen(path, PATH_MAX) + 1); @@ -331,7 +330,7 @@ uint_t aubio_source_sndfile_close (aubio_source_sndfile_t *s) { } void del_aubio_source_sndfile(aubio_source_sndfile_t * s){ - if (!s) return; + AUBIO_ASSERT(s); aubio_source_sndfile_close(s); #ifdef HAVE_SAMPLERATE if (s->resamplers != NULL) { diff --git a/src/io/source_wavread.c b/src/io/source_wavread.c index 90638af8..deec9604 100644 --- a/src/io/source_wavread.c +++ b/src/io/source_wavread.c @@ -91,7 +91,6 @@ aubio_source_wavread_t * new_aubio_source_wavread(const char_t * path, uint_t sa goto beach; } - if (s->path) AUBIO_FREE(s->path); s->path = AUBIO_ARRAY(char_t, strnlen(path, PATH_MAX) + 1); strncpy(s->path, path, strnlen(path, PATH_MAX) + 1); @@ -471,7 +470,7 @@ uint_t aubio_source_wavread_close (aubio_source_wavread_t * s) { } void del_aubio_source_wavread(aubio_source_wavread_t * s) { - if (!s) return; + AUBIO_ASSERT(s); aubio_source_wavread_close(s); if (s->short_output) AUBIO_FREE(s->short_output); if (s->output) del_fmat(s->output); diff --git a/src/io/utils_apple_audio.c b/src/io/utils_apple_audio.c index 34c35784..a05d65d3 100644 --- a/src/io/utils_apple_audio.c +++ b/src/io/utils_apple_audio.c @@ -12,11 +12,12 @@ void freeAudioBufferList(AudioBufferList *bufferList); CFURLRef getURLFromPath(const char * path); char_t *getPrintableOSStatusError(char_t *str, OSStatus error); -int createAubioBufferList(AudioBufferList * bufferList, int channels, int max_source_samples) { +int createAudioBufferList(AudioBufferList * bufferList, int channels, + int max_source_samples) { bufferList->mNumberBuffers = 1; bufferList->mBuffers[0].mNumberChannels = channels; - bufferList->mBuffers[0].mData = AUBIO_ARRAY(short, max_source_samples); - bufferList->mBuffers[0].mDataByteSize = max_source_samples * sizeof(short); + bufferList->mBuffers[0].mData = AUBIO_ARRAY(smpl_t, max_source_samples); + bufferList->mBuffers[0].mDataByteSize = max_source_samples * sizeof(smpl_t); return 0; } diff --git a/tests/src/io/base-sink_custom.h b/tests/src/io/base-sink_custom.h new file mode 100644 index 00000000..e8c8886f --- /dev/null +++ b/tests/src/io/base-sink_custom.h @@ -0,0 +1,167 @@ +// this should be included *after* custom functions have been defined + +#ifndef aubio_sink_custom +#define aubio_sink_custom "undefined" +#endif /* aubio_sink_custom */ + +#ifdef HAVE_AUBIO_SINK_CUSTOM +int test_wrong_params(void); + +int base_main(int argc, char **argv) +{ + uint_t err = 0; + if (argc < 3 || argc >= 6) { + PRINT_ERR("wrong number of arguments, running tests\n"); + err = test_wrong_params(); + PRINT_MSG("usage: %s [samplerate] [hop_size]\n", + argv[0]); + return err; + } + + uint_t samplerate = 0; + uint_t hop_size = 512; + uint_t n_frames = 0, read = 0; + + char_t *source_path = argv[1]; + char_t *sink_path = argv[2]; + + aubio_source_t *src = NULL; + aubio_sink_custom_t *snk = NULL; + + if ( argc >= 4 ) samplerate = atoi(argv[3]); + if ( argc >= 5 ) hop_size = atoi(argv[4]); + + fvec_t *vec = new_fvec(hop_size); + if (!vec) { err = 1; goto failure; } + + src = new_aubio_source(source_path, samplerate, hop_size); + if (!src) { err = 1; goto failure; } + if (samplerate == 0 ) samplerate = aubio_source_get_samplerate(src); + + snk = new_aubio_sink_custom(sink_path, samplerate); + if (!snk) { err = 1; goto failure; } + + do { + aubio_source_do(src, vec, &read); + aubio_sink_custom_do(snk, vec, read); + n_frames += read; + } while ( read == hop_size ); + + PRINT_MSG("%d frames at %dHz (%d blocks) read from %s, wrote to %s\n", + n_frames, samplerate, n_frames / hop_size, + source_path, sink_path); + + // close sink now (optional) + aubio_sink_custom_close(snk); + +failure: + if (snk) + del_aubio_sink_custom(snk); + if (src) + del_aubio_source(src); + if (vec) + del_fvec(vec); + + return err; +} + +int test_wrong_params(void) +{ + fvec_t *vec; + fmat_t *mat; + aubio_sink_custom_t *s; + char_t sink_path[PATH_MAX] = "tmp_aubio_XXXXXX"; + uint_t samplerate = 44100; + uint_t hop_size = 256; + uint_t oversized_hop_size = 4097; + uint_t oversized_samplerate = 192000 * 8 + 1; + uint_t channels = 3; + uint_t oversized_channels = 1025; + // create temp file + int fd = create_temp_sink(sink_path); + + if (!fd) return 1; + + if (new_aubio_sink_custom( 0, samplerate)) return 1; + if (new_aubio_sink_custom("\0", samplerate)) return 1; + if (new_aubio_sink_custom(sink_path, -1)) return 1; + + s = new_aubio_sink_custom(sink_path, 0); + + // check setting wrong parameters fails + if (!aubio_sink_custom_preset_samplerate(s, oversized_samplerate)) return 1; + if (!aubio_sink_custom_preset_channels(s, oversized_channels)) return 1; + if (!aubio_sink_custom_preset_channels(s, -1)) return 1; + + // check setting valid parameters passes + if (aubio_sink_custom_preset_samplerate(s, samplerate)) return 1; + if (aubio_sink_custom_preset_channels(s, 1)) return 1; + + // check writing a vector with valid length + vec = new_fvec(hop_size); + aubio_sink_custom_do(s, vec, hop_size); + // check writing more than in the input + aubio_sink_custom_do(s, vec, hop_size+1); + // check write 0 frames + aubio_sink_custom_do(s, vec, 0); + del_fvec(vec); + + // check writing an oversized vector + vec = new_fvec(oversized_hop_size); + aubio_sink_custom_do(s, vec, oversized_hop_size); + del_fvec(vec); + + // test delete without closing + del_aubio_sink_custom(s); + + s = new_aubio_sink_custom(sink_path, 0); + + // preset channels first + if (aubio_sink_custom_preset_channels(s, channels)) return 1; + if (aubio_sink_custom_preset_samplerate(s, samplerate)) return 1; + + if (aubio_sink_custom_get_samplerate(s) != samplerate) return 1; + if (aubio_sink_custom_get_channels(s) != channels) return 1; + + mat = new_fmat(channels, hop_size); + // check writing a vector with valid length + aubio_sink_custom_do_multi(s, mat, hop_size); + // check writing 0 frames + aubio_sink_custom_do_multi(s, mat, 0); + // check writing more than in the input + aubio_sink_custom_do_multi(s, mat, hop_size+1); + del_fmat(mat); + + // check writing oversized input + mat = new_fmat(channels, oversized_hop_size); + aubio_sink_custom_do_multi(s, mat, oversized_hop_size); + del_fmat(mat); + + // check writing undersized input + mat = new_fmat(channels - 1, hop_size); + aubio_sink_custom_do_multi(s, mat, hop_size); + del_fmat(mat); + + aubio_sink_custom_close(s); + // test closing twice + aubio_sink_custom_close(s); + + del_aubio_sink_custom(s); + + // delete temp file + close_temp_sink(sink_path, fd); + + return run_on_default_source_and_sink(base_main); +} + +#else /* HAVE_AUBIO_SINK_CUSTOM */ + +int base_main(int argc, char** argv) +{ + PRINT_ERR("aubio was not compiled with aubio_sink_" + aubio_sink_custom ", failed running %s with %d args\n", + argv[0], argc); + return 0; +} + +#endif /* HAVE_AUBIO_SINK_CUSTOM */ diff --git a/tests/src/io/base-source_custom.h b/tests/src/io/base-source_custom.h new file mode 100644 index 00000000..cff2d3e4 --- /dev/null +++ b/tests/src/io/base-source_custom.h @@ -0,0 +1,125 @@ +// this should be included *after* custom functions have been defined + +#ifndef aubio_source_custom +#define aubio_source_custom "undefined" +#endif /* aubio_source_custom */ + +#ifdef HAVE_AUBIO_SOURCE_CUSTOM +int test_wrong_params(void); + +int base_main(int argc, char **argv) +{ + uint_t err = 0; + if (argc < 2) { + PRINT_ERR("not enough arguments, running tests\n"); + err = test_wrong_params(); + PRINT_MSG("read a wave file as a mono vector\n"); + PRINT_MSG("usage: %s [samplerate] [hop_size]\n", argv[0]); + PRINT_MSG("examples:\n"); + PRINT_MSG(" - read file.wav at original samplerate\n"); + PRINT_MSG(" %s file.wav\n", argv[0]); + PRINT_MSG(" - read file.wav at 32000Hz\n"); + PRINT_MSG(" %s file.aif 32000\n", argv[0]); + PRINT_MSG(" - read file.wav at original samplerate with 4096 blocks\n"); + PRINT_MSG(" %s file.wav 0 4096 \n", argv[0]); + return err; + } + + uint_t samplerate = 0; + uint_t hop_size = 256; + uint_t n_frames = 0, read = 0; + if ( argc >= 3 ) samplerate = atoi(argv[2]); + if ( argc >= 4 ) hop_size = atoi(argv[3]); + + char_t *source_path = argv[1]; + + aubio_source_custom_t * s = + new_aubio_source_custom(source_path, samplerate, hop_size); + fvec_t *vec = new_fvec(hop_size); + if (!s || !vec) { err = 1; goto beach; } + + uint_t n_frames_expected = aubio_source_custom_get_duration(s); + + samplerate = aubio_source_custom_get_samplerate(s); + + do { + aubio_source_custom_do(s, vec, &read); + fvec_print (vec); + n_frames += read; + } while ( read == hop_size ); + + PRINT_MSG("read %d frames (expected %d) at %dHz (%d blocks) from %s\n", + n_frames, n_frames_expected, samplerate, n_frames / hop_size, + source_path); + + // close the file (optional) + aubio_source_custom_close(s); + +beach: + if (vec) + del_fvec(vec); + if (s) + del_aubio_source_custom(s); + return err; +} + +int test_wrong_params(void) +{ + char_t *uri = DEFINEDSTRING(AUBIO_TESTS_SOURCE); + uint_t samplerate = 44100; + uint_t hop_size = 512; + uint_t channels, read = 0; + fvec_t *vec; + fmat_t *mat; + aubio_source_custom_t *s; + + if (new_aubio_source_custom(0, samplerate, hop_size)) return 1; + if (new_aubio_source_custom("\0", samplerate, hop_size)) return 1; + if (new_aubio_source_custom(uri, -1, hop_size)) return 1; + if (new_aubio_source_custom(uri, 0, 0)) return 1; + + s = new_aubio_source_custom(uri, samplerate, hop_size); + if (!s) return 1; + channels = aubio_source_custom_get_channels(s); + + // vector to read downmixed samples + vec = new_fvec(hop_size); + // matrix to read individual channels + mat = new_fmat(channels, hop_size); + + if (aubio_source_custom_get_samplerate(s) != samplerate) return 1; + + // read first hop_size frames + aubio_source_custom_do(s, vec, &read); + if (read != hop_size) return 1; + + // seek to 0 + if(aubio_source_custom_seek(s, 0)) return 1; + + // read again as multiple channels + aubio_source_custom_do_multi(s, mat, &read); + if (read != hop_size) return 1; + + // close the file (optional) + aubio_source_custom_close(s); + // test closing the file a second time + aubio_source_custom_close(s); + + del_aubio_source_custom(s); + del_fmat(mat); + del_fvec(vec); + + return run_on_default_source(base_main); +} + +#else /* HAVE_AUBIO_SOURCE_CUSTOM */ + +int base_main(int argc, char** argv) +{ + PRINT_ERR("aubio was not compiled with aubio_source_" + aubio_source_custom ", failed running %s with %d args\n", + argv[0], argc); + return 0; +} + +#endif /* HAVE_AUBIO_SOURCE_CUSTOM */ diff --git a/tests/src/io/test-sink-multi.c b/tests/src/io/test-sink-multi.c deleted file mode 100644 index f30aa059..00000000 --- a/tests/src/io/test-sink-multi.c +++ /dev/null @@ -1,72 +0,0 @@ -#include -#include "utils_tests.h" - -// same as test-sink.c, but uses aubio_source_do_multi to read multiple -// channels - -int main (int argc, char **argv) -{ - sint_t err = 0; - - if (argc < 3) { - PRINT_ERR("not enough arguments, running tests\n"); - err = run_on_default_source_and_sink(main); - PRINT_MSG("usage: %s [samplerate] [channels] [hop_size]\n", argv[0]); - return err; - } - - uint_t samplerate = 0; - uint_t channels = 0; - uint_t hop_size = 512; - uint_t n_frames = 0, read = 0; - - char_t *source_path = argv[1]; - char_t *sink_path = argv[2]; - - if ( argc >= 4 ) samplerate = atoi(argv[3]); - if ( argc >= 5 ) channels = atoi(argv[4]); - if ( argc >= 6 ) hop_size = atoi(argv[5]); - if ( argc >= 7 ) { - err = 2; - PRINT_ERR("too many arguments\n"); - return err; - } - - aubio_source_t *i = new_aubio_source(source_path, samplerate, hop_size); - if (!i) { err = 1; goto beach_source; } - - if (samplerate == 0 ) samplerate = aubio_source_get_samplerate(i); - if (channels == 0 ) channels = aubio_source_get_channels(i); - - fmat_t *mat = new_fmat(channels, hop_size); - if (!mat) { err = 1; goto beach_fmat; } - - aubio_sink_t *o = new_aubio_sink(sink_path, 0); - if (!o) { err = 1; goto beach_sink; } - err = aubio_sink_preset_samplerate(o, samplerate); - if (err) { goto beach; } - err = aubio_sink_preset_channels(o, channels); - if (err) { goto beach; } - - do { - aubio_source_do_multi(i, mat, &read); - aubio_sink_do_multi(o, mat, read); - n_frames += read; - } while ( read == hop_size ); - - PRINT_MSG("read %d frames at %dHz in %d channels (%d blocks) from %s written to %s\n", - n_frames, samplerate, channels, n_frames / hop_size, - source_path, sink_path); - PRINT_MSG("wrote %s with %dHz in %d channels\n", sink_path, - aubio_sink_get_samplerate(o), - aubio_sink_get_channels(o) ); - -beach: - del_aubio_sink(o); -beach_sink: - del_fmat(mat); -beach_fmat: - del_aubio_source(i); -beach_source: - return err; -} diff --git a/tests/src/io/test-sink.c b/tests/src/io/test-sink.c index ce232b17..e004268f 100644 --- a/tests/src/io/test-sink.c +++ b/tests/src/io/test-sink.c @@ -1,14 +1,16 @@ #include #include "utils_tests.h" -int main (int argc, char **argv) -{ - sint_t err = 0; +int test_wrong_params(void); - if (argc < 3) { - PRINT_ERR("not enough arguments, running tests\n"); - err = run_on_default_source_and_sink(main); - PRINT_MSG("usage: %s [samplerate] [hop_size]\n", argv[0]); +int main(int argc, char **argv) +{ + uint_t err = 0; + if (argc < 3 || argc >= 6) { + PRINT_ERR("wrong number of arguments, running tests\n"); + err = test_wrong_params(); + PRINT_MSG("usage: %s [samplerate] [hop_size]\n", + argv[0]); return err; } @@ -19,40 +21,131 @@ int main (int argc, char **argv) char_t *source_path = argv[1]; char_t *sink_path = argv[2]; + aubio_source_t *src = NULL; + aubio_sink_t *snk = NULL; + if ( argc >= 4 ) samplerate = atoi(argv[3]); if ( argc >= 5 ) hop_size = atoi(argv[4]); - if ( argc >= 6 ) { - err = 2; - PRINT_ERR("too many arguments\n"); - return err; - } fvec_t *vec = new_fvec(hop_size); - if (!vec) { err = 1; goto beach_fvec; } - - aubio_source_t *i = new_aubio_source(source_path, samplerate, hop_size); - if (!i) { err = 1; goto beach_source; } + if (!vec) { err = 1; goto failure; } - if (samplerate == 0 ) samplerate = aubio_source_get_samplerate(i); + src = new_aubio_source(source_path, samplerate, hop_size); + if (!src) { err = 1; goto failure; } + if (samplerate == 0 ) samplerate = aubio_source_get_samplerate(src); - aubio_sink_t *o = new_aubio_sink(sink_path, samplerate); - if (!o) { err = 1; goto beach_sink; } + snk = new_aubio_sink(sink_path, samplerate); + if (!snk) { err = 1; goto failure; } do { - aubio_source_do(i, vec, &read); - aubio_sink_do(o, vec, read); + aubio_source_do(src, vec, &read); + aubio_sink_do(snk, vec, read); n_frames += read; } while ( read == hop_size ); - PRINT_MSG("read %d frames at %dHz (%d blocks) from %s written to %s\n", + PRINT_MSG("%d frames read at %dHz (%d blocks) from %s and written to %s\n", n_frames, samplerate, n_frames / hop_size, source_path, sink_path); - del_aubio_sink(o); -beach_sink: - del_aubio_source(i); -beach_source: - del_fvec(vec); -beach_fvec: + // close sink now (optional) + aubio_sink_close(snk); + +failure: + if (snk) + del_aubio_sink(snk); + if (src) + del_aubio_source(src); + if (vec) + del_fvec(vec); + return err; } + +int test_wrong_params(void) +{ + fvec_t *vec; + fmat_t *mat; + aubio_sink_t *s; + char_t sink_path[PATH_MAX] = "tmp_aubio_XXXXXX"; + uint_t samplerate = 44100; + uint_t hop_size = 256; + uint_t oversized_hop_size = 4097; + uint_t oversized_samplerate = 192000 * 8 + 1; + uint_t channels = 3; + uint_t oversized_channels = 1025; + // create temp file + int fd = create_temp_sink(sink_path); + + if (!fd) return 1; + + if (new_aubio_sink( 0, samplerate)) return 1; + if (new_aubio_sink("\0", samplerate)) return 1; + if (new_aubio_sink(sink_path, -1)) return 1; + + s = new_aubio_sink(sink_path, 0); + + // check setting wrong parameters fails + if (!aubio_sink_preset_samplerate(s, oversized_samplerate)) return 1; + if (!aubio_sink_preset_channels(s, oversized_channels)) return 1; + if (!aubio_sink_preset_channels(s, -1)) return 1; + + // check setting valid parameters passes + if (aubio_sink_preset_samplerate(s, samplerate)) return 1; + if (aubio_sink_preset_channels(s, 1)) return 1; + + // check writing a vector with valid length + vec = new_fvec(hop_size); + aubio_sink_do(s, vec, hop_size); + // check writing more than in the input + aubio_sink_do(s, vec, hop_size+1); + // check write 0 frames + aubio_sink_do(s, vec, 0); + del_fvec(vec); + + // check writing an oversized vector + vec = new_fvec(oversized_hop_size); + aubio_sink_do(s, vec, oversized_hop_size); + del_fvec(vec); + + // test delete without closing + del_aubio_sink(s); + + s = new_aubio_sink(sink_path, 0); + + // preset channels first + if (aubio_sink_preset_channels(s, channels)) return 1; + if (aubio_sink_preset_samplerate(s, samplerate)) return 1; + + if (aubio_sink_get_samplerate(s) != samplerate) return 1; + if (aubio_sink_get_channels(s) != channels) return 1; + + mat = new_fmat(channels, hop_size); + // check writing a vector with valid length + aubio_sink_do_multi(s, mat, hop_size); + // check writing 0 frames + aubio_sink_do_multi(s, mat, 0); + // check writing more than in the input + aubio_sink_do_multi(s, mat, hop_size+1); + del_fmat(mat); + + // check writing oversized input + mat = new_fmat(channels, oversized_hop_size); + aubio_sink_do_multi(s, mat, oversized_hop_size); + del_fmat(mat); + + // check writing undersized input + mat = new_fmat(channels - 1, hop_size); + aubio_sink_do_multi(s, mat, hop_size); + del_fmat(mat); + + aubio_sink_close(s); + // test closing twice + aubio_sink_close(s); + + del_aubio_sink(s); + + // delete temp file + close_temp_sink(sink_path, fd); + + return run_on_default_source_and_sink(main); +} diff --git a/tests/src/io/test-sink_apple_audio-multi.c b/tests/src/io/test-sink_apple_audio-multi.c deleted file mode 100644 index ffff6935..00000000 --- a/tests/src/io/test-sink_apple_audio-multi.c +++ /dev/null @@ -1,78 +0,0 @@ -#define AUBIO_UNSTABLE 1 -#include -#include "utils_tests.h" - -// this file uses the unstable aubio api to test aubio_sink_apple_audio, please -// use aubio_sink instead see src/io/sink.h and tests/src/sink/test-sink.c - -int main (int argc, char **argv) -{ - sint_t err = 0; - - if (argc < 3) { - PRINT_ERR("not enough arguments, running tests\n"); - err = run_on_default_source_and_sink(main); - PRINT_MSG("usage: %s [samplerate] [channels] [hop_size]\n", argv[0]); - return err; - } - -#ifdef HAVE_SINK_APPLE_AUDIO - uint_t samplerate = 0; - uint_t channels = 0; - uint_t hop_size = 512; - uint_t n_frames = 0, read = 0; - - char_t *source_path = argv[1]; - char_t *sink_path = argv[2]; - - if ( argc >= 4 ) samplerate = atoi(argv[3]); - if ( argc >= 5 ) channels = atoi(argv[4]); - if ( argc >= 6 ) hop_size = atoi(argv[5]); - if ( argc >= 7 ) { - err = 2; - PRINT_ERR("too many arguments\n"); - return err; - } - - aubio_source_t *i = new_aubio_source(source_path, samplerate, hop_size); - if (!i) { err = 1; goto beach_source; } - - if (samplerate == 0 ) samplerate = aubio_source_get_samplerate(i); - if (channels == 0 ) channels = aubio_source_get_channels(i); - - fmat_t *mat = new_fmat(channels, hop_size); - if (!mat) { err = 1; goto beach_fmat; } - - aubio_sink_apple_audio_t *o = new_aubio_sink_apple_audio(sink_path, 0); - if (!o) { err = 1; goto beach_sink; } - err = aubio_sink_apple_audio_preset_samplerate(o, samplerate); - if (err) { goto beach; } - err = aubio_sink_apple_audio_preset_channels(o, channels); - if (err) { goto beach; } - - do { - aubio_source_do_multi(i, mat, &read); - aubio_sink_apple_audio_do_multi(o, mat, read); - n_frames += read; - } while ( read == hop_size ); - - PRINT_MSG("read %d frames at %dHz in %d channels (%d blocks) from %s written to %s\n", - n_frames, samplerate, channels, n_frames / hop_size, - source_path, sink_path); - PRINT_MSG("wrote %s with %dHz in %d channels\n", sink_path, - aubio_sink_apple_audio_get_samplerate(o), - aubio_sink_apple_audio_get_channels(o) ); - -beach: - del_aubio_sink_apple_audio(o); -beach_sink: - del_fmat(mat); -beach_fmat: - del_aubio_source(i); -beach_source: -#else /* HAVE_SINK_APPLE_AUDIO */ - err = 0; - PRINT_ERR("aubio was not compiled with aubio_sink_apple_audio\n"); -#endif /* HAVE_SINK_APPLE_AUDIO */ - return err; -} diff --git a/tests/src/io/test-sink_apple_audio.c b/tests/src/io/test-sink_apple_audio.c index 2200d500..8349cc8a 100644 --- a/tests/src/io/test-sink_apple_audio.c +++ b/tests/src/io/test-sink_apple_audio.c @@ -2,66 +2,28 @@ #include #include "utils_tests.h" -// this file uses the unstable aubio api, please use aubio_sink instead -// see src/io/sink.h and tests/src/sink/test-sink.c - -int main (int argc, char **argv) -{ - sint_t err = 0; - - if (argc < 3) { - PRINT_ERR("not enough arguments, running tests\n"); - err = run_on_default_source_and_sink(main); - PRINT_MSG("usage: %s [samplerate] [hop_size]\n", argv[0]); - return err; - } +#define aubio_sink_custom "apple_audio" #ifdef HAVE_SINK_APPLE_AUDIO - uint_t samplerate = 0; - uint_t hop_size = 512; - uint_t n_frames = 0, read = 0; - - char_t *source_path = argv[1]; - char_t *sink_path = argv[2]; - - if ( argc >= 4 ) samplerate = atoi(argv[3]); - if ( argc >= 5 ) hop_size = atoi(argv[4]); - if ( argc >= 6 ) { - err = 2; - PRINT_ERR("too many arguments\n"); - return err; - } - - fvec_t *vec = new_fvec(hop_size); - if (!vec) { err = 1; goto beach_fvec; } - - aubio_source_t *i = new_aubio_source(source_path, samplerate, hop_size); - if (!i) { err = 1; goto beach_source; } - - if (samplerate == 0 ) samplerate = aubio_source_get_samplerate(i); - - aubio_sink_apple_audio_t *o = new_aubio_sink_apple_audio(sink_path, samplerate); - if (!o) { err = 1; goto beach_sink; } +#define HAVE_AUBIO_SINK_CUSTOM +#define aubio_sink_custom_t aubio_sink_apple_audio_t +#define new_aubio_sink_custom new_aubio_sink_apple_audio +#define del_aubio_sink_custom del_aubio_sink_apple_audio +#define aubio_sink_custom_do aubio_sink_apple_audio_do +#define aubio_sink_custom_do_multi aubio_sink_apple_audio_do_multi +#define aubio_sink_custom_close aubio_sink_apple_audio_close +#define aubio_sink_custom_preset_samplerate aubio_sink_apple_audio_preset_samplerate +#define aubio_sink_custom_preset_channels aubio_sink_apple_audio_preset_channels +#define aubio_sink_custom_get_samplerate aubio_sink_apple_audio_get_samplerate +#define aubio_sink_custom_get_channels aubio_sink_apple_audio_get_channels +#endif /* HAVE_SINK_APPLE_AUDIO */ - do { - aubio_source_do(i, vec, &read); - aubio_sink_apple_audio_do(o, vec, read); - n_frames += read; - } while ( read == hop_size ); +#include "base-sink_custom.h" - PRINT_MSG("read %d frames at %dHz (%d blocks) from %s written to %s\n", - n_frames, samplerate, n_frames / hop_size, - source_path, sink_path); +// this file uses the unstable aubio api, please use aubio_sink instead +// see src/io/sink.h and tests/src/sink/test-sink.c - del_aubio_sink_apple_audio(o); -beach_sink: - del_aubio_source(i); -beach_source: - del_fvec(vec); -beach_fvec: -#else /* HAVE_SINK_APPLE_AUDIO */ - err = 0; - PRINT_ERR("aubio was not compiled with aubio_source_apple_audio\n"); -#endif /* HAVE_SINK_APPLE_AUDIO */ - return err; +int main (int argc, char **argv) +{ + return base_main(argc, argv); } diff --git a/tests/src/io/test-sink_sndfile-multi.c b/tests/src/io/test-sink_sndfile-multi.c deleted file mode 100644 index 1a8677a4..00000000 --- a/tests/src/io/test-sink_sndfile-multi.c +++ /dev/null @@ -1,78 +0,0 @@ -#define AUBIO_UNSTABLE 1 -#include -#include "utils_tests.h" - -// this file uses the unstable aubio api to test aubio_sink_sndfile, please -// use aubio_sink instead see src/io/sink.h and tests/src/sink/test-sink.c - -int main (int argc, char **argv) -{ - sint_t err = 0; - - if (argc < 3) { - PRINT_ERR("not enough arguments, running tests\n"); - err = run_on_default_source_and_sink(main); - PRINT_MSG("usage: %s [samplerate] [channels] [hop_size]\n", argv[0]); - return err; - } - -#ifdef HAVE_SNDFILE - uint_t samplerate = 0; - uint_t channels = 0; - uint_t hop_size = 512; - uint_t n_frames = 0, read = 0; - - char_t *source_path = argv[1]; - char_t *sink_path = argv[2]; - - if ( argc >= 4 ) samplerate = atoi(argv[3]); - if ( argc >= 5 ) channels = atoi(argv[4]); - if ( argc >= 6 ) hop_size = atoi(argv[5]); - if ( argc >= 7 ) { - err = 2; - PRINT_ERR("too many arguments\n"); - return err; - } - - aubio_source_t *i = new_aubio_source(source_path, samplerate, hop_size); - if (!i) { err = 1; goto beach_source; } - - if (samplerate == 0 ) samplerate = aubio_source_get_samplerate(i); - if (channels == 0 ) channels = aubio_source_get_channels(i); - - fmat_t *mat = new_fmat(channels, hop_size); - if (!mat) { err = 1; goto beach_fmat; } - - aubio_sink_sndfile_t *o = new_aubio_sink_sndfile(sink_path, 0); - if (!o) { err = 1; goto beach_sink; } - err = aubio_sink_sndfile_preset_samplerate(o, samplerate); - if (err) { goto beach; } - err = aubio_sink_sndfile_preset_channels(o, channels); - if (err) { goto beach; } - - do { - aubio_source_do_multi(i, mat, &read); - aubio_sink_sndfile_do_multi(o, mat, read); - n_frames += read; - } while ( read == hop_size ); - - PRINT_MSG("read %d frames at %dHz in %d channels (%d blocks) from %s written to %s\n", - n_frames, samplerate, channels, n_frames / hop_size, - source_path, sink_path); - PRINT_MSG("wrote %s with %dHz in %d channels\n", sink_path, - aubio_sink_sndfile_get_samplerate(o), - aubio_sink_sndfile_get_channels(o) ); - -beach: - del_aubio_sink_sndfile(o); -beach_sink: - del_fmat(mat); -beach_fmat: - del_aubio_source(i); -beach_source: -#else - err = 0; - PRINT_ERR("aubio was not compiled with aubio_sink_sndfile\n"); -#endif /* HAVE_SNDFILE */ - return err; -} diff --git a/tests/src/io/test-sink_sndfile.c b/tests/src/io/test-sink_sndfile.c index 1ecbba5c..51950862 100644 --- a/tests/src/io/test-sink_sndfile.c +++ b/tests/src/io/test-sink_sndfile.c @@ -2,66 +2,28 @@ #include #include "utils_tests.h" -// this file uses the unstable aubio api, please use aubio_sink instead -// see src/io/sink.h and tests/src/sink/test-sink.c - -int main (int argc, char **argv) -{ - sint_t err = 0; - - if (argc < 3) { - PRINT_ERR("not enough arguments, running tests\n"); - err = run_on_default_source_and_sink(main); - PRINT_MSG("usage: %s [samplerate] [hop_size]\n", argv[0]); - return err; - } +#define aubio_sink_custom "sndfile" #ifdef HAVE_SNDFILE - uint_t samplerate = 0; - uint_t hop_size = 512; - uint_t n_frames = 0, read = 0; - - char_t *source_path = argv[1]; - char_t *sink_path = argv[2]; - - if ( argc >= 4 ) samplerate = atoi(argv[3]); - if ( argc >= 5 ) hop_size = atoi(argv[4]); - if ( argc >= 6 ) { - err = 2; - PRINT_ERR("too many arguments\n"); - return err; - } - - fvec_t *vec = new_fvec(hop_size); - if (!vec) { err = 1; goto beach_fvec; } - - aubio_source_t *i = new_aubio_source(source_path, samplerate, hop_size); - if (!i) { err = 1; goto beach_source; } - - if (samplerate == 0 ) samplerate = aubio_source_get_samplerate(i); - - aubio_sink_sndfile_t *o = new_aubio_sink_sndfile(sink_path, samplerate); - if (!o) { err = 1; goto beach_sink; } +#define HAVE_AUBIO_SINK_CUSTOM +#define aubio_sink_custom_t aubio_sink_sndfile_t +#define new_aubio_sink_custom new_aubio_sink_sndfile +#define del_aubio_sink_custom del_aubio_sink_sndfile +#define aubio_sink_custom_do aubio_sink_sndfile_do +#define aubio_sink_custom_do_multi aubio_sink_sndfile_do_multi +#define aubio_sink_custom_close aubio_sink_sndfile_close +#define aubio_sink_custom_preset_samplerate aubio_sink_sndfile_preset_samplerate +#define aubio_sink_custom_preset_channels aubio_sink_sndfile_preset_channels +#define aubio_sink_custom_get_samplerate aubio_sink_sndfile_get_samplerate +#define aubio_sink_custom_get_channels aubio_sink_sndfile_get_channels +#endif /* HAVE_SNDFILE */ - do { - aubio_source_do(i, vec, &read); - aubio_sink_sndfile_do(o, vec, read); - n_frames += read; - } while ( read == hop_size ); +#include "base-sink_custom.h" - PRINT_MSG("read %d frames at %dHz (%d blocks) from %s written to %s\n", - n_frames, samplerate, n_frames / hop_size, - source_path, sink_path); +// this file uses the unstable aubio api, please use aubio_sink instead +// see src/io/sink.h and tests/src/sink/test-sink.c - del_aubio_sink_sndfile(o); -beach_sink: - del_aubio_source(i); -beach_source: - del_fvec(vec); -beach_fvec: -#else - err = 0; - PRINT_ERR("aubio was not compiled with aubio_source_sndfile\n"); -#endif /* HAVE_SNDFILE */ - return err; +int main (int argc, char **argv) +{ + return base_main(argc, argv); } diff --git a/tests/src/io/test-sink_wavwrite-multi.c b/tests/src/io/test-sink_wavwrite-multi.c deleted file mode 100644 index 2388677e..00000000 --- a/tests/src/io/test-sink_wavwrite-multi.c +++ /dev/null @@ -1,78 +0,0 @@ -#define AUBIO_UNSTABLE 1 -#include -#include "utils_tests.h" - -// this file uses the unstable aubio api to test aubio_sink_wavwrite, please -// use aubio_sink instead see src/io/sink.h and tests/src/sink/test-sink.c - -int main (int argc, char **argv) -{ - sint_t err = 0; - - if (argc < 3) { - PRINT_ERR("not enough arguments, running tests\n"); - err = run_on_default_source_and_sink(main); - PRINT_MSG("usage: %s [samplerate] [channels] [hop_size]\n", argv[0]); - return err; - } - -#ifdef HAVE_WAVWRITE - uint_t samplerate = 0; - uint_t channels = 0; - uint_t hop_size = 512; - uint_t n_frames = 0, read = 0; - - char_t *source_path = argv[1]; - char_t *sink_path = argv[2]; - - if ( argc >= 4 ) samplerate = atoi(argv[3]); - if ( argc >= 5 ) channels = atoi(argv[4]); - if ( argc >= 6 ) hop_size = atoi(argv[5]); - if ( argc >= 7 ) { - err = 2; - PRINT_ERR("too many arguments\n"); - return err; - } - - aubio_source_t *i = new_aubio_source(source_path, samplerate, hop_size); - if (!i) { err = 1; goto beach_source; } - - if (samplerate == 0 ) samplerate = aubio_source_get_samplerate(i); - if (channels == 0 ) channels = aubio_source_get_channels(i); - - fmat_t *mat = new_fmat(channels, hop_size); - if (!mat) { err = 1; goto beach_fmat; } - - aubio_sink_wavwrite_t *o = new_aubio_sink_wavwrite(sink_path, 0); - if (!o) { err = 1; goto beach_sink; } - err = aubio_sink_wavwrite_preset_samplerate(o, samplerate); - if (err) { goto beach; } - err = aubio_sink_wavwrite_preset_channels(o, channels); - if (err) { goto beach; } - - do { - aubio_source_do_multi(i, mat, &read); - aubio_sink_wavwrite_do_multi(o, mat, read); - n_frames += read; - } while ( read == hop_size ); - - PRINT_MSG("read %d frames at %dHz in %d channels (%d blocks) from %s written to %s\n", - n_frames, samplerate, channels, n_frames / hop_size, - source_path, sink_path); - PRINT_MSG("wrote %s with %dHz in %d channels\n", sink_path, - aubio_sink_wavwrite_get_samplerate(o), - aubio_sink_wavwrite_get_channels(o) ); - -beach: - del_aubio_sink_wavwrite(o); -beach_sink: - del_fmat(mat); -beach_fmat: - del_aubio_source(i); -beach_source: -#else - err = 0; - PRINT_ERR("aubio was not compiled with aubio_sink_wavwrite\n"); -#endif /* HAVE_WAVWRITE */ - return err; -} diff --git a/tests/src/io/test-sink_wavwrite.c b/tests/src/io/test-sink_wavwrite.c index f1a8006e..e219fe65 100644 --- a/tests/src/io/test-sink_wavwrite.c +++ b/tests/src/io/test-sink_wavwrite.c @@ -2,66 +2,28 @@ #include #include "utils_tests.h" -// this file uses the unstable aubio api, please use aubio_sink instead -// see src/io/sink.h and tests/src/sink/test-sink.c - -int main (int argc, char **argv) -{ - sint_t err = 0; - - if (argc < 3) { - PRINT_ERR("not enough arguments, running tests\n"); - err = run_on_default_source_and_sink(main); - PRINT_MSG("usage: %s [samplerate] [hop_size]\n", argv[0]); - return err; - } +#define aubio_sink_custom "wavwrite" #ifdef HAVE_WAVWRITE - uint_t samplerate = 0; - uint_t hop_size = 512; - uint_t n_frames = 0, read = 0; - - char_t *source_path = argv[1]; - char_t *sink_path = argv[2]; - - if ( argc >= 4 ) samplerate = atoi(argv[3]); - if ( argc >= 5 ) hop_size = atoi(argv[4]); - if ( argc >= 6 ) { - err = 2; - PRINT_ERR("too many arguments\n"); - return err; - } - - fvec_t *vec = new_fvec(hop_size); - if (!vec) { err = 1; goto beach_fvec; } - - aubio_source_t *i = new_aubio_source(source_path, samplerate, hop_size); - if (!i) { err = 1; goto beach_source; } - - if (samplerate == 0 ) samplerate = aubio_source_get_samplerate(i); - - aubio_sink_wavwrite_t *o = new_aubio_sink_wavwrite(sink_path, samplerate); - if (!o) { err = 1; goto beach_sink; } +#define HAVE_AUBIO_SINK_CUSTOM +#define aubio_sink_custom_t aubio_sink_wavwrite_t +#define new_aubio_sink_custom new_aubio_sink_wavwrite +#define del_aubio_sink_custom del_aubio_sink_wavwrite +#define aubio_sink_custom_do aubio_sink_wavwrite_do +#define aubio_sink_custom_do_multi aubio_sink_wavwrite_do_multi +#define aubio_sink_custom_close aubio_sink_wavwrite_close +#define aubio_sink_custom_preset_samplerate aubio_sink_wavwrite_preset_samplerate +#define aubio_sink_custom_preset_channels aubio_sink_wavwrite_preset_channels +#define aubio_sink_custom_get_samplerate aubio_sink_wavwrite_get_samplerate +#define aubio_sink_custom_get_channels aubio_sink_wavwrite_get_channels +#endif /* HAVE_WAVWRITE */ - do { - aubio_source_do(i, vec, &read); - aubio_sink_wavwrite_do(o, vec, read); - n_frames += read; - } while ( read == hop_size ); +#include "base-sink_custom.h" - PRINT_MSG("read %d frames at %dHz (%d blocks) from %s written to %s\n", - n_frames, samplerate, n_frames / hop_size, - source_path, sink_path); +// this file uses the unstable aubio api, please use aubio_sink instead +// see src/io/sink.h and tests/src/sink/test-sink.c - del_aubio_sink_wavwrite(o); -beach_sink: - del_aubio_source(i); -beach_source: - del_fvec(vec); -beach_fvec: -#else - err = 0; - PRINT_ERR("aubio was not compiled with aubio_sink_wavwrite\n"); -#endif /* HAVE_WAVWRITE */ - return err; +int main (int argc, char **argv) +{ + return base_main(argc, argv); } diff --git a/tests/src/io/test-source.c b/tests/src/io/test-source.c index 66471dc1..426bdc91 100644 --- a/tests/src/io/test-source.c +++ b/tests/src/io/test-source.c @@ -1,12 +1,14 @@ #include #include "utils_tests.h" -int main (int argc, char **argv) +int test_wrong_params(void); + +int main(int argc, char **argv) { uint_t err = 0; if (argc < 2) { PRINT_ERR("not enough arguments, running tests\n"); - err = run_on_default_source(main); + err = test_wrong_params(); PRINT_MSG("read a wave file as a mono vector\n"); PRINT_MSG("usage: %s [samplerate] [hop_size]\n", argv[0]); PRINT_MSG("examples:\n"); @@ -27,11 +29,10 @@ int main (int argc, char **argv) char_t *source_path = argv[1]; - aubio_source_t* s = new_aubio_source(source_path, samplerate, hop_size); - if (!s) { err = 1; goto beach; } fvec_t *vec = new_fvec(hop_size); + if (!s || !vec) { err = 1; goto beach; } uint_t n_frames_expected = aubio_source_get_duration(s); @@ -49,11 +50,60 @@ int main (int argc, char **argv) // close the file (optional) aubio_source_close(s); - // test closing the file a second time - aubio_source_close(s); - del_fvec (vec); - del_aubio_source (s); beach: + if (vec) + del_fvec(vec); + if (s) + del_aubio_source(s); return err; } + +int test_wrong_params(void) +{ + char_t *uri = DEFINEDSTRING(AUBIO_TESTS_SOURCE); + uint_t samplerate = 44100; + uint_t hop_size = 512; + uint_t channels, read = 0; + fvec_t *vec; + fmat_t *mat; + aubio_source_t *s; + + if (new_aubio_source(0, samplerate, hop_size)) return 1; + if (new_aubio_source("\0", samplerate, hop_size)) return 1; + if (new_aubio_source(uri, -1, hop_size)) return 1; + if (new_aubio_source(uri, 0, 0)) return 1; + + s = new_aubio_source(uri, samplerate, hop_size); + if (!s) return 1; + channels = aubio_source_get_channels(s); + + // vector to read downmixed samples + vec = new_fvec(hop_size); + // matrix to read individual channels + mat = new_fmat(channels, hop_size); + + if (aubio_source_get_samplerate(s) != samplerate) return 1; + + // read first hop_size frames + aubio_source_do(s, vec, &read); + if (read != hop_size) return 1; + + // seek to 0 + if(aubio_source_seek(s, 0)) return 1; + + // read again as multiple channels + aubio_source_do_multi(s, mat, &read); + if (read != hop_size) return 1; + + // close the file (optional) + aubio_source_close(s); + // test closing the file a second time + aubio_source_close(s); + + del_aubio_source(s); + del_fmat(mat); + del_fvec(vec); + + return run_on_default_source(main); +} diff --git a/tests/src/io/test-source_apple_audio.c b/tests/src/io/test-source_apple_audio.c index b38ed95b..25fec53c 100644 --- a/tests/src/io/test-source_apple_audio.c +++ b/tests/src/io/test-source_apple_audio.c @@ -2,62 +2,29 @@ #include #include "utils_tests.h" +#define aubio_source_custom "apple_audio" + +#ifdef HAVE_SOURCE_APPLE_AUDIO +#define HAVE_AUBIO_SOURCE_CUSTOM +#define aubio_source_custom_t aubio_source_apple_audio_t +#define new_aubio_source_custom new_aubio_source_apple_audio +#define del_aubio_source_custom del_aubio_source_apple_audio +#define aubio_source_custom_get_samplerate aubio_source_apple_audio_get_samplerate +#define aubio_source_custom_get_duration aubio_source_apple_audio_get_duration +#define aubio_source_custom_do aubio_source_apple_audio_do +#define aubio_source_custom_do_multi aubio_source_apple_audio_do_multi +#define aubio_source_custom_seek aubio_source_apple_audio_seek +#define aubio_source_custom_close aubio_source_apple_audio_close +#define aubio_source_custom_get_channels aubio_source_apple_audio_get_channels +#define aubio_source_custom_get_samplerate aubio_source_apple_audio_get_samplerate +#endif /* HAVE_SOURCE_APPLE_AUDIO */ + +#include "base-source_custom.h" + // this file uses the unstable aubio api, please use aubio_source instead // see src/io/source.h and tests/src/source/test-source.c int main (int argc, char **argv) { - uint_t err = 0; - if (argc < 2) { - PRINT_ERR("not enough arguments, running tests\n"); - err = run_on_default_source(main); - PRINT_MSG("read a wave file as a mono vector\n"); - PRINT_MSG("usage: %s [samplerate] [hop_size]\n", argv[0]); - PRINT_MSG("examples:\n"); - PRINT_MSG(" - read file.wav at original samplerate\n"); - PRINT_MSG(" %s file.wav\n", argv[0]); - PRINT_MSG(" - read file.aif at 32000Hz\n"); - PRINT_MSG(" %s file.aif 32000\n", argv[0]); - PRINT_MSG(" - read file.mp3 at original samplerate with 4096 blocks\n"); - PRINT_MSG(" %s file.mp3 0 4096 \n", argv[0]); - return err; - } - -#if HAVE_SOURCE_APPLE_AUDIO - uint_t samplerate = 0; - uint_t hop_size = 256; - uint_t n_frames = 0, read = 0; - if ( argc >= 3 ) samplerate = atoi(argv[2]); - if ( argc >= 4 ) hop_size = atoi(argv[3]); - - char_t *source_path = argv[1]; - - - aubio_source_apple_audio_t * s = - new_aubio_source_apple_audio(source_path, samplerate, hop_size); - if (!s) { err = 1; goto beach; } - fvec_t *vec = new_fvec(hop_size); - - uint_t n_frames_expected = aubio_source_apple_audio_get_duration(s); - - samplerate = aubio_source_apple_audio_get_samplerate(s); - - do { - aubio_source_apple_audio_do(s, vec, &read); - fvec_print (vec); - n_frames += read; - } while ( read == hop_size ); - - PRINT_MSG("read %d frames (expected %d) at %dHz (%d blocks) from %s\n", - n_frames, n_frames_expected, samplerate, n_frames / hop_size, - source_path); - - del_fvec (vec); - del_aubio_source_apple_audio (s); -beach: -#else /* HAVE_SOURCE_APPLE_AUDIO */ - err = 0; - PRINT_ERR("aubio was not compiled with aubio_source_apple_audio\n"); -#endif /* HAVE_SOURCE_APPLE_AUDIO */ - return err; + return base_main(argc, argv); } diff --git a/tests/src/io/test-source_avcodec.c b/tests/src/io/test-source_avcodec.c index 962b578e..c2c2a138 100644 --- a/tests/src/io/test-source_avcodec.c +++ b/tests/src/io/test-source_avcodec.c @@ -2,62 +2,29 @@ #include #include "utils_tests.h" -// this file uses the unstable aubio api, please use aubio_source instead -// see src/io/source.h and tests/src/source/test-source.c - -int main (int argc, char **argv) -{ - uint_t err = 0; - if (argc < 2) { - PRINT_ERR("not enough arguments, running tests\n"); - err = run_on_default_source(main); - PRINT_MSG("read a wave file as a mono vector\n"); - PRINT_MSG("usage: %s [samplerate] [hop_size]\n", argv[0]); - PRINT_MSG("examples:\n"); - PRINT_MSG(" - read file.wav at original samplerate\n"); - PRINT_MSG(" %s file.wav\n", argv[0]); - PRINT_MSG(" - read file.wav at 32000Hz\n"); - PRINT_MSG(" %s file.aif 32000\n", argv[0]); - PRINT_MSG(" - read file.wav at original samplerate with 4096 blocks\n"); - PRINT_MSG(" %s file.wav 0 4096 \n", argv[0]); - return err; - } +#define aubio_source_custom "avcodec" #ifdef HAVE_LIBAV - uint_t samplerate = 0; - uint_t hop_size = 256; - uint_t n_frames = 0, read = 0; - if ( argc >= 3 ) samplerate = atoi(argv[2]); - if ( argc >= 4 ) hop_size = atoi(argv[3]); - - char_t *source_path = argv[1]; - - - aubio_source_avcodec_t * s = - new_aubio_source_avcodec(source_path, samplerate, hop_size); - if (!s) { err = 1; goto beach; } - fvec_t *vec = new_fvec(hop_size); - - uint_t n_frames_expected = aubio_source_avcodec_get_duration(s); - - samplerate = aubio_source_avcodec_get_samplerate(s); +#define HAVE_AUBIO_SOURCE_CUSTOM +#define aubio_source_custom_t aubio_source_avcodec_t +#define new_aubio_source_custom new_aubio_source_avcodec +#define del_aubio_source_custom del_aubio_source_avcodec +#define aubio_source_custom_get_samplerate aubio_source_avcodec_get_samplerate +#define aubio_source_custom_get_duration aubio_source_avcodec_get_duration +#define aubio_source_custom_do aubio_source_avcodec_do +#define aubio_source_custom_do_multi aubio_source_avcodec_do_multi +#define aubio_source_custom_seek aubio_source_avcodec_seek +#define aubio_source_custom_close aubio_source_avcodec_close +#define aubio_source_custom_get_channels aubio_source_avcodec_get_channels +#define aubio_source_custom_get_samplerate aubio_source_avcodec_get_samplerate +#endif /* HAVE_LIBAV */ - do { - aubio_source_avcodec_do(s, vec, &read); - fvec_print (vec); - n_frames += read; - } while ( read == hop_size ); +#include "base-source_custom.h" - PRINT_MSG("read %d frames (expected %d) at %dHz (%d blocks) from %s\n", - n_frames, n_frames_expected, samplerate, n_frames / hop_size, - source_path); +// this file uses the unstable aubio api, please use aubio_source instead +// see src/io/source.h and tests/src/source/test-source.c - del_fvec (vec); - del_aubio_source_avcodec (s); -beach: -#else /* HAVE_LIBAV */ - err = 0; - PRINT_ERR("aubio was not compiled with aubio_source_avcodec\n"); -#endif /* HAVE_LIBAV */ - return err; +int main (int argc, char **argv) +{ + return base_main(argc, argv); } diff --git a/tests/src/io/test-source_multi.c b/tests/src/io/test-source_multi.c deleted file mode 100644 index 69d88165..00000000 --- a/tests/src/io/test-source_multi.c +++ /dev/null @@ -1,57 +0,0 @@ -#include -#include "utils_tests.h" - -int main (int argc, char **argv) -{ - sint_t err = 0; - if (argc < 2) { - PRINT_ERR("not enough arguments, running tests\n"); - err = run_on_default_source(main); - PRINT_MSG("read a wave file as a mono vector\n"); - PRINT_MSG("usage: %s [samplerate] [hop_size]\n", argv[0]); - PRINT_MSG("examples:\n"); - PRINT_MSG(" - read file.wav at original samplerate\n"); - PRINT_MSG(" %s file.wav\n", argv[0]); - PRINT_MSG(" - read file.wav at 32000Hz\n"); - PRINT_MSG(" %s file.aif 32000\n", argv[0]); - PRINT_MSG(" - read file.wav at original samplerate with 4096 blocks\n"); - PRINT_MSG(" %s file.wav 0 4096 \n", argv[0]); - PRINT_MSG(" - read file.wav at original samplerate with 256 frames blocks, mono\n"); - PRINT_MSG(" %s file.wav 0 4096 1\n", argv[0]); - return err; - } - - uint_t samplerate = 0; - uint_t hop_size = 256; - uint_t n_frames = 0, read = 0; - uint_t n_channels = 0; - if ( argc >= 3 ) samplerate = atoi(argv[2]); - if ( argc >= 4 ) hop_size = atoi(argv[3]); - if ( argc >= 5 ) n_channels = atoi(argv[4]); - - char_t *source_path = argv[1]; - - aubio_source_t* s = new_aubio_source(source_path, samplerate, hop_size); - if (!s) { err = -1; goto beach; } - - if ( samplerate == 0 ) samplerate = aubio_source_get_samplerate(s); - - if ( n_channels == 0 ) n_channels = aubio_source_get_channels(s); - - fmat_t *mat = new_fmat(n_channels, hop_size); - - do { - aubio_source_do_multi (s, mat, &read); - fmat_print (mat); - n_frames += read; - } while ( read == hop_size ); - - PRINT_MSG("read %d frames in %d channels at %dHz (%d blocks) from %s\n", - n_frames, n_channels, samplerate, n_frames / hop_size, source_path); - - del_fmat (mat); - del_aubio_source (s); -beach: - - return err; -} diff --git a/tests/src/io/test-source_seek.c b/tests/src/io/test-source_seek.c deleted file mode 100644 index 8defe22e..00000000 --- a/tests/src/io/test-source_seek.c +++ /dev/null @@ -1,92 +0,0 @@ -#include -#include "utils_tests.h" - -int main (int argc, char **argv) -{ - uint_t err = 0; - if (argc < 2) { - PRINT_ERR("not enough arguments, running tests\n"); - err = run_on_default_source(main); - PRINT_MSG("read a wave file as a mono vector\n"); - PRINT_MSG("usage: %s [samplerate] [hop_size]\n", argv[0]); - PRINT_MSG("examples:\n"); - PRINT_MSG(" - read file.wav at original samplerate\n"); - PRINT_MSG(" %s file.wav\n", argv[0]); - PRINT_MSG(" - read file.wav at 32000Hz\n"); - PRINT_MSG(" %s file.aif 32000\n", argv[0]); - PRINT_MSG(" - read file.wav at original samplerate with 4096 blocks\n"); - PRINT_MSG(" %s file.wav 0 4096 \n", argv[0]); - return err; - } - - uint_t samplerate = 0; - uint_t hop_size = 256; - uint_t n_frames = 0, read = 0; - uint_t old_n_frames_1 = 0, old_n_frames_2 = 0, old_n_frames_3 = 0; - if ( argc >= 3 ) samplerate = atoi(argv[2]); - if ( argc >= 4 ) hop_size = atoi(argv[3]); - - char_t *source_path = argv[1]; - - fvec_t *vec = new_fvec(hop_size); - - aubio_source_t* s = new_aubio_source(source_path, samplerate, hop_size); - if (!s) { err = 1; goto beach; } - - if (samplerate == 0 ) samplerate = aubio_source_get_samplerate(s); - - do { - aubio_source_do(s, vec, &read); - //fvec_print (vec); - n_frames += read; - } while ( read == hop_size ); - - PRINT_MSG("read %.2fs, %d frames at %dHz (%d blocks) from %s\n", - n_frames * 1. / samplerate, - n_frames, samplerate, - n_frames / hop_size, source_path); - - old_n_frames_1 = n_frames; - - aubio_source_seek (s, 0); - - n_frames = 0; - do { - aubio_source_do(s, vec, &read); - //fvec_print (vec); - n_frames += read; - } while ( read == hop_size ); - - PRINT_MSG("read %.2fs, %d frames at %dHz (%d blocks) from %s\n", - n_frames * 1. / samplerate, - n_frames, samplerate, - n_frames / hop_size, source_path); - - old_n_frames_2 = n_frames; - - aubio_source_seek (s, old_n_frames_1 / 2); - - n_frames = 0; - do { - aubio_source_do(s, vec, &read); - //fvec_print (vec); - n_frames += read; - } while ( read == hop_size ); - - PRINT_MSG("read %.2fs, %d frames at %dHz (%d blocks) from %s\n", - n_frames * 1. / samplerate, - n_frames, samplerate, - n_frames / hop_size, source_path); - - old_n_frames_3 = n_frames; - - del_aubio_source (s); -beach: - del_fvec (vec); - - // check that we got exactly the same number of frames - assert ( old_n_frames_2 == old_n_frames_1 ); - // check that we got about half the frames, with 3 decimals - assert ( roundf(1.e3 * old_n_frames_1 / old_n_frames_3) / 1.e3 == 2.); - return err; -} diff --git a/tests/src/io/test-source_sndfile.c b/tests/src/io/test-source_sndfile.c index e50ae472..5c2c06fe 100644 --- a/tests/src/io/test-source_sndfile.c +++ b/tests/src/io/test-source_sndfile.c @@ -2,62 +2,29 @@ #include #include "utils_tests.h" +#define aubio_source_custom "sndfile" + +#ifdef HAVE_SNDFILE +#define HAVE_AUBIO_SOURCE_CUSTOM +#define aubio_source_custom_t aubio_source_sndfile_t +#define new_aubio_source_custom new_aubio_source_sndfile +#define del_aubio_source_custom del_aubio_source_sndfile +#define aubio_source_custom_get_samplerate aubio_source_sndfile_get_samplerate +#define aubio_source_custom_get_duration aubio_source_sndfile_get_duration +#define aubio_source_custom_do aubio_source_sndfile_do +#define aubio_source_custom_do_multi aubio_source_sndfile_do_multi +#define aubio_source_custom_seek aubio_source_sndfile_seek +#define aubio_source_custom_close aubio_source_sndfile_close +#define aubio_source_custom_get_channels aubio_source_sndfile_get_channels +#define aubio_source_custom_get_samplerate aubio_source_sndfile_get_samplerate +#endif /* HAVE_LIBAV */ + +#include "base-source_custom.h" + // this file uses the unstable aubio api, please use aubio_source instead // see src/io/source.h and tests/src/source/test-source.c int main (int argc, char **argv) { - uint_t err = 0; - if (argc < 2) { - PRINT_ERR("not enough arguments, running tests\n"); - err = run_on_default_source(main); - PRINT_MSG("read a wave file as a mono vector\n"); - PRINT_MSG("usage: %s [samplerate] [hop_size]\n", argv[0]); - PRINT_MSG("examples:\n"); - PRINT_MSG(" - read file.wav at original samplerate\n"); - PRINT_MSG(" %s file.wav\n", argv[0]); - PRINT_MSG(" - read file.wav at 32000Hz\n"); - PRINT_MSG(" %s file.aif 32000\n", argv[0]); - PRINT_MSG(" - read file.wav at original samplerate with 4096 blocks\n"); - PRINT_MSG(" %s file.wav 0 4096 \n", argv[0]); - return err; - } - -#ifdef HAVE_SNDFILE - uint_t samplerate = 0; - uint_t hop_size = 256; - uint_t n_frames = 0, read = 0; - if ( argc >= 3 ) samplerate = atoi(argv[2]); - if ( argc >= 4 ) hop_size = atoi(argv[3]); - - char_t *source_path = argv[1]; - - - aubio_source_sndfile_t * s = - new_aubio_source_sndfile(source_path, samplerate, hop_size); - if (!s) { err = 1; goto beach; } - fvec_t *vec = new_fvec(hop_size); - - uint_t n_frames_expected = aubio_source_sndfile_get_duration(s); - - samplerate = aubio_source_sndfile_get_samplerate(s); - - do { - aubio_source_sndfile_do(s, vec, &read); - fvec_print (vec); - n_frames += read; - } while ( read == hop_size ); - - PRINT_MSG("read %d frames (expected %d) at %dHz (%d blocks) from %s\n", - n_frames, n_frames_expected, samplerate, n_frames / hop_size, - source_path); - - del_fvec (vec); - del_aubio_source_sndfile (s); -beach: -#else - err = 0; - PRINT_ERR("aubio was not compiled with aubio_source_sndfile\n"); -#endif /* HAVE_SNDFILE */ - return err; + return base_main(argc, argv); } diff --git a/tests/src/io/test-source_wavread.c b/tests/src/io/test-source_wavread.c index a3363f03..81fa6a8f 100644 --- a/tests/src/io/test-source_wavread.c +++ b/tests/src/io/test-source_wavread.c @@ -2,62 +2,29 @@ #include #include "utils_tests.h" -// this file uses the unstable aubio api, please use aubio_source instead -// see src/io/source.h and tests/src/source/test-source.c - -int main (int argc, char **argv) -{ - uint_t err = 0; - if (argc < 2) { - PRINT_ERR("not enough arguments, running tests\n"); - err = run_on_default_source(main); - PRINT_MSG("read a wave file as a mono vector\n"); - PRINT_MSG("usage: %s [samplerate] [hop_size]\n", argv[0]); - PRINT_MSG("examples:\n"); - PRINT_MSG(" - read file.wav at original samplerate\n"); - PRINT_MSG(" %s file.wav\n", argv[0]); - PRINT_MSG(" - read file.wav at 32000Hz\n"); - PRINT_MSG(" %s file.aif 32000\n", argv[0]); - PRINT_MSG(" - read file.wav at original samplerate with 4096 blocks\n"); - PRINT_MSG(" %s file.wav 0 4096 \n", argv[0]); - return err; - } +#define aubio_source_custom "wavread" #ifdef HAVE_WAVREAD - uint_t samplerate = 0; - uint_t hop_size = 256; - uint_t n_frames = 0, read = 0; - if ( argc >= 3 ) samplerate = atoi(argv[2]); - if ( argc >= 4 ) hop_size = atoi(argv[3]); - - char_t *source_path = argv[1]; - - - aubio_source_wavread_t * s = - new_aubio_source_wavread(source_path, samplerate, hop_size); - if (!s) { err = 1; goto beach; } - fvec_t *vec = new_fvec(hop_size); - - uint_t n_frames_expected = aubio_source_wavread_get_duration(s); - - samplerate = aubio_source_wavread_get_samplerate(s); +#define HAVE_AUBIO_SOURCE_CUSTOM +#define aubio_source_custom_t aubio_source_wavread_t +#define new_aubio_source_custom new_aubio_source_wavread +#define del_aubio_source_custom del_aubio_source_wavread +#define aubio_source_custom_get_samplerate aubio_source_wavread_get_samplerate +#define aubio_source_custom_get_duration aubio_source_wavread_get_duration +#define aubio_source_custom_do aubio_source_wavread_do +#define aubio_source_custom_do_multi aubio_source_wavread_do_multi +#define aubio_source_custom_seek aubio_source_wavread_seek +#define aubio_source_custom_close aubio_source_wavread_close +#define aubio_source_custom_get_channels aubio_source_wavread_get_channels +#define aubio_source_custom_get_samplerate aubio_source_wavread_get_samplerate +#endif /* HAVE_WAVREAD */ - do { - aubio_source_wavread_do(s, vec, &read); - fvec_print (vec); - n_frames += read; - } while ( read == hop_size ); +#include "base-source_custom.h" - PRINT_MSG("read %d frames (expected %d) at %dHz (%d blocks) from %s\n", - n_frames, n_frames_expected, samplerate, n_frames / hop_size, - source_path); +// this file uses the unstable aubio api, please use aubio_source instead +// see src/io/source.h and tests/src/source/test-source.c - del_fvec (vec); - del_aubio_source_wavread (s); -beach: -#else - err = 0; - PRINT_ERR("aubio was not compiled with aubio_source_wavread\n"); -#endif /* HAVE_WAVREAD */ - return err; +int main (int argc, char **argv) +{ + return base_main(argc, argv); } diff --git a/tests/src/onset/test-onset.c b/tests/src/onset/test-onset.c index 71936447..cd93651e 100644 --- a/tests/src/onset/test-onset.c +++ b/tests/src/onset/test-onset.c @@ -69,21 +69,19 @@ int test_wrong_params(void) uint_t hop_size = win_size / 2; uint_t samplerate = 44100; // hop_size < 1 - if (new_aubio_onset("default", 5, 0, samplerate)) - return 1; + if (new_aubio_onset("default", 5, 0, samplerate)) return 1; + // buf_size < 2 - if (new_aubio_onset("default", 1, 1, samplerate)) - return 1; + if (new_aubio_onset("default", 1, 1, samplerate)) return 1; + // buf_size < hop_size - if (new_aubio_onset("default", hop_size, win_size, samplerate)) - return 1; + if (new_aubio_onset("default", hop_size, win_size, samplerate)) return 1; + // samplerate < 1 - if (new_aubio_onset("default", 1024, 512, 0)) - return 1; + if (new_aubio_onset("default", 1024, 512, 0)) return 1; // specdesc creation failed - if (new_aubio_onset("abcd", win_size, win_size/2, samplerate)) - return 1; + if (new_aubio_onset("abcd", win_size, win_size/2, samplerate)) return 1; aubio_onset_t *o; @@ -92,8 +90,7 @@ int test_wrong_params(void) if (o) del_aubio_onset(o); o = new_aubio_onset("default", win_size, hop_size, samplerate); - if (!aubio_onset_set_default_parameters(o, "wrong_type")) - return 1; + if (!aubio_onset_set_default_parameters(o, "wrong_type")) return 1; del_aubio_onset(o); return run_on_default_source(main); diff --git a/tests/src/tempo/test-tempo.c b/tests/src/tempo/test-tempo.c index 59791524..d14e9ae5 100644 --- a/tests/src/tempo/test-tempo.c +++ b/tests/src/tempo/test-tempo.c @@ -81,35 +81,28 @@ int test_wrong_params(void) uint_t i; // test wrong method fails - if (new_aubio_tempo("unexisting_method", win_size, hop_size, samplerate)) - return 1; + if (new_aubio_tempo("undefined", win_size, hop_size, samplerate)) return 1; // test hop > win fails - if (new_aubio_tempo("default", hop_size, win_size, samplerate)) - return 1; + 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; + 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; + 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; + 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; + if (!t) return 1; del_aubio_tempo(t); t = new_aubio_tempo("default", win_size, hop_size, samplerate); - if (!t) - return 1; + if (!t) return 1; in = new_fvec(hop_size); out = new_fvec(1); diff --git a/tests/src/temporal/test-filter.c b/tests/src/temporal/test-filter.c index cc9c8f55..b1563163 100644 --- a/tests/src/temporal/test-filter.c +++ b/tests/src/temporal/test-filter.c @@ -9,17 +9,13 @@ int main (void) aubio_filter_t *o = new_aubio_filter_c_weighting (44100); - if (new_aubio_filter(0)) - return 1; + if (new_aubio_filter(0)) return 1; - if (aubio_filter_get_samplerate(o) != 44100) - return 1; + if (aubio_filter_get_samplerate(o) != 44100) return 1; - if (aubio_filter_set_c_weighting (o, -1) == 0) - return 1; + if (aubio_filter_set_c_weighting (o, -1) == 0) return 1; - if (aubio_filter_set_c_weighting (0, 32000) == 0) - return 1; + if (aubio_filter_set_c_weighting (0, 32000) == 0) return 1; in->data[impulse_at] = 0.5; fvec_print (in); @@ -29,10 +25,9 @@ int main (void) o = new_aubio_filter_a_weighting (32000); - if (aubio_filter_set_a_weighting (o, -1) == 0) - return 1; - if (aubio_filter_set_a_weighting (0, 32000) == 0) - return 1; + if (aubio_filter_set_a_weighting (o, -1) == 0) return 1; + + if (aubio_filter_set_a_weighting (0, 32000) == 0) return 1; in->data[impulse_at] = 0.5; fvec_print (in); diff --git a/tests/src/test-delnull.c b/tests/src/test-delnull.c deleted file mode 100644 index bb245090..00000000 --- a/tests/src/test-delnull.c +++ /dev/null @@ -1,24 +0,0 @@ -#include -#include "aubio.h" - -// When creating an aubio object, the user should check whether the object is -// set NULL, indicating the creation failed and the object was not allocated. - -int main (void) -{ - uint_t return_code = 0; - fvec_t *f = new_fvec(-12); - cvec_t *c = new_cvec(-12); - lvec_t *l = new_lvec(-12); - aubio_fft_t *fft = new_aubio_fft(-12); - if (f != NULL) { - return_code = 1; - } else if (c != NULL) { - return_code = 2; - } else if (l != NULL) { - return_code = 3; - } else if (fft != NULL) { - return_code = 3; - } - return return_code; -} diff --git a/tests/utils_tests.h b/tests/utils_tests.h index af968b58..cf1a4460 100644 --- a/tests/utils_tests.h +++ b/tests/utils_tests.h @@ -55,21 +55,20 @@ #define RAND_MAX 32767 #endif -// are we on windows ? or are we using -std=c99 ? -#if defined(HAVE_WIN_HACKS) || defined(__STRICT_ANSI__) -// http://en.wikipedia.org/wiki/Linear_congruential_generator -// no srandom/random on win32 +#if defined(HAVE_WIN_HACKS) -uint_t srandom_seed = 1029; +// use srand/rand on windows +#define srandom srand +#define random rand -void srandom(uint_t new_seed) { - srandom_seed = new_seed; -} +#elif defined(__STRICT_ANSI__) + +// workaround to build with -std=c99 (for instance with older cygwin), +// assuming libbc is recent enough to supports these functions. +extern void srandom(unsigned); +extern int random(void); +extern char mkstemp(const char *pat); -uint_t random(void) { - srandom_seed = 1664525 * srandom_seed + 1013904223; - return srandom_seed; -} #endif void utils_init_random (void); diff --git a/wscript b/wscript index 86208cdf..0690a36e 100644 --- a/wscript +++ b/wscript @@ -555,9 +555,10 @@ def doxygen(bld): + bld.path.find_dir('src').ant_glob('**/*.h'), target = bld.path.find_or_declare('api/index.html'), cwd = bld.path.find_dir('doc')) + # evaluate nodes lazily to prevent build directory traversal warnings bld.install_files('${DATAROOTDIR}/doc/libaubio-doc/api', - bld.path.find_or_declare('api').ant_glob('**/*'), - cwd=bld.path.find_or_declare('api'), + bld.path.find_or_declare('api').ant_glob('**/*', + generator=True), cwd=bld.path.find_or_declare('api'), relative_trick=True) def sphinx(bld): @@ -579,9 +580,10 @@ def sphinx(bld): cwd = bld.path.find_dir('doc'), source = bld.path.find_dir('doc').ant_glob('*.rst'), target = bld.path.find_or_declare('manual/index.html')) + # evaluate nodes lazily to prevent build directory traversal warnings bld.install_files('${DATAROOTDIR}/doc/libaubio-doc/manual', - bld.path.find_or_declare('manual').ant_glob('**/*'), - cwd=bld.path.find_or_declare('manual'), + bld.path.find_or_declare('manual').ant_glob('**/*', + generator=True), cwd=bld.path.find_or_declare('manual'), relative_trick=True) # register the previous rules as build rules