GNU Radio C++ API
digital_constellation_receiver_cb.h
Go to the documentation of this file.
1 /* -*- c++ -*- */
2 /*
3  * Copyright 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_RECEIVER_CB_H
24 #define INCLUDED_DIGITAL_CONSTELLATION_RECEIVER_CB_H
25 
26 #include <digital_api.h>
27 #include <gr_block.h>
28 #include <digital_constellation.h>
29 #include <gruel/attributes.h>
30 #include <gri_control_loop.h>
31 #include <gr_complex.h>
32 #include <math.h>
33 #include <fstream>
34 
37 
38 // public constructor
41  float loop_bw, float fmin, float fmax);
42 
43 /*!
44  * \brief This block takes care of receiving generic modulated signals
45  * through phase, frequency, and symbol synchronization.
46  * \ingroup sync_blk
47  * \ingroup demod_blk
48  * \ingroup digital
49  *
50  * This block takes care of receiving generic modulated signals
51  * through phase, frequency, and symbol synchronization. It performs
52  * carrier frequency and phase locking as well as symbol timing
53  * recovery.
54  *
55  * The phase and frequency synchronization are based on a Costas loop
56  * that finds the error of the incoming signal point compared to its
57  * nearest constellation point. The frequency and phase of the NCO are
58  * updated according to this error.
59  *
60  * The symbol synchronization is done using a modified Mueller and
61  * Muller circuit from the paper:
62  *
63  * G. R. Danesfahani, T.G. Jeans, "Optimisation of modified Mueller
64  * and Muller algorithm," Electronics Letters, Vol. 31, no. 13, 22
65  * June 1995, pp. 1032 - 1033.
66  *
67  * This circuit interpolates the downconverted sample (using the NCO
68  * developed by the Costas loop) every mu samples, then it finds the
69  * sampling error based on this and the past symbols and the decision
70  * made on the samples. Like the phase error detector, there are
71  * optimized decision algorithms for BPSK and QPKS, but 8PSK uses
72  * another brute force computation against all possible symbols. The
73  * modifications to the M&M used here reduce self-noise.
74  *
75  */
76 
78 {
79 public:
80  int general_work (int noutput_items,
81  gr_vector_int &ninput_items,
82  gr_vector_const_void_star &input_items,
83  gr_vector_void_star &output_items);
84 
85 protected:
86 
87  /*!
88  * \brief Constructor to synchronize incoming M-PSK symbols
89  *
90  * \param constellation constellation of points for generic modulation
91  * \param loop_bw Loop bandwidth of the Costas Loop (~ 2pi/100)
92  * \param fmin minimum normalized frequency value the loop can achieve
93  * \param fmax maximum normalized frequency value the loop can achieve
94  *
95  * The constructor also chooses which phase detector and decision maker to use in the
96  * work loop based on the value of M.
97  */
99  float loop_bw, float fmin, float fmax);
100 
101  void phase_error_tracking(float phase_error);
102 
103 private:
104  unsigned int d_M;
105 
106  digital_constellation_sptr d_constellation;
107  unsigned int d_current_const_point;
108 
109  //! delay line length.
110  static const unsigned int DLLEN = 8;
111 
112  //! delay line plus some length for overflow protection
113  __GR_ATTR_ALIGNED(8) gr_complex d_dl[2*DLLEN];
114 
115  //! index to delay line
116  unsigned int d_dl_idx;
117 
120  float loop_bw, float fmin, float fmax);
121 };
122 
123 #endif