# HG changeset patch # User Chris Cannam # Date 1518104433 0 # Node ID 8742125177aeaf009a1ec45817a06199b82fc97c # Parent d129bf797f24a37e64d4fc189e2bb7be351bc576# Parent 70e52a6d7e99322f4cb9ec40e1659e46057fdbb1 Merge from branch vamp-kiss-naming diff -r d129bf797f24 -r 8742125177ae .appveyor.yml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.appveyor.yml Thu Feb 08 15:40:33 2018 +0000 @@ -0,0 +1,19 @@ + +configuration: + - Release + +platform: + - Win32 + - x64 + +install: + - cinst wget + - c:\ProgramData\chocolatey\bin\wget.exe http://www.mega-nerd.com/libsndfile/files/libsndfile-1.0.28-w32-setup.exe + - c:\ProgramData\chocolatey\bin\wget.exe http://www.mega-nerd.com/libsndfile/files/libsndfile-1.0.28-w64-setup.exe + - ps: .\libsndfile-1.0.28-w32-setup.exe /silent /sp- /norestart + - ps: .\libsndfile-1.0.28-w64-setup.exe /silent /sp- /norestart + +build_script: + - msbuild build\VampSDK.sln + - msbuild build\VampHostSDK.sln + diff -r d129bf797f24 -r 8742125177ae build/VampSimpleHost.vcxproj --- a/build/VampSimpleHost.vcxproj Tue Jan 30 15:28:15 2018 +0000 +++ b/build/VampSimpleHost.vcxproj Thu Feb 08 15:40:33 2018 +0000 @@ -1,4 +1,4 @@ - + @@ -116,14 +116,14 @@ true true WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - ..;C:\Program Files\Mega-Nerd\libsndfile\include + ..;C:\Program Files (x86)\Mega-Nerd\libsndfile\include Console true true true - Release\VampHostSDK.lib;C:\Program Files\Mega-Nerd\libsndfile\lib\libsndfile-1.lib;%(AdditionalDependencies) + Release\VampHostSDK.lib;C:\Program Files (x86)\Mega-Nerd\libsndfile\lib\libsndfile-1.lib;%(AdditionalDependencies) @@ -154,4 +154,4 @@ - \ No newline at end of file + diff -r d129bf797f24 -r 8742125177ae examples/AmplitudeFollower.cpp --- a/examples/AmplitudeFollower.cpp Tue Jan 30 15:28:15 2018 +0000 +++ b/examples/AmplitudeFollower.cpp Thu Feb 08 15:40:33 2018 +0000 @@ -106,10 +106,15 @@ AmplitudeFollower::initialise(size_t channels, size_t stepSize, size_t blockSize) { if (channels < getMinChannelCount() || - channels > getMaxChannelCount()) return false; + channels > getMaxChannelCount()) { + cerr << "ERROR: AmplitudeFollower::initialise: " + << "channel count " << channels << " out of supported range" + << endl; + return false; + } m_stepSize = std::min(stepSize, blockSize); - + // Translate the coefficients // from their "convenient" 60dB convergence-time values // to real coefficients diff -r d129bf797f24 -r 8742125177ae src/vamp-hostsdk/PluginInputDomainAdapter.cpp --- a/src/vamp-hostsdk/PluginInputDomainAdapter.cpp Tue Jan 30 15:28:15 2018 +0000 +++ b/src/vamp-hostsdk/PluginInputDomainAdapter.cpp Thu Feb 08 15:40:33 2018 +0000 @@ -86,18 +86,18 @@ int m_stepSize; int m_blockSize; float **m_freqbuf; - Kiss::kiss_fft_scalar *m_ri; + Kiss::vamp_kiss_fft_scalar *m_ri; WindowType m_windowType; - typedef Window W; + typedef Window W; W *m_window; ProcessTimestampMethod m_method; int m_processCount; float **m_shiftBuffers; - Kiss::kiss_fftr_cfg m_cfg; - Kiss::kiss_fft_cpx *m_cbuf; + Kiss::vamp_kiss_fftr_cfg m_cfg; + Kiss::vamp_kiss_fft_cpx *m_cbuf; FeatureSet processShiftingTimestamp(const float *const *inputBuffers, RealTime timestamp); FeatureSet processShiftingData(const float *const *inputBuffers, RealTime timestamp); @@ -221,7 +221,7 @@ delete[] m_freqbuf; delete[] m_ri; if (m_cfg) { - Kiss::kiss_fftr_free(m_cfg); + Kiss::vamp_kiss_fftr_free(m_cfg); m_cfg = 0; delete[] m_cbuf; m_cbuf = 0; @@ -264,7 +264,7 @@ delete[] m_freqbuf; delete[] m_ri; if (m_cfg) { - Kiss::kiss_fftr_free(m_cfg); + Kiss::vamp_kiss_fftr_free(m_cfg); m_cfg = 0; delete[] m_cbuf; m_cbuf = 0; @@ -280,12 +280,12 @@ for (int c = 0; c < m_channels; ++c) { m_freqbuf[c] = new float[m_blockSize + 2]; } - m_ri = new Kiss::kiss_fft_scalar[m_blockSize]; + m_ri = new Kiss::vamp_kiss_fft_scalar[m_blockSize]; m_window = new W(convertType(m_windowType), m_blockSize); - m_cfg = Kiss::kiss_fftr_alloc(m_blockSize, false, 0, 0); - m_cbuf = new Kiss::kiss_fft_cpx[m_blockSize/2+1]; + m_cfg = Kiss::vamp_kiss_fftr_alloc(m_blockSize, false, 0, 0); + m_cbuf = new Kiss::vamp_kiss_fft_cpx[m_blockSize/2+1]; m_processCount = 0; @@ -452,12 +452,12 @@ for (int i = 0; i < m_blockSize/2; ++i) { // FFT shift - Kiss::kiss_fft_scalar value = m_ri[i]; + Kiss::vamp_kiss_fft_scalar value = m_ri[i]; m_ri[i] = m_ri[i + m_blockSize/2]; m_ri[i + m_blockSize/2] = value; } - Kiss::kiss_fftr(m_cfg, m_ri, m_cbuf); + Kiss::vamp_kiss_fftr(m_cfg, m_ri, m_cbuf); for (int i = 0; i <= m_blockSize/2; ++i) { m_freqbuf[c][i * 2] = float(m_cbuf[i].r); @@ -501,12 +501,12 @@ for (int i = 0; i < m_blockSize/2; ++i) { // FFT shift - Kiss::kiss_fft_scalar value = m_ri[i]; + Kiss::vamp_kiss_fft_scalar value = m_ri[i]; m_ri[i] = m_ri[i + m_blockSize/2]; m_ri[i + m_blockSize/2] = value; } - Kiss::kiss_fftr(m_cfg, m_ri, m_cbuf); + Kiss::vamp_kiss_fftr(m_cfg, m_ri, m_cbuf); for (int i = 0; i <= m_blockSize/2; ++i) { m_freqbuf[c][i * 2] = float(m_cbuf[i].r); diff -r d129bf797f24 -r 8742125177ae src/vamp-sdk/FFT.cpp --- a/src/vamp-sdk/FFT.cpp Tue Jan 30 15:28:15 2018 +0000 +++ b/src/vamp-sdk/FFT.cpp Thu Feb 08 15:40:33 2018 +0000 @@ -51,15 +51,17 @@ namespace Vamp { +using namespace Kiss; + void FFT::forward(unsigned int un, const double *ri, const double *ii, double *ro, double *io) { int n(un); - Kiss::kiss_fft_cfg c = Kiss::kiss_fft_alloc(n, false, 0, 0); - Kiss::kiss_fft_cpx *in = new Kiss::kiss_fft_cpx[n]; - Kiss::kiss_fft_cpx *out = new Kiss::kiss_fft_cpx[n]; + vamp_kiss_fft_cfg c = vamp_kiss_fft_alloc(n, false, 0, 0); + vamp_kiss_fft_cpx *in = new vamp_kiss_fft_cpx[n]; + vamp_kiss_fft_cpx *out = new vamp_kiss_fft_cpx[n]; for (int i = 0; i < n; ++i) { in[i].r = ri[i]; in[i].i = 0; @@ -69,12 +71,12 @@ in[i].i = ii[i]; } } - kiss_fft(c, in, out); + vamp_kiss_fft(c, in, out); for (int i = 0; i < n; ++i) { ro[i] = out[i].r; io[i] = out[i].i; } - Kiss::kiss_fft_free(c); + vamp_kiss_fft_free(c); delete[] in; delete[] out; } @@ -85,9 +87,9 @@ double *ro, double *io) { int n(un); - Kiss::kiss_fft_cfg c = Kiss::kiss_fft_alloc(n, true, 0, 0); - Kiss::kiss_fft_cpx *in = new Kiss::kiss_fft_cpx[n]; - Kiss::kiss_fft_cpx *out = new Kiss::kiss_fft_cpx[n]; + vamp_kiss_fft_cfg c = vamp_kiss_fft_alloc(n, true, 0, 0); + vamp_kiss_fft_cpx *in = new vamp_kiss_fft_cpx[n]; + vamp_kiss_fft_cpx *out = new vamp_kiss_fft_cpx[n]; for (int i = 0; i < n; ++i) { in[i].r = ri[i]; in[i].i = 0; @@ -97,13 +99,13 @@ in[i].i = ii[i]; } } - kiss_fft(c, in, out); + vamp_kiss_fft(c, in, out); double scale = 1.0 / double(n); for (int i = 0; i < n; ++i) { ro[i] = out[i].r * scale; io[i] = out[i].i * scale; } - Kiss::kiss_fft_free(c); + vamp_kiss_fft_free(c); delete[] in; delete[] out; } @@ -113,14 +115,14 @@ public: D(int n) : m_n(n), - m_fconf(Kiss::kiss_fft_alloc(n, false, 0, 0)), - m_iconf(Kiss::kiss_fft_alloc(n, true, 0, 0)), - m_ci(new Kiss::kiss_fft_cpx[m_n]), - m_co(new Kiss::kiss_fft_cpx[m_n]) { } + m_fconf(vamp_kiss_fft_alloc(n, false, 0, 0)), + m_iconf(vamp_kiss_fft_alloc(n, true, 0, 0)), + m_ci(new vamp_kiss_fft_cpx[m_n]), + m_co(new vamp_kiss_fft_cpx[m_n]) { } ~D() { - Kiss::kiss_fftr_free(m_fconf); - Kiss::kiss_fftr_free(m_iconf); + vamp_kiss_fftr_free(m_fconf); + vamp_kiss_fftr_free(m_iconf); delete[] m_ci; delete[] m_co; } @@ -130,7 +132,7 @@ m_ci[i].r = ci[i*2]; m_ci[i].i = ci[i*2+1]; } - Kiss::kiss_fft(m_fconf, m_ci, m_co); + vamp_kiss_fft(m_fconf, m_ci, m_co); for (int i = 0; i < m_n; ++i) { co[i*2] = m_co[i].r; co[i*2+1] = m_co[i].i; @@ -142,7 +144,7 @@ m_ci[i].r = ci[i*2]; m_ci[i].i = ci[i*2+1]; } - Kiss::kiss_fft(m_iconf, m_ci, m_co); + vamp_kiss_fft(m_iconf, m_ci, m_co); double scale = 1.0 / double(m_n); for (int i = 0; i < m_n; ++i) { co[i*2] = m_co[i].r * scale; @@ -152,10 +154,10 @@ private: int m_n; - Kiss::kiss_fft_cfg m_fconf; - Kiss::kiss_fft_cfg m_iconf; - Kiss::kiss_fft_cpx *m_ci; - Kiss::kiss_fft_cpx *m_co; + vamp_kiss_fft_cfg m_fconf; + vamp_kiss_fft_cfg m_iconf; + vamp_kiss_fft_cpx *m_ci; + vamp_kiss_fft_cpx *m_co; }; FFTComplex::FFTComplex(unsigned int n) : @@ -185,15 +187,15 @@ public: D(int n) : m_n(n), - m_fconf(Kiss::kiss_fftr_alloc(n, false, 0, 0)), - m_iconf(Kiss::kiss_fftr_alloc(n, true, 0, 0)), - m_ri(new Kiss::kiss_fft_scalar[m_n]), - m_ro(new Kiss::kiss_fft_scalar[m_n]), - m_freq(new Kiss::kiss_fft_cpx[n/2+1]) { } + m_fconf(vamp_kiss_fftr_alloc(n, false, 0, 0)), + m_iconf(vamp_kiss_fftr_alloc(n, true, 0, 0)), + m_ri(new vamp_kiss_fft_scalar[m_n]), + m_ro(new vamp_kiss_fft_scalar[m_n]), + m_freq(new vamp_kiss_fft_cpx[n/2+1]) { } ~D() { - Kiss::kiss_fftr_free(m_fconf); - Kiss::kiss_fftr_free(m_iconf); + vamp_kiss_fftr_free(m_fconf); + vamp_kiss_fftr_free(m_iconf); delete[] m_ri; delete[] m_ro; delete[] m_freq; @@ -201,10 +203,10 @@ void forward(const double *ri, double *co) { for (int i = 0; i < m_n; ++i) { - // in case kiss_fft_scalar is float + // in case vamp_kiss_fft_scalar is float m_ri[i] = ri[i]; } - Kiss::kiss_fftr(m_fconf, m_ri, m_freq); + vamp_kiss_fftr(m_fconf, m_ri, m_freq); int hs = m_n/2 + 1; for (int i = 0; i < hs; ++i) { co[i*2] = m_freq[i].r; @@ -218,7 +220,7 @@ m_freq[i].r = ci[i*2]; m_freq[i].i = ci[i*2+1]; } - Kiss::kiss_fftri(m_iconf, m_freq, m_ro); + vamp_kiss_fftri(m_iconf, m_freq, m_ro); double scale = 1.0 / double(m_n); for (int i = 0; i < m_n; ++i) { ro[i] = m_ro[i] * scale; @@ -227,11 +229,11 @@ private: int m_n; - Kiss::kiss_fftr_cfg m_fconf; - Kiss::kiss_fftr_cfg m_iconf; - Kiss::kiss_fft_scalar *m_ri; - Kiss::kiss_fft_scalar *m_ro; - Kiss::kiss_fft_cpx *m_freq; + vamp_kiss_fftr_cfg m_fconf; + vamp_kiss_fftr_cfg m_iconf; + vamp_kiss_fft_scalar *m_ri; + vamp_kiss_fft_scalar *m_ro; + vamp_kiss_fft_cpx *m_freq; }; FFTReal::FFTReal(unsigned int n) : diff -r d129bf797f24 -r 8742125177ae src/vamp-sdk/FFTimpl.cpp --- a/src/vamp-sdk/FFTimpl.cpp Tue Jan 30 15:28:15 2018 +0000 +++ b/src/vamp-sdk/FFTimpl.cpp Thu Feb 08 15:40:33 2018 +0000 @@ -2,37 +2,29 @@ // Override C linkage for KissFFT headers. So long as we have already // included all of the other (system etc) headers KissFFT depends on, // this should work out OK -#define KISSFFT_USE_CPP_LINKAGE 1 +#define VAMP_KISSFFT_USE_CPP_LINKAGE 1 namespace Kiss { -#undef KISS_FFT_H -#undef KISS_FTR_H -#undef KISS_FFT__GUTS_H -#undef FIXED_POINT -#undef USE_SIMD -#undef kiss_fft_scalar - #ifdef SINGLE_PRECISION_FFT #pragma message("Using single-precision FFTs") -typedef float kiss_fft_scalar; -#define kiss_fft_scalar float +typedef float vamp_kiss_fft_scalar; +#define vamp_kiss_fft_scalar float #else -typedef double kiss_fft_scalar; -#define kiss_fft_scalar double +typedef double vamp_kiss_fft_scalar; +#define vamp_kiss_fft_scalar double #endif -inline void free(void *ptr) { ::free(ptr); } -#include "ext/kiss_fft.c" -#include "ext/kiss_fftr.c" +#include "ext/vamp_kiss_fft.c" +#include "ext/vamp_kiss_fftr.c" -#undef kiss_fft_scalar // leaving only the namespaced typedef +#undef vamp_kiss_fft_scalar // leaving only the namespaced typedef } // Check that this worked, i.e. that we have our own suitably // hacked KissFFT header which set this after making the // appropriate change -#ifndef KISSFFT_USED_CPP_LINKAGE +#ifndef VAMP_KISSFFT_USED_CPP_LINKAGE #error "KissFFT header lacks specific linkage adjustment needed for Vamp SDK" #endif diff -r d129bf797f24 -r 8742125177ae src/vamp-sdk/ext/_kiss_fft_guts.h --- a/src/vamp-sdk/ext/_kiss_fft_guts.h Tue Jan 30 15:28:15 2018 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,168 +0,0 @@ -#ifndef KISS_FFT__GUTS_H -#define KISS_FFT__GUTS_H -/* -Copyright (c) 2003-2010, Mark Borgerding - -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* kiss_fft.h - defines kiss_fft_scalar as either short or a float type - and defines - typedef struct { kiss_fft_scalar r; kiss_fft_scalar i; }kiss_fft_cpx; */ -#include "kiss_fft.h" -#include - -#define MAXFACTORS 32 -/* e.g. an fft of length 128 has 4 factors - as far as kissfft is concerned - 4*4*4*2 - */ - -struct kiss_fft_state{ - int nfft; - int inverse; - int factors[2*MAXFACTORS]; - kiss_fft_cpx twiddles[1]; -}; - -/* - Explanation of macros dealing with complex math: - - C_MUL(m,a,b) : m = a*b - C_FIXDIV( c , div ) : if a fixed point impl., c /= div. noop otherwise - C_SUB( res, a,b) : res = a - b - C_SUBFROM( res , a) : res -= a - C_ADDTO( res , a) : res += a - * */ -#ifdef FIXED_POINT -#if (FIXED_POINT==32) -# define FRACBITS 31 -# define SAMPPROD int64_t -#define SAMP_MAX 2147483647 -#else -# define FRACBITS 15 -# define SAMPPROD int32_t -#define SAMP_MAX 32767 -#endif - -#define SAMP_MIN -SAMP_MAX - -#if defined(CHECK_OVERFLOW) -# define CHECK_OVERFLOW_OP(a,op,b) \ - if ( (SAMPPROD)(a) op (SAMPPROD)(b) > SAMP_MAX || (SAMPPROD)(a) op (SAMPPROD)(b) < SAMP_MIN ) { \ - fprintf(stderr,"WARNING:overflow @ " __FILE__ "(%d): (%d " #op" %d) = %ld\n",__LINE__,(a),(b),(SAMPPROD)(a) op (SAMPPROD)(b) ); } -#endif - - -# define smul(a,b) ( (SAMPPROD)(a)*(b) ) -# define sround( x ) (kiss_fft_scalar)( ( (x) + (1<<(FRACBITS-1)) ) >> FRACBITS ) - -# define S_MUL(a,b) sround( smul(a,b) ) - -# define C_MUL(m,a,b) \ - do{ (m).r = sround( smul((a).r,(b).r) - smul((a).i,(b).i) ); \ - (m).i = sround( smul((a).r,(b).i) + smul((a).i,(b).r) ); }while(0) - -# define DIVSCALAR(x,k) \ - (x) = sround( smul( x, SAMP_MAX/k ) ) - -# define C_FIXDIV(c,div) \ - do { DIVSCALAR( (c).r , div); \ - DIVSCALAR( (c).i , div); }while (0) - -# define C_MULBYSCALAR( c, s ) \ - do{ (c).r = sround( smul( (c).r , s ) ) ;\ - (c).i = sround( smul( (c).i , s ) ) ; }while(0) - -#else /* not FIXED_POINT*/ - -# define S_MUL(a,b) ( (a)*(b) ) -#define C_MUL(m,a,b) \ - do{ (m).r = (a).r*(b).r - (a).i*(b).i;\ - (m).i = (a).r*(b).i + (a).i*(b).r; }while(0) -# define C_FIXDIV(c,div) /* NOOP */ -# define C_MULBYSCALAR( c, s ) \ - do{ (c).r *= (s);\ - (c).i *= (s); }while(0) -#endif - -#ifndef CHECK_OVERFLOW_OP -# define CHECK_OVERFLOW_OP(a,op,b) /* noop */ -#endif - -#define C_ADD( res, a,b)\ - do { \ - CHECK_OVERFLOW_OP((a).r,+,(b).r)\ - CHECK_OVERFLOW_OP((a).i,+,(b).i)\ - (res).r=(a).r+(b).r; (res).i=(a).i+(b).i; \ - }while(0) -#define C_SUB( res, a,b)\ - do { \ - CHECK_OVERFLOW_OP((a).r,-,(b).r)\ - CHECK_OVERFLOW_OP((a).i,-,(b).i)\ - (res).r=(a).r-(b).r; (res).i=(a).i-(b).i; \ - }while(0) -#define C_ADDTO( res , a)\ - do { \ - CHECK_OVERFLOW_OP((res).r,+,(a).r)\ - CHECK_OVERFLOW_OP((res).i,+,(a).i)\ - (res).r += (a).r; (res).i += (a).i;\ - }while(0) - -#define C_SUBFROM( res , a)\ - do {\ - CHECK_OVERFLOW_OP((res).r,-,(a).r)\ - CHECK_OVERFLOW_OP((res).i,-,(a).i)\ - (res).r -= (a).r; (res).i -= (a).i; \ - }while(0) - - -#ifdef FIXED_POINT -# define KISS_FFT_COS(phase) floor(.5+SAMP_MAX * cos (phase)) -# define KISS_FFT_SIN(phase) floor(.5+SAMP_MAX * sin (phase)) -# define HALF_OF(x) ((x)>>1) -#elif defined(USE_SIMD) -# define KISS_FFT_COS(phase) _mm_set1_ps( cos(phase) ) -# define KISS_FFT_SIN(phase) _mm_set1_ps( sin(phase) ) -# define HALF_OF(x) ((x)*_mm_set1_ps(.5)) -#else -# define KISS_FFT_COS(phase) (kiss_fft_scalar) cos(phase) -# define KISS_FFT_SIN(phase) (kiss_fft_scalar) sin(phase) -# define HALF_OF(x) ((x)*.5) -#endif - -#define kf_cexp(x,phase) \ - do{ \ - (x)->r = KISS_FFT_COS(phase);\ - (x)->i = KISS_FFT_SIN(phase);\ - }while(0) - - -/* a debugging function */ -#define pcpx(c)\ - fprintf(stderr,"%g + %gi\n",(double)((c)->r),(double)((c)->i) ) - - -#ifdef KISS_FFT_USE_ALLOCA -// define this to allow use of alloca instead of malloc for temporary buffers -// Temporary buffers are used in two case: -// 1. FFT sizes that have "bad" factors. i.e. not 2,3 and 5 -// 2. "in-place" FFTs. Notice the quotes, since kissfft does not really do an in-place transform. -#include -#define KISS_FFT_TMP_ALLOC(nbytes) alloca(nbytes) -#define KISS_FFT_TMP_FREE(ptr) -#else -#define KISS_FFT_TMP_ALLOC(nbytes) KISS_FFT_MALLOC(nbytes) -#define KISS_FFT_TMP_FREE(ptr) KISS_FFT_FREE(ptr) -#endif - -#endif diff -r d129bf797f24 -r 8742125177ae src/vamp-sdk/ext/kiss_fft.c --- a/src/vamp-sdk/ext/kiss_fft.c Tue Jan 30 15:28:15 2018 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,409 +0,0 @@ -/* -Copyright (c) 2003-2010, Mark Borgerding - -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "_kiss_fft_guts.h" -/* The guts header contains all the multiplication and addition macros that are defined for - fixed or floating point complex numbers. It also delares the kf_ internal functions. - */ - -static void kf_bfly2( - kiss_fft_cpx * Fout, - const size_t fstride, - const kiss_fft_cfg st, - int m - ) -{ - kiss_fft_cpx * Fout2; - kiss_fft_cpx * tw1 = st->twiddles; - kiss_fft_cpx t; - Fout2 = Fout + m; - do{ - C_FIXDIV(*Fout,2); C_FIXDIV(*Fout2,2); - - C_MUL (t, *Fout2 , *tw1); - tw1 += fstride; - C_SUB( *Fout2 , *Fout , t ); - C_ADDTO( *Fout , t ); - ++Fout2; - ++Fout; - }while (--m); -} - -static void kf_bfly4( - kiss_fft_cpx * Fout, - const size_t fstride, - const kiss_fft_cfg st, - const size_t m - ) -{ - kiss_fft_cpx *tw1,*tw2,*tw3; - kiss_fft_cpx scratch[6]; - size_t k=m; - const size_t m2=2*m; - const size_t m3=3*m; - - - tw3 = tw2 = tw1 = st->twiddles; - - do { - C_FIXDIV(*Fout,4); C_FIXDIV(Fout[m],4); C_FIXDIV(Fout[m2],4); C_FIXDIV(Fout[m3],4); - - C_MUL(scratch[0],Fout[m] , *tw1 ); - C_MUL(scratch[1],Fout[m2] , *tw2 ); - C_MUL(scratch[2],Fout[m3] , *tw3 ); - - C_SUB( scratch[5] , *Fout, scratch[1] ); - C_ADDTO(*Fout, scratch[1]); - C_ADD( scratch[3] , scratch[0] , scratch[2] ); - C_SUB( scratch[4] , scratch[0] , scratch[2] ); - C_SUB( Fout[m2], *Fout, scratch[3] ); - tw1 += fstride; - tw2 += fstride*2; - tw3 += fstride*3; - C_ADDTO( *Fout , scratch[3] ); - - if(st->inverse) { - Fout[m].r = scratch[5].r - scratch[4].i; - Fout[m].i = scratch[5].i + scratch[4].r; - Fout[m3].r = scratch[5].r + scratch[4].i; - Fout[m3].i = scratch[5].i - scratch[4].r; - }else{ - Fout[m].r = scratch[5].r + scratch[4].i; - Fout[m].i = scratch[5].i - scratch[4].r; - Fout[m3].r = scratch[5].r - scratch[4].i; - Fout[m3].i = scratch[5].i + scratch[4].r; - } - ++Fout; - }while(--k); -} - -static void kf_bfly3( - kiss_fft_cpx * Fout, - const size_t fstride, - const kiss_fft_cfg st, - size_t m - ) -{ - size_t k=m; - const size_t m2 = 2*m; - kiss_fft_cpx *tw1,*tw2; - kiss_fft_cpx scratch[5]; - kiss_fft_cpx epi3; - epi3 = st->twiddles[fstride*m]; - - tw1=tw2=st->twiddles; - - do{ - C_FIXDIV(*Fout,3); C_FIXDIV(Fout[m],3); C_FIXDIV(Fout[m2],3); - - C_MUL(scratch[1],Fout[m] , *tw1); - C_MUL(scratch[2],Fout[m2] , *tw2); - - C_ADD(scratch[3],scratch[1],scratch[2]); - C_SUB(scratch[0],scratch[1],scratch[2]); - tw1 += fstride; - tw2 += fstride*2; - - Fout[m].r = Fout->r - HALF_OF(scratch[3].r); - Fout[m].i = Fout->i - HALF_OF(scratch[3].i); - - C_MULBYSCALAR( scratch[0] , epi3.i ); - - C_ADDTO(*Fout,scratch[3]); - - Fout[m2].r = Fout[m].r + scratch[0].i; - Fout[m2].i = Fout[m].i - scratch[0].r; - - Fout[m].r -= scratch[0].i; - Fout[m].i += scratch[0].r; - - ++Fout; - }while(--k); -} - -static void kf_bfly5( - kiss_fft_cpx * Fout, - const size_t fstride, - const kiss_fft_cfg st, - int m - ) -{ - kiss_fft_cpx *Fout0,*Fout1,*Fout2,*Fout3,*Fout4; - int u; - kiss_fft_cpx scratch[13]; - kiss_fft_cpx * twiddles = st->twiddles; - kiss_fft_cpx *tw; - kiss_fft_cpx ya,yb; - ya = twiddles[fstride*m]; - yb = twiddles[fstride*2*m]; - - Fout0=Fout; - Fout1=Fout0+m; - Fout2=Fout0+2*m; - Fout3=Fout0+3*m; - Fout4=Fout0+4*m; - - tw=st->twiddles; - for ( u=0; ur += scratch[7].r + scratch[8].r; - Fout0->i += scratch[7].i + scratch[8].i; - - scratch[5].r = scratch[0].r + S_MUL(scratch[7].r,ya.r) + S_MUL(scratch[8].r,yb.r); - scratch[5].i = scratch[0].i + S_MUL(scratch[7].i,ya.r) + S_MUL(scratch[8].i,yb.r); - - scratch[6].r = S_MUL(scratch[10].i,ya.i) + S_MUL(scratch[9].i,yb.i); - scratch[6].i = -S_MUL(scratch[10].r,ya.i) - S_MUL(scratch[9].r,yb.i); - - C_SUB(*Fout1,scratch[5],scratch[6]); - C_ADD(*Fout4,scratch[5],scratch[6]); - - scratch[11].r = scratch[0].r + S_MUL(scratch[7].r,yb.r) + S_MUL(scratch[8].r,ya.r); - scratch[11].i = scratch[0].i + S_MUL(scratch[7].i,yb.r) + S_MUL(scratch[8].i,ya.r); - scratch[12].r = - S_MUL(scratch[10].i,yb.i) + S_MUL(scratch[9].i,ya.i); - scratch[12].i = S_MUL(scratch[10].r,yb.i) - S_MUL(scratch[9].r,ya.i); - - C_ADD(*Fout2,scratch[11],scratch[12]); - C_SUB(*Fout3,scratch[11],scratch[12]); - - ++Fout0;++Fout1;++Fout2;++Fout3;++Fout4; - } -} - -/* perform the butterfly for one stage of a mixed radix FFT */ -static void kf_bfly_generic( - kiss_fft_cpx * Fout, - const size_t fstride, - const kiss_fft_cfg st, - int m, - int p - ) -{ - int u,k,q1,q; - kiss_fft_cpx * twiddles = st->twiddles; - kiss_fft_cpx t; - int Norig = st->nfft; - - kiss_fft_cpx * scratch = (kiss_fft_cpx*)KISS_FFT_TMP_ALLOC(sizeof(kiss_fft_cpx)*p); - - for ( u=0; u=Norig) twidx-=Norig; - C_MUL(t,scratch[q] , twiddles[twidx] ); - C_ADDTO( Fout[ k ] ,t); - } - k += m; - } - } - KISS_FFT_TMP_FREE(scratch); -} - -static -void kf_work( - kiss_fft_cpx * Fout, - const kiss_fft_cpx * f, - const size_t fstride, - int in_stride, - int * factors, - const kiss_fft_cfg st - ) -{ - kiss_fft_cpx * Fout_beg=Fout; - const int p=*factors++; /* the radix */ - const int m=*factors++; /* stage's fft length/p */ - const kiss_fft_cpx * Fout_end = Fout + p*m; - -#ifdef _OPENMP - // use openmp extensions at the - // top-level (not recursive) - if (fstride==1 && p<=5) - { - int k; - - // execute the p different work units in different threads -# pragma omp parallel for - for (k=0;kr = f->r; - Fout->i = f->i; - f += fstride*in_stride; - }while(++Fout != Fout_end ); - }else{ - do{ - // recursive call: - // DFT of size m*p performed by doing - // p instances of smaller DFTs of size m, - // each one takes a decimated version of the input - kf_work( Fout , f, fstride*p, in_stride, factors,st); - f += fstride*in_stride; - }while( (Fout += m) != Fout_end ); - } - - Fout=Fout_beg; - - // recombine the p smaller DFTs - switch (p) { - case 2: kf_bfly2(Fout,fstride,st,m); break; - case 3: kf_bfly3(Fout,fstride,st,m); break; - case 4: kf_bfly4(Fout,fstride,st,m); break; - case 5: kf_bfly5(Fout,fstride,st,m); break; - default: kf_bfly_generic(Fout,fstride,st,m,p); break; - } -} - -/* facbuf is populated by p1,m1,p2,m2, ... - where - p[i] * m[i] = m[i-1] - m0 = n */ -static -void kf_factor(int n,int * facbuf) -{ - int p=4; - double floor_sqrt; - floor_sqrt = floor( sqrt((double)n) ); - - /*factor out powers of 4, powers of 2, then any remaining primes */ - do { - while (n % p) { - switch (p) { - case 4: p = 2; break; - case 2: p = 3; break; - default: p += 2; break; - } - if (p > floor_sqrt) - p = n; /* no more factors, skip to end */ - } - n /= p; - *facbuf++ = p; - *facbuf++ = n; - } while (n > 1); -} - -/* - * - * User-callable function to allocate all necessary storage space for the fft. - * - * The return value is a contiguous block of memory, allocated with malloc. As such, - * It can be freed with free(), rather than a kiss_fft-specific function. - * */ -kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem ) -{ - kiss_fft_cfg st=NULL; - size_t memneeded = sizeof(struct kiss_fft_state) - + sizeof(kiss_fft_cpx)*(nfft-1); /* twiddle factors*/ - - if ( lenmem==NULL ) { - st = ( kiss_fft_cfg)KISS_FFT_MALLOC( memneeded ); - }else{ - if (mem != NULL && *lenmem >= memneeded) - st = (kiss_fft_cfg)mem; - *lenmem = memneeded; - } - if (st) { - int i; - st->nfft=nfft; - st->inverse = inverse_fft; - - for (i=0;iinverse) - phase *= -1; - kf_cexp(st->twiddles+i, phase ); - } - - kf_factor(nfft,st->factors); - } - return st; -} - - -void kiss_fft_stride(kiss_fft_cfg st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int in_stride) -{ - if (fin == fout) { - //NOTE: this is not really an in-place FFT algorithm. - //It just performs an out-of-place FFT into a temp buffer - kiss_fft_cpx * tmpbuf = (kiss_fft_cpx*)KISS_FFT_TMP_ALLOC( sizeof(kiss_fft_cpx)*st->nfft); - kf_work(tmpbuf,fin,1,in_stride, st->factors,st); - memcpy(fout,tmpbuf,sizeof(kiss_fft_cpx)*st->nfft); - KISS_FFT_TMP_FREE(tmpbuf); - }else{ - kf_work( fout, fin, 1,in_stride, st->factors,st ); - } -} - -void kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout) -{ - kiss_fft_stride(cfg,fin,fout,1); -} - - -void kiss_fft_cleanup(void) -{ - // nothing needed any more -} - -int kiss_fft_next_fast_size(int n) -{ - while(1) { - int m=n; - while ( (m%2) == 0 ) m/=2; - while ( (m%3) == 0 ) m/=3; - while ( (m%5) == 0 ) m/=5; - if (m<=1) - break; /* n is completely factorable by twos, threes, and fives */ - n++; - } - return n; -} diff -r d129bf797f24 -r 8742125177ae src/vamp-sdk/ext/kiss_fft.h --- a/src/vamp-sdk/ext/kiss_fft.h Tue Jan 30 15:28:15 2018 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,132 +0,0 @@ -#ifndef KISS_FFT_H -#define KISS_FFT_H - -#include -#include -#include -#include - -#ifndef KISSFFT_USE_CPP_LINKAGE -#ifdef __cplusplus -extern "C" { -#endif -#endif - -/* - ATTENTION! - If you would like a : - -- a utility that will handle the caching of fft objects - -- real-only (no imaginary time component ) FFT - -- a multi-dimensional FFT - -- a command-line utility to perform ffts - -- a command-line utility to perform fast-convolution filtering - - Then see kfc.h kiss_fftr.h kiss_fftnd.h fftutil.c kiss_fastfir.c - in the tools/ directory. -*/ - -#ifdef USE_SIMD -# include -# define kiss_fft_scalar __m128 -#define KISS_FFT_MALLOC(nbytes) _mm_malloc(nbytes,16) -#define KISS_FFT_FREE _mm_free -#else -#define KISS_FFT_MALLOC malloc -#define KISS_FFT_FREE free -#endif - - -#ifdef FIXED_POINT -#include -# if (FIXED_POINT == 32) -# define kiss_fft_scalar int32_t -# else -# define kiss_fft_scalar int16_t -# endif -#else -# ifndef kiss_fft_scalar -/* default is float */ -# define kiss_fft_scalar float -# endif -#endif - -typedef struct { - kiss_fft_scalar r; - kiss_fft_scalar i; -}kiss_fft_cpx; - -typedef struct kiss_fft_state* kiss_fft_cfg; - -/* - * kiss_fft_alloc - * - * Initialize a FFT (or IFFT) algorithm's cfg/state buffer. - * - * typical usage: kiss_fft_cfg mycfg=kiss_fft_alloc(1024,0,NULL,NULL); - * - * The return value from fft_alloc is a cfg buffer used internally - * by the fft routine or NULL. - * - * If lenmem is NULL, then kiss_fft_alloc will allocate a cfg buffer using malloc. - * The returned value should be free()d when done to avoid memory leaks. - * - * The state can be placed in a user supplied buffer 'mem': - * If lenmem is not NULL and mem is not NULL and *lenmem is large enough, - * then the function places the cfg in mem and the size used in *lenmem - * and returns mem. - * - * If lenmem is not NULL and ( mem is NULL or *lenmem is not large enough), - * then the function returns NULL and places the minimum cfg - * buffer size in *lenmem. - * */ - -kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem); - -/* - * kiss_fft(cfg,in_out_buf) - * - * Perform an FFT on a complex input buffer. - * for a forward FFT, - * fin should be f[0] , f[1] , ... ,f[nfft-1] - * fout will be F[0] , F[1] , ... ,F[nfft-1] - * Note that each element is complex and can be accessed like - f[k].r and f[k].i - * */ -void kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout); - -/* - A more generic version of the above function. It reads its input from every Nth sample. - * */ -void kiss_fft_stride(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int fin_stride); - -/* If kiss_fft_alloc allocated a buffer, it is one contiguous - buffer and can be simply free()d when no longer needed*/ -#define kiss_fft_free free - -/* - Cleans up some memory that gets managed internally. Not necessary to call, but it might clean up - your compiler output to call this before you exit. -*/ -void kiss_fft_cleanup(void); - - -/* - * Returns the smallest integer k, such that k>=n and k has only "fast" factors (2,3,5) - */ -int kiss_fft_next_fast_size(int n); - -/* for real ffts, we need an even size */ -#define kiss_fftr_next_fast_size_real(n) \ - (kiss_fft_next_fast_size( ((n)+1)>>1)<<1) - -#ifndef KISSFFT_USE_CPP_LINKAGE -#ifdef __cplusplus -} -#endif -#endif - -#ifdef KISSFFT_USE_CPP_LINKAGE -#define KISSFFT_USED_CPP_LINKAGE 1 -#endif - -#endif diff -r d129bf797f24 -r 8742125177ae src/vamp-sdk/ext/kiss_fftr.c --- a/src/vamp-sdk/ext/kiss_fftr.c Tue Jan 30 15:28:15 2018 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,159 +0,0 @@ -/* -Copyright (c) 2003-2004, Mark Borgerding - -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "kiss_fftr.h" -#include "_kiss_fft_guts.h" - -struct kiss_fftr_state{ - kiss_fft_cfg substate; - kiss_fft_cpx * tmpbuf; - kiss_fft_cpx * super_twiddles; -#ifdef USE_SIMD - void * pad; -#endif -}; - -kiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem) -{ - int i; - kiss_fftr_cfg st = NULL; - size_t subsize, memneeded; - - if (nfft & 1) { - fprintf(stderr,"Real FFT optimization must be even.\n"); - return NULL; - } - nfft >>= 1; - - kiss_fft_alloc (nfft, inverse_fft, NULL, &subsize); - memneeded = sizeof(struct kiss_fftr_state) + subsize + sizeof(kiss_fft_cpx) * ( nfft * 3 / 2); - - if (lenmem == NULL) { - st = (kiss_fftr_cfg) KISS_FFT_MALLOC (memneeded); - } else { - if (*lenmem >= memneeded) - st = (kiss_fftr_cfg) mem; - *lenmem = memneeded; - } - if (!st) - return NULL; - - st->substate = (kiss_fft_cfg) (st + 1); /*just beyond kiss_fftr_state struct */ - st->tmpbuf = (kiss_fft_cpx *) (((char *) st->substate) + subsize); - st->super_twiddles = st->tmpbuf + nfft; - kiss_fft_alloc(nfft, inverse_fft, st->substate, &subsize); - - for (i = 0; i < nfft/2; ++i) { - double phase = - -3.14159265358979323846264338327 * ((double) (i+1) / nfft + .5); - if (inverse_fft) - phase *= -1; - kf_cexp (st->super_twiddles+i,phase); - } - return st; -} - -void kiss_fftr(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_cpx *freqdata) -{ - /* input buffer timedata is stored row-wise */ - int k,ncfft; - kiss_fft_cpx fpnk,fpk,f1k,f2k,tw,tdc; - - if ( st->substate->inverse) { - fprintf(stderr,"kiss fft usage error: improper alloc\n"); - exit(1); - } - - ncfft = st->substate->nfft; - - /*perform the parallel fft of two real signals packed in real,imag*/ - kiss_fft( st->substate , (const kiss_fft_cpx*)timedata, st->tmpbuf ); - /* The real part of the DC element of the frequency spectrum in st->tmpbuf - * contains the sum of the even-numbered elements of the input time sequence - * The imag part is the sum of the odd-numbered elements - * - * The sum of tdc.r and tdc.i is the sum of the input time sequence. - * yielding DC of input time sequence - * The difference of tdc.r - tdc.i is the sum of the input (dot product) [1,-1,1,-1... - * yielding Nyquist bin of input time sequence - */ - - tdc.r = st->tmpbuf[0].r; - tdc.i = st->tmpbuf[0].i; - C_FIXDIV(tdc,2); - CHECK_OVERFLOW_OP(tdc.r ,+, tdc.i); - CHECK_OVERFLOW_OP(tdc.r ,-, tdc.i); - freqdata[0].r = tdc.r + tdc.i; - freqdata[ncfft].r = tdc.r - tdc.i; -#ifdef USE_SIMD - freqdata[ncfft].i = freqdata[0].i = _mm_set1_ps(0); -#else - freqdata[ncfft].i = freqdata[0].i = 0; -#endif - - for ( k=1;k <= ncfft/2 ; ++k ) { - fpk = st->tmpbuf[k]; - fpnk.r = st->tmpbuf[ncfft-k].r; - fpnk.i = - st->tmpbuf[ncfft-k].i; - C_FIXDIV(fpk,2); - C_FIXDIV(fpnk,2); - - C_ADD( f1k, fpk , fpnk ); - C_SUB( f2k, fpk , fpnk ); - C_MUL( tw , f2k , st->super_twiddles[k-1]); - - freqdata[k].r = HALF_OF(f1k.r + tw.r); - freqdata[k].i = HALF_OF(f1k.i + tw.i); - freqdata[ncfft-k].r = HALF_OF(f1k.r - tw.r); - freqdata[ncfft-k].i = HALF_OF(tw.i - f1k.i); - } -} - -void kiss_fftri(kiss_fftr_cfg st,const kiss_fft_cpx *freqdata,kiss_fft_scalar *timedata) -{ - /* input buffer timedata is stored row-wise */ - int k, ncfft; - - if (st->substate->inverse == 0) { - fprintf (stderr, "kiss fft usage error: improper alloc\n"); - exit (1); - } - - ncfft = st->substate->nfft; - - st->tmpbuf[0].r = freqdata[0].r + freqdata[ncfft].r; - st->tmpbuf[0].i = freqdata[0].r - freqdata[ncfft].r; - C_FIXDIV(st->tmpbuf[0],2); - - for (k = 1; k <= ncfft / 2; ++k) { - kiss_fft_cpx fk, fnkc, fek, fok, tmp; - fk = freqdata[k]; - fnkc.r = freqdata[ncfft - k].r; - fnkc.i = -freqdata[ncfft - k].i; - C_FIXDIV( fk , 2 ); - C_FIXDIV( fnkc , 2 ); - - C_ADD (fek, fk, fnkc); - C_SUB (tmp, fk, fnkc); - C_MUL (fok, tmp, st->super_twiddles[k-1]); - C_ADD (st->tmpbuf[k], fek, fok); - C_SUB (st->tmpbuf[ncfft - k], fek, fok); -#ifdef USE_SIMD - st->tmpbuf[ncfft - k].i *= _mm_set1_ps(-1.0); -#else - st->tmpbuf[ncfft - k].i *= -1; -#endif - } - kiss_fft (st->substate, st->tmpbuf, (kiss_fft_cpx *) timedata); -} diff -r d129bf797f24 -r 8742125177ae src/vamp-sdk/ext/kiss_fftr.h --- a/src/vamp-sdk/ext/kiss_fftr.h Tue Jan 30 15:28:15 2018 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -#ifndef KISS_FTR_H -#define KISS_FTR_H - -#include "kiss_fft.h" - -#ifndef KISSFFT_USE_CPP_LINKAGE -#ifdef __cplusplus -extern "C" { -#endif -#endif - - -/* - - Real optimized version can save about 45% cpu time vs. complex fft of a real seq. - - - - */ - -typedef struct kiss_fftr_state *kiss_fftr_cfg; - - -kiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem, size_t * lenmem); -/* - nfft must be even - - If you don't care to allocate space, use mem = lenmem = NULL -*/ - - -void kiss_fftr(kiss_fftr_cfg cfg,const kiss_fft_scalar *timedata,kiss_fft_cpx *freqdata); -/* - input timedata has nfft scalar points - output freqdata has nfft/2+1 complex points -*/ - -void kiss_fftri(kiss_fftr_cfg cfg,const kiss_fft_cpx *freqdata,kiss_fft_scalar *timedata); -/* - input freqdata has nfft/2+1 complex points - output timedata has nfft scalar points -*/ - -#define kiss_fftr_free free - -#ifndef KISSFFT_USE_CPP_LINKAGE -#ifdef __cplusplus -} -#endif -#endif - -#ifdef KISSFFT_USE_CPP_LINKAGE -#define KISSFFT_USED_CPP_LINKAGE 1 -#endif - -#endif diff -r d129bf797f24 -r 8742125177ae src/vamp-sdk/ext/vamp_kiss_fft.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/vamp-sdk/ext/vamp_kiss_fft.c Thu Feb 08 15:40:33 2018 +0000 @@ -0,0 +1,413 @@ +/* +Copyright (c) 2003-2010, Mark Borgerding + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#include "vamp_kiss_fft_guts.h" +/* The guts header contains all the multiplication and addition macros that are defined for + fixed or floating point complex numbers. It also delares the kf_ internal functions. + */ + +static void kf_bfly2( + vamp_kiss_fft_cpx * Fout, + const size_t fstride, + const vamp_kiss_fft_cfg st, + int m + ) +{ + vamp_kiss_fft_cpx * Fout2; + vamp_kiss_fft_cpx * tw1 = st->twiddles; + vamp_kiss_fft_cpx t; + Fout2 = Fout + m; + do{ + C_FIXDIV(*Fout,2); C_FIXDIV(*Fout2,2); + + C_MUL (t, *Fout2 , *tw1); + tw1 += fstride; + C_SUB( *Fout2 , *Fout , t ); + C_ADDTO( *Fout , t ); + ++Fout2; + ++Fout; + }while (--m); +} + +static void kf_bfly4( + vamp_kiss_fft_cpx * Fout, + const size_t fstride, + const vamp_kiss_fft_cfg st, + const size_t m + ) +{ + vamp_kiss_fft_cpx *tw1,*tw2,*tw3; + vamp_kiss_fft_cpx scratch[6]; + size_t k=m; + const size_t m2=2*m; + const size_t m3=3*m; + + + tw3 = tw2 = tw1 = st->twiddles; + + do { + C_FIXDIV(*Fout,4); C_FIXDIV(Fout[m],4); C_FIXDIV(Fout[m2],4); C_FIXDIV(Fout[m3],4); + + C_MUL(scratch[0],Fout[m] , *tw1 ); + C_MUL(scratch[1],Fout[m2] , *tw2 ); + C_MUL(scratch[2],Fout[m3] , *tw3 ); + + C_SUB( scratch[5] , *Fout, scratch[1] ); + C_ADDTO(*Fout, scratch[1]); + C_ADD( scratch[3] , scratch[0] , scratch[2] ); + C_SUB( scratch[4] , scratch[0] , scratch[2] ); + C_SUB( Fout[m2], *Fout, scratch[3] ); + tw1 += fstride; + tw2 += fstride*2; + tw3 += fstride*3; + C_ADDTO( *Fout , scratch[3] ); + + if(st->inverse) { + Fout[m].r = scratch[5].r - scratch[4].i; + Fout[m].i = scratch[5].i + scratch[4].r; + Fout[m3].r = scratch[5].r + scratch[4].i; + Fout[m3].i = scratch[5].i - scratch[4].r; + }else{ + Fout[m].r = scratch[5].r + scratch[4].i; + Fout[m].i = scratch[5].i - scratch[4].r; + Fout[m3].r = scratch[5].r - scratch[4].i; + Fout[m3].i = scratch[5].i + scratch[4].r; + } + ++Fout; + }while(--k); +} + +static void kf_bfly3( + vamp_kiss_fft_cpx * Fout, + const size_t fstride, + const vamp_kiss_fft_cfg st, + size_t m + ) +{ + size_t k=m; + const size_t m2 = 2*m; + vamp_kiss_fft_cpx *tw1,*tw2; + vamp_kiss_fft_cpx scratch[5]; + vamp_kiss_fft_cpx epi3; + epi3 = st->twiddles[fstride*m]; + + tw1=tw2=st->twiddles; + + do{ + C_FIXDIV(*Fout,3); C_FIXDIV(Fout[m],3); C_FIXDIV(Fout[m2],3); + + C_MUL(scratch[1],Fout[m] , *tw1); + C_MUL(scratch[2],Fout[m2] , *tw2); + + C_ADD(scratch[3],scratch[1],scratch[2]); + C_SUB(scratch[0],scratch[1],scratch[2]); + tw1 += fstride; + tw2 += fstride*2; + + Fout[m].r = Fout->r - HALF_OF(scratch[3].r); + Fout[m].i = Fout->i - HALF_OF(scratch[3].i); + + C_MULBYSCALAR( scratch[0] , epi3.i ); + + C_ADDTO(*Fout,scratch[3]); + + Fout[m2].r = Fout[m].r + scratch[0].i; + Fout[m2].i = Fout[m].i - scratch[0].r; + + Fout[m].r -= scratch[0].i; + Fout[m].i += scratch[0].r; + + ++Fout; + }while(--k); +} + +static void kf_bfly5( + vamp_kiss_fft_cpx * Fout, + const size_t fstride, + const vamp_kiss_fft_cfg st, + int m + ) +{ + vamp_kiss_fft_cpx *Fout0,*Fout1,*Fout2,*Fout3,*Fout4; + int u; + vamp_kiss_fft_cpx scratch[13]; + vamp_kiss_fft_cpx * twiddles = st->twiddles; + vamp_kiss_fft_cpx *tw; + vamp_kiss_fft_cpx ya,yb; + ya = twiddles[fstride*m]; + yb = twiddles[fstride*2*m]; + + Fout0=Fout; + Fout1=Fout0+m; + Fout2=Fout0+2*m; + Fout3=Fout0+3*m; + Fout4=Fout0+4*m; + + tw=st->twiddles; + for ( u=0; ur += scratch[7].r + scratch[8].r; + Fout0->i += scratch[7].i + scratch[8].i; + + scratch[5].r = scratch[0].r + S_MUL(scratch[7].r,ya.r) + S_MUL(scratch[8].r,yb.r); + scratch[5].i = scratch[0].i + S_MUL(scratch[7].i,ya.r) + S_MUL(scratch[8].i,yb.r); + + scratch[6].r = S_MUL(scratch[10].i,ya.i) + S_MUL(scratch[9].i,yb.i); + scratch[6].i = -S_MUL(scratch[10].r,ya.i) - S_MUL(scratch[9].r,yb.i); + + C_SUB(*Fout1,scratch[5],scratch[6]); + C_ADD(*Fout4,scratch[5],scratch[6]); + + scratch[11].r = scratch[0].r + S_MUL(scratch[7].r,yb.r) + S_MUL(scratch[8].r,ya.r); + scratch[11].i = scratch[0].i + S_MUL(scratch[7].i,yb.r) + S_MUL(scratch[8].i,ya.r); + scratch[12].r = - S_MUL(scratch[10].i,yb.i) + S_MUL(scratch[9].i,ya.i); + scratch[12].i = S_MUL(scratch[10].r,yb.i) - S_MUL(scratch[9].r,ya.i); + + C_ADD(*Fout2,scratch[11],scratch[12]); + C_SUB(*Fout3,scratch[11],scratch[12]); + + ++Fout0;++Fout1;++Fout2;++Fout3;++Fout4; + } +} + +/* perform the butterfly for one stage of a mixed radix FFT */ +static void kf_bfly_generic( + vamp_kiss_fft_cpx * Fout, + const size_t fstride, + const vamp_kiss_fft_cfg st, + int m, + int p + ) +{ + int u,k,q1,q; + vamp_kiss_fft_cpx * twiddles = st->twiddles; + vamp_kiss_fft_cpx t; + int Norig = st->nfft; + + vamp_kiss_fft_cpx * scratch = (vamp_kiss_fft_cpx*)VAMP_KISS_FFT_TMP_ALLOC(sizeof(vamp_kiss_fft_cpx)*p); + + for ( u=0; u=Norig) twidx-=Norig; + C_MUL(t,scratch[q] , twiddles[twidx] ); + C_ADDTO( Fout[ k ] ,t); + } + k += m; + } + } + VAMP_KISS_FFT_TMP_FREE(scratch); +} + +static +void kf_work( + vamp_kiss_fft_cpx * Fout, + const vamp_kiss_fft_cpx * f, + const size_t fstride, + int in_stride, + int * factors, + const vamp_kiss_fft_cfg st + ) +{ + vamp_kiss_fft_cpx * Fout_beg=Fout; + const int p=*factors++; /* the radix */ + const int m=*factors++; /* stage's fft length/p */ + const vamp_kiss_fft_cpx * Fout_end = Fout + p*m; + +#ifdef _OPENMP + // use openmp extensions at the + // top-level (not recursive) + if (fstride==1 && p<=5) + { + int k; + + // execute the p different work units in different threads +# pragma omp parallel for + for (k=0;kr = f->r; + Fout->i = f->i; + f += fstride*in_stride; + }while(++Fout != Fout_end ); + }else{ + do{ + // recursive call: + // DFT of size m*p performed by doing + // p instances of smaller DFTs of size m, + // each one takes a decimated version of the input + kf_work( Fout , f, fstride*p, in_stride, factors,st); + f += fstride*in_stride; + }while( (Fout += m) != Fout_end ); + } + + Fout=Fout_beg; + + // recombine the p smaller DFTs + switch (p) { + case 2: kf_bfly2(Fout,fstride,st,m); break; + case 3: kf_bfly3(Fout,fstride,st,m); break; + case 4: kf_bfly4(Fout,fstride,st,m); break; + case 5: kf_bfly5(Fout,fstride,st,m); break; + default: kf_bfly_generic(Fout,fstride,st,m,p); break; + } +} + +/* facbuf is populated by p1,m1,p2,m2, ... + where + p[i] * m[i] = m[i-1] + m0 = n */ +static +void kf_factor(int n,int * facbuf) +{ + int p=4; + double floor_sqrt; + floor_sqrt = floor( sqrt((double)n) ); + + /*factor out powers of 4, powers of 2, then any remaining primes */ + do { + while (n % p) { + switch (p) { + case 4: p = 2; break; + case 2: p = 3; break; + default: p += 2; break; + } + if (p > floor_sqrt) + p = n; /* no more factors, skip to end */ + } + n /= p; + *facbuf++ = p; + *facbuf++ = n; + } while (n > 1); +} + +/* + * + * User-callable function to allocate all necessary storage space for the fft. + * + * The return value is a contiguous block of memory, allocated with malloc. As such, + * It can be freed with free(), rather than a kiss_fft-specific function. + * */ +vamp_kiss_fft_cfg vamp_kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem ) +{ + vamp_kiss_fft_cfg st=NULL; + size_t memneeded = sizeof(struct vamp_kiss_fft_state) + + sizeof(vamp_kiss_fft_cpx)*(nfft-1); /* twiddle factors*/ + + if ( lenmem==NULL ) { + st = ( vamp_kiss_fft_cfg)VAMP_KISS_FFT_MALLOC( memneeded ); + }else{ + if (mem != NULL && *lenmem >= memneeded) + st = (vamp_kiss_fft_cfg)mem; + *lenmem = memneeded; + } + if (st) { + int i; + st->nfft=nfft; + st->inverse = inverse_fft; + + for (i=0;iinverse) + phase *= -1; + kf_cexp(st->twiddles+i, phase ); + } + + kf_factor(nfft,st->factors); + } + return st; +} + +void vamp_kiss_fft_free(void *mem) +{ + free(mem); +} + +void vamp_kiss_fft_stride(vamp_kiss_fft_cfg st,const vamp_kiss_fft_cpx *fin,vamp_kiss_fft_cpx *fout,int in_stride) +{ + if (fin == fout) { + //NOTE: this is not really an in-place FFT algorithm. + //It just performs an out-of-place FFT into a temp buffer + vamp_kiss_fft_cpx * tmpbuf = (vamp_kiss_fft_cpx*)VAMP_KISS_FFT_TMP_ALLOC( sizeof(vamp_kiss_fft_cpx)*st->nfft); + kf_work(tmpbuf,fin,1,in_stride, st->factors,st); + memcpy(fout,tmpbuf,sizeof(vamp_kiss_fft_cpx)*st->nfft); + VAMP_KISS_FFT_TMP_FREE(tmpbuf); + }else{ + kf_work( fout, fin, 1,in_stride, st->factors,st ); + } +} + +void vamp_kiss_fft(vamp_kiss_fft_cfg cfg,const vamp_kiss_fft_cpx *fin,vamp_kiss_fft_cpx *fout) +{ + vamp_kiss_fft_stride(cfg,fin,fout,1); +} + + +void vamp_kiss_fft_cleanup(void) +{ + // nothing needed any more +} + +int vamp_kiss_fft_next_fast_size(int n) +{ + while(1) { + int m=n; + while ( (m%2) == 0 ) m/=2; + while ( (m%3) == 0 ) m/=3; + while ( (m%5) == 0 ) m/=5; + if (m<=1) + break; /* n is completely factorable by twos, threes, and fives */ + n++; + } + return n; +} diff -r d129bf797f24 -r 8742125177ae src/vamp-sdk/ext/vamp_kiss_fft.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/vamp-sdk/ext/vamp_kiss_fft.h Thu Feb 08 15:40:33 2018 +0000 @@ -0,0 +1,109 @@ +#ifndef VAMP_KISS_FFT_H +#define VAMP_KISS_FFT_H + +#include +#include +#include +#include + +#ifndef _VAMP_IN_PLUGINSDK +# ifndef _VAMP_IN_HOSTSDK +# error "Do not use the Vamp SDK mangled KissFFT header except through the Vamp SDK API" +# endif +#endif + +#ifdef VAMP_KISSFFT_USE_CPP_LINKAGE +#define VAMP_KISS_FFT_MALLOC ::malloc +#define VAMP_KISS_FFT_FREE ::free +#else +#ifdef __cplusplus +extern "C" { +#define VAMP_KISS_FFT_MALLOC malloc +#define VAMP_KISS_FFT_FREE free +#endif +#endif + +# ifndef vamp_kiss_fft_scalar +# error "vamp_kiss_fft_scalar must be defined before inclusion, we don't have a default in this build" +# endif + +typedef struct { + vamp_kiss_fft_scalar r; + vamp_kiss_fft_scalar i; +} vamp_kiss_fft_cpx; + +typedef struct vamp_kiss_fft_state* vamp_kiss_fft_cfg; + +/* + * kiss_fft_alloc + * + * Initialize a FFT (or IFFT) algorithm's cfg/state buffer. + * + * typical usage: kiss_fft_cfg mycfg=kiss_fft_alloc(1024,0,NULL,NULL); + * + * The return value from fft_alloc is a cfg buffer used internally + * by the fft routine or NULL. + * + * If lenmem is NULL, then kiss_fft_alloc will allocate a cfg buffer using malloc. + * The returned value should be free()d when done to avoid memory leaks. + * + * The state can be placed in a user supplied buffer 'mem': + * If lenmem is not NULL and mem is not NULL and *lenmem is large enough, + * then the function places the cfg in mem and the size used in *lenmem + * and returns mem. + * + * If lenmem is not NULL and ( mem is NULL or *lenmem is not large enough), + * then the function returns NULL and places the minimum cfg + * buffer size in *lenmem. + * */ + +vamp_kiss_fft_cfg vamp_kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem); + +/* + * kiss_fft(cfg,in_out_buf) + * + * Perform an FFT on a complex input buffer. + * for a forward FFT, + * fin should be f[0] , f[1] , ... ,f[nfft-1] + * fout will be F[0] , F[1] , ... ,F[nfft-1] + * Note that each element is complex and can be accessed like + f[k].r and f[k].i + * */ +void vamp_kiss_fft(vamp_kiss_fft_cfg cfg,const vamp_kiss_fft_cpx *fin,vamp_kiss_fft_cpx *fout); + +/* + A more generic version of the above function. It reads its input from every Nth sample. + * */ +void vamp_kiss_fft_stride(vamp_kiss_fft_cfg cfg,const vamp_kiss_fft_cpx *fin,vamp_kiss_fft_cpx *fout,int fin_stride); + +/* If kiss_fft_alloc allocated a buffer, it is one contiguous + buffer and can be simply free()d when no longer needed*/ +void vamp_kiss_fft_free(void *); + +/* + Cleans up some memory that gets managed internally. Not necessary to call, but it might clean up + your compiler output to call this before you exit. +*/ +void vamp_kiss_fft_cleanup(void); + + +/* + * Returns the smallest integer k, such that k>=n and k has only "fast" factors (2,3,5) + */ +int vamp_kiss_fft_next_fast_size(int n); + +/* for real ffts, we need an even size */ +#define vamp_kiss_fftr_next_fast_size_real(n) \ + (vamp_kiss_fft_next_fast_size( ((n)+1)>>1)<<1) + +#ifndef VAMP_KISSFFT_USE_CPP_LINKAGE +#ifdef __cplusplus +} +#endif +#endif + +#ifdef VAMP_KISSFFT_USE_CPP_LINKAGE +#define VAMP_KISSFFT_USED_CPP_LINKAGE 1 +#endif + +#endif diff -r d129bf797f24 -r 8742125177ae src/vamp-sdk/ext/vamp_kiss_fft_guts.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/vamp-sdk/ext/vamp_kiss_fft_guts.h Thu Feb 08 15:40:33 2018 +0000 @@ -0,0 +1,102 @@ +#ifndef VAMP_KISS_FFT__GUTS_H +#define VAMP_KISS_FFT__GUTS_H +/* +Copyright (c) 2003-2010, Mark Borgerding + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* kiss_fft.h + defines kiss_fft_scalar as either short or a float type + and defines + typedef struct { kiss_fft_scalar r; kiss_fft_scalar i; }kiss_fft_cpx; */ +#include "vamp_kiss_fft.h" +#include + +#define MAXFACTORS 32 +/* e.g. an fft of length 128 has 4 factors + as far as kissfft is concerned + 4*4*4*2 + */ + +struct vamp_kiss_fft_state{ + int nfft; + int inverse; + int factors[2*MAXFACTORS]; + vamp_kiss_fft_cpx twiddles[1]; +}; + +/* + Explanation of macros dealing with complex math: + + C_MUL(m,a,b) : m = a*b + C_FIXDIV( c , div ) : if a fixed point impl., c /= div. noop otherwise + C_SUB( res, a,b) : res = a - b + C_SUBFROM( res , a) : res -= a + C_ADDTO( res , a) : res += a + * */ + +# define S_MUL(a,b) ( (a)*(b) ) +#define C_MUL(m,a,b) \ + do{ (m).r = (a).r*(b).r - (a).i*(b).i;\ + (m).i = (a).r*(b).i + (a).i*(b).r; }while(0) +# define C_FIXDIV(c,div) /* NOOP */ +# define C_MULBYSCALAR( c, s ) \ + do{ (c).r *= (s);\ + (c).i *= (s); }while(0) + +# define CHECK_OVERFLOW_OP(a,op,b) /* noop */ + +#define C_ADD( res, a,b)\ + do { \ + CHECK_OVERFLOW_OP((a).r,+,(b).r)\ + CHECK_OVERFLOW_OP((a).i,+,(b).i)\ + (res).r=(a).r+(b).r; (res).i=(a).i+(b).i; \ + }while(0) +#define C_SUB( res, a,b)\ + do { \ + CHECK_OVERFLOW_OP((a).r,-,(b).r)\ + CHECK_OVERFLOW_OP((a).i,-,(b).i)\ + (res).r=(a).r-(b).r; (res).i=(a).i-(b).i; \ + }while(0) +#define C_ADDTO( res , a)\ + do { \ + CHECK_OVERFLOW_OP((res).r,+,(a).r)\ + CHECK_OVERFLOW_OP((res).i,+,(a).i)\ + (res).r += (a).r; (res).i += (a).i;\ + }while(0) + +#define C_SUBFROM( res , a)\ + do {\ + CHECK_OVERFLOW_OP((res).r,-,(a).r)\ + CHECK_OVERFLOW_OP((res).i,-,(a).i)\ + (res).r -= (a).r; (res).i -= (a).i; \ + }while(0) + + +# define VAMP_KISS_FFT_COS(phase) (vamp_kiss_fft_scalar) cos(phase) +# define VAMP_KISS_FFT_SIN(phase) (vamp_kiss_fft_scalar) sin(phase) +# define HALF_OF(x) ((x)*.5) + +#define kf_cexp(x,phase) \ + do{ \ + (x)->r = VAMP_KISS_FFT_COS(phase);\ + (x)->i = VAMP_KISS_FFT_SIN(phase);\ + }while(0) + +#define VAMP_KISS_FFT_TMP_ALLOC(nbytes) VAMP_KISS_FFT_MALLOC(nbytes) +#define VAMP_KISS_FFT_TMP_FREE(ptr) VAMP_KISS_FFT_FREE(ptr) + +/* a debugging function */ +#define pcpx(c)\ + fprintf(stderr,"%g + %gi\n",(double)((c)->r),(double)((c)->i) ) + +#endif diff -r d129bf797f24 -r 8742125177ae src/vamp-sdk/ext/vamp_kiss_fftr.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/vamp-sdk/ext/vamp_kiss_fftr.c Thu Feb 08 15:40:33 2018 +0000 @@ -0,0 +1,153 @@ +/* +Copyright (c) 2003-2004, Mark Borgerding + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "vamp_kiss_fftr.h" +#include "vamp_kiss_fft_guts.h" + +struct vamp_kiss_fftr_state{ + vamp_kiss_fft_cfg substate; + vamp_kiss_fft_cpx * tmpbuf; + vamp_kiss_fft_cpx * super_twiddles; +}; + +vamp_kiss_fftr_cfg vamp_kiss_fftr_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem) +{ + int i; + vamp_kiss_fftr_cfg st = NULL; + size_t subsize, memneeded; + + if (nfft & 1) { + fprintf(stderr,"Real FFT optimization must be even.\n"); + return NULL; + } + nfft >>= 1; + + vamp_kiss_fft_alloc (nfft, inverse_fft, NULL, &subsize); + memneeded = sizeof(struct vamp_kiss_fftr_state) + subsize + sizeof(vamp_kiss_fft_cpx) * ( nfft * 3 / 2); + + if (lenmem == NULL) { + st = (vamp_kiss_fftr_cfg) VAMP_KISS_FFT_MALLOC (memneeded); + } else { + if (*lenmem >= memneeded) + st = (vamp_kiss_fftr_cfg) mem; + *lenmem = memneeded; + } + if (!st) + return NULL; + + st->substate = (vamp_kiss_fft_cfg) (st + 1); /*just beyond vamp_kiss_fftr_state struct */ + st->tmpbuf = (vamp_kiss_fft_cpx *) (((char *) st->substate) + subsize); + st->super_twiddles = st->tmpbuf + nfft; + vamp_kiss_fft_alloc(nfft, inverse_fft, st->substate, &subsize); + + for (i = 0; i < nfft/2; ++i) { + double phase = + -3.14159265358979323846264338327 * ((double) (i+1) / nfft + .5); + if (inverse_fft) + phase *= -1; + kf_cexp (st->super_twiddles+i,phase); + } + return st; +} + +void vamp_kiss_fftr_free(void *mem) +{ + free(mem); +} + +void vamp_kiss_fftr(vamp_kiss_fftr_cfg st,const vamp_kiss_fft_scalar *timedata,vamp_kiss_fft_cpx *freqdata) +{ + /* input buffer timedata is stored row-wise */ + int k,ncfft; + vamp_kiss_fft_cpx fpnk,fpk,f1k,f2k,tw,tdc; + + if ( st->substate->inverse) { + fprintf(stderr,"kiss fft usage error: improper alloc\n"); + exit(1); + } + + ncfft = st->substate->nfft; + + /*perform the parallel fft of two real signals packed in real,imag*/ + vamp_kiss_fft( st->substate , (const vamp_kiss_fft_cpx*)timedata, st->tmpbuf ); + /* The real part of the DC element of the frequency spectrum in st->tmpbuf + * contains the sum of the even-numbered elements of the input time sequence + * The imag part is the sum of the odd-numbered elements + * + * The sum of tdc.r and tdc.i is the sum of the input time sequence. + * yielding DC of input time sequence + * The difference of tdc.r - tdc.i is the sum of the input (dot product) [1,-1,1,-1... + * yielding Nyquist bin of input time sequence + */ + + tdc.r = st->tmpbuf[0].r; + tdc.i = st->tmpbuf[0].i; + C_FIXDIV(tdc,2); + CHECK_OVERFLOW_OP(tdc.r ,+, tdc.i); + CHECK_OVERFLOW_OP(tdc.r ,-, tdc.i); + freqdata[0].r = tdc.r + tdc.i; + freqdata[ncfft].r = tdc.r - tdc.i; + freqdata[ncfft].i = freqdata[0].i = 0; + + for ( k=1;k <= ncfft/2 ; ++k ) { + fpk = st->tmpbuf[k]; + fpnk.r = st->tmpbuf[ncfft-k].r; + fpnk.i = - st->tmpbuf[ncfft-k].i; + C_FIXDIV(fpk,2); + C_FIXDIV(fpnk,2); + + C_ADD( f1k, fpk , fpnk ); + C_SUB( f2k, fpk , fpnk ); + C_MUL( tw , f2k , st->super_twiddles[k-1]); + + freqdata[k].r = HALF_OF(f1k.r + tw.r); + freqdata[k].i = HALF_OF(f1k.i + tw.i); + freqdata[ncfft-k].r = HALF_OF(f1k.r - tw.r); + freqdata[ncfft-k].i = HALF_OF(tw.i - f1k.i); + } +} + +void vamp_kiss_fftri(vamp_kiss_fftr_cfg st,const vamp_kiss_fft_cpx *freqdata,vamp_kiss_fft_scalar *timedata) +{ + /* input buffer timedata is stored row-wise */ + int k, ncfft; + + if (st->substate->inverse == 0) { + fprintf (stderr, "kiss fft usage error: improper alloc\n"); + exit (1); + } + + ncfft = st->substate->nfft; + + st->tmpbuf[0].r = freqdata[0].r + freqdata[ncfft].r; + st->tmpbuf[0].i = freqdata[0].r - freqdata[ncfft].r; + C_FIXDIV(st->tmpbuf[0],2); + + for (k = 1; k <= ncfft / 2; ++k) { + vamp_kiss_fft_cpx fk, fnkc, fek, fok, tmp; + fk = freqdata[k]; + fnkc.r = freqdata[ncfft - k].r; + fnkc.i = -freqdata[ncfft - k].i; + C_FIXDIV( fk , 2 ); + C_FIXDIV( fnkc , 2 ); + + C_ADD (fek, fk, fnkc); + C_SUB (tmp, fk, fnkc); + C_MUL (fok, tmp, st->super_twiddles[k-1]); + C_ADD (st->tmpbuf[k], fek, fok); + C_SUB (st->tmpbuf[ncfft - k], fek, fok); + st->tmpbuf[ncfft - k].i *= -1; + } + vamp_kiss_fft (st->substate, st->tmpbuf, (vamp_kiss_fft_cpx *) timedata); +} diff -r d129bf797f24 -r 8742125177ae src/vamp-sdk/ext/vamp_kiss_fftr.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/vamp-sdk/ext/vamp_kiss_fftr.h Thu Feb 08 15:40:33 2018 +0000 @@ -0,0 +1,56 @@ +#ifndef VAMP_KISS_FFTR_H +#define VAMP_KISS_FFTR_H + +#include "vamp_kiss_fft.h" + +#ifndef VAMP_KISSFFT_USE_CPP_LINKAGE +#ifdef __cplusplus +extern "C" { +#endif +#endif + + +/* + + Real optimized version can save about 45% cpu time vs. complex fft of a real seq. + + + + */ + +typedef struct vamp_kiss_fftr_state *vamp_kiss_fftr_cfg; + + +vamp_kiss_fftr_cfg vamp_kiss_fftr_alloc(int nfft,int inverse_fft,void * mem, size_t * lenmem); +/* + nfft must be even + + If you don't care to allocate space, use mem = lenmem = NULL +*/ + + +void vamp_kiss_fftr(vamp_kiss_fftr_cfg cfg,const vamp_kiss_fft_scalar *timedata,vamp_kiss_fft_cpx *freqdata); +/* + input timedata has nfft scalar points + output freqdata has nfft/2+1 complex points +*/ + +void vamp_kiss_fftri(vamp_kiss_fftr_cfg cfg,const vamp_kiss_fft_cpx *freqdata,vamp_kiss_fft_scalar *timedata); +/* + input freqdata has nfft/2+1 complex points + output timedata has nfft scalar points +*/ + +void vamp_kiss_fftr_free(void *); + +#ifndef VAMP_KISSFFT_USE_CPP_LINKAGE +#ifdef __cplusplus +} +#endif +#endif + +#ifdef VAMP_KISSFFT_USE_CPP_LINKAGE +#define VAMP_KISSFFT_USED_CPP_LINKAGE 1 +#endif + +#endif diff -r d129bf797f24 -r 8742125177ae vamp-hostsdk/hostguard.h --- a/vamp-hostsdk/hostguard.h Tue Jan 30 15:28:15 2018 +0000 +++ b/vamp-hostsdk/hostguard.h Thu Feb 08 15:40:33 2018 +0000 @@ -41,7 +41,7 @@ #error You have included headers from both vamp-sdk and vamp-hostsdk in the same source file. Please include only vamp-sdk headers in plugin code, and only vamp-hostsdk headers in host code. #else -#define _VAMP_IN_HOSTSDK +#define _VAMP_IN_HOSTSDK 1 #define VAMP_SDK_VERSION "2.7.1" #define VAMP_SDK_MAJOR_VERSION 2