178e18f3e8469313b50996a9b39d662ac4c1406c
[debian/gnuradio] / gnuradio-core / src / lib / general / gr_fll_band_edge_cc.h
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2009 Free Software Foundation, Inc.
4  * 
5  * This file is part of GNU Radio
6  * 
7  * GNU Radio is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3, or (at your option)
10  * any later version.
11  * 
12  * GNU Radio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with GNU Radio; see the file COPYING.  If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street,
20  * Boston, MA 02110-1301, USA.
21  */
22
23
24 #ifndef INCLUDED_GR_FLL_BAND_EDGE_CC_H
25 #define INCLUDED_GR_FLL_BAND_EDGE_CC_H
26
27 #include <gr_sync_block.h>
28
29 class gr_fll_band_edge_cc;
30 typedef boost::shared_ptr<gr_fll_band_edge_cc> gr_fll_band_edge_cc_sptr;
31 gr_fll_band_edge_cc_sptr gr_make_fll_band_edge_cc (float samps_per_sym, float rolloff,
32                                                    int filter_size, float alpha, float beta);
33
34 class gr_fir_ccc;
35 class gri_fft_complex;
36
37 /*!
38  * \class gr_fll_band_edge_cc
39  * \brief Frequency Lock Loop using band-edge filters
40  *
41  * \ingroup general
42  *
43  * The frequency lock loop derives a band-edge filter that covers the upper and lower bandwidths
44  * of a digitally-modulated signal. The bandwidth range is determined by the excess bandwidth
45  * (e.g., rolloff factor) of the modulated signal. The placement in frequency of the band-edges
46  * is determined by the oversampling ratio (number of samples per symbol) and the excess bandwidth.
47  * The size of the filters should be fairly large so as to average over a number of symbols.
48  *
49  * The FLL works by filtering the upper and lower band edges into x_u(t) and x_l(t), respectively.
50  * These are combined to form cc(t) = x_u(t) + x_l(t) and ss(t) = x_u(t) - x_l(t). Combining
51  * these to form the signal e(t) = Re{cc(t) \times ss(t)^*} (where ^* is the complex conjugate)
52  * provides an error signal at the DC term that is directly proportional to the carrier frequency.
53  * We then make a second-order loop using the error signal that is the running average of e(t).
54  *
55  * In theory, the band-edge filter is the derivative of the matched filter in frequency, 
56  * (H_be(f) = \frac{H(f)}{df}. In practice, this comes down to a quarter sine wave at the point
57  * of the matched filter's rolloff (if it's a raised-cosine, the derivative of a cosine is a sine).
58  * Extend this sine by another quarter wave to make a half wave around the band-edges is equivalent
59  * in time to the sum of two sinc functions. The baseband filter fot the band edges is therefore
60  * derived from this sum of sincs. The band edge filters are then just the baseband signal
61  * modulated to the correct place in frequency. All of these calculations are done in the
62  * 'design_filter' function.
63  *
64  * Note: We use FIR filters here because the filters have to have a flat phase response over the
65  * entire frequency range to allow their comparisons to be valid.
66  */
67
68 class gr_fll_band_edge_cc : public gr_sync_block
69 {
70  private:
71   /*!
72    * Build the FLL
73    * \param samps_per_sym    (float) Number of samples per symbol of signal
74    * \param rolloff          (float) Rolloff factor of signal
75    * \param filter_size      (int)   Size (in taps) of the filter
76    * \param alpha            (float) Loop gain 1
77    * \param beta             (float) Loop gain 2
78    */
79   friend gr_fll_band_edge_cc_sptr gr_make_fll_band_edge_cc (float samps_per_sym, float rolloff,
80                                                             int filter_size, float alpha, float beta);
81
82   float                   d_alpha;
83   float                   d_beta;
84   float                   d_max_freq;
85   float                   d_min_freq;
86
87   gr_fir_ccc*             d_filter_upper;
88   gr_fir_ccc*             d_filter_lower;
89   bool                    d_updated;
90   float                   d_error;
91   float                   d_freq;
92   float                   d_phase;
93
94   /*!
95    * Build the FLL
96    * \param taps    (vector/list of gr_complex) The taps of the band-edge filter
97    */
98   gr_fll_band_edge_cc(float samps_per_sym, float rolloff,
99                       int filter_size, float alpha, float beta);
100
101 public:
102   ~gr_fll_band_edge_cc ();
103   
104   /*!
105    * Design the band-edge filter based on the number of samples per symbol,
106    * filter rolloff factor, and the filter size
107    * \param samps_per_sym    (float) Number of samples per symbol of signal
108    * \param rolloff          (float) Rolloff factor of signal
109    * \param filter_size      (int)   Size (in taps) of the filter
110    */
111   void design_filter(float samps_per_sym, float rolloff, int filter_size);
112
113   /*!
114    * Set the alpha gainvalue
115    * \param alpha    (float) new gain value
116    */
117   void set_alpha(float alpha);
118
119   /*!
120    * Set the beta gain value
121    * \param beta    (float) new gain value
122    */
123   void set_beta(float beta) { d_beta = beta; }
124
125   /*!
126    * Print the taps to screen.
127    */
128   void print_taps();
129    
130   int work (int noutput_items,
131             gr_vector_const_void_star &input_items,
132             gr_vector_void_star &output_items);
133 };
134
135 #endif