fun_ofdm  1.0
802.11a Physical Layer for USRP
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Macros Pages
modulator.cpp
Go to the documentation of this file.
1 
13 #include <cstring>
14 
15 #include "modulator.h"
16 #include "qam.h"
17 
18 namespace fun
19 {
20 
29  std::vector<std::complex<double> > modulator::modulate(std::vector<unsigned char> data, Rate rate)
30  {
31  // Modualate the data
32  int modulated_sample_count = data.size();
33  std::vector<double> data_mod_buffer;
34  switch(rate)
35  {
36  // BPSK
37  case RATE_1_2_BPSK: case RATE_2_3_BPSK: case RATE_3_4_BPSK:
38  {
39  QAM<1> bpsk(1.0);
40  data_mod_buffer = std::vector<double>(modulated_sample_count * 2, 0);
41  for(int x = 0; x < modulated_sample_count; x++)
42  {
43  bpsk.encode((const char *)&data[x], &data_mod_buffer[x*2]);
44  }
45 
46  break;
47  }
48 
49  // QPSK
50  case RATE_1_2_QPSK: case RATE_2_3_QPSK: case RATE_3_4_QPSK:
51  {
52  QAM<1> qpsk(0.5);
53  modulated_sample_count /= 2;
54  data_mod_buffer = std::vector<double>(modulated_sample_count * 2, 0);
55  for(int x = 0; x < modulated_sample_count; x++)
56  {
57  qpsk.encode((const char *)&data[x*2], &data_mod_buffer[x*2]);
58  qpsk.encode((const char *)&data[x*2+1], &data_mod_buffer[x*2+1]);
59  }
60 
61  break;
62  }
63 
64  // QAM16
66  {
67  QAM<2> qam16(0.5);
68  modulated_sample_count /= 4;
69  data_mod_buffer = std::vector<double>(modulated_sample_count * 2, 0);
70  for(int x = 0; x < modulated_sample_count; x++)
71  {
72  qam16.encode((const char *)&data[x*4], &data_mod_buffer[x*2]);
73  qam16.encode((const char *)&data[x*4+2], &data_mod_buffer[x*2+1]);
74  }
75 
76  break;
77  }
78 
79  // QAM64
80  case RATE_2_3_QAM64: case RATE_3_4_QAM64:
81  {
82  QAM<3> qam64(0.5);
83  modulated_sample_count /= 6;
84  data_mod_buffer = std::vector<double>(modulated_sample_count * 2, 0);
85  for(int x = 0; x < modulated_sample_count; x++)
86  {
87  qam64.encode((const char *)&data[x*6], &data_mod_buffer[x*2]);
88  qam64.encode((const char *)&data[x*6+3], &data_mod_buffer[x*2+1]);
89  }
90 
91  break;
92  }
93  }
94 
95  std::vector<std::complex<double> > modulated_data(data_mod_buffer.size() / 2);
96  memcpy(&modulated_data[0], &data_mod_buffer[0], modulated_data.size() * sizeof(std::complex<double>));
97  return modulated_data;
98  }
99 
108  std::vector<unsigned char> modulator::demodulate(std::vector<std::complex<double> > data, Rate rate)
109  {
110  RateParams rp = RateParams(rate);
111 
112  // Demodulate the data
113  int coded_bit_count = data.size();
114  std::vector<unsigned char>data_demodulated(coded_bit_count * rp.bpsc, 0);
115  switch(rate)
116  {
117  // BPSK
118  case RATE_1_2_BPSK: case RATE_2_3_BPSK: case RATE_3_4_BPSK:
119  {
120  QAM<1> bpsk(1.0);
121  for(int s = 0; s < coded_bit_count; s++)
122  bpsk.decode(data[s].real(), &data_demodulated[s]);
123  break;
124  }
125 
126  // QPSK
127  case RATE_1_2_QPSK: case RATE_2_3_QPSK: case RATE_3_4_QPSK:
128  {
129  QAM<1> qpsk(0.5);
130  for(int s = 0; s < coded_bit_count; s++)
131  {
132  qpsk.decode(data[s].real(), &data_demodulated[s*2]);
133  qpsk.decode(data[s].imag(), &data_demodulated[s*2+1]);
134  }
135  break;
136  }
137 
138  // QAM16
140  {
141  QAM<2> qam16(0.5);
142  for(int s = 0; s < coded_bit_count; s++)
143  {
144  qam16.decode(data[s].real(), &data_demodulated[s*4]);
145  qam16.decode(data[s].imag(), &data_demodulated[s*4+2]);
146  }
147  break;
148  }
149 
150  // QAM64
151  case RATE_2_3_QAM64: case RATE_3_4_QAM64:
152  {
153  QAM<3> qam64(0.5);
154  for(int s = 0; s < coded_bit_count; s++)
155  {
156  qam64.decode(data[s].real(), &data_demodulated[s*6]);
157  qam64.decode(data[s].imag(), &data_demodulated[s*6+3]);
158  }
159  break;
160  }
161  }
162 
163  return data_demodulated;
164  }
165 }
166