fun_ofdm  1.0
802.11a Physical Layer for USRP
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Macros Pages
symbol_mapper.cpp
Go to the documentation of this file.
1 
9 #include <cstring>
10 #include <assert.h>
11 
12 #include "symbol_mapper.h"
13 
14 namespace fun
15 {
16 
24  const std::vector<unsigned char> symbol_mapper::m_active_map =
25  {
26  0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,
27  1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
28  1, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0
29  };
30 
38  const double symbol_mapper::POLARITY[127] =
39  {
40  1, 1, 1, 1,-1,-1,-1, 1,-1,-1,-1,-1, 1, 1,-1, 1,
41  -1,-1, 1, 1,-1, 1, 1,-1, 1, 1, 1, 1, 1, 1,-1, 1,
42  1, 1,-1, 1, 1,-1,-1, 1, 1, 1,-1, 1,-1,-1,-1, 1,
43  -1, 1,-1,-1, 1,-1,-1, 1, 1, 1, 1, 1,-1,-1, 1, 1,
44  -1,-1, 1,-1, 1,-1, 1, 1,-1,-1,-1, 1, 1,-1,-1,-1,
45  -1, 1,-1,-1, 1,-1, 1, 1, 1, 1,-1, 1,-1, 1,-1, 1,
46  -1,-1,-1,-1,-1, 1,-1, 1, 1,-1, 1,-1, 1, 1, 1,-1,
47  -1, 1,-1,-1,-1, 1, 1, 1,-1,-1,-1,-1,-1,-1,-1
48  };
49 
55  const std::complex<double> symbol_mapper::PILOTS[4] =
56  {
57  { 1, 0},
58  { 1, 0},
59  { 1, 0},
60  {-1, 0}
61  };
62 
69  m_data_subcarrier_count(48),
70  m_pilot_count(4)
71  {
72  }
73 
81  std::vector<std::complex<double> > symbol_mapper::map(std::vector<std::complex<double> > data_samples)
82  {
83  assert(data_samples.size() % m_data_subcarrier_count == 0);
84 
85  std::complex<double> pilot_value = std::complex<double>(1, 0);
86  std::complex<double> null_value = std::complex<double>(0, 0);
87 
88  std::vector<std::complex<double> > samples(data_samples.size() * m_active_map.size() / m_data_subcarrier_count);
89  int out_index = 0, in_index = 0;
90  int symbol_count = 0;
91 
92  for(int x = 0; x < data_samples.size(); x+= m_data_subcarrier_count)
93  {
94  int pilot_index = 0;
95  for(int s = 0; s < m_active_map.size(); s++)
96  {
97  switch(m_active_map[s])
98  {
99  // Null subcarrier
100  case 0:
101  samples[out_index++] = null_value;
102  break;
103 
104  // Data subcarrier
105  case 1:
106  samples[out_index++] = data_samples[in_index++];
107  break;
108 
109  // Pilot subcarrier
110  case 2:
111  samples[out_index++] = PILOTS[pilot_index++] * POLARITY[symbol_count % 127];
112  break;
113  }
114  }
115  symbol_count++;
116  }
117 
118  return samples;
119  }
120 
121  // Remove pilots and null subcarriers, leaving only data subcarriers
128  std::vector<std::complex<double> > symbol_mapper::demap(std::vector<std::complex<double> > samples)
129  {
130  assert(samples.size() % m_active_map.size() == 0);
131 
132  std::vector<std::complex<double> > data_samples(samples.size() * m_data_subcarrier_count / m_active_map.size());
133  int out_index = 0;
134  for(int x = 0; x < samples.size(); x++)
135  {
136  int index = x % m_active_map.size();
137  if(m_active_map[index] == 1)
138  data_samples[out_index++] = samples[x];
139  }
140 
141  return data_samples;
142  }
143 
144  // Get the active subcarrier map
145  std::vector<unsigned char> symbol_mapper::get_active_map()
146  {
147  return m_active_map;
148  }
149 
150 }
151