ref: bfbfafa5cb3c42aa2eb201a5db3656a5232554ff
parent: 7b7a58e087d43e0586b52412034bc6fd87e60f71
parent: 25db68c4eefe354f18c58a47eeb5643fc534eb81
author: Paul Brossier <piem@piem.org>
date: Tue Oct 3 18:31:12 EDT 2017
Merge branch 'master' into dct
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -7,27 +7,27 @@
# pre-installed python version, see:
# http://www.appveyor.com/docs/installed-software#python
- - PYTHON: "C:\\Python27"
+ - PYTHONDIR: "C:\\Python27"
PYTHON_VERSION: "2.7.x"
PYTHON_ARCH: "32"
- - PYTHON: "C:\\Python27-x64"
+ - PYTHONDIR: "C:\\Python27-x64"
PYTHON_VERSION: "2.7.x"
PYTHON_ARCH: "64"
- - PYTHON: "C:\\Python34"
+ - PYTHONDIR: "C:\\Python34"
PYTHON_VERSION: "3.4.x"
PYTHON_ARCH: "32"
- - PYTHON: "C:\\Python34-x64"
+ - PYTHONDIR: "C:\\Python34-x64"
PYTHON_VERSION: "3.4.x"
PYTHON_ARCH: "64"
- - PYTHON: "C:\\Python35"
+ - PYTHONDIR: "C:\\Python35"
PYTHON_VERSION: "3.5.x"
PYTHON_ARCH: "32"
- - PYTHON: "C:\\Python35-x64"
+ - PYTHONDIR: "C:\\Python35-x64"
PYTHON_VERSION: "3.5.x"
PYTHON_ARCH: "64"
# add path required to run preprocessor step
@@ -39,20 +39,19 @@
- ps: "ls \"C:/Program Files/Microsoft SDKs/Windows\""
# Check that we have the expected version and architecture for Python
- - "%PYTHON%\\python.exe --version"
- - "%PYTHON%\\python.exe -c \"import struct; print(struct.calcsize('P') * 8)\""
+ - "%PYTHONDIR%\\python.exe --version"
+ - "%PYTHONDIR%\\python.exe -c \"import struct; print(struct.calcsize('P') * 8)\""
# We need wheel installed to build wheels
- - "%PYTHON%\\python.exe -m pip install wheel"
+ - "%PYTHONDIR%\\python.exe -m pip install wheel"
- - "SET PATH=%PATH_EXTRAS%;%PYTHON%;%PYTHON%\\Scripts;%PATH%"
+ - "SET PATH=%PATH_EXTRAS%;%PYTHONDIR%;%PYTHONDIR%\\Scripts;%PATH%"
- "pip install --disable-pip-version-check --user --upgrade pip"
- "pip install --upgrade setuptools"
before_build:
- - curl -fsS -o waf https://waf.io/waf-1.8.22
- - curl -fsS -o waf.bat https://raw.githubusercontent.com/waf-project/waf/master/utils/waf.bat
+ - "bash scripts/get_waf.sh"
build_script:
# build python module without using libaubio
@@ -62,8 +61,6 @@
- "python python\\demos\\demo_create_test_sounds.py"
- "nose2 --verbose"
# clean up
- - waf distclean
+ - "python waf distclean"
# build libaubio
- - waf configure build --verbose
- # build python module using libaubio dll
- - "python setup.py build"
+ - python waf configure build --verbose --msvc_version="msvc 14.0"
--- /dev/null
+++ b/.coveragerc
@@ -1,0 +1,3 @@
+[run]
+branch = True
+source = aubio
--- a/.travis.yml
+++ b/.travis.yml
@@ -81,6 +81,7 @@
- libasound2-dev
- libfftw3-dev
- sox
+ - lcov
before_install:
- |
@@ -89,6 +90,7 @@
brew install sox
brew install ffmpeg
brew install libsndfile
+ brew install lcov
export PATH="$HOME/Library/Python/2.7/bin/:$PATH"
fi;
@@ -97,6 +99,8 @@
- travis_retry make getwaf expandwaf deps_python
- which pip
- pip --version
+ - pip install python-coveralls
+ - gem install coveralls-lcov
script:
- make create_test_sounds
@@ -103,10 +107,21 @@
- |
if [[ -z "$AUBIO_NOTESTS" ]]; then
make test_lib_python_clean
- make test_python_only_clean
+ make coverage
else
make test_lib_only_clean
fi;
+
+after_success:
+ - |
+ if [[ -z "$AUBIO_NOTESTS" ]]; then
+ # upload lcov coverage to coveralls.io
+ coveralls-lcov build/coverage.info
+ # upload python coverage
+ #coveralls
+ # upload to codecov
+ bash <(curl -s https://codecov.io/bash)
+ fi
notifications:
irc:
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,70 @@
+2017-10-02 Paul Brossier <piem@aubio.org>
+
+ [ Overview ]
+
+ * VERSION: bump to 0.4.6
+ * src/spectral/fft.c, src/*.c: add support for Intel IPP (many thanks to
+ Eduard Mueller)
+ * wscript: add support for emscripten (thanks to Martin Hermant)
+ * src/pitch/pitchyinfast.h: new fast method to compute YIN algorithm
+ * src/pitch/pitchyin*.c: improve confidence measure, making sure its value
+ corresponds to the selected period (thanks to Eduard Mueller)
+ * python/lib/aubio/cmd.py: add `quiet`, `cut`, and `help` subcommands
+
+ [ Library ]
+
+ * src/aubio_priv.h: add missing aubio_vDSP_vclr (Eduard Mueller)
+ * src/io/source_avcodec.c: improve error message, prevent un-opened bracket,
+ no declaration after statements for older compilers, avoid unused variable
+ * src/mathutils.c: prevent segfault with Accelerate.framework (closes #58,
+ closes #102)
+ * src/spectral/phasevoc.h: add aubio_pvoc_set_window to change the windowing
+ function
+ * src/mathutils.c: add window type `ones` (no windowing)
+
+ [ Python ]
+
+ * python/demos/demo_tapthebeat.py: add a real-time example to play beats
+ using pyaudio
+ * python/lib/gen_external.py: improve parsing and syntax, use results in
+ emscripten build (Martin Hermant)
+ * python/lib/aubio/cmd.py: add option `-u` to `aubio pitch`, improve error
+ messages, add `quiet` subcommand (closes #124), improve syntax, add some
+ documentation, add `cut` and `help` subcommand, add silence and time format
+ options
+ * python/lib/aubio/cut.py: upgrade to argparse, set samplerate as needed
+ * python/demos/demo_yin_compare.py: add comparison of yin implementations
+ * python/demos/demo_wav2midi.py: add an example to create a midi from a
+ sound file using mido (closes: #134)
+ * python/demos/demo_bpm_extract.py: use argparse, use beats_to_bpm function
+ * python/ext/py-cvec.c: fix support for pypy by changing setters to return a
+ negative value on error (closes #17)
+
+ [ Documentation ]
+
+ * src/tempo/beattracking.h: fix typo (thanks to Hannes Fritz)
+ * doc/requirements.rst: fix broken link (thanks to @ssj71, closes #99)
+ * doc/aubiomfcc.txt: fix typo in 'coefficients'
+
+ [ Tests ]
+
+ * python/tests/tests_aubio_{cmd,cut}.py: add basic tests
+ * python/tests/test_filterbank*.py: ignore UserWarnings, clean-up,
+ improve get_coeff tests
+
+ [ Build system ]
+
+ * wscript: add support for emscripten, see scripts/build_emscripten
+ * scripts/get_waf.sh: update waf to 2.0.1, build waf from source tarball
+ * scripts/build_emscripten: update to build aubio.js
+ * Makefile: add coverage and coverage_report targets, run tests once
+
+ [ Continuous integration ]
+
+ * .travis.yml: add coverage report on osx
+ * .appveyor.yml: use msvc 14.0 (VS 2015) and scripts/get_waf.sh
+ * .coveragerc: add minimal python coverage configuration
+
2017-04-10 Paul Brossier <piem@aubio.org>
[Overview]
--- a/Makefile
+++ b/Makefile
@@ -35,6 +35,9 @@
DATAROOTDIR?=$(PREFIX)/share
MANDIR?=$(DATAROOTDIR)/man
+# default nose2 command
+NOSE2?=nose2 -N 4 --verbose
+
SOX=sox
TESTSOUNDS := python/tests/sounds
@@ -135,9 +138,9 @@
test_python: export PYTHONPATH=$(PYDESTDIR)/$(LIBDIR)
test_python: local_dylib
# run test with installed package
- ./python/tests/run_all_tests --verbose
- # also run with nose, multiple processes
- nose2 -N 4
+ # ./python/tests/run_all_tests --verbose
+ # run with nose2, multiple processes
+ $(NOSE2)
clean_python:
./setup.py clean
@@ -230,6 +233,27 @@
test_python_only_clean: test_python_only \
uninstall_python \
check_clean_python
+
+coverage: export CFLAGS=--coverage
+coverage: export LDFLAGS=--coverage
+coverage: export PYTHONPATH=$(PWD)/python/lib
+coverage: export LD_LIBRARY_PATH=$(PWD)/build/src
+coverage: force_uninstall_python deps_python \
+ clean_python clean distclean build local_dylib
+ lcov --capture --no-external --directory . --output-file build/coverage_lib.info
+ pip install -v -e .
+ coverage run `which nose2`
+ lcov --capture --no-external --directory . --output-file build/coverage_python.info
+ lcov -a build/coverage_python.info -a build/coverage_lib.info -o build/coverage.info
+
+coverage_report: coverage
+ genhtml build/coverage.info --output-directory lcov_html
+ mkdir -p gcovr_html/
+ gcovr -r . --html --html-details \
+ --output gcovr_html/index.html \
+ --exclude ".*tests/.*" --exclude ".*examples/.*"
+ coverage report
+ coverage html
sphinx: configure
$(WAFCMD) sphinx $(WAFOPTS)
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
[![Travis build status](https://travis-ci.org/aubio/aubio.svg?branch=master)](https://travis-ci.org/aubio/aubio "Travis build status")
[![Appveyor build status](https://img.shields.io/appveyor/ci/piem/aubio/master.svg)](https://ci.appveyor.com/project/piem/aubio "Appveyor build status")
[![Landscape code health](https://landscape.io/github/aubio/aubio/master/landscape.svg?style=flat)](https://landscape.io/github/aubio/aubio/master "Landscape code health")
-[![Commits since last release](https://img.shields.io/github/commits-since/aubio/aubio/0.4.5.svg)](https://github.com/aubio/aubio "Commits since last release")
+[![Commits since last release](https://img.shields.io/github/commits-since/aubio/aubio/0.4.6.svg)](https://github.com/aubio/aubio "Commits since last release")
[![Documentation](https://readthedocs.org/projects/aubio/badge/?version=latest)](http://aubio.readthedocs.io/en/latest/?badge=latest "Latest documentation")
[![DOI](https://zenodo.org/badge/396389.svg)](https://zenodo.org/badge/latestdoi/396389)
--- a/VERSION
+++ b/VERSION
@@ -1,7 +1,7 @@
AUBIO_MAJOR_VERSION=0
AUBIO_MINOR_VERSION=4
-AUBIO_PATCH_VERSION=6
+AUBIO_PATCH_VERSION=7
AUBIO_VERSION_STATUS='~alpha'
LIBAUBIO_LT_CUR=5
-LIBAUBIO_LT_REV=2
-LIBAUBIO_LT_AGE=6
+LIBAUBIO_LT_REV=3
+LIBAUBIO_LT_AGE=7
--- a/doc/statuslinks.rst
+++ b/doc/statuslinks.rst
@@ -17,7 +17,7 @@
:target: https://aubio.readthedocs.io/en/latest/?badge=latest
:alt: Documentation status
-.. image:: https://img.shields.io/github/commits-since/aubio/aubio/0.4.5.svg?maxAge=2592000
+.. image:: https://img.shields.io/github/commits-since/aubio/aubio/0.4.6.svg?maxAge=2592000
:target: https://github.com/aubio/aubio
:alt: Commits since last release
--- a/python/ext/py-cvec.c
+++ b/python/ext/py-cvec.c
@@ -142,7 +142,7 @@
{
npy_intp length;
if (!PyAubio_IsValidVector(input)) {
- return 1;
+ return -1;
}
length = PyArray_SIZE ((PyArrayObject *)input);
if (length != vec->length) {
@@ -149,7 +149,7 @@
PyErr_Format (PyExc_ValueError,
"input array has length %" NPY_INTP_FMT ", but cvec has length %d", length,
vec->length);
- return 1;
+ return -1;
}
Py_XDECREF(vec->norm);
@@ -163,7 +163,7 @@
{
npy_intp length;
if (!PyAubio_IsValidVector(input)) {
- return 1;
+ return -1;
}
length = PyArray_SIZE ((PyArrayObject *)input);
if (length != vec->length) {
@@ -170,7 +170,7 @@
PyErr_Format (PyExc_ValueError,
"input array has length %" NPY_INTP_FMT ", but cvec has length %d", length,
vec->length);
- return 1;
+ return -1;
}
Py_XDECREF(vec->phas);
--- a/python/tests/test_aubio_cmd.py
+++ b/python/tests/test_aubio_cmd.py
@@ -10,7 +10,11 @@
self.a_parser = aubio.cmd.aubio_parser()
def test_default_creation(self):
- assert self.a_parser.parse_args(['-V']).show_version
+ try:
+ assert self.a_parser.parse_args(['-V']).show_version
+ except SystemExit:
+ url = 'https://bugs.python.org/issue9253'
+ self.skipTest('subcommand became optional in py3, see %s' % url)
class aubio_cmd_utils(TestCase):
--- a/scripts/build_emscripten
+++ b/scripts/build_emscripten
@@ -1,4 +1,4 @@
-#! /bin/sh
+#! /bin/bash
function checkprog() {
type $1 >/dev/null 2>&1 || { echo >&2 "$1 required but not found, aborting."; exit 1; }
@@ -9,13 +9,10 @@
checkprog emmake
# clean
-emmake ./waf distclean
+./waf distclean
# configure
-emconfigure ./waf configure --prefix=$EMSCRIPTEN/system/local/ --with-target-platform emscripten
+emconfigure ./waf configure --with-target-platform emscripten $*
# build
-emmake ./waf --testcmd="node %s"
-
-# intall
-#emmake ./waf install
+emmake ./waf build
--- a/scripts/build_mingw
+++ b/scripts/build_mingw
@@ -14,7 +14,7 @@
VERSION=`python $PWD/this_version.py -v`
FFMPEG_BUILDS_URL="https://ffmpeg.zeranoe.com/builds"
-FFMPEG_DEFAULT="20170404-1229007"
+FFMPEG_DEFAULT="3.3.3"
# define some default CFLAGS
DEF_CFLAGS="-Os -I/usr/share/mingw-w64"
@@ -80,10 +80,7 @@
./waf distclean configure build install $WAFOPTS_TGT --testcmd='echo %s'
# fix dll location (see https://github.com/waf-project/waf/issues/1860)
mv $DESTDIR/lib/libaubio-5.dll $DESTDIR/bin
- # generate def file (see https://github.com/aubio/aubio/issues/97)
- ( echo -e "EXPORTS"; $NM $DESTDIR/bin/libaubio-5.dll | grep T\ | \
- egrep "(aubio|fvec|cvec|lvec|fmat)" | sed 's/^.* T _\?//' ) \
- > $DESTDIR/bin/libaubio-5.def
+ mv $DESTDIR/lib/libaubio-5.def $DESTDIR/bin
zip -r $DESTDIR.zip `basename $DESTDIR`
rm -rf $DESTDIR
sha256sum $DESTDIR.zip > $DESTDIR.zip.sha256
--- a/scripts/get_waf.sh
+++ b/scripts/get_waf.sh
@@ -1,10 +1,37 @@
-#! /bin/sh
+#! /bin/bash
set -e
set -x
-WAFURL=https://waf.io/waf-1.9.12
+WAFVERSION=2.0.1
+WAFTARBALL=waf-$WAFVERSION.tar.bz2
+WAFURL=https://waf.io/$WAFTARBALL
-( which wget > /dev/null && wget -qO waf $WAFURL ) || ( which curl > /dev/null && curl $WAFURL > waf )
+WAFBUILDDIR=`mktemp -d`
-chmod +x waf
+function cleanup () {
+ rm -rf $WAFBUILDDIR
+}
+
+trap cleanup SIGINT SIGTERM
+
+function buildwaf () {
+ pushd $WAFBUILDDIR
+
+ ( which wget > /dev/null && wget -qO $WAFTARBALL $WAFURL ) || ( which curl > /dev/null && curl $WAFURL > $WAFTARBALL )
+
+ tar xf $WAFTARBALL
+ pushd waf-$WAFVERSION
+ NOCLIMB=1 python waf-light --tools=c_emscripten $*
+
+ popd
+ popd
+
+ cp -prv $WAFBUILDDIR/waf-$WAFVERSION/waf $PWD
+
+ chmod +x waf
+}
+
+buildwaf
+
+cleanup
--- a/src/aubio_priv.h
+++ b/src/aubio_priv.h
@@ -93,6 +93,7 @@
#define aubio_vDSP_minv vDSP_minv
#define aubio_vDSP_minvi vDSP_minvi
#define aubio_vDSP_dotpr vDSP_dotpr
+#define aubio_vDSP_vclr vDSP_vclr
#else /* HAVE_AUBIO_DOUBLE */
#define aubio_vDSP_mmov vDSP_mmovD
#define aubio_vDSP_vmul vDSP_vmulD
@@ -104,6 +105,7 @@
#define aubio_vDSP_minv vDSP_minvD
#define aubio_vDSP_minvi vDSP_minviD
#define aubio_vDSP_dotpr vDSP_dotprD
+#define aubio_vDSP_vclr vDSP_vclrD
#endif /* HAVE_AUBIO_DOUBLE */
#endif /* HAVE_ACCELERATE */
@@ -121,7 +123,38 @@
#endif /* HAVE_AUBIO_DOUBLE */
#endif /* HAVE_ATLAS */
-#if !defined(HAVE_MEMCPY_HACKS) && !defined(HAVE_ACCELERATE) && !defined(HAVE_ATLAS)
+#if defined HAVE_INTEL_IPP
+#include <ippcore.h>
+#include <ippvm.h>
+#include <ipps.h>
+#ifndef HAVE_AUBIO_DOUBLE
+#define aubio_ippsSet ippsSet_32f
+#define aubio_ippsZero ippsZero_32f
+#define aubio_ippsCopy ippsCopy_32f
+#define aubio_ippsMul ippsMul_32f
+#define aubio_ippsMulC ippsMulC_32f
+#define aubio_ippsAddC ippsAddC_32f
+#define aubio_ippsLn ippsLn_32f_A21
+#define aubio_ippsMean(a,b,c) ippsMean_32f(a, b, c, ippAlgHintFast)
+#define aubio_ippsSum(a,b,c) ippsSum_32f(a, b, c, ippAlgHintFast)
+#define aubio_ippsMax ippsMax_32f
+#define aubio_ippsMin ippsMin_32f
+#else /* HAVE_AUBIO_DOUBLE */
+#define aubio_ippsSet ippsSet_64f
+#define aubio_ippsZero ippsZero_64f
+#define aubio_ippsCopy ippsCopy_64f
+#define aubio_ippsMul ippsMul_64f
+#define aubio_ippsMulC ippsMulC_64f
+#define aubio_ippsAddC ippsAddC_64f
+#define aubio_ippsLn ippsLn_64f_A26
+#define aubio_ippsMean ippsMean_64f
+#define aubio_ippsSum ippsSum_64f
+#define aubio_ippsMax ippsMax_64f
+#define aubio_ippsMin ippsMin_64f
+#endif /* HAVE_AUBIO_DOUBLE */
+#endif
+
+#if !defined(HAVE_MEMCPY_HACKS) && !defined(HAVE_ACCELERATE) && !defined(HAVE_ATLAS) && !defined(HAVE_INTEL_IPP)
#define HAVE_NOOPT 1
#else
#undef HAVE_NOOPT
--- a/src/cvec.c
+++ b/src/cvec.c
@@ -85,31 +85,40 @@
s->length, t->length);
return;
}
-#ifdef HAVE_MEMCPY_HACKS
+#if defined(HAVE_INTEL_IPP)
+ aubio_ippsCopy(s->phas, t->phas, (int)s->length);
+ aubio_ippsCopy(s->norm, t->norm, (int)s->length);
+#elif defined(HAVE_MEMCPY_HACKS)
memcpy(t->norm, s->norm, t->length * sizeof(smpl_t));
memcpy(t->phas, s->phas, t->length * sizeof(smpl_t));
-#else /* HAVE_MEMCPY_HACKS */
+#else
uint_t j;
for (j=0; j< t->length; j++) {
t->norm[j] = s->norm[j];
t->phas[j] = s->phas[j];
}
-#endif /* HAVE_MEMCPY_HACKS */
+#endif
}
-void cvec_norm_set_all (cvec_t *s, smpl_t val) {
+void cvec_norm_set_all(cvec_t *s, smpl_t val) {
+#if defined(HAVE_INTEL_IPP)
+ aubio_ippsSet(val, s->norm, (int)s->length);
+#else
uint_t j;
for (j=0; j< s->length; j++) {
s->norm[j] = val;
}
+#endif
}
void cvec_norm_zeros(cvec_t *s) {
-#ifdef HAVE_MEMCPY_HACKS
+#if defined(HAVE_INTEL_IPP)
+ aubio_ippsZero(s->norm, (int)s->length);
+#elif defined(HAVE_MEMCPY_HACKS)
memset(s->norm, 0, s->length * sizeof(smpl_t));
-#else /* HAVE_MEMCPY_HACKS */
+#else
cvec_norm_set_all (s, 0.);
-#endif /* HAVE_MEMCPY_HACKS */
+#endif
}
void cvec_norm_ones(cvec_t *s) {
@@ -117,14 +126,20 @@
}
void cvec_phas_set_all (cvec_t *s, smpl_t val) {
+#if defined(HAVE_INTEL_IPP)
+ aubio_ippsSet(val, s->phas, (int)s->length);
+#else
uint_t j;
for (j=0; j< s->length; j++) {
s->phas[j] = val;
}
+#endif
}
void cvec_phas_zeros(cvec_t *s) {
-#ifdef HAVE_MEMCPY_HACKS
+#if defined(HAVE_INTEL_IPP)
+ aubio_ippsZero(s->phas, (int)s->length);
+#elif defined(HAVE_MEMCPY_HACKS)
memset(s->phas, 0, s->length * sizeof(smpl_t));
#else
cvec_phas_set_all (s, 0.);
@@ -141,8 +156,14 @@
}
void cvec_logmag(cvec_t *s, smpl_t lambda) {
+#if defined(HAVE_INTEL_IPP)
+ aubio_ippsMulC(s->norm, lambda, s->norm, (int)s->length);
+ aubio_ippsAddC(s->norm, 1.0, s->norm, (int)s->length);
+ aubio_ippsLn(s->norm, s->norm, (int)s->length);
+#else
uint_t j;
for (j=0; j< s->length; j++) {
s->norm[j] = LOG(lambda * s->norm[j] + 1);
}
+#endif
}
--- a/src/fvec.c
+++ b/src/fvec.c
@@ -60,28 +60,31 @@
}
void fvec_set_all (fvec_t *s, smpl_t val) {
-#if !defined(HAVE_ACCELERATE) && !defined(HAVE_ATLAS)
- uint_t j;
- for (j=0; j< s->length; j++) {
- s->data[j] = val;
- }
+#if defined(HAVE_INTEL_IPP)
+ aubio_ippsSet(val, s->data, (int)s->length);
#elif defined(HAVE_ATLAS)
aubio_catlas_set(s->length, val, s->data, 1);
#elif defined(HAVE_ACCELERATE)
aubio_vDSP_vfill(&val, s->data, 1, s->length);
+#else
+ uint_t j;
+ for ( j = 0; j< s->length; j++ )
+ {
+ s->data[j] = val;
+ }
#endif
}
void fvec_zeros(fvec_t *s) {
-#if !defined(HAVE_MEMCPY_HACKS) && !defined(HAVE_ACCELERATE)
- fvec_set_all (s, 0.);
-#else
-#if defined(HAVE_MEMCPY_HACKS)
+#if defined(HAVE_INTEL_IPP)
+ aubio_ippsZero(s->data, (int)s->length);
+#elif defined(HAVE_ACCELERATE)
+ aubio_vDSP_vclr(s->data, 1, s->length);
+#elif defined(HAVE_MEMCPY_HACKS)
memset(s->data, 0, s->length * sizeof(smpl_t));
#else
- aubio_vDSP_vclr(s->data, 1, s->length);
+ fvec_set_all(s, 0.);
#endif
-#endif
}
void fvec_ones(fvec_t *s) {
@@ -96,27 +99,31 @@
}
void fvec_weight(fvec_t *s, const fvec_t *weight) {
-#ifndef HAVE_ACCELERATE
- uint_t j;
uint_t length = MIN(s->length, weight->length);
- for (j=0; j< length; j++) {
+#if defined(HAVE_INTEL_IPP)
+ aubio_ippsMul(s->data, weight->data, s->data, (int)length);
+#elif defined(HAVE_ACCELERATE)
+ aubio_vDSP_vmul( s->data, 1, weight->data, 1, s->data, 1, length );
+#else
+ uint_t j;
+ for (j = 0; j < length; j++) {
s->data[j] *= weight->data[j];
}
-#else
- aubio_vDSP_vmul(s->data, 1, weight->data, 1, s->data, 1, s->length);
#endif /* HAVE_ACCELERATE */
}
void fvec_weighted_copy(const fvec_t *in, const fvec_t *weight, fvec_t *out) {
-#ifndef HAVE_ACCELERATE
+ uint_t length = MIN(in->length, MIN(out->length, weight->length));
+#if defined(HAVE_INTEL_IPP)
+ aubio_ippsMul(in->data, weight->data, out->data, (int)length);
+#elif defined(HAVE_ACCELERATE)
+ aubio_vDSP_vmul(in->data, 1, weight->data, 1, out->data, 1, length);
+#else
uint_t j;
- uint_t length = MIN(out->length, weight->length);
- for (j=0; j< length; j++) {
+ for (j = 0; j < length; j++) {
out->data[j] = in->data[j] * weight->data[j];
}
-#else
- aubio_vDSP_vmul(in->data, 1, weight->data, 1, out->data, 1, out->length);
-#endif /* HAVE_ACCELERATE */
+#endif
}
void fvec_copy(const fvec_t *s, fvec_t *t) {
@@ -125,16 +132,18 @@
s->length, t->length);
return;
}
-#ifdef HAVE_NOOPT
- uint_t j;
- for (j=0; j< t->length; j++) {
- t->data[j] = s->data[j];
- }
-#elif defined(HAVE_MEMCPY_HACKS)
- memcpy(t->data, s->data, t->length * sizeof(smpl_t));
+#if defined(HAVE_INTEL_IPP)
+ aubio_ippsCopy(s->data, t->data, (int)s->length);
#elif defined(HAVE_ATLAS)
aubio_cblas_copy(s->length, s->data, 1, t->data, 1);
#elif defined(HAVE_ACCELERATE)
aubio_vDSP_mmov(s->data, t->data, 1, s->length, 1, 1);
+#elif defined(HAVE_MEMCPY_HACKS)
+ memcpy(t->data, s->data, t->length * sizeof(smpl_t));
+#else
+ uint_t j;
+ for (j = 0; j < t->length; j++) {
+ t->data[j] = s->data[j];
+ }
#endif
}
--- a/src/mathutils.c
+++ b/src/mathutils.c
@@ -159,16 +159,19 @@
fvec_mean (fvec_t * s)
{
smpl_t tmp = 0.0;
-#ifndef HAVE_ACCELERATE
+#if defined(HAVE_INTEL_IPP)
+ aubio_ippsMean(s->data, (int)s->length, &tmp);
+ return tmp;
+#elif defined(HAVE_ACCELERATE)
+ aubio_vDSP_meanv(s->data, 1, &tmp, s->length);
+ return tmp;
+#else
uint_t j;
for (j = 0; j < s->length; j++) {
tmp += s->data[j];
}
- return tmp / (smpl_t) (s->length);
-#else
- aubio_vDSP_meanv(s->data, 1, &tmp, s->length);
- return tmp;
-#endif /* HAVE_ACCELERATE */
+ return tmp / (smpl_t)(s->length);
+#endif
}
smpl_t
@@ -175,14 +178,16 @@
fvec_sum (fvec_t * s)
{
smpl_t tmp = 0.0;
-#ifndef HAVE_ACCELERATE
+#if defined(HAVE_INTEL_IPP)
+ aubio_ippsSum(s->data, (int)s->length, &tmp);
+#elif defined(HAVE_ACCELERATE)
+ aubio_vDSP_sve(s->data, 1, &tmp, s->length);
+#else
uint_t j;
for (j = 0; j < s->length; j++) {
tmp += s->data[j];
}
-#else
- aubio_vDSP_sve(s->data, 1, &tmp, s->length);
-#endif /* HAVE_ACCELERATE */
+#endif
return tmp;
}
@@ -189,15 +194,18 @@
smpl_t
fvec_max (fvec_t * s)
{
-#ifndef HAVE_ACCELERATE
+#if defined(HAVE_INTEL_IPP)
+ smpl_t tmp = 0.;
+ aubio_ippsMax( s->data, (int)s->length, &tmp);
+#elif defined(HAVE_ACCELERATE)
+ smpl_t tmp = 0.;
+ aubio_vDSP_maxv( s->data, 1, &tmp, s->length );
+#else
uint_t j;
- smpl_t tmp = 0.0;
- for (j = 0; j < s->length; j++) {
+ smpl_t tmp = s->data[0];
+ for (j = 1; j < s->length; j++) {
tmp = (tmp > s->data[j]) ? tmp : s->data[j];
}
-#else
- smpl_t tmp = 0.;
- aubio_vDSP_maxv(s->data, 1, &tmp, s->length);
#endif
return tmp;
}
@@ -205,15 +213,18 @@
smpl_t
fvec_min (fvec_t * s)
{
-#ifndef HAVE_ACCELERATE
+#if defined(HAVE_INTEL_IPP)
+ smpl_t tmp = 0.;
+ aubio_ippsMin(s->data, (int)s->length, &tmp);
+#elif defined(HAVE_ACCELERATE)
+ smpl_t tmp = 0.;
+ aubio_vDSP_minv(s->data, 1, &tmp, s->length);
+#else
uint_t j;
smpl_t tmp = s->data[0];
- for (j = 0; j < s->length; j++) {
+ for (j = 1; j < s->length; j++) {
tmp = (tmp < s->data[j]) ? tmp : s->data[j];
}
-#else
- smpl_t tmp = 0.;
- aubio_vDSP_minv(s->data, 1, &tmp, s->length);
#endif
return tmp;
}
@@ -572,6 +583,17 @@
uint_t i = 1;
while (i < a) i <<= 1;
return i;
+}
+
+uint_t
+aubio_power_of_two_order (uint_t a)
+{
+ int order = 0;
+ int temp = aubio_next_power_of_two(a);
+ while (temp >>= 1) {
+ ++order;
+ }
+ return order;
}
smpl_t
--- a/src/mathutils.h
+++ b/src/mathutils.h
@@ -312,6 +312,9 @@
/** return the next power of power of 2 greater than a */
uint_t aubio_next_power_of_two(uint_t a);
+/** return the log2 factor of the given power of 2 value a */
+uint_t aubio_power_of_two_order(uint_t a);
+
/** compute normalised autocorrelation function
\param input vector to compute autocorrelation from
--- a/src/pitch/pitchyin.c
+++ b/src/pitch/pitchyin.c
@@ -36,7 +36,7 @@
{
fvec_t *yin;
smpl_t tol;
- smpl_t confidence;
+ uint_t peak_pos;
};
/** compute difference function
@@ -67,6 +67,7 @@
aubio_pitchyin_t *o = AUBIO_NEW (aubio_pitchyin_t);
o->yin = new_fvec (bufsize / 2);
o->tol = 0.15;
+ o->peak_pos = 0;
return o;
}
@@ -156,19 +157,18 @@
period = tau - 3;
if (tau > 4 && (yin_data[period] < tol) &&
(yin_data[period] < yin_data[period + 1])) {
- out->data[0] = fvec_quadratic_peak_pos (yin, period);
- goto beach;
+ o->peak_pos = (uint_t)period;
+ out->data[0] = fvec_quadratic_peak_pos (yin, o->peak_pos);
+ return;
}
}
- out->data[0] = fvec_quadratic_peak_pos (yin, fvec_min_elem (yin));
-beach:
- return;
+ o->peak_pos = (uint_t)fvec_min_elem (yin);
+ out->data[0] = fvec_quadratic_peak_pos (yin, o->peak_pos);
}
smpl_t
aubio_pitchyin_get_confidence (aubio_pitchyin_t * o) {
- o->confidence = 1. - fvec_min (o->yin);
- return o->confidence;
+ return 1. - o->yin->data[o->peak_pos];
}
uint_t
--- a/src/pitch/pitchyinfast.c
+++ b/src/pitch/pitchyinfast.c
@@ -38,7 +38,7 @@
{
fvec_t *yin;
smpl_t tol;
- smpl_t confidence;
+ uint_t peak_pos;
fvec_t *tmpdata;
fvec_t *sqdiff;
fvec_t *kernel;
@@ -59,6 +59,7 @@
o->kernel_fft = new_fvec (bufsize);
o->fft = new_aubio_fft (bufsize);
o->tol = 0.15;
+ o->peak_pos = 0;
return o;
}
@@ -85,7 +86,6 @@
uint_t B = o->tmpdata->length;
uint_t W = o->yin->length; // B / 2
fvec_t tmp_slice, kernel_ptr;
- smpl_t *yin_data = yin->data;
uint_t tau;
sint_t period;
smpl_t tmp2 = 0.;
@@ -142,15 +142,15 @@
aubio_fft_rdo_complex(o->fft, compmul, rt_of_tau);
// compute square difference r_t(tau) = sqdiff - 2 * r_t_tau[W-1:-1]
for (tau = 0; tau < W; tau++) {
- yin_data[tau] = o->sqdiff->data[tau] - 2. * rt_of_tau->data[tau+W];
+ yin->data[tau] = o->sqdiff->data[tau] - 2. * rt_of_tau->data[tau+W];
}
}
// now build yin and look for first minimum
- fvec_set_all(out, 0.);
- yin_data[0] = 1.;
+ fvec_zeros(out);
+ yin->data[0] = 1.;
for (tau = 1; tau < length; tau++) {
- tmp2 += yin_data[tau];
+ tmp2 += yin->data[tau];
if (tmp2 != 0) {
yin->data[tau] *= tau / tmp2;
} else {
@@ -157,21 +157,21 @@
yin->data[tau] = 1.;
}
period = tau - 3;
- if (tau > 4 && (yin_data[period] < tol) &&
- (yin_data[period] < yin_data[period + 1])) {
- out->data[0] = fvec_quadratic_peak_pos (yin, period);
- goto beach;
+ if (tau > 4 && (yin->data[period] < tol) &&
+ (yin->data[period] < yin->data[period + 1])) {
+ o->peak_pos = (uint_t)period;
+ out->data[0] = fvec_quadratic_peak_pos (yin, o->peak_pos);
+ return;
}
}
- out->data[0] = fvec_quadratic_peak_pos (yin, fvec_min_elem (yin) );
-beach:
- return;
+ // use global minimum
+ o->peak_pos = (uint_t)fvec_min_elem (yin);
+ out->data[0] = fvec_quadratic_peak_pos (yin, o->peak_pos);
}
smpl_t
aubio_pitchyinfast_get_confidence (aubio_pitchyinfast_t * o) {
- o->confidence = 1. - fvec_min (o->yin);
- return o->confidence;
+ return 1. - o->yin->data[o->peak_pos];
}
uint_t
--- a/src/pitch/pitchyinfft.c
+++ b/src/pitch/pitchyinfft.c
@@ -36,7 +36,7 @@
aubio_fft_t *fft; /**< fft object to compute square difference function */
fvec_t *yinfft; /**< Yin function */
smpl_t tol; /**< Yin tolerance */
- smpl_t confidence; /**< confidence */
+ uint_t peak_pos; /**< currently selected peak pos*/
uint_t short_period; /** shortest period under which to check for octave error */
};
@@ -67,6 +67,7 @@
p->sqrmag = new_fvec (bufsize);
p->yinfft = new_fvec (bufsize / 2 + 1);
p->tol = 0.85;
+ p->peak_pos = 0;
p->win = new_aubio_window ("hanningz", bufsize);
p->weight = new_fvec (bufsize / 2 + 1);
for (i = 0; i < p->weight->length; i++) {
@@ -161,11 +162,13 @@
/* should compare the minimum value of each interpolated peaks */
halfperiod = FLOOR (tau / 2 + .5);
if (yin->data[halfperiod] < p->tol)
- output->data[0] = fvec_quadratic_peak_pos (yin, halfperiod);
+ p->peak_pos = halfperiod;
else
- output->data[0] = fvec_quadratic_peak_pos (yin, tau);
+ p->peak_pos = tau;
+ output->data[0] = fvec_quadratic_peak_pos (yin, p->peak_pos);
}
} else {
+ p->peak_pos = 0;
output->data[0] = 0.;
}
}
@@ -185,8 +188,7 @@
smpl_t
aubio_pitchyinfft_get_confidence (aubio_pitchyinfft_t * o) {
- o->confidence = 1. - fvec_min (o->yinfft);
- return o->confidence;
+ return 1. - o->yinfft->data[o->peak_pos];
}
uint_t
--- a/src/spectral/fft.c
+++ b/src/spectral/fft.c
@@ -77,8 +77,7 @@
// a global mutex for FFTW thread safety
pthread_mutex_t aubio_fftw_mutex = PTHREAD_MUTEX_INITIALIZER;
-#else
-#ifdef HAVE_ACCELERATE // using ACCELERATE
+#elif defined HAVE_ACCELERATE // using ACCELERATE
// https://developer.apple.com/library/mac/#documentation/Accelerate/Reference/vDSPRef/Reference/reference.html
#include <Accelerate/Accelerate.h>
@@ -112,32 +111,65 @@
#define aubio_vvsqrt vvsqrt
#endif /* HAVE_AUBIO_DOUBLE */
-#else // using OOURA
+#elif defined HAVE_INTEL_IPP // using INTEL IPP
+
+#if !HAVE_AUBIO_DOUBLE
+#define aubio_IppFloat Ipp32f
+#define aubio_IppComplex Ipp32fc
+#define aubio_FFTSpec FFTSpec_R_32f
+#define aubio_ippsMalloc_complex ippsMalloc_32fc
+#define aubio_ippsFFTInit_R ippsFFTInit_R_32f
+#define aubio_ippsFFTGetSize_R ippsFFTGetSize_R_32f
+#define aubio_ippsFFTInv_CCSToR ippsFFTInv_CCSToR_32f
+#define aubio_ippsFFTFwd_RToCCS ippsFFTFwd_RToCCS_32f
+#define aubio_ippsAtan2 ippsAtan2_32f_A21
+#else /* HAVE_AUBIO_DOUBLE */
+#define aubio_IppFloat Ipp64f
+#define aubio_IppComplex Ipp64fc
+#define aubio_FFTSpec FFTSpec_R_64f
+#define aubio_ippsMalloc_complex ippsMalloc_64fc
+#define aubio_ippsFFTInit_R ippsFFTInit_R_64f
+#define aubio_ippsFFTGetSize_R ippsFFTGetSize_R_64f
+#define aubio_ippsFFTInv_CCSToR ippsFFTInv_CCSToR_64f
+#define aubio_ippsFFTFwd_RToCCS ippsFFTFwd_RToCCS_64f
+#define aubio_ippsAtan2 ippsAtan2_64f_A50
+#endif
+
+
+#else // using OOURA
// let's use ooura instead
extern void aubio_ooura_rdft(int, int, smpl_t *, int *, smpl_t *);
-#endif /* HAVE_ACCELERATE */
-#endif /* HAVE_FFTW3 */
+#endif
struct _aubio_fft_t {
uint_t winsize;
uint_t fft_size;
+
#ifdef HAVE_FFTW3 // using FFTW3
real_t *in, *out;
fftw_plan pfw, pbw;
- fft_data_t * specdata; /* complex spectral data */
-#else
-#ifdef HAVE_ACCELERATE // using ACCELERATE
+ fft_data_t * specdata; /* complex spectral data */
+
+#elif defined HAVE_ACCELERATE // using ACCELERATE
int log2fftsize;
aubio_FFTSetup fftSetup;
aubio_DSPSplitComplex spec;
smpl_t *in, *out;
+
+#elif defined HAVE_INTEL_IPP // using Intel IPP
+ smpl_t *in, *out;
+ Ipp8u* memSpec;
+ Ipp8u* memInit;
+ Ipp8u* memBuffer;
+ struct aubio_FFTSpec* fftSpec;
+ aubio_IppComplex* complexOut;
#else // using OOURA
smpl_t *in, *out;
smpl_t *w;
int *ip;
-#endif /* HAVE_ACCELERATE */
-#endif /* HAVE_FFTW3 */
+#endif /* using OOURA */
+
fvec_t * compspec;
};
@@ -147,6 +179,7 @@
AUBIO_ERR("fft: got winsize %d, but can not be < 2\n", winsize);
goto beach;
}
+
#ifdef HAVE_FFTW3
uint_t i;
s->winsize = winsize;
@@ -175,17 +208,55 @@
for (i = 0; i < s->fft_size; i++) {
s->specdata[i] = 0.;
}
-#else
-#ifdef HAVE_ACCELERATE // using ACCELERATE
+
+#elif defined HAVE_ACCELERATE // using ACCELERATE
s->winsize = winsize;
s->fft_size = winsize;
s->compspec = new_fvec(winsize);
- s->log2fftsize = (uint_t)log2f(s->fft_size);
+ s->log2fftsize = aubio_power_of_two_order(s->fft_size);
s->in = AUBIO_ARRAY(smpl_t, s->fft_size);
s->out = AUBIO_ARRAY(smpl_t, s->fft_size);
s->spec.realp = AUBIO_ARRAY(smpl_t, s->fft_size/2);
s->spec.imagp = AUBIO_ARRAY(smpl_t, s->fft_size/2);
s->fftSetup = aubio_vDSP_create_fftsetup(s->log2fftsize, FFT_RADIX2);
+
+#elif defined HAVE_INTEL_IPP // using Intel IPP
+ const IppHintAlgorithm qualityHint = ippAlgHintAccurate; // OR ippAlgHintFast;
+ const int flags = IPP_FFT_NODIV_BY_ANY; // we're scaling manually afterwards
+ int order = aubio_power_of_two_order(winsize);
+ int sizeSpec, sizeInit, sizeBuffer;
+ IppStatus status;
+
+ if (winsize <= 4 || aubio_is_power_of_two(winsize) != 1)
+ {
+ AUBIO_ERR("intel IPP fft: can only create with sizes > 4 and power of two, requested %d,"
+ " try recompiling aubio with --enable-fftw3\n", winsize);
+ goto beach;
+ }
+
+ status = aubio_ippsFFTGetSize_R(order, flags, qualityHint,
+ &sizeSpec, &sizeInit, &sizeBuffer);
+ if (status != ippStsNoErr) {
+ AUBIO_ERR("fft: failed to initialize fft. IPP error: %d\n", status);
+ goto beach;
+ }
+ s->fft_size = s->winsize = winsize;
+ s->compspec = new_fvec(winsize);
+ s->in = AUBIO_ARRAY(smpl_t, s->winsize);
+ s->out = AUBIO_ARRAY(smpl_t, s->winsize);
+ s->memSpec = ippsMalloc_8u(sizeSpec);
+ s->memBuffer = ippsMalloc_8u(sizeBuffer);
+ if (sizeInit > 0 ) {
+ s->memInit = ippsMalloc_8u(sizeInit);
+ }
+ s->complexOut = aubio_ippsMalloc_complex(s->fft_size / 2 + 1);
+ status = aubio_ippsFFTInit_R(
+ &s->fftSpec, order, flags, qualityHint, s->memSpec, s->memInit);
+ if (status != ippStsNoErr) {
+ AUBIO_ERR("fft: failed to initialize. IPP error: %d\n", status);
+ goto beach;
+ }
+
#else // using OOURA
if (aubio_is_power_of_two(winsize) != 1) {
AUBIO_ERR("fft: can only create with sizes power of two, requested %d,"
@@ -200,9 +271,10 @@
s->ip = AUBIO_ARRAY(int , s->fft_size);
s->w = AUBIO_ARRAY(smpl_t, s->fft_size);
s->ip[0] = 0;
-#endif /* HAVE_ACCELERATE */
-#endif /* HAVE_FFTW3 */
+#endif /* using OOURA */
+
return s;
+
beach:
AUBIO_FREE(s);
return NULL;
@@ -210,7 +282,6 @@
void del_aubio_fft(aubio_fft_t * s) {
/* destroy data */
- del_fvec(s->compspec);
#ifdef HAVE_FFTW3 // using FFTW3
pthread_mutex_lock(&aubio_fftw_mutex);
fftw_destroy_plan(s->pfw);
@@ -217,18 +288,26 @@
fftw_destroy_plan(s->pbw);
fftw_free(s->specdata);
pthread_mutex_unlock(&aubio_fftw_mutex);
-#else /* HAVE_FFTW3 */
-#ifdef HAVE_ACCELERATE // using ACCELERATE
+
+#elif defined HAVE_ACCELERATE // using ACCELERATE
AUBIO_FREE(s->spec.realp);
AUBIO_FREE(s->spec.imagp);
aubio_vDSP_destroy_fftsetup(s->fftSetup);
+
+#elif defined HAVE_INTEL_IPP // using Intel IPP
+ ippFree(s->memSpec);
+ ippFree(s->memInit);
+ ippFree(s->memBuffer);
+ ippFree(s->complexOut);
+
#else // using OOURA
AUBIO_FREE(s->w);
AUBIO_FREE(s->ip);
-#endif /* HAVE_ACCELERATE */
-#endif /* HAVE_FFTW3 */
- AUBIO_FREE(s->out);
+#endif
+
+ del_fvec(s->compspec);
AUBIO_FREE(s->in);
+ AUBIO_FREE(s->out);
AUBIO_FREE(s);
}
@@ -251,6 +330,7 @@
#else
memcpy(s->in, input->data, s->winsize * sizeof(smpl_t));
#endif /* HAVE_MEMCPY_HACKS */
+
#ifdef HAVE_FFTW3 // using FFTW3
fftw_execute(s->pfw);
#ifdef HAVE_COMPLEX_H
@@ -265,8 +345,8 @@
compspec->data[i] = s->specdata[i];
}
#endif /* HAVE_COMPLEX_H */
-#else /* HAVE_FFTW3 */
-#ifdef HAVE_ACCELERATE // using ACCELERATE
+
+#elif defined HAVE_ACCELERATE // using ACCELERATE
// convert real data to even/odd format used in vDSP
aubio_vDSP_ctoz((aubio_DSPComplex*)s->in, 2, &s->spec, 1, s->fft_size/2);
// compute the FFT
@@ -281,6 +361,19 @@
// apply scaling
smpl_t scale = 1./2.;
aubio_vDSP_vsmul(compspec->data, 1, &scale, compspec->data, 1, s->fft_size);
+
+#elif defined HAVE_INTEL_IPP // using Intel IPP
+
+ // apply fft
+ aubio_ippsFFTFwd_RToCCS(s->in, (aubio_IppFloat*)s->complexOut, s->fftSpec, s->memBuffer);
+ // convert complex buffer to [ r0, r1, ..., rN, iN-1, .., i2, i1]
+ compspec->data[0] = s->complexOut[0].re;
+ compspec->data[s->fft_size / 2] = s->complexOut[s->fft_size / 2].re;
+ for (i = 1; i < s->fft_size / 2; i++) {
+ compspec->data[i] = s->complexOut[i].re;
+ compspec->data[s->fft_size - i] = s->complexOut[i].im;
+ }
+
#else // using OOURA
aubio_ooura_rdft(s->winsize, 1, s->in, s->ip, s->w);
compspec->data[0] = s->in[0];
@@ -289,8 +382,7 @@
compspec->data[i] = s->in[2 * i];
compspec->data[s->winsize - i] = - s->in[2 * i + 1];
}
-#endif /* HAVE_ACCELERATE */
-#endif /* HAVE_FFTW3 */
+#endif /* using OOURA */
}
void aubio_fft_rdo_complex(aubio_fft_t * s, const fvec_t * compspec, fvec_t * output) {
@@ -313,8 +405,8 @@
for (i = 0; i < output->length; i++) {
output->data[i] = s->out[i]*renorm;
}
-#else /* HAVE_FFTW3 */
-#ifdef HAVE_ACCELERATE // using ACCELERATE
+
+#elif defined HAVE_ACCELERATE // using ACCELERATE
// convert from real imag [ r0, r1, ..., rN, iN-1, .., i2, i1]
// to vDSP packed format [ r0, rN, r1, i1, ..., rN-1, iN-1 ]
s->out[0] = compspec->data[0];
@@ -332,6 +424,23 @@
// apply scaling
smpl_t scale = 1.0 / s->winsize;
aubio_vDSP_vsmul(output->data, 1, &scale, output->data, 1, s->fft_size);
+
+#elif defined HAVE_INTEL_IPP // using Intel IPP
+
+ // convert from real imag [ r0, 0, ..., rN, iN-1, .., i2, i1, iN-1] to complex format
+ s->complexOut[0].re = compspec->data[0];
+ s->complexOut[0].im = 0;
+ s->complexOut[s->fft_size / 2].re = compspec->data[s->fft_size / 2];
+ s->complexOut[s->fft_size / 2].im = 0.0;
+ for (i = 1; i < s->fft_size / 2; i++) {
+ s->complexOut[i].re = compspec->data[i];
+ s->complexOut[i].im = compspec->data[s->fft_size - i];
+ }
+ // apply fft
+ aubio_ippsFFTInv_CCSToR((const aubio_IppFloat *)s->complexOut, output->data, s->fftSpec, s->memBuffer);
+ // apply scaling
+ aubio_ippsMulC(output->data, 1.0 / s->winsize, output->data, s->fft_size);
+
#else // using OOURA
smpl_t scale = 2.0 / s->winsize;
s->out[0] = compspec->data[0];
@@ -344,8 +453,7 @@
for (i=0; i < s->winsize; i++) {
output->data[i] = s->out[i] * scale;
}
-#endif /* HAVE_ACCELERATE */
-#endif /* HAVE_FFTW3 */
+#endif
}
void aubio_fft_get_spectrum(const fvec_t * compspec, cvec_t * spectrum) {
@@ -365,10 +473,26 @@
} else {
spectrum->phas[0] = 0.;
}
+#if defined(HAVE_INTEL_IPP)
+ // convert from real imag [ r0, r1, ..., rN, iN-1, ..., i2, i1, i0]
+ // to [ r0, r1, ..., rN, i0, i1, i2, ..., iN-1]
+ for (i = 1; i < spectrum->length / 2; i++) {
+ ELEM_SWAP(compspec->data[compspec->length - i],
+ compspec->data[spectrum->length + i - 1]);
+ }
+ aubio_ippsAtan2(compspec->data + spectrum->length,
+ compspec->data + 1, spectrum->phas + 1, spectrum->length - 1);
+ // revert the imaginary part back again
+ for (i = 1; i < spectrum->length / 2; i++) {
+ ELEM_SWAP(compspec->data[spectrum->length + i - 1],
+ compspec->data[compspec->length - i]);
+ }
+#else
for (i=1; i < spectrum->length - 1; i++) {
spectrum->phas[i] = ATAN2(compspec->data[compspec->length-i],
compspec->data[i]);
}
+#endif
if (compspec->data[compspec->length/2] < 0) {
spectrum->phas[spectrum->length - 1] = PI;
} else {
--- a/src/wscript_build
+++ b/src/wscript_build
@@ -3,6 +3,7 @@
uselib = []
uselib += ['M']
uselib += ['FFTW3', 'FFTW3F']
+uselib += ['INTEL_IPP']
uselib += ['SAMPLERATE']
uselib += ['SNDFILE']
uselib += ['AVCODEC']
@@ -24,7 +25,7 @@
if ctx.env['DEST_OS'] in ['ios', 'iosimulator']:
build_features = ['cstlib', 'cshlib']
elif ctx.env['DEST_OS'] in ['win32', 'win64']:
- build_features = ['cstlib', 'cshlib']
+ build_features = ['cstlib', 'cshlib gensyms']
elif ctx.env['DEST_OS'] in ['emscripten']:
build_features = ['cstlib','cshlib']
elif '--static' in ctx.env['LDFLAGS'] or '--static' in ctx.env['LINKFLAGS']:
@@ -36,13 +37,13 @@
# also install static lib
from waflib.Tools.c import cstlib
-from waflib.Tools.fc import fcstlib
-fcstlib.inst_to = cstlib.inst_to = '${LIBDIR}'
+cstlib.inst_to = '${LIBDIR}'
for target in build_features:
ctx(features = 'c ' + target,
use = uselib + ['lib_objects'],
target = 'aubio',
+ export_symbols_regex=r'(?:.*aubio|fvec|lvec|cvec|fmat|new|del)_.*',
vnum = ctx.env['LIB_VERSION'])
# install headers, except _priv.h ones
--- a/tests/src/io/test-sink-multi.c
+++ b/tests/src/io/test-sink-multi.c
@@ -1,9 +1,8 @@
-#define AUBIO_UNSTABLE 1
#include <aubio.h>
#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
+// same as test-sink.c, but uses aubio_source_do_multi to read multiple
+// channels
int main (int argc, char **argv)
{
--- a/tests/src/io/test-sink_apple_audio-multi.c
+++ b/tests/src/io/test-sink_apple_audio-multi.c
@@ -2,8 +2,8 @@
#include <aubio.h>
#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
+// 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)
{
--- a/tests/src/io/test-sink_sndfile-multi.c
+++ b/tests/src/io/test-sink_sndfile-multi.c
@@ -2,8 +2,8 @@
#include <aubio.h>
#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
+// 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)
{
--- a/tests/src/io/test-sink_wavwrite-multi.c
+++ b/tests/src/io/test-sink_wavwrite-multi.c
@@ -2,8 +2,8 @@
#include <aubio.h>
#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
+// 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)
{
--- /dev/null
+++ b/waf_gensyms.py
@@ -1,0 +1,40 @@
+import re
+import os.path
+from waflib import TaskGen, Task
+from waflib.Context import STDOUT
+from waflib.Utils import O644
+
+class gen_sym_file(Task.Task):
+ color = 'BLUE'
+ inst_to = '${LIBDIR}'
+ def run(self):
+ syms = {}
+ reg = getattr(self.generator, 'export_symbols_regex','.+?')
+ if 'msvc' in self.env.CC_NAME:
+ outputs = [x.abspath() for x in self.generator.link_task.outputs]
+ binary_path = list(filter(lambda x: x.endswith('lib'), outputs))[0]
+ reg_compiled = re.compile(r'External\s+\|\s+(?P<symbol>%s)\b' % reg)
+ cmd =(self.env.LINK_CC) + ['/dump', '/symbols', binary_path]
+ else: # using gcc? assume we have nm
+ outputs = [x.abspath() for x in self.generator.link_task.outputs]
+ binary_path = list(filter(lambda x: x.endswith('dll'), outputs))[0]
+ reg_compiled = re.compile(r'(T|D)\s+_(?P<symbol>%s)\b'%reg)
+ cmd = (self.env.NM or ['nm']) + ['-g', binary_path]
+ dump_output = self.generator.bld.cmd_and_log(cmd, quiet=STDOUT)
+ syms = set([])
+ for m in reg_compiled.finditer(dump_output):
+ syms.add(m.group('symbol'))
+ syms = list(syms)
+ syms.sort()
+ self.outputs[0].write('EXPORTS\n'+'\n'.join(syms))
+
+@TaskGen.feature('gensyms')
+@TaskGen.after_method('process_source','process_use','apply_link','process_uselib_local','propagate_uselib_vars')
+def gen_symbols(self):
+ #sym_file = self.path.find_or_declare(self.target + '.def')
+ sym_file_name = os.path.splitext(self.link_task.outputs[0].abspath())[0] + '.def'
+ sym_file = self.path.find_or_declare(sym_file_name)
+ symtask = self.create_task('gen_sym_file', self.link_task.outputs, sym_file)
+ self.add_install_files(install_to=self.link_task.inst_to, install_from=sym_file,
+ chmod=O644, task=self.link_task)
+
--- a/wscript
+++ b/wscript
@@ -50,6 +50,9 @@
add_option_enable_disable(ctx, 'fftw3', default = False,
help_str = 'compile with fftw3 instead of ooura',
help_disable_str = 'do not compile with fftw3')
+ add_option_enable_disable(ctx, 'intelipp', default = False,
+ help_str = 'use Intel IPP libraries (auto)',
+ help_disable_str = 'do not use Intel IPP libraries')
add_option_enable_disable(ctx, 'complex', default = False,
help_str ='compile with C99 complex',
help_disable_str = 'do not use C99 complex (default)' )
@@ -100,25 +103,24 @@
ctx.load('compiler_c')
ctx.load('waf_unit_test')
ctx.load('gnu_dirs')
+ ctx.load('waf_gensyms', tooldir='.')
def configure(ctx):
- from waflib import Options
- ctx.load('compiler_c')
- ctx.load('waf_unit_test')
- ctx.load('gnu_dirs')
-
target_platform = sys.platform
if ctx.options.target_platform:
target_platform = ctx.options.target_platform
+ from waflib import Options
if target_platform=='emscripten':
- # need to force spaces between flag -o and path
- # inspired from :
- # https://github.com/waf-project/waf/blob/master/waflib/extras/c_emscripten.py (#1885)
- # (OSX /emscripten 1.37.9)
- ctx.env.CC_TGT_F = ['-c', '-o', '']
- ctx.env.CCLNK_TGT_F = ['-o', '']
+ ctx.load('c_emscripten')
+ else:
+ ctx.load('compiler_c')
+
+ ctx.load('waf_unit_test')
+ ctx.load('gnu_dirs')
+ ctx.load('waf_gensyms', tooldir='.')
+
# check for common headers
ctx.check(header_name='stdlib.h')
ctx.check(header_name='stdio.h')
@@ -151,10 +153,17 @@
ctx.env.prepend_value('CFLAGS', ['-g', '-Wall', '-Wextra'])
else:
# enable debug symbols
- ctx.env.CFLAGS += ['/Z7', '/FS']
+ ctx.env.CFLAGS += ['/Z7']
+ # /FS flag available in msvc >= 12 (2013)
+ if 'MSVC_VERSION' in ctx.env and ctx.env.MSVC_VERSION >= 12:
+ ctx.env.CFLAGS += ['/FS']
ctx.env.LINKFLAGS += ['/DEBUG', '/INCREMENTAL:NO']
# configure warnings
ctx.env.CFLAGS += ['/W4', '/D_CRT_SECURE_NO_WARNINGS']
+ # ignore "possible loss of data" warnings
+ ctx.env.CFLAGS += ['/wd4305', '/wd4244', '/wd4245', '/wd4267']
+ # ignore "unreferenced formal parameter" warnings
+ ctx.env.CFLAGS += ['/wd4100']
# set optimization level and runtime libs
if (ctx.options.build_type == "release"):
ctx.env.CFLAGS += ['/Ox']
@@ -226,9 +235,6 @@
ctx.env.LINKFLAGS += [ '-isysroot' , SDKROOT]
if target_platform == 'emscripten':
- import os.path
- ctx.env.CFLAGS += [ '-I' + os.path.join(os.environ['EMSCRIPTEN'], 'system', 'include') ]
-
if ctx.options.build_type == "debug":
ctx.env.cshlib_PATTERN = '%s.js'
ctx.env.LINKFLAGS += ['-s','ASSERTIONS=2']
@@ -247,9 +253,11 @@
ctx.env.cstlib_PATTERN = '%s.a'
# tell emscripten functions we want to expose
- from python.lib.gen_external import get_c_declarations, get_cpp_objects_from_c_declarations, get_all_func_names_from_lib, generate_lib_from_c_declarations
+ from python.lib.gen_external import get_c_declarations, \
+ get_cpp_objects_from_c_declarations, get_all_func_names_from_lib, \
+ generate_lib_from_c_declarations
c_decls = get_c_declarations(usedouble=False) # emscripten can't use double
- objects = get_cpp_objects_from_c_declarations(c_decls)
+ objects = list(get_cpp_objects_from_c_declarations(c_decls))
# ensure that aubio structs are exported
objects += ['fvec_t', 'cvec_t', 'fmat_t']
lib = generate_lib_from_c_declarations(objects, c_decls)
@@ -286,6 +294,21 @@
else:
ctx.msg('Checking if complex.h is enabled', 'no')
+ # check for Intel IPP
+ if (ctx.options.enable_intelipp != False):
+ has_ipp_headers = ctx.check(header_name=['ippcore.h', 'ippvm.h', 'ipps.h'],
+ mandatory = False)
+ has_ipp_libs = ctx.check(lib=['ippcore', 'ippvm', 'ipps'],
+ uselib_store='INTEL_IPP', mandatory = False)
+ if (has_ipp_headers and has_ipp_libs):
+ ctx.msg('Checking if Intel IPP is available', 'yes')
+ ctx.define('HAVE_INTEL_IPP', 1)
+ if ctx.env.CC_NAME == 'msvc':
+ # force linking multi-threaded static IPP libraries on Windows with msvc
+ ctx.define('_IPP_SEQUENTIAL_STATIC', 1)
+ else:
+ ctx.msg('Checking if Intel IPP is available', 'no')
+
# check for fftw3
if (ctx.options.enable_fftw3 != False or ctx.options.enable_fftw3f != False):
# one of fftwf or fftw3f
@@ -309,7 +332,7 @@
mandatory = ctx.options.enable_fftw3)
ctx.define('HAVE_FFTW3', 1)
- # fftw not enabled, use vDSP or ooura
+ # fftw not enabled, use vDSP, intelIPP or ooura
if 'HAVE_FFTW3F' in ctx.env.define_key:
ctx.msg('Checking for FFT implementation', 'fftw3f')
elif 'HAVE_FFTW3' in ctx.env.define_key:
@@ -316,6 +339,8 @@
ctx.msg('Checking for FFT implementation', 'fftw3')
elif 'HAVE_ACCELERATE' in ctx.env.define_key:
ctx.msg('Checking for FFT implementation', 'vDSP')
+ elif 'HAVE_INTEL_IPP' in ctx.env.define_key:
+ ctx.msg('Checking for FFT implementation', 'Intel IPP')
else:
ctx.msg('Checking for FFT implementation', 'ooura')
@@ -446,6 +471,8 @@
# add sub directories
if bld.env['DEST_OS'] not in ['ios', 'iosimulator', 'android']:
+ if bld.env['DEST_OS']=='emscripten' and not bld.options.testcmd:
+ bld.options.testcmd = 'node %s'
bld.recurse('examples')
bld.recurse('tests')
@@ -557,3 +584,4 @@
ctx.excl += ' **/.travis.yml'
ctx.excl += ' **/.landscape.yml'
ctx.excl += ' **/.appveyor.yml'
+ ctx.excl += ' **/circlei.yml'