fun_ofdm  1.0
802.11a Physical Layer for USRP
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Macros Pages
qam.h
Go to the documentation of this file.
1 
9 #ifndef QAM_H
10 #define QAM_H
11 
12 #include <climits>
13 
14 namespace fun
15 {
16 
23  template<int NumBits>
24  class QAM
25  {
26  int d_gain;
27  double d_scale_e;
28  double d_scale_d;
29  public:
35  QAM (double power, int gain = 0)
36  {
37  d_gain = gain + CHAR_BIT - NumBits;
38  const int nn = (1<<(NumBits-1));
39  // sum((2k+1)^2,k=0..n-1)
40  #if 0
41  int sum2 = 0;
42  for (int i = 0; i < nn; ++i) {
43  sum2+= (2*i + 1)*(2*i + 1);
44  }
45  #else
46  int sum2 = (4*nn*nn*nn-nn)/3;
47  #endif
48  double sf = sqrt(power * double(nn) / double(sum2));
49  d_scale_e = sf;
50  d_scale_d = (1 << d_gain) / sf;
51  }
52 
58  static inline int sign(int v)
59  {
60  return +1 | (v >> (sizeof(int) * CHAR_BIT - 1));
61  }
62 
68  static inline int clamp(int i)
69  {
70  return i < 0 ? 0 : (i > 255 ? 255 : i);
71  }
72 
83  inline void encode (const char* bits, double *sym)
84  {
85  int pt = 0; // constellation point
86  int flip = 1; // +1 or -1 -- for gray coding
87  // unrolled with -O3
88  for (int i = 0; i < NumBits; ++i)
89  {
90  int bit = *bits * 2 - 1; // +1 or -1
91  pt = bit * flip + pt * 2;
92  flip *= -bit;
93  ++bits;
94  }
95  *sym = pt * d_scale_e;
96  }
97 
110  inline void decode (double sym, unsigned char *bits)
111  {
112  int pt = sym * d_scale_d;
113  int flip = 1; // +1 or -1 -- for gray coding
114  int amp = (1 << (NumBits-1)) << d_gain;
115  // unrolled with -O3
116  for (int i = 0; i < NumBits; ++i)
117  {
118  *bits = clamp(flip * pt + 128);
119  int bit = sign(pt);
120  pt -= bit * amp;
121  flip = -bit;
122  amp /= 2;
123  ++bits;
124  }
125  }
126  };
127 }
128 
129 #endif // QAM_H