GNU Radio 3.4.2 C++ API
gr_fll_band_edge_cc.h
Go to the documentation of this file.
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