GNU Radio v3.6.2-149-ga6d285d9 C++ API
digital_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 
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