GNU Radio 3.3.0 C++ API
|
00001 /* -*- c++ -*- */ 00002 /* 00003 * Copyright 2006 Free Software Foundation, Inc. 00004 * 00005 * This file is part of GNU Radio 00006 * 00007 * GNU Radio is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 3, or (at your option) 00010 * any later version. 00011 * 00012 * GNU Radio is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with GNU Radio; see the file COPYING. If not, write to 00019 * the Free Software Foundation, Inc., 51 Franklin Street, 00020 * Boston, MA 02110-1301, USA. 00021 */ 00022 00023 00024 #ifndef INCLUDED_GR_COSTAS_LOOP_CC_H 00025 #define INCLUDED_GR_COSTAS_LOOP_CC_H 00026 00027 #include <gr_sync_block.h> 00028 #include <stdexcept> 00029 #include <fstream> 00030 00031 00032 /*! \brief A Costas loop carrier recovery module. 00033 * \ingroup sync_blk 00034 * 00035 * The Costas loop locks to the center frequency of a signal and 00036 * downconverts it to baseband. The second (order=2) order loop is 00037 * used for BPSK where the real part of the output signal is the 00038 * baseband BPSK signal and the imaginary part is the error 00039 * signal. When order=4, it can be used for quadrature modulations 00040 * where both I and Q (real and imaginary) are outputted. 00041 * 00042 * More details can be found online: 00043 * 00044 * J. Feigin, "Practical Costas loop design: Designing a simple and inexpensive 00045 * BPSK Costas loop carrier recovery circuit," RF signal processing, pp. 20-36, 00046 * 2002. 00047 * 00048 * http://rfdesign.com/images/archive/0102Feigin20.pdf 00049 * 00050 * \param alpha the loop gain used for phase adjustment 00051 * \param beta the loop gain for frequency adjustments 00052 * \param max_freq the maximum frequency deviation (radians/sample) the loop can handle 00053 * \param min_freq the minimum frequency deviation (radians/sample) the loop can handle 00054 * \param order the loop order, either 2 or 4 00055 */ 00056 class gr_costas_loop_cc; 00057 typedef boost::shared_ptr<gr_costas_loop_cc> gr_costas_loop_cc_sptr; 00058 00059 00060 gr_costas_loop_cc_sptr 00061 gr_make_costas_loop_cc (float alpha, float beta, 00062 float max_freq, float min_freq, 00063 int order 00064 ) throw (std::invalid_argument); 00065 00066 00067 /*! 00068 * \brief Carrier tracking PLL for QPSK 00069 * \ingroup sync_blk 00070 * input: complex; output: complex 00071 * <br>The Costas loop can have two output streams: 00072 * stream 1 is the baseband I and Q; 00073 * stream 2 is the normalized frequency of the loop 00074 * 00075 * \p order must be 2 or 4. 00076 */ 00077 class gr_costas_loop_cc : public gr_sync_block 00078 { 00079 friend gr_costas_loop_cc_sptr gr_make_costas_loop_cc (float alpha, float beta, 00080 float max_freq, float min_freq, 00081 int order 00082 ) throw (std::invalid_argument); 00083 00084 float d_alpha, d_beta, d_max_freq, d_min_freq, d_phase, d_freq; 00085 int d_order; 00086 00087 gr_costas_loop_cc (float alpha, float beta, 00088 float max_freq, float min_freq, 00089 int order 00090 ) throw (std::invalid_argument); 00091 00092 /*! \brief the phase detector circuit for fourth-order loops 00093 * \param sample complex sample 00094 * \return the phase error 00095 */ 00096 float phase_detector_4(gr_complex sample) const; // for QPSK 00097 00098 /*! \brief the phase detector circuit for second-order loops 00099 * \param sample a complex sample 00100 * \return the phase error 00101 */ 00102 float phase_detector_2(gr_complex sample) const; // for BPSK 00103 00104 00105 float (gr_costas_loop_cc::*d_phase_detector)(gr_complex sample) const; 00106 00107 public: 00108 00109 /*! \brief set the first order gain 00110 * \param alpha 00111 */ 00112 void set_alpha(float alpha); 00113 00114 /*! \brief get the first order gain 00115 * 00116 */ 00117 float alpha() const { return d_alpha; } 00118 00119 /*! \brief set the second order gain 00120 * \param beta 00121 */ 00122 void set_beta(float beta); 00123 00124 /*! \brief get the second order gain 00125 * 00126 */ 00127 float beta() const { return d_beta; } 00128 00129 int work (int noutput_items, 00130 gr_vector_const_void_star &input_items, 00131 gr_vector_void_star &output_items); 00132 00133 /*! \brief returns the current NCO frequency in radians/sample 00134 * 00135 */ 00136 float freq() const { return d_freq; } 00137 }; 00138 00139 #endif