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