GNU Radio 3.7.0 C++ API
fll_band_edge_cc.h
Go to the documentation of this file.
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 */