16 #include <gsl/gsl_sf.h>
17 #define bessel_i0 gsl_sf_bessel_I0
21 int length = lrint(pow(2.0, (ceil(log(length0) / log(2.0)))));
22 length = std::min(length, (
int)lrint(pow(2.0, (ceil(log(length0 / 3.0) / log(2.0))))) * 3);
23 length = std::min(length, (
int)lrint(pow(2.0, (ceil(log(length0 / 5.0) / log(2.0))))) * 5);
24 length = std::min(length, (
int)lrint(pow(2.0, (ceil(log(length0 / 7.0) / log(2.0))))) * 7);
25 length = std::min(length, (
int)lrint(pow(2.0, (ceil(log(length0 / 9.0) / log(2.0))))) * 9);
26 assert(length0 <= length);
31 double FFTBase::windowFuncRect(
double x) {
32 return (fabs(x) <= 0.5) ? 1 : 0;
35 double FFTBase::windowFuncTri(
double x) {
36 return std::max(0.0, 1.0 - 2.0 * fabs(x));
38 double FFTBase::windowFuncHanning(
double x) {
41 return 0.5 + 0.5*cos(2*M_PI*x);
43 double FFTBase::windowFuncHamming(
double x) {
46 return 0.54 + 0.46*cos(2*M_PI*x);
48 double FFTBase::windowFuncBlackman(
double x) {
51 return 0.42323+0.49755*cos(2*M_PI*x)+0.07922*cos(4*M_PI*x);
53 double FFTBase::windowFuncBlackmanHarris(
double x) {
56 return 0.35875+0.48829*cos(2*M_PI*x)+0.14128*cos(4*M_PI*x)+0.01168*cos(6*M_PI*x);
58 double FFTBase::windowFuncFlatTop(
double x) {
59 return windowFuncHamming(x)*((fabs(x) < 1e-4) ? 1 : sin(4*M_PI*x)/(4*M_PI*x));
61 double FFTBase::windowFuncKaiser(
double x,
double alpha) {
65 x = sqrt(std::max(1 - x*x, 0.0));
66 return bessel_i0(M_PI*alpha*x) / bessel_i0(M_PI*alpha);
68 double FFTBase::windowFuncKaiser1(
double x) {
69 return windowFuncKaiser(x, 3.0);
71 double FFTBase::windowFuncKaiser2(
double x) {
72 return windowFuncKaiser(x, 7.2);
74 double FFTBase::windowFuncKaiser3(
double x) {
75 return windowFuncKaiser(x, 15.0);
78 double FFTBase::windowFuncFlatTopLong(
double x) {
79 return windowFuncHamming(x)*((fabs(x) < 1e-4) ? 1 : sin(6*M_PI*x)/(6*M_PI*x));
81 double FFTBase::windowFuncFlatTopLongLong(
double x) {
82 return windowFuncHamming(x)*((fabs(x) < 1e-4) ? 1 : sin(8*M_PI*x)/(8*M_PI*x));
84 double FFTBase::windowFuncHalfSin(
double x) {
91 FFTBase::FFTBase(
int length) {
93 m_fftplan.reset(
new fftw_plan);
96 fftw_destroy_plan(*m_fftplan);
99 m_pBufin = (fftw_complex*)fftw_malloc(
sizeof(fftw_complex) * length);
100 m_pBufout = (fftw_complex*)fftw_malloc(
sizeof(fftw_complex) * length);
101 *m_fftplan = fftw_plan_dft_1d(length, m_pBufin, m_pBufout,
102 (sign > 0) ? FFTW_BACKWARD : FFTW_FORWARD, FFTW_ESTIMATE);
106 fftw_free(m_pBufout);
109 FFT::exec(
const std::vector<std::complex<double> >& wavein,
110 std::vector<std::complex<double> >& waveout) {
111 int size = wavein.size();
112 assert(size == length());
113 waveout.resize(size);
114 const std::complex<double> *pin = &wavein[0];
115 fftw_complex *pout = m_pBufin;
116 for(
int i = 0; i < size; i++) {
117 ( *pout)[0] = pin->real();
118 ( *pout)[1] = pin->imag();
122 fftw_execute( *m_fftplan);
123 const fftw_complex *pin2 = m_pBufout;
124 std::complex<double> *pout2 = &waveout[0];
125 for(
int i = 0; i < size; i++) {
126 *pout2 = std::complex<double>(( *pin2)[0], ( *pin2)[1]);
133 m_pBufin = (
double*)fftw_malloc(
sizeof(
double) * length);
134 m_pBufout = (fftw_complex*)fftw_malloc(
sizeof(fftw_complex) * (length / 2 + 1));
135 *m_fftplan = fftw_plan_dft_r2c_1d(length, m_pBufin, m_pBufout, FFTW_ESTIMATE);
139 fftw_free(m_pBufout);
142 RFFT::exec(
const std::vector<double>& wavein,
143 std::vector<std::complex<double> >& waveout) {
144 int size = wavein.size();
145 assert(size == length());
146 waveout.resize(size / 2 + 1);
147 const double *pin = &wavein[0];
148 double *pout = m_pBufin;
149 for(
int i = 0; i < size; i++) {
152 fftw_execute(*m_fftplan);
153 const fftw_complex *pin2 = m_pBufout;
154 std::complex<double> *pout2 = &waveout[0];
155 for(
int i = 0; i < size / 2 + 1; i++) {
156 *pout2 = std::complex<double>(( *pin2)[0], ( *pin2)[1]);
163 m_pBufin = (fftw_complex*)fftw_malloc(
sizeof(fftw_complex) * (length / 2 + 1));
164 m_pBufout = (
double*)fftw_malloc(
sizeof(
double) * length);
165 *m_fftplan = fftw_plan_dft_c2r_1d(length, m_pBufin, m_pBufout, FFTW_ESTIMATE);
169 fftw_free(m_pBufout);
172 RIFFT::exec(
const std::vector<std::complex<double> >& wavein,
173 std::vector<double>& waveout) {
175 assert((
int)wavein.size() == length() / 2 + 1);
176 waveout.resize(size);
177 const std::complex<double> *pin = &wavein[0];
178 fftw_complex *pout = m_pBufin;
179 for(
int i = 0; i < size / 2 + 1; i++) {
180 ( *pout)[0] = pin->real();
181 ( *pout)[1] = pin->imag();
185 fftw_execute( *m_fftplan);
186 const double *pin2 = m_pBufout;
187 double *pout2 = &waveout[0];
188 for(
int i = 0; i < size; i++) {