91 lines
5.3 KiB
C++
91 lines
5.3 KiB
C++
/*
|
|
PIP - Platform Independent Primitives
|
|
Class for FFT, IFFT and Hilbert transformations
|
|
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU Lesser General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
|
|
#include "pifft.h"
|
|
#include "pifftw_p.h"
|
|
#include "pip_fftw_export.h"
|
|
|
|
#include <fftw3.h>
|
|
|
|
|
|
PIFFTWCommon & PIFFTWCommon::instance() {
|
|
static PIFFTWCommon ret;
|
|
return ret;
|
|
}
|
|
|
|
|
|
#define FFTW_IMPLEMENTATION(T, PREFIX) \
|
|
PIP_FFTW_EXPORT void * FFTWInterface<T>::createPlan_c2c_1d(int size, const void * in, void * out, bool hard, bool forward) { \
|
|
int flags = FFTW_UNALIGNED | (hard ? FFTW_MEASURE : FFTW_ESTIMATE); \
|
|
return PREFIX##_plan_dft_1d(size, (PREFIX##_complex *)in, (PREFIX##_complex *)out, forward ? FFTW_FORWARD : FFTW_BACKWARD, flags); \
|
|
} \
|
|
PIP_FFTW_EXPORT void * FFTWInterface<T>::createPlan_r2c_1d(int size, const void * in, void * out, bool hard) { \
|
|
int flags = FFTW_UNALIGNED | (hard ? FFTW_MEASURE : FFTW_ESTIMATE); \
|
|
return PREFIX##_plan_dft_r2c_1d(size, (T *)in, (PREFIX##_complex *)out, flags); \
|
|
} \
|
|
PIP_FFTW_EXPORT void FFTWInterface<T>::executePlan_c2c(void * plan, const void * in, void * out) { \
|
|
PREFIX##_execute_dft((PREFIX##_plan)plan, (PREFIX##_complex *)in, (PREFIX##_complex *)out); \
|
|
} \
|
|
PIP_FFTW_EXPORT void FFTWInterface<T>::executePlan_r2c(void * plan, const void * in, void * out) { \
|
|
PREFIX##_execute_dft_r2c((PREFIX##_plan)plan, (T *)in, (PREFIX##_complex *)out); \
|
|
} \
|
|
PIP_FFTW_EXPORT void FFTWInterface<T>::destroyPlan(void *& plan) { \
|
|
if (plan) PREFIX##_destroy_plan((PREFIX##_plan)plan); \
|
|
plan = nullptr; \
|
|
}
|
|
|
|
#define PIFFTW_SPECIFY(T) \
|
|
PRIVATE_DEFINITION_START(PIFFTW<T>) \
|
|
FFTW<T> fftw; \
|
|
PRIVATE_DEFINITION_END(PIFFTW<T>) \
|
|
const PIVector<complex<T>> & PIFFTW<T>::calcFFT(const PIVector<complex<T>> & in) { \
|
|
PRIVATE->fftw.calcFFT(in, m_result); \
|
|
return m_result; \
|
|
} \
|
|
const PIVector<complex<T>> & PIFFTW<T>::calcFFT(const PIVector<T> & in) { \
|
|
PRIVATE->fftw.calcFFT(in, m_result); \
|
|
return m_result; \
|
|
} \
|
|
const PIVector<complex<T>> & PIFFTW<T>::calcFFTinverse(const PIVector<complex<T>> & in) { \
|
|
PRIVATE->fftw.calcFFTinverse(in, m_result); \
|
|
return m_result; \
|
|
} \
|
|
bool PIFFTW<T>::prepareForSize(size_t count) { \
|
|
return PRIVATE->fftw.preparePlans(count); \
|
|
}
|
|
|
|
|
|
#ifdef PIP_FFTWf
|
|
FFTW_IMPLEMENTATION(float, fftwf)
|
|
PIFFTW_SPECIFY(float)
|
|
#endif // PIP_FFTWf
|
|
|
|
|
|
#ifdef PIP_FFTW
|
|
FFTW_IMPLEMENTATION(double, fftw)
|
|
PIFFTW_SPECIFY(double)
|
|
#endif // PIP_FFTW
|
|
|
|
|
|
#ifdef PIP_FFTWl
|
|
FFTW_IMPLEMENTATION(ldouble, fftwl)
|
|
PIFFTW_SPECIFY(ldouble)
|
|
#endif // PIP_FFTWl
|