fun_ofdm  1.0
802.11a Physical Layer for USRP
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Macros Pages
fft.cpp
Go to the documentation of this file.
1 
8 #include <cstring>
9 #include <assert.h>
10 
11 #include "fft.h"
12 
13 namespace fun
14 {
15 
20  const int fft::fft_map[64] =
21  {
22  32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
23  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
24  };
25 
30  fft::fft(int fft_length) :
31  m_fft_length(fft_length)
32  {
33  // Allocate the FFT buffers
34  m_fftw_in_forward = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * m_fft_length);
35  m_fftw_out_forward = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * m_fft_length);
36  m_fftw_in_inverse = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * m_fft_length);
37  m_fftw_out_inverse = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * m_fft_length);
38  m_fftw_plan_forward = fftw_plan_dft_1d(m_fft_length, m_fftw_in_forward, m_fftw_out_forward, FFTW_FORWARD, FFTW_MEASURE);
39  m_fftw_plan_inverse = fftw_plan_dft_1d(m_fft_length, m_fftw_in_inverse, m_fftw_out_inverse, FFTW_BACKWARD, FFTW_MEASURE);
40  }
41 
42 
50  void fft::forward(std::complex<double> data[64])
51  {
52  memcpy(m_fftw_in_forward, &data[0], m_fft_length * sizeof(std::complex<double>));
53  fftw_execute(m_fftw_plan_forward);
54 
55  for(int s = 0; s < 64; s++)
56  {
57  memcpy(&data[s], &m_fftw_out_forward[fft_map[s]], sizeof(std::complex<double>));
58  }
59  }
60 
68  void fft::inverse(std::vector<std::complex<double> > & data)
69  {
70  assert(data.size() % m_fft_length == 0);
71 
72  // Run the IFFT on each m_fft_length samples
73  for(int x = 0; x < data.size(); x += m_fft_length)
74  {
75  if(m_fft_length == 64)
76  {
77  for(int s = 0; s < 64; s++)
78  {
79  memcpy(&m_fftw_in_inverse[s], &data[x + fft_map[s]], sizeof(std::complex<double>));
80  }
81  }
82  else
83  {
84  memcpy(&m_fftw_in_inverse[0], &data[x], m_fft_length * sizeof(std::complex<double>));
85  }
86 
87  fftw_execute(m_fftw_plan_inverse);
88  memcpy(&data[x], m_fftw_out_inverse, m_fft_length * sizeof(std::complex<double>));
89  }
90 
91  // Scale by 1/fft_length
92  for(int x = 0; x < data.size(); x++)
93  {
94  data[x] /= m_fft_length;
95  }
96  }
97 }
98 
99