GNU Radio 3.7.1 C++ API
|
00001 /* -*- c++ -*- */ 00002 /* 00003 * Copyright 2009,2011,2012 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 #ifndef INCLUDED_DIGITAL_FLL_BAND_EDGE_CC_H 00024 #define INCLUDED_DIGITAL_FLL_BAND_EDGE_CC_H 00025 00026 #include <gnuradio/digital/api.h> 00027 #include <gnuradio/sync_block.h> 00028 #include <gnuradio/blocks/control_loop.h> 00029 00030 namespace gr { 00031 namespace digital { 00032 00033 /*! 00034 * \brief Frequency Lock Loop using band-edge filters 00035 * \ingroup synchronizers_blk 00036 * 00037 * \details 00038 * The frequency lock loop derives a band-edge filter that covers 00039 * the upper and lower bandwidths of a digitally-modulated 00040 * signal. The bandwidth range is determined by the excess 00041 * bandwidth (e.g., rolloff factor) of the modulated signal. The 00042 * placement in frequency of the band-edges is determined by the 00043 * oversampling ratio (number of samples per symbol) and the 00044 * excess bandwidth. The size of the filters should be fairly 00045 * large so as to average over a number of symbols. 00046 * 00047 * The FLL works by filtering the upper and lower band edges into 00048 * x_u(t) and x_l(t), respectively. These are combined to form 00049 * cc(t) = x_u(t) + x_l(t) and ss(t) = x_u(t) - x_l(t). Combining 00050 * these to form the signal e(t) = Re{cc(t) \\times ss(t)^*} 00051 * (where ^* is the complex conjugate) provides an error signal at 00052 * the DC term that is directly proportional to the carrier 00053 * frequency. We then make a second-order loop using the error 00054 * signal that is the running average of e(t). 00055 * 00056 * In practice, the above equation can be simplified by just 00057 * comparing the absolute value squared of the output of both 00058 * filters: abs(x_l(t))^2 - abs(x_u(t))^2 = norm(x_l(t)) - 00059 * norm(x_u(t)). 00060 * 00061 * In theory, the band-edge filter is the derivative of the 00062 * matched filter in frequency, (H_be(f) = frac{H(f)}{df}). In 00063 * practice, this comes down to a quarter sine wave at the point 00064 * of the matched filter's rolloff (if it's a raised-cosine, the 00065 * derivative of a cosine is a sine). Extend this sine by another 00066 * quarter wave to make a half wave around the band-edges is 00067 * equivalent in time to the sum of two sinc functions. The 00068 * baseband filter fot the band edges is therefore derived from 00069 * this sum of sincs. The band edge filters are then just the 00070 * baseband signal modulated to the correct place in 00071 * frequency. All of these calculations are done in the 00072 * 'design_filter' function. 00073 * 00074 * Note: We use FIR filters here because the filters have to have 00075 * a flat phase response over the entire frequency range to allow 00076 * their comparisons to be valid. 00077 * 00078 * It is very important that the band edge filters be the 00079 * derivatives of the pulse shaping filter, and that they be 00080 * linear phase. Otherwise, the variance of the error will be very 00081 * large. 00082 */ 00083 class DIGITAL_API fll_band_edge_cc 00084 : virtual public sync_block, 00085 virtual public blocks::control_loop 00086 { 00087 public: 00088 // gr::digital::fll_band_edge_cc::sptr 00089 typedef boost::shared_ptr<fll_band_edge_cc> sptr; 00090 00091 /*! 00092 * Make an FLL block. 00093 * 00094 * \param samps_per_sym (float) number of samples per symbol 00095 * \param rolloff (float) Rolloff (excess bandwidth) of signal filter 00096 * \param filter_size (int) number of filter taps to generate 00097 * \param bandwidth (float) Loop bandwidth 00098 */ 00099 static sptr make(float samps_per_sym, float rolloff, 00100 int filter_size, float bandwidth); 00101 00102 /******************************************************************* 00103 SET FUNCTIONS 00104 *******************************************************************/ 00105 00106 /*! 00107 * \brief Set the number of samples per symbol 00108 * 00109 * Set's the number of samples per symbol the system should 00110 * use. This value is uesd to calculate the filter taps and will 00111 * force a recalculation. 00112 * 00113 * \param sps (float) new samples per symbol 00114 */ 00115 virtual void set_samples_per_symbol(float sps) = 0; 00116 00117 /*! 00118 * \brief Set the rolloff factor of the shaping filter 00119 * 00120 * This sets the rolloff factor that is used in the pulse 00121 * shaping filter and is used to calculate the filter 00122 * taps. Changing this will force a recalculation of the filter 00123 * taps. 00124 * 00125 * This should be the same value that is used in the 00126 * transmitter's pulse shaping filter. It must be between 0 and 00127 * 1 and is usually between 0.2 and 0.5 (where 0.22 and 0.35 are 00128 * commonly used values). 00129 * 00130 * \param rolloff (float) new shaping filter rolloff factor [0,1] 00131 */ 00132 virtual void set_rolloff(float rolloff) = 0; 00133 00134 /*! 00135 * \brief Set the number of taps in the filter 00136 * 00137 * This sets the number of taps in the band-edge 00138 * filters. Setting this will force a recalculation of the 00139 * filter taps. 00140 * 00141 * This should be about the same number of taps used in the 00142 * transmitter's shaping filter and also not very large. A large 00143 * number of taps will result in a large delay between input and 00144 * frequency estimation, and so will not be as accurate. Between 00145 * 30 and 70 taps is usual. 00146 * 00147 * \param filter_size (float) number of taps in the filters 00148 */ 00149 virtual void set_filter_size(int filter_size) = 0; 00150 00151 /******************************************************************* 00152 GET FUNCTIONS 00153 *******************************************************************/ 00154 00155 /*! 00156 * \brief Returns the number of sampler per symbol used for the filter 00157 */ 00158 virtual float samples_per_symbol() const = 0; 00159 00160 /*! 00161 * \brief Returns the rolloff factor used for the filter 00162 */ 00163 virtual float rolloff() const = 0; 00164 00165 /*! 00166 * \brief Returns the number of taps of the filter 00167 */ 00168 virtual int filter_size() const = 0; 00169 00170 /*! 00171 * Print the taps to screen. 00172 */ 00173 virtual void print_taps() = 0; 00174 }; 00175 00176 } /* namespace digital */ 00177 } /* namespace gr */ 00178 00179 #endif /* INCLUDED_DIGITAL_FLL_BAND_EDGE_CC_H */