gr-baz Package
digital_constellation.h
Go to the documentation of this file.
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2010, 2011 Free Software Foundation, Inc.
4  *
5  * This file is part of GNU Radio
6  *
7  * GNU Radio is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3, or (at your option)
10  * any later version.
11  *
12  * GNU Radio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with GNU Radio; see the file COPYING. If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street,
20  * Boston, MA 02110-1301, USA.
21  */
22 
23 #ifndef INCLUDED_DIGITAL_CONSTELLATION_H
24 #define INCLUDED_DIGITAL_CONSTELLATION_H
25 
26 #include <digital_api.h>
27 #include <vector>
28 #include <math.h>
29 #include <gr_complex.h>
30 #include <boost/enable_shared_from_this.hpp>
31 #include <digital_metric_type.h>
32 
33 /************************************************************/
34 /* digital_constellation */
35 /* */
36 /* Base class defining interface. */
37 /************************************************************/
38 
41 
42 /*!
43  * \brief An abstracted constellation object
44  * \ingroup digital
45  *
46  * The constellation objects hold the necessary information to pass
47  * around constellation information for modulators and
48  * demodulators. These objects contain the mapping between the bits
49  * and the constellation points used to represent them as well as
50  * methods for slicing the symbol space. Various implementations are
51  * possible for efficiency and ease of use.
52  *
53  * Standard constellations (BPSK, QPSK, QAM, etc) can be inherited
54  * from this class and overloaded to perform optimized slicing and
55  * constellation mappings.
56  */
57 class DIGITAL_API digital_constellation : public boost::enable_shared_from_this<digital_constellation>
58 {
59 public:
60  digital_constellation (std::vector<gr_complex> constellation,
61  std::vector<unsigned int> pre_diff_code,
62  unsigned int rotational_symmetry,
63  unsigned int dimensionality);
65 
66  //! Returns the constellation points for a symbol value
67  void map_to_points(unsigned int value, gr_complex *points);
68  std::vector<gr_complex> map_to_points_v(unsigned int value);
69 
70  //! Returns the constellation point that matches best.
71  virtual unsigned int decision_maker (const gr_complex *sample) = 0;
72  //! Takes a vector rather than a pointer. Better for SWIG wrapping.
73  unsigned int decision_maker_v (std::vector<gr_complex> sample);
74  //! Also calculates the phase error.
75  unsigned int decision_maker_pe (const gr_complex *sample, float *phase_error);
76  //! Calculates distance.
77  unsigned int decision_maker_e (const gr_complex *sample, float *error);
78 
79  //! Calculates metrics for all points in the constellation.
80  //! For use with the viterbi algorithm.
81  virtual void calc_metric(const gr_complex *sample, float *metric, trellis_metric_type_t type);
82  virtual void calc_euclidean_metric(const gr_complex *sample, float *metric);
83  virtual void calc_hard_symbol_metric(const gr_complex *sample, float *metric);
84 
85  //! Returns the set of points in this constellation.
86  std::vector<gr_complex> points() { return d_constellation;}
87  //! Returns the vector of points in this constellation.
88  //! Raise error if dimensionality is not one.
89  std::vector<gr_complex> s_points();
90  //! Returns a vector of vectors of points.
91  std::vector<std::vector<gr_complex> > v_points();
92  //! Whether to apply an encoding before doing differential encoding. (e.g. gray coding)
93  bool apply_pre_diff_code() { return d_apply_pre_diff_code;}
94  //! Whether to apply an encoding before doing differential encoding. (e.g. gray coding)
95  void set_pre_diff_code(bool a) { d_apply_pre_diff_code = a;}
96  //! Returns the encoding to apply before differential encoding.
97  std::vector<unsigned int> pre_diff_code() { return d_pre_diff_code;}
98  //! Returns the order of rotational symmetry.
99  unsigned int rotational_symmetry() { return d_rotational_symmetry;}
100  //! Returns the number of complex numbers in a single symbol.
101  unsigned int dimensionality() {return d_dimensionality;}
102 
103  unsigned int bits_per_symbol () {
104  return floor(log(double(d_constellation.size()))/d_dimensionality/log(2.0));
105  }
106 
107  unsigned int arity () {
108  return d_arity;
109  }
110 
112  return shared_from_this();
113  }
114 
115  protected:
116 
117  std::vector<gr_complex> d_constellation;
118  std::vector<unsigned int> d_pre_diff_code;
120  unsigned int d_rotational_symmetry;
121  unsigned int d_dimensionality;
122  unsigned int d_arity;
123  // The orignal constellation points were multiplied by this factor to get a
124  // constellation with average magnitude 1.
126 
127  float get_distance(unsigned int index, const gr_complex *sample);
128  unsigned int get_closest_point(const gr_complex *sample);
129  void calc_arity ();
130 };
131 
132 /************************************************************/
133 /* digital_constellation_calcdist */
134 /* */
135 /************************************************************/
136 
139 
140 // public constructor
142 digital_make_constellation_calcdist (std::vector<gr_complex> constellation,
143  std::vector<unsigned int> pre_diff_code,
144  unsigned int rotational_symmetry,
145  unsigned int dimensionality);
146 
147 
148 /*! \brief Calculate Euclidian distance for any constellation
149  * \ingroup digital
150  *
151  * Constellation which calculates the distance to each point in the
152  * constellation for decision making. Inefficient for large
153  * constellations.
154  */
156 {
157  public:
158  digital_constellation_calcdist (std::vector<gr_complex> constellation,
159  std::vector<unsigned int> pre_diff_code,
160  unsigned int rotational_symmetry,
161  unsigned int dimensionality);
162  unsigned int decision_maker (const gr_complex *sample);
163  // void calc_metric(gr_complex *sample, float *metric, trellis_metric_type_t type);
164  // void calc_euclidean_metric(gr_complex *sample, float *metric);
165  // void calc_hard_symbol_metric(gr_complex *sample, float *metric);
166 
167  private:
169  digital_make_constellation_calcdist (std::vector<gr_complex> constellation);
170 };
171 
172 
173 /************************************************************/
174 /*! digital_constellation_sector */
175 /************************************************************/
176 
177 /*!
178  * \brief Sectorized digital constellation
179  * \ingroup digital
180  *
181  * Constellation space is divided into sectors. Each sector is
182  * associated with the nearest constellation point.
183  *
184  */
186 {
187  public:
188 
189  digital_constellation_sector (std::vector<gr_complex> constellation,
190  std::vector<unsigned int> pre_diff_code,
191  unsigned int rotational_symmetry,
192  unsigned int dimensionality,
193  unsigned int n_sectors);
194 
195  unsigned int decision_maker (const gr_complex *sample);
196 
197  protected:
198 
199  virtual unsigned int get_sector (const gr_complex *sample) = 0;
200  virtual unsigned int calc_sector_value (unsigned int sector) = 0;
201  void find_sector_values ();
202 
203  unsigned int n_sectors;
204 
205  private:
206 
207  std::vector<unsigned int> sector_values;
208 
209 };
210 
211 /************************************************************/
212 /* digital_constellation_rect */
213 /************************************************************/
214 
215 /*!
216  * \brief Rectangular digital constellation
217  * \ingroup digital
218  *
219  * Only implemented for 1-(complex)dimensional constellation.
220  *
221  * Constellation space is divided into rectangular sectors. Each
222  * sector is associated with the nearest constellation point.
223  *
224  * Works well for square QAM.
225  *
226  * Works for any generic constellation provided sectors are not too
227  * large.
228  */
229 
232 
233 // public constructor
235 digital_make_constellation_rect (std::vector<gr_complex> constellation,
236  std::vector<unsigned int> pre_diff_code,
237  unsigned int rotational_symmetry,
238  unsigned int real_sectors,
239  unsigned int imag_sectors,
240  float width_real_sectors,
241  float width_imag_sectors);
242 
244 {
245  public:
246 
247  digital_constellation_rect (std::vector<gr_complex> constellation,
248  std::vector<unsigned int> pre_diff_code,
249  unsigned int rotational_symmetry,
250  unsigned int real_sectors,
251  unsigned int imag_sectors,
252  float width_real_sectors,
253  float width_imag_sectors);
254 
255  protected:
256 
257  unsigned int get_sector (const gr_complex *sample);
258 
259  unsigned int calc_sector_value (unsigned int sector);
260 
261  private:
262 
263  unsigned int n_real_sectors;
264  unsigned int n_imag_sectors;
265  float d_width_real_sectors;
266  float d_width_imag_sectors;
267 
269  digital_make_constellation_rect (std::vector<gr_complex> constellation,
270  std::vector<unsigned int> pre_diff_code,
271  unsigned int rotational_symmetry,
272  unsigned int real_sectors,
273  unsigned int imag_sectors,
274  float width_real_sectors,
275  float width_imag_sectors);
276 
277 };
278 
279 
280 /************************************************************/
281 /* digital_constellation_psk */
282 /************************************************************/
283 
286 
287 // public constructor
289 digital_make_constellation_psk (std::vector<gr_complex> constellation,
290  std::vector<unsigned int> pre_diff_code,
291  unsigned int n_sectors);
292 
293 /*!
294  * \brief digital_constellation_psk
295  * \ingroup digital
296  *
297  * Constellation space is divided into pie slices sectors.
298  *
299  * Each slice is associated with the nearest constellation point.
300  *
301  * Works well for PSK but nothing else.
302  *
303  * Assumes that there is a constellation point at 1.x
304  */
306 {
307  public:
308 
309  digital_constellation_psk (std::vector<gr_complex> constellation,
310  std::vector<unsigned int> pre_diff_code,
311  unsigned int n_sectors);
312 
313  protected:
314 
315  unsigned int get_sector (const gr_complex *sample);
316 
317  unsigned int calc_sector_value (unsigned int sector);
318 
319  private:
320 
322  digital_make_constellation_psk (std::vector<gr_complex> constellation,
323  std::vector<unsigned int> pre_diff_code,
324  unsigned int n_sectors);
325 
326 };
327 
328 
329 /************************************************************/
330 /* digital_constellation_bpsk */
331 /* */
332 /* Only works for BPSK. */
333 /* */
334 /************************************************************/
335 
338 
339 // public constructor
342 
343 /*!
344  * \brief Digital constellation for BPSK
345  * \ingroup digital
346  */
348 {
349  public:
350 
352  unsigned int decision_maker (const gr_complex *sample);
353 
356 
357 };
358 
359 
360 /************************************************************/
361 /* digital_constellation_qpsk */
362 /* */
363 /* Only works for QPSK. */
364 /* */
365 /************************************************************/
366 
369 
370 // public constructor
373 
374 /*!
375  * \brief Digital constellation for QPSK
376  * \ingroup digital
377  */
379 {
380  public:
381 
383  unsigned int decision_maker (const gr_complex *sample);
384 
387 
388 };
389 
390 
391 /************************************************************/
392 /* digital_constellation_dqpsk */
393 /* */
394 /* Works with differential encoding; slower decisions. */
395 /* */
396 /************************************************************/
397 
400 
401 // public constructor
404 
405 /*!
406  * \brief Digital constellation for DQPSK
407  * \ingroup digital
408  */
410 {
411  public:
412 
414  unsigned int decision_maker (const gr_complex *sample);
415 
418 
419 };
420 
421 
422 /************************************************************/
423 /* digital_constellation_8psk */
424 /* */
425 /* Only works for 8PSK. */
426 /* */
427 /************************************************************/
428 
431 
432 // public constructor
435 
436 /*!
437  * \brief Digital constellation for 8PSK
438  * \ingroup digital
439  */
441 {
442  public:
443 
445  unsigned int decision_maker (const gr_complex *sample);
446 
449 
450 };
451 
452 #endif