GNU Radio 3.5.3.2 C++ API
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 
124  float get_distance(unsigned int index, const gr_complex *sample);
125  unsigned int get_closest_point(const gr_complex *sample);
126  void calc_arity ();
127 };
128 
129 /************************************************************/
130 /* digital_constellation_calcdist */
131 /* */
132 /************************************************************/
133 
136 
137 // public constructor
139 digital_make_constellation_calcdist (std::vector<gr_complex> constellation,
140  std::vector<unsigned int> pre_diff_code,
141  unsigned int rotational_symmetry,
142  unsigned int dimensionality);
143 
144 
145 /*! \brief Calculate Euclidian distance for any constellation
146  * \ingroup digital
147  *
148  * Constellation which calculates the distance to each point in the
149  * constellation for decision making. Inefficient for large
150  * constellations.
151  */
153 {
154  public:
155  digital_constellation_calcdist (std::vector<gr_complex> constellation,
156  std::vector<unsigned int> pre_diff_code,
157  unsigned int rotational_symmetry,
158  unsigned int dimensionality);
159  unsigned int decision_maker (const gr_complex *sample);
160  // void calc_metric(gr_complex *sample, float *metric, trellis_metric_type_t type);
161  // void calc_euclidean_metric(gr_complex *sample, float *metric);
162  // void calc_hard_symbol_metric(gr_complex *sample, float *metric);
163 
164  private:
166  digital_make_constellation_calcdist (std::vector<gr_complex> constellation);
167 };
168 
169 
170 /************************************************************/
171 /*! digital_constellation_sector */
172 /************************************************************/
173 
174 /*!
175  * \brief Sectorized digital constellation
176  * \ingroup digital
177  *
178  * Constellation space is divided into sectors. Each sector is
179  * associated with the nearest constellation point.
180  *
181  */
183 {
184  public:
185 
186  digital_constellation_sector (std::vector<gr_complex> constellation,
187  std::vector<unsigned int> pre_diff_code,
188  unsigned int rotational_symmetry,
189  unsigned int dimensionality,
190  unsigned int n_sectors);
191 
192  unsigned int decision_maker (const gr_complex *sample);
193 
194  protected:
195 
196  virtual unsigned int get_sector (const gr_complex *sample) = 0;
197  virtual unsigned int calc_sector_value (unsigned int sector) = 0;
198  void find_sector_values ();
199 
200  unsigned int n_sectors;
201 
202  private:
203 
204  std::vector<unsigned int> sector_values;
205 
206 };
207 
208 /************************************************************/
209 /* digital_constellation_rect */
210 /************************************************************/
211 
212 /*!
213  * \brief Rectangular digital constellation
214  * \ingroup digital
215  *
216  * Only implemented for 1-(complex)dimensional constellation.
217  *
218  * Constellation space is divided into rectangular sectors. Each
219  * sector is associated with the nearest constellation point.
220  *
221  * Works well for square QAM.
222  *
223  * Works for any generic constellation provided sectors are not too
224  * large.
225  */
226 
229 
230 // public constructor
232 digital_make_constellation_rect (std::vector<gr_complex> constellation,
233  std::vector<unsigned int> pre_diff_code,
234  unsigned int rotational_symmetry,
235  unsigned int real_sectors,
236  unsigned int imag_sectors,
237  float width_real_sectors,
238  float width_imag_sectors);
239 
241 {
242  public:
243 
244  digital_constellation_rect (std::vector<gr_complex> constellation,
245  std::vector<unsigned int> pre_diff_code,
246  unsigned int rotational_symmetry,
247  unsigned int real_sectors,
248  unsigned int imag_sectors,
249  float width_real_sectors,
250  float width_imag_sectors);
251 
252  protected:
253 
254  unsigned int get_sector (const gr_complex *sample);
255 
256  unsigned int calc_sector_value (unsigned int sector);
257 
258  private:
259 
260  unsigned int n_real_sectors;
261  unsigned int n_imag_sectors;
262  float d_width_real_sectors;
263  float d_width_imag_sectors;
264 
266  digital_make_constellation_rect (std::vector<gr_complex> constellation,
267  std::vector<unsigned int> pre_diff_code,
268  unsigned int rotational_symmetry,
269  unsigned int real_sectors,
270  unsigned int imag_sectors,
271  float width_real_sectors,
272  float width_imag_sectors);
273 
274 };
275 
276 
277 /************************************************************/
278 /* digital_constellation_psk */
279 /************************************************************/
280 
283 
284 // public constructor
286 digital_make_constellation_psk (std::vector<gr_complex> constellation,
287  std::vector<unsigned int> pre_diff_code,
288  unsigned int n_sectors);
289 
290 /*!
291  * \brief digital_constellation_psk
292  * \ingroup digital
293  *
294  * Constellation space is divided into pie slices sectors.
295  *
296  * Each slice is associated with the nearest constellation point.
297  *
298  * Works well for PSK but nothing else.
299  *
300  * Assumes that there is a constellation point at 1.x
301  */
303 {
304  public:
305 
306  digital_constellation_psk (std::vector<gr_complex> constellation,
307  std::vector<unsigned int> pre_diff_code,
308  unsigned int n_sectors);
309 
310  protected:
311 
312  unsigned int get_sector (const gr_complex *sample);
313 
314  unsigned int calc_sector_value (unsigned int sector);
315 
316  private:
317 
319  digital_make_constellation_psk (std::vector<gr_complex> constellation,
320  std::vector<unsigned int> pre_diff_code,
321  unsigned int n_sectors);
322 
323 };
324 
325 
326 /************************************************************/
327 /* digital_constellation_bpsk */
328 /* */
329 /* Only works for BPSK. */
330 /* */
331 /************************************************************/
332 
335 
336 // public constructor
339 
340 /*!
341  * \brief Digital constellation for BPSK
342  * \ingroup digital
343  */
345 {
346  public:
347 
349  unsigned int decision_maker (const gr_complex *sample);
350 
353 
354 };
355 
356 
357 /************************************************************/
358 /* digital_constellation_qpsk */
359 /* */
360 /* Only works for QPSK. */
361 /* */
362 /************************************************************/
363 
366 
367 // public constructor
370 
371 /*!
372  * \brief Digital constellation for QPSK
373  * \ingroup digital
374  */
376 {
377  public:
378 
380  unsigned int decision_maker (const gr_complex *sample);
381 
384 
385 };
386 
387 
388 /************************************************************/
389 /* digital_constellation_dqpsk */
390 /* */
391 /* Works with differential encoding; slower decisions. */
392 /* */
393 /************************************************************/
394 
397 
398 // public constructor
401 
402 /*!
403  * \brief Digital constellation for DQPSK
404  * \ingroup digital
405  */
407 {
408  public:
409 
411  unsigned int decision_maker (const gr_complex *sample);
412 
415 
416 };
417 
418 
419 /************************************************************/
420 /* digital_constellation_8psk */
421 /* */
422 /* Only works for 8PSK. */
423 /* */
424 /************************************************************/
425 
428 
429 // public constructor
432 
433 /*!
434  * \brief Digital constellation for 8PSK
435  * \ingroup digital
436  */
438 {
439  public:
440 
442  unsigned int decision_maker (const gr_complex *sample);
443 
446 
447 };
448 
449 #endif