# HG changeset patch # User Chris Cannam # Date 1471527832 -3600 # Node ID 7bab0c5422f4b5c8e3637a8b0cd77d8acc5dd3be # Parent d3f676c07359e3448f18d3aade144e1aedfc2aae Make single/double-precision selectable for input domain adapter windowing and FFTs. Double precision is necessary to pass Sonic Annotator regression tests, though in practice most real-world methods would be fine with single precision. diff -r d3f676c07359 -r 7bab0c5422f4 src/vamp-hostsdk/PluginInputDomainAdapter.cpp --- a/src/vamp-hostsdk/PluginInputDomainAdapter.cpp Thu Aug 18 12:03:09 2016 +0100 +++ b/src/vamp-hostsdk/PluginInputDomainAdapter.cpp Thu Aug 18 14:43:52 2016 +0100 @@ -49,22 +49,40 @@ #include #include +// Define this symbol in the build if you want to use single-precision +// FFTs in the input domain adapter. The default is to use +// double-precision FFTs. +// +//#define SINGLE_PRECISION_INPUT_DOMAIN_ADAPTER 1 + // 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 #undef __cplusplus -namespace KissSingle { +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_INPUT_DOMAIN_ADAPTER +typedef float kiss_fft_scalar; #define kiss_fft_scalar float +#else +typedef double kiss_fft_scalar; +#define kiss_fft_scalar double +#endif + inline void free(void *ptr) { ::free(ptr); } #include "../vamp-sdk/ext/kiss_fft.c" #include "../vamp-sdk/ext/kiss_fftr.c" + +#undef kiss_fft_scalar // leaving only the namespaced typedef + } _VAMP_SDK_HOSTSPACE_BEGIN(PluginInputDomainAdapter.cpp) @@ -102,24 +120,25 @@ int m_stepSize; int m_blockSize; float **m_freqbuf; - float *m_ri; + Kiss::kiss_fft_scalar *m_ri; WindowType m_windowType; - Window *m_window; + typedef Window W; + W *m_window; ProcessTimestampMethod m_method; int m_processCount; float **m_shiftBuffers; - KissSingle::kiss_fftr_cfg m_cfg; - KissSingle::kiss_fft_cpx *m_cbuf; + Kiss::kiss_fftr_cfg m_cfg; + Kiss::kiss_fft_cpx *m_cbuf; FeatureSet processShiftingTimestamp(const float *const *inputBuffers, RealTime timestamp); FeatureSet processShiftingData(const float *const *inputBuffers, RealTime timestamp); size_t makeBlockSizeAcceptable(size_t) const; - Window::WindowType convertType(WindowType t) const; + W::WindowType convertType(WindowType t) const; }; PluginInputDomainAdapter::PluginInputDomainAdapter(Plugin *plugin) : @@ -236,7 +255,7 @@ delete[] m_freqbuf; delete[] m_ri; if (m_cfg) { - KissSingle::kiss_fftr_free(m_cfg); + Kiss::kiss_fftr_free(m_cfg); m_cfg = 0; delete[] m_cbuf; m_cbuf = 0; @@ -279,7 +298,7 @@ delete[] m_freqbuf; delete[] m_ri; if (m_cfg) { - KissSingle::kiss_fftr_free(m_cfg); + Kiss::kiss_fftr_free(m_cfg); m_cfg = 0; delete[] m_cbuf; m_cbuf = 0; @@ -295,12 +314,12 @@ for (int c = 0; c < m_channels; ++c) { m_freqbuf[c] = new float[m_blockSize + 2]; } - m_ri = new float[m_blockSize]; + m_ri = new Kiss::kiss_fft_scalar[m_blockSize]; - m_window = new Window(convertType(m_windowType), m_blockSize); + m_window = new W(convertType(m_windowType), m_blockSize); - m_cfg = KissSingle::kiss_fftr_alloc(m_blockSize, false, 0, 0); - m_cbuf = new KissSingle::kiss_fft_cpx[m_blockSize/2+1]; + m_cfg = Kiss::kiss_fftr_alloc(m_blockSize, false, 0, 0); + m_cbuf = new Kiss::kiss_fft_cpx[m_blockSize/2+1]; m_processCount = 0; @@ -393,7 +412,7 @@ m_windowType = t; if (m_window) { delete m_window; - m_window = new Window(convertType(m_windowType), m_blockSize); + m_window = new W(convertType(m_windowType), m_blockSize); } } @@ -403,26 +422,26 @@ return m_windowType; } -Window::WindowType +PluginInputDomainAdapter::Impl::W::WindowType PluginInputDomainAdapter::Impl::convertType(WindowType t) const { switch (t) { case RectangularWindow: - return Window::RectangularWindow; + return W::RectangularWindow; case BartlettWindow: - return Window::BartlettWindow; + return W::BartlettWindow; case HammingWindow: - return Window::HammingWindow; + return W::HammingWindow; case HanningWindow: - return Window::HanningWindow; + return W::HanningWindow; case BlackmanWindow: - return Window::BlackmanWindow; + return W::BlackmanWindow; case NuttallWindow: - return Window::NuttallWindow; + return W::NuttallWindow; case BlackmanHarrisWindow: - return Window::BlackmanHarrisWindow; + return W::BlackmanHarrisWindow; default: - return Window::HanningWindow; + return W::HanningWindow; } } @@ -467,12 +486,12 @@ for (int i = 0; i < m_blockSize/2; ++i) { // FFT shift - float value = m_ri[i]; + Kiss::kiss_fft_scalar value = m_ri[i]; m_ri[i] = m_ri[i + m_blockSize/2]; m_ri[i + m_blockSize/2] = value; } - KissSingle::kiss_fftr(m_cfg, m_ri, m_cbuf); + Kiss::kiss_fftr(m_cfg, m_ri, m_cbuf); for (int i = 0; i <= m_blockSize/2; ++i) { m_freqbuf[c][i * 2] = m_cbuf[i].r; @@ -516,12 +535,12 @@ for (int i = 0; i < m_blockSize/2; ++i) { // FFT shift - float value = m_ri[i]; + Kiss::kiss_fft_scalar value = m_ri[i]; m_ri[i] = m_ri[i + m_blockSize/2]; m_ri[i + m_blockSize/2] = value; } - KissSingle::kiss_fftr(m_cfg, m_ri, m_cbuf); + Kiss::kiss_fftr(m_cfg, m_ri, m_cbuf); for (int i = 0; i <= m_blockSize/2; ++i) { m_freqbuf[c][i * 2] = m_cbuf[i].r; diff -r d3f676c07359 -r 7bab0c5422f4 src/vamp-hostsdk/PluginSummarisingAdapter.cpp --- a/src/vamp-hostsdk/PluginSummarisingAdapter.cpp Thu Aug 18 12:03:09 2016 +0100 +++ b/src/vamp-hostsdk/PluginSummarisingAdapter.cpp Thu Aug 18 14:43:52 2016 +0100 @@ -868,10 +868,19 @@ map distribution; +#ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER + cerr << "summing (discrete): "; +#endif for (int k = 0; k < sz; ++k) { +#ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER + cerr << accumulator.results[k].values[bin] << " "; +#endif summary.sum += accumulator.results[k].values[bin]; distribution[accumulator.results[k].values[bin]] += 1; } +#ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER + cerr << endl; +#endif int md = 0; @@ -908,11 +917,21 @@ double sum_c = 0.0; +#ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER + cerr << "summing (continuous): "; +#endif for (int k = 0; k < sz; ++k) { +#ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER + cerr << accumulator.results[k].values[bin] << "*" + << toSec(accumulator.results[k].duration) << " "; +#endif double value = accumulator.results[k].values[bin] * toSec(accumulator.results[k].duration); sum_c += value; } +#ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER + cerr << endl; +#endif #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER cerr << "mean_c = " << sum_c << " / " << totalDuration << " = " diff -r d3f676c07359 -r 7bab0c5422f4 src/vamp-hostsdk/Window.h --- a/src/vamp-hostsdk/Window.h Thu Aug 18 12:03:09 2016 +0100 +++ b/src/vamp-hostsdk/Window.h Thu Aug 18 14:43:52 2016 +0100 @@ -76,8 +76,8 @@ void cut(T *src, T *dst) const { for (size_t i = 0; i < m_size; ++i) dst[i] = src[i] * m_cache[i]; } - template - void cut(T0 *src, T *dst) const { + template + void cut(T0 *src, T1 *dst) const { for (size_t i = 0; i < m_size; ++i) dst[i] = src[i] * m_cache[i]; }