GNU Radio 3.4.2 C++ API
|
00001 /* -*- c++ -*- */ 00002 /* 00003 * Copyright 2009 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_FLL_BAND_EDGE_CC_H 00025 #define INCLUDED_GR_FLL_BAND_EDGE_CC_H 00026 00027 #include <gr_sync_block.h> 00028 00029 class gr_fll_band_edge_cc; 00030 typedef boost::shared_ptr<gr_fll_band_edge_cc> gr_fll_band_edge_cc_sptr; 00031 gr_fll_band_edge_cc_sptr gr_make_fll_band_edge_cc (float samps_per_sym, float rolloff, 00032 int filter_size, float alpha, float beta); 00033 00034 class gr_fir_ccc; 00035 class gri_fft_complex; 00036 00037 /*! 00038 * \class gr_fll_band_edge_cc 00039 * \brief Frequency Lock Loop using band-edge filters 00040 * 00041 * \ingroup general 00042 * 00043 * The frequency lock loop derives a band-edge filter that covers the upper and lower bandwidths 00044 * of a digitally-modulated signal. The bandwidth range is determined by the excess bandwidth 00045 * (e.g., rolloff factor) of the modulated signal. The placement in frequency of the band-edges 00046 * is determined by the oversampling ratio (number of samples per symbol) and the excess bandwidth. 00047 * The size of the filters should be fairly large so as to average over a number of symbols. 00048 * 00049 * The FLL works by filtering the upper and lower band edges into x_u(t) and x_l(t), respectively. 00050 * These are combined to form cc(t) = x_u(t) + x_l(t) and ss(t) = x_u(t) - x_l(t). Combining 00051 * these to form the signal e(t) = Re{cc(t) \\times ss(t)^*} (where ^* is the complex conjugate) 00052 * provides an error signal at the DC term that is directly proportional to the carrier frequency. 00053 * We then make a second-order loop using the error signal that is the running average of e(t). 00054 * 00055 * In theory, the band-edge filter is the derivative of the matched filter in frequency, 00056 * (H_be(f) = \\frac{H(f)}{df}. In practice, this comes down to a quarter sine wave at the point 00057 * of the matched filter's rolloff (if it's a raised-cosine, the derivative of a cosine is a sine). 00058 * Extend this sine by another quarter wave to make a half wave around the band-edges is equivalent 00059 * in time to the sum of two sinc functions. The baseband filter fot the band edges is therefore 00060 * derived from this sum of sincs. The band edge filters are then just the baseband signal 00061 * modulated to the correct place in frequency. All of these calculations are done in the 00062 * 'design_filter' function. 00063 * 00064 * Note: We use FIR filters here because the filters have to have a flat phase response over the 00065 * entire frequency range to allow their comparisons to be valid. 00066 */ 00067 00068 class gr_fll_band_edge_cc : public gr_sync_block 00069 { 00070 private: 00071 /*! 00072 * Build the FLL 00073 * \param samps_per_sym (float) Number of samples per symbol of signal 00074 * \param rolloff (float) Rolloff factor of signal 00075 * \param filter_size (int) Size (in taps) of the filter 00076 * \param alpha (float) Loop gain 1 00077 * \param beta (float) Loop gain 2 00078 */ 00079 friend gr_fll_band_edge_cc_sptr gr_make_fll_band_edge_cc (float samps_per_sym, float rolloff, 00080 int filter_size, float alpha, float beta); 00081 00082 float d_alpha; 00083 float d_beta; 00084 float d_max_freq; 00085 float d_min_freq; 00086 00087 gr_fir_ccc* d_filter_upper; 00088 gr_fir_ccc* d_filter_lower; 00089 bool d_updated; 00090 float d_error; 00091 float d_freq; 00092 float d_phase; 00093 00094 /*! 00095 * Build the FLL 00096 * \param samps_per_sym (float) number of samples per symbol 00097 * \param rolloff (float) Rolloff (excess bandwidth) of signal filter 00098 * \param filter_size (int) number of filter taps to generate 00099 * \param alpha (float) Alpha gain in the control loop 00100 * \param beta (float) Beta gain in the control loop 00101 */ 00102 gr_fll_band_edge_cc(float samps_per_sym, float rolloff, 00103 int filter_size, float alpha, float beta); 00104 00105 public: 00106 ~gr_fll_band_edge_cc (); 00107 00108 /*! 00109 * Design the band-edge filter based on the number of samples per symbol, 00110 * filter rolloff factor, and the filter size 00111 * \param samps_per_sym (float) Number of samples per symbol of signal 00112 * \param rolloff (float) Rolloff factor of signal 00113 * \param filter_size (int) Size (in taps) of the filter 00114 */ 00115 void design_filter(float samps_per_sym, float rolloff, int filter_size); 00116 00117 /*! 00118 * Set the alpha gainvalue 00119 * \param alpha (float) new gain value 00120 */ 00121 void set_alpha(float alpha); 00122 00123 /*! 00124 * Set the beta gain value 00125 * \param beta (float) new gain value 00126 */ 00127 void set_beta(float beta) { d_beta = beta; } 00128 00129 /*! 00130 * Print the taps to screen. 00131 */ 00132 void print_taps(); 00133 00134 int work (int noutput_items, 00135 gr_vector_const_void_star &input_items, 00136 gr_vector_void_star &output_items); 00137 }; 00138 00139 #endif