GNU Radio 3.6.5 C++ API
|
00001 /* -*- c++ -*- */ 00002 /* 00003 * Copyright 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_FILTER_POLYPHASE_FILTERBANK_H 00025 #define INCLUDED_FILTER_POLYPHASE_FILTERBANK_H 00026 00027 #include <filter/api.h> 00028 #include <filter/fir_filter.h> 00029 #include <fft/fft.h> 00030 00031 namespace gr { 00032 namespace filter { 00033 namespace kernel { 00034 00035 /*! 00036 * \brief Polyphase filterbank parent class 00037 * \ingroup filter_blk 00038 * \ingroup pfb_blk 00039 * 00040 * \details 00041 * This block takes in complex inputs and channelizes it to 00042 * <EM>M</EM> channels of equal bandwidth. Each of the resulting 00043 * channels is decimated to the new rate that is the input 00044 * sampling rate <EM>fs</EM> divided by the number of channels, 00045 * <EM>M</EM>. 00046 * 00047 * The PFB channelizer code takes the taps generated above and 00048 * builds a set of filters. The set contains <EM>M</EM> number 00049 * of filters and each filter contains ceil(taps.size()/decim) 00050 * number of taps. Each tap from the filter prototype is 00051 * sequentially inserted into the next filter. When all of the 00052 * input taps are used, the remaining filters in the filterbank 00053 * are filled out with 0's to make sure each filter has the same 00054 * number of taps. 00055 * 00056 * Each filter operates using the gr_fir filter classs of GNU 00057 * Radio, which takes the input stream at <EM>i</EM> and 00058 * performs the inner product calculation to <EM>i+(n-1)</EM> 00059 * where <EM>n</EM> is the number of filter taps. To efficiently 00060 * handle this in the GNU Radio structure, each filter input 00061 * must come from its own input stream. So the channelizer must 00062 * be provided with <EM>M</EM> streams where the input stream 00063 * has been deinterleaved. This is most easily done using the 00064 * gr_stream_to_streams block. 00065 * 00066 * The output is then produced as a vector, where index 00067 * <EM>i</EM> in the vector is the next sample from the 00068 * <EM>i</EM>th channel. This is most easily handled by sending 00069 * the output to a gr_vector_to_streams block to handle the 00070 * conversion and passing <EM>M</EM> streams out. 00071 * 00072 * The input and output formatting is done using a hier_block2 00073 * called pfb_channelizer_ccf. This can take in a single stream 00074 * and outputs <EM>M</EM> streams based on the behavior 00075 * described above. 00076 * 00077 * The filter's taps should be based on the input sampling rate. 00078 * 00079 * For example, using the GNU Radio's firdes utility to building 00080 * filters, we build a low-pass filter with a sampling rate of 00081 * <EM>fs</EM>, a 3-dB bandwidth of <EM>BW</EM> and a transition 00082 * bandwidth of <EM>TB</EM>. We can also specify the out-of-band 00083 * attenuation to use, <EM>ATT</EM>, and the filter window 00084 * function (a Blackman-harris window in this case). The first 00085 * input is the gain of the filter, which we specify here as 00086 * unity. 00087 * 00088 * <B><EM>self._taps = filter.firdes.low_pass_2(1, fs, BW, TB, 00089 * attenuation_dB=ATT, window=filter.firdes.WIN_BLACKMAN_hARRIS)</EM></B> 00090 * 00091 * More on the theory of polyphase filterbanks can be found in 00092 * the following book. 00093 * 00094 * <B><EM>f. harris, "Multirate Signal Processing for 00095 * Communication Systems," Upper Saddle River, NJ: 00096 * Prentice Hall, Inc. 2004.</EM></B> 00097 * 00098 */ 00099 00100 class FILTER_API polyphase_filterbank 00101 { 00102 protected: 00103 unsigned int d_nfilts; 00104 std::vector<kernel::fir_filter_ccf*> d_filters; 00105 std::vector< std::vector<float> > d_taps; 00106 unsigned int d_taps_per_filter; 00107 fft::fft_complex *d_fft; 00108 00109 public: 00110 /*! 00111 * Build the polyphase filterbank decimator. 00112 * \param nfilts (unsigned integer) Specifies the number of 00113 * channels <EM>M</EM> 00114 * \param taps (vector/list of floats) The prototype filter to 00115 * populate the filterbank. 00116 */ 00117 polyphase_filterbank(unsigned int nfilts, 00118 const std::vector<float> &taps); 00119 00120 ~polyphase_filterbank(); 00121 00122 /*! 00123 * Update the filterbank's filter taps from a prototype 00124 * filter. 00125 * 00126 * \param taps (vector/list of floats) The prototype filter to 00127 * populate the filterbank. 00128 */ 00129 void set_taps(const std::vector<float> &taps); 00130 00131 /*! 00132 * Print all of the filterbank taps to screen. 00133 */ 00134 void print_taps(); 00135 00136 /*! 00137 * Return a vector<vector<>> of the filterbank taps 00138 */ 00139 std::vector<std::vector<float> > taps() const; 00140 }; 00141 00142 } /* namespace kernel */ 00143 } /* namespace filter */ 00144 } /* namespace gr */ 00145 00146 #endif /* INCLUDED_FILTER_POLYPHASE_FILTERBANK_H */