GNU Radio 3.7.0 C++ API
pfb_arb_resampler_fff.h
Go to the documentation of this file.
00001 /* -*- c++ -*- */
00002 /*
00003  * Copyright 2009-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_PFB_ARB_RESAMPLER_FFF_H
00025 #define INCLUDED_PFB_ARB_RESAMPLER_FFF_H
00026 
00027 #include <gnuradio/filter/api.h>
00028 #include <gnuradio/block.h>
00029 
00030 namespace gr {
00031   namespace filter {
00032 
00033     /*!
00034      * \brief Polyphase filterbank arbitrary resampler with
00035      *        float input, float output and float taps
00036      * \ingroup resamplers_blk
00037      *
00038      * \details
00039      * This block takes in a signal stream and performs arbitrary
00040      * resampling. The resampling rate can be any real number
00041      * <EM>r</EM>. The resampling is done by constructing <EM>N</EM>
00042      * filters where <EM>N</EM> is the interpolation rate.  We then
00043      * calculate <EM>D</EM> where <EM>D = floor(N/r)</EM>.
00044      *
00045      * Using <EM>N</EM> and <EM>D</EM>, we can perform rational
00046      * resampling where <EM>N/D</EM> is a rational number close to the
00047      * input rate <EM>r</EM> where we have <EM>N</EM> filters and we
00048      * cycle through them as a polyphase filterbank with a stride of
00049      * <EM>D</EM> so that <EM>i+1 = (i + D) % N</EM>.
00050      *
00051      * To get the arbitrary rate, we want to interpolate between two
00052      * points. For each value out, we take an output from the current
00053      * filter, <EM>i</EM>, and the next filter <EM>i+1</EM> and then
00054      * linearly interpolate between the two based on the real
00055      * resampling rate we want.
00056      *
00057      * The linear interpolation only provides us with an approximation
00058      * to the real sampling rate specified. The error is a
00059      * quantization error between the two filters we used as our
00060      * interpolation points.  To this end, the number of filters,
00061      * <EM>N</EM>, used determines the quantization error; the larger
00062      * <EM>N</EM>, the smaller the noise. You can design for a
00063      * specified noise floor by setting the filter size (parameters
00064      * <EM>filter_size</EM>). The size defaults to 32 filters, which
00065      * is about as good as most implementations need.
00066      *
00067      * The trick with designing this filter is in how to specify the
00068      * taps of the prototype filter. Like the PFB interpolator, the
00069      * taps are specified using the interpolated filter rate. In this
00070      * case, that rate is the input sample rate multiplied by the
00071      * number of filters in the filterbank, which is also the
00072      * interpolation rate. All other values should be relative to this
00073      * rate.
00074      *
00075      * For example, for a 32-filter arbitrary resampler and using the
00076      * GNU Radio's firdes utility to build the filter, we build a
00077      * low-pass filter with a sampling rate of <EM>fs</EM>, a 3-dB
00078      * bandwidth of <EM>BW</EM> and a transition bandwidth of
00079      * <EM>TB</EM>. We can also specify the out-of-band attenuation to
00080      * use, <EM>ATT</EM>, and the filter window function (a
00081      * Blackman-harris window in this case). The first input is the
00082      * gain of the filter, which we specify here as the interpolation
00083      * rate (<EM>32</EM>).
00084      *
00085      *   <B><EM>self._taps = filter.firdes.low_pass_2(32, 32*fs, BW, TB,
00086      *      attenuation_dB=ATT, window=filter.firdes.WIN_BLACKMAN_hARRIS)</EM></B>
00087      *
00088      * The theory behind this block can be found in Chapter 7.5 of the
00089      * following book.
00090      *
00091      *   <B><EM>f. harris, "Multirate Signal Processing for Communication
00092      *      Systems", Upper Saddle River, NJ: Prentice Hall, Inc. 2004.</EM></B>
00093      */
00094 
00095     class FILTER_API pfb_arb_resampler_fff : virtual public block
00096     {
00097     public:
00098       // gr::filter::pfb_arb_resampler_fff::sptr
00099       typedef boost::shared_ptr<pfb_arb_resampler_fff> sptr;
00100 
00101       /*!
00102        * Build the polyphase filterbank arbitray resampler.
00103        * \param rate  (float) Specifies the resampling rate to use
00104        * \param taps  (vector/list of floats) The prototype filter to populate the filterbank. The taps
00105        *                                      should be generated at the filter_size sampling rate.
00106        * \param filter_size (unsigned int) The number of filters in the filter bank. This is directly
00107        *                                   related to quantization noise introduced during the resampling.
00108        *                                   Defaults to 32 filters.
00109        */
00110       static sptr make(float rate,
00111                        const std::vector<float> &taps,
00112                        unsigned int filter_size=32);
00113 
00114       /*!
00115        * Resets the filterbank's filter taps with the new prototype filter
00116        * \param taps    (vector/list of floats) The prototype filter to populate the filterbank.
00117        */
00118       virtual void set_taps(const std::vector<float> &taps) = 0;
00119 
00120       /*!
00121        * Return a vector<vector<>> of the filterbank taps
00122        */
00123       virtual std::vector<std::vector<float> > taps() const = 0;
00124 
00125       /*!
00126        * Print all of the filterbank taps to screen.
00127        */
00128       virtual void print_taps() = 0;
00129 
00130       /*!
00131        * Sets the resampling rate of the block.
00132        */
00133       virtual void set_rate (float rate) = 0;
00134 
00135       /*!
00136        * Sets the current phase offset in radians (0 to 2pi).
00137        */
00138       virtual void set_phase(float ph) = 0;
00139 
00140       /*!
00141        * Gets the current phase of the resampler in radians (2 to 2pi).
00142        */
00143       virtual float phase() const = 0;
00144 
00145       /*!
00146        * Gets the number of taps per filter.
00147        */
00148       virtual unsigned int taps_per_filter() const = 0;
00149 
00150       /*!
00151        * Gets the interpolation rate of the filter.
00152        */
00153       virtual unsigned int interpolation_rate() const = 0;
00154 
00155       /*!
00156        * Gets the decimation rate of the filter.
00157        */    
00158       virtual unsigned int decimation_rate() const =0;
00159       
00160       /*!
00161        * Gets the fractional rate of the filter.
00162        */    
00163       virtual float fractional_rate() const = 0;
00164 
00165       /*!
00166        * Get the group delay of the filter.
00167        */
00168       virtual int group_delay() const = 0;
00169 
00170       /*!
00171        * Calculates the phase offset expected by a sine wave of
00172        * frequency \p freq and sampling rate \p fs (assuming input
00173        * sine wave has 0 degree phase).
00174        */
00175       virtual float phase_offset(float freq, float fs) = 0;
00176     };
00177 
00178   } /* namespace filter */
00179 } /* namespace gr */
00180 
00181 #endif /* INCLUDED_PFB_ARB_RESAMPLER_FFF_H */