GNU Radio v3.6.2-149-ga6d285d9 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 00024 #ifndef INCLUDED_DIGITAL_FLL_BAND_EDGE_CC_H 00025 #define INCLUDED_DIGITAL_FLL_BAND_EDGE_CC_H 00026 00027 #include <digital_api.h> 00028 #include <gr_sync_block.h> 00029 #include <gri_control_loop.h> 00030 #include <gr_fir_util.h> 00031 #include <gr_fir_ccc.h> 00032 00033 typedef gr_fir_ccc* (*fir_maker_t)(const std::vector<gr_complex> &taps); 00034 typedef gr_fir_ccc filter_t; 00035 00036 class digital_fll_band_edge_cc; 00037 typedef boost::shared_ptr<digital_fll_band_edge_cc> digital_fll_band_edge_cc_sptr; 00038 DIGITAL_API digital_fll_band_edge_cc_sptr 00039 digital_make_fll_band_edge_cc(float samps_per_sym, 00040 float rolloff, 00041 int filter_size, 00042 float bandwidth); 00043 00044 /*! 00045 * \class digital_fll_band_edge_cc 00046 * \brief Frequency Lock Loop using band-edge filters 00047 * 00048 * \ingroup general 00049 * \ingroup digital 00050 * 00051 * The frequency lock loop derives a band-edge filter that covers the 00052 * upper and lower bandwidths of a digitally-modulated signal. The 00053 * bandwidth range is determined by the excess bandwidth (e.g., 00054 * rolloff factor) of the modulated signal. The placement in frequency 00055 * of the band-edges is determined by the oversampling ratio (number 00056 * of samples per symbol) and the excess bandwidth. The size of the 00057 * filters should be fairly large so as to average over a number of 00058 * symbols. 00059 * 00060 * The FLL works by filtering the upper and lower band edges into 00061 * x_u(t) and x_l(t), respectively. These are combined to form cc(t) 00062 * = x_u(t) + x_l(t) and ss(t) = x_u(t) - x_l(t). Combining these to 00063 * form the signal e(t) = Re{cc(t) \\times ss(t)^*} (where ^* is the 00064 * complex conjugate) provides an error signal at the DC term that is 00065 * directly proportional to the carrier frequency. We then make a 00066 * second-order loop using the error signal that is the running 00067 * average of e(t). 00068 * 00069 * In practice, the above equation can be simplified by just comparing 00070 * the absolute value squared of the output of both filters: 00071 * abs(x_l(t))^2 - abs(x_u(t))^2 = norm(x_l(t)) - norm(x_u(t)). 00072 * 00073 * In theory, the band-edge filter is the derivative of the matched 00074 * filter in frequency, (H_be(f) = frac{H(f)}{df}). In practice, 00075 * this comes down to a quarter sine wave at the point of the matched 00076 * filter's rolloff (if it's a raised-cosine, the derivative of a 00077 * cosine is a sine). Extend this sine by another quarter wave to 00078 * make a half wave around the band-edges is equivalent in time to the 00079 * sum of two sinc functions. The baseband filter fot the band edges 00080 * is therefore derived from this sum of sincs. The band edge filters 00081 * are then just the baseband signal modulated to the correct place in 00082 * frequency. All of these calculations are done in the 00083 * 'design_filter' function. 00084 * 00085 * Note: We use FIR filters here because the filters have to have a 00086 * flat phase response over the entire frequency range to allow their 00087 * comparisons to be valid. 00088 * 00089 * It is very important that the band edge filters be the derivatives 00090 * of the pulse shaping filter, and that they be linear 00091 * phase. Otherwise, the variance of the error will be very large. 00092 * 00093 */ 00094 00095 class DIGITAL_API digital_fll_band_edge_cc : 00096 public gr_sync_block, public gri_control_loop 00097 { 00098 private: 00099 /*! 00100 * Build the FLL 00101 * \param samps_per_sym (float) Number of samples per symbol of signal 00102 * \param rolloff (float) Rolloff factor of signal 00103 * \param filter_size (int) Size (in taps) of the filter 00104 * \param bandwidth (float) Loop bandwidth 00105 */ 00106 friend DIGITAL_API digital_fll_band_edge_cc_sptr 00107 digital_make_fll_band_edge_cc(float samps_per_sym, 00108 float rolloff, 00109 int filter_size, 00110 float bandwidth); 00111 00112 float d_sps; 00113 float d_rolloff; 00114 int d_filter_size; 00115 00116 std::vector<gr_complex> d_taps_lower; 00117 std::vector<gr_complex> d_taps_upper; 00118 bool d_updated; 00119 filter_t* d_filter_lower; 00120 filter_t* d_filter_upper; 00121 std::vector<gr_complex> d_output_hist; 00122 std::vector<gr_complex> d_fllbuffer; 00123 00124 /*! 00125 * Build the FLL 00126 * \param samps_per_sym (float) number of samples per symbol 00127 * \param rolloff (float) Rolloff (excess bandwidth) of signal filter 00128 * \param filter_size (int) number of filter taps to generate 00129 * \param bandwidth (float) Loop bandwidth 00130 */ 00131 digital_fll_band_edge_cc(float samps_per_sym, float rolloff, 00132 int filter_size, float bandwidth); 00133 00134 /*! 00135 * Design the band-edge filter based on the number of samples per symbol, 00136 * filter rolloff factor, and the filter size 00137 * 00138 * \param samps_per_sym (float) Number of samples per symbol of signal 00139 * \param rolloff (float) Rolloff factor of signal 00140 * \param filter_size (int) Size (in taps) of the filter 00141 */ 00142 void design_filter(float samps_per_sym, float rolloff, int filter_size); 00143 00144 public: 00145 ~digital_fll_band_edge_cc(); 00146 00147 /******************************************************************* 00148 SET FUNCTIONS 00149 *******************************************************************/ 00150 00151 /*! 00152 * \brief Set the number of samples per symbol 00153 * 00154 * Set's the number of samples per symbol the system should 00155 * use. This value is uesd to calculate the filter taps and will 00156 * force a recalculation. 00157 * 00158 * \param sps (float) new samples per symbol 00159 * 00160 */ 00161 void set_samples_per_symbol(float sps); 00162 00163 /*! 00164 * \brief Set the rolloff factor of the shaping filter 00165 * 00166 * This sets the rolloff factor that is used in the pulse shaping 00167 * filter and is used to calculate the filter taps. Changing this 00168 * will force a recalculation of the filter taps. 00169 * 00170 * This should be the same value that is used in the transmitter's 00171 * pulse shaping filter. It must be between 0 and 1 and is usually 00172 * between 0.2 and 0.5 (where 0.22 and 0.35 are commonly used 00173 * values). 00174 * 00175 * \param rolloff (float) new shaping filter rolloff factor [0,1] 00176 * 00177 */ 00178 void set_rolloff(float rolloff); 00179 00180 /*! 00181 * \brief Set the number of taps in the filter 00182 * 00183 * This sets the number of taps in the band-edge filters. Setting 00184 * this will force a recalculation of the filter taps. 00185 * 00186 * This should be about the same number of taps used in the 00187 * transmitter's shaping filter and also not very large. A large 00188 * number of taps will result in a large delay between input and 00189 * frequency estimation, and so will not be as accurate. Between 30 00190 * and 70 taps is usual. 00191 * 00192 * \param filter_size (float) number of taps in the filters 00193 * 00194 */ 00195 void set_filter_size(int filter_size); 00196 00197 /******************************************************************* 00198 GET FUNCTIONS 00199 *******************************************************************/ 00200 00201 /*! 00202 * \brief Returns the number of sampler per symbol used for the filter 00203 */ 00204 float get_samples_per_symbol() const; 00205 00206 /*! 00207 * \brief Returns the rolloff factor used for the filter 00208 */ 00209 float get_rolloff() const; 00210 00211 /*! 00212 * \brief Returns the number of taps of the filter 00213 */ 00214 int get_filter_size() const; 00215 00216 /*! 00217 * Print the taps to screen. 00218 */ 00219 void print_taps(); 00220 00221 int work(int noutput_items, 00222 gr_vector_const_void_star &input_items, 00223 gr_vector_void_star &output_items); 00224 }; 00225 00226 #endif