diff options
author | Manoj Gudi | 2013-10-07 20:19:55 +0530 |
---|---|---|
committer | Manoj Gudi | 2013-10-07 20:20:35 +0530 |
commit | 1826d0763c8595997f5f4af1fdb0354e9c0998ad (patch) | |
tree | acbd852cd5a1bf17241b1038b5e37a0e72e64612 /gr-filter/include | |
parent | 452defdb4a78e9e826740ddf4b9673e926c568a4 (diff) | |
parent | 24b640997ba7fee0c725e65f401f5cbebdab8d08 (diff) | |
download | gnuradio-1826d0763c8595997f5f4af1fdb0354e9c0998ad.tar.gz gnuradio-1826d0763c8595997f5f4af1fdb0354e9c0998ad.tar.bz2 gnuradio-1826d0763c8595997f5f4af1fdb0354e9c0998ad.zip |
README change
Diffstat (limited to 'gr-filter/include')
37 files changed, 4374 insertions, 0 deletions
diff --git a/gr-filter/include/filter/CMakeLists.txt b/gr-filter/include/filter/CMakeLists.txt new file mode 100644 index 000000000..4c126fcbd --- /dev/null +++ b/gr-filter/include/filter/CMakeLists.txt @@ -0,0 +1,116 @@ +# Copyright 2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. + +######################################################################## +# generate helper scripts to expand templated files +######################################################################## +include(GrPython) + +file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py " +#!${PYTHON_EXECUTABLE} + +import sys, os, re +sys.path.append('${GR_CORE_PYTHONPATH}') +os.environ['srcdir'] = '${CMAKE_CURRENT_SOURCE_DIR}' +os.chdir('${CMAKE_CURRENT_BINARY_DIR}') + +if __name__ == '__main__': + import build_utils + root, inp = sys.argv[1:3] + for sig in sys.argv[3:]: + name = re.sub ('X+', sig, root) + d = build_utils.standard_dict2(name, sig, 'filter') + build_utils.expand_template(d, inp) + +") + +macro(expand_h root) + #make a list of all the generated files + unset(expanded_files_h) + foreach(sig ${ARGN}) + string(REGEX REPLACE "X+" ${sig} name ${root}) + list(APPEND expanded_files_h ${CMAKE_CURRENT_BINARY_DIR}/${name}.h) + endforeach(sig) + + #create a command to generate the files + add_custom_command( + OUTPUT ${expanded_files_h} + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}.h.t + COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B} + ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py + ${root} ${root}.h.t ${ARGN} + ) + + #install rules for the generated h files + list(APPEND generated_includes ${expanded_files_h}) +endmacro(expand_h) + +######################################################################## +# Invoke macro to generate various sources +####################################################################### +expand_h(fir_filter_XXX ccc ccf fcc fff fsf scc) +expand_h(freq_xlating_fir_filter_XXX ccc ccf fcc fcf scf scc) +expand_h(interp_fir_filter_XXX ccc ccf fcc fff fsf scc) +expand_h(rational_resampler_base_XXX ccc ccf fcc fff fsf scc) + +add_custom_target(filter_generated_includes DEPENDS + ${generated_includes} +) + +######################################################################## +# Install header files +######################################################################## +install(FILES + ${generated_includes} + api.h + firdes.h + fir_filter.h + fir_filter_with_buffer.h + fft_filter.h + iir_filter.h + interpolator_taps.h + mmse_fir_interpolator_cc.h + mmse_fir_interpolator_ff.h + pm_remez.h + polyphase_filterbank.h + single_pole_iir.h + adaptive_fir_ccc.h + adaptive_fir_ccf.h + dc_blocker_cc.h + dc_blocker_ff.h + filter_delay_fc.h + fft_filter_ccc.h + fft_filter_fff.h + fractional_interpolator_cc.h + fractional_interpolator_ff.h + hilbert_fc.h + iir_filter_ffd.h + pfb_arb_resampler_ccf.h + pfb_arb_resampler_fff.h + pfb_channelizer_ccf.h + pfb_decimator_ccf.h + pfb_interpolator_ccf.h + pfb_synthesizer_ccf.h + single_pole_iir_filter_cc.h + single_pole_iir_filter_ff.h + channel_model.h + DESTINATION ${GR_INCLUDE_DIR}/gnuradio/filter + COMPONENT "filter_devel" +) + diff --git a/gr-filter/include/filter/adaptive_fir_ccc.h b/gr-filter/include/filter/adaptive_fir_ccc.h new file mode 100644 index 000000000..261259957 --- /dev/null +++ b/gr-filter/include/filter/adaptive_fir_ccc.h @@ -0,0 +1,85 @@ +/* -*- c++ -*- */ +/* + * Copyright 2011,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_FILTER_ADAPTIVE_FIR_CCC_H +#define INCLUDED_FILTER_ADAPTIVE_FIR_CCC_H + +#include <filter/api.h> +#include <gr_sync_decimator.h> +#include <filter/fir_filter.h> + +namespace gr { + namespace filter { + + /*! + * \brief Adaptive FIR filter with gr_complex input, gr_complex output and gr_complex taps + * \ingroup filter_blk + * + * This is a base class to implement an adaptive FIR + * filter. Generally, another block will inherit from this one to + * build a new type of adaptive filter such as an equalizer. + * + * This class implements two functions that are designed to be + * overloaded by the child class: error(gr_complex out) and + * update_tap(gr_complex tap, gr_complex in). + * + * The error() function calculates the error value that will be + * used to adjust the taps. The update_tap function then uses the + * error and the input signal value to update a particular + * tap. Typically, the error is calculated for a given output and + * then this is used in a loop to update all of the filter taps in + * a loop: + * + * \code + * d_error = error(sum); + * for(k = 0; k < l; k++) { + * update_tap(d_taps[ntaps-k-1], in[i+k]); + * } + * \endcode + * + * See digital::cma_equalizer_cc and digital::lms_dd_equalizer_cc + * for example usage. + */ + class FILTER_API adaptive_fir_ccc : virtual public gr_sync_decimator + { + public: + // gr::filter::adaptive_fir_ccc::sptr + typedef boost::shared_ptr<adaptive_fir_ccc> sptr; + + /*! + * \brief Adaptive FIR filter with gr_complex input, gr_complex output and gr_complex taps + * + * \param name Provides a name to identify this type of algorithm + * \param decimation (interger) decimation rate of the filter + * \param taps (complex) filter taps + */ + static sptr make(const char *name, int decimation, + const std::vector<gr_complex> &taps); + + virtual void set_taps(const std::vector<gr_complex> &taps) = 0; + virtual std::vector<gr_complex> taps() const = 0; + }; + + } /* namespace filter */ +} /* namespace gr */ + +#endif /* INCLUDED_FILTER_ADAPTIVE_FIR_CCC_H */ diff --git a/gr-filter/include/filter/adaptive_fir_ccf.h b/gr-filter/include/filter/adaptive_fir_ccf.h new file mode 100644 index 000000000..0fd8d5746 --- /dev/null +++ b/gr-filter/include/filter/adaptive_fir_ccf.h @@ -0,0 +1,81 @@ +/* -*- c++ -*- */ +/* + * Copyright 2011,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_FILTER_ADAPTIVE_FIR_CCF_H +#define INCLUDED_FILTER_ADAPTIVE_FIR_CCF_H + +#include <filter/api.h> +#include <gr_sync_decimator.h> + +namespace gr { + namespace filter { + + /*! + * \brief Adaptive FIR filter with gr_complex input, gr_complex output and float taps + * \ingroup filter_blk + * + * This is a base class to implement an adaptive FIR + * filter. Generally, another block will inherit from this one to + * build a new type of adaptive filter such as an equalizer. + * + * This class implements two functions that are designed to be + * overloaded by the child class: error(gr_complex out) and + * update_tap(float tap, gr_complex in). + * + * The error() function calculates the error value that will be + * used to adjust the taps. The update_tap function then uses the + * error and the input signal value to update a particular + * tap. Typically, the error is calculated for a given output and + * then this is used in a loop to update all of the filter taps in + * a loop: + * + * \code + * d_error = error(sum); + * for(k = 0; k < l; k++) { + * update_tap(d_taps[ntaps-k-1], in[i+k]); + * } + * \endcode + */ + class FILTER_API adaptive_fir_ccf : virtual public gr_sync_decimator + { + public: + // gr::filter::adaptive_fir_ccf::sptr + typedef boost::shared_ptr<adaptive_fir_ccf> sptr; + + /*! + * \brief Adaptive FIR filter with gr_complex input, gr_complex output and float taps + * + * \param name Provides a name to identify this type of algorithm + * \param decimation (interger) decimation rate of the filter + * \param taps (real) filter taps + */ + static sptr make(const char *name, int decimation, + const std::vector<float> &taps); + + virtual void set_taps(const std::vector<float> &taps) = 0; + virtual std::vector<float> taps() = 0; + }; + + } /* namespace filter */ +} /* namespace gr */ + +#endif /* INCLUDED_FILTER_ADAPTIVE_FIR_CCF_H */ diff --git a/gr-filter/include/filter/api.h b/gr-filter/include/filter/api.h new file mode 100644 index 000000000..025b0bd4a --- /dev/null +++ b/gr-filter/include/filter/api.h @@ -0,0 +1,33 @@ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_FILTER_API_H +#define INCLUDED_FILTER_API_H + +#include <gruel/attributes.h> + +#ifdef gnuradio_filter_EXPORTS +# define FILTER_API __GR_ATTR_EXPORT +#else +# define FILTER_API __GR_ATTR_IMPORT +#endif + +#endif /* INCLUDED_FILTER_API_H */ diff --git a/gr-filter/include/filter/channel_model.h b/gr-filter/include/filter/channel_model.h new file mode 100644 index 000000000..49c08181f --- /dev/null +++ b/gr-filter/include/filter/channel_model.h @@ -0,0 +1,87 @@ +/* -*- c++ -*- */ +/* + * Copyright 2009,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_FILTER_CHANNEL_MODEL_H +#define INCLUDED_FILTER_CHANNEL_MODEL_H + +#include <filter/api.h> +#include <gr_hier_block2.h> +#include <gr_types.h> + +namespace gr { + namespace filter { + + /*! + * \brief channel simulator + * \ingroup misc_blk + * + * This block implements a basic channel model simulator that can + * be used to help evaluate, design, and test various signals, + * waveforms, and algorithms. This model allows the user to set + * the voltage of an AWGN noise source, a (normalized) frequency + * offset, a sample timing offset, and a noise seed to randomize + * the AWGN noise source. + * + * Multipath can be approximated in this model by using a FIR + * filter representation of a multipath delay profile.. + */ + class FILTER_API channel_model : virtual public gr_hier_block2 + { + public: + // gr::filter::channel_model::sptr + typedef boost::shared_ptr<channel_model> sptr; + + /*! \brief Build the channel simulator. + * + * \param noise_voltage The AWGN noise level as a voltage (to be + * calculated externally to meet, say, a + * desired SNR). + * \param frequency_offset The normalized frequency offset. 0 is + * no offset; 0.25 would be, for a digital + * modem, one quarter of the symbol rate. + * \param epsilon The sample timing offset to emulate the + * different rates between the sample clocks of + * the transmitter and receiver. 1.0 is no difference. + * \param taps Taps of a FIR filter to emulate a multipath delay profile. + * \param noise_seed A random number generator seed for the noise source. + */ + static sptr make(double noise_voltage=0.0, + double frequency_offset=0.0, + double epsilon=1.0, + const std::vector<gr_complex> &taps=std::vector<gr_complex>(1,1), + double noise_seed=0); + + virtual void set_noise_voltage(double noise_voltage) = 0; + virtual void set_frequency_offset(double frequency_offset) = 0; + virtual void set_taps(const std::vector<gr_complex> &taps) = 0; + virtual void set_timing_offset(double epsilon) = 0; + + virtual double noise_voltage() const = 0; + virtual double frequency_offset() const = 0; + virtual std::vector<gr_complex> taps() const = 0; + virtual double timing_offset() const = 0; + }; + + } /* namespace filter */ +} /* namespace gr */ + +#endif /* INCLUDED_FILTER_CHANNEL_MODEL_H */ diff --git a/gr-filter/include/filter/dc_blocker_cc.h b/gr-filter/include/filter/dc_blocker_cc.h new file mode 100644 index 000000000..df4c815d6 --- /dev/null +++ b/gr-filter/include/filter/dc_blocker_cc.h @@ -0,0 +1,76 @@ +/* -*- c++ -*- */ +/* + * Copyright 2011,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_FILTER_DC_BLOCKER_CC_H +#define INCLUDED_FILTER_DC_BLOCKER_CC_H + +#include <filter/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace filter { + + class FILTER_API dc_blocker_cc : virtual public gr_sync_block + { + public: + + // gr::filter::dc_blocker_cc::sptr + typedef boost::shared_ptr<dc_blocker_cc> sptr; + + /*! + * \class dc_blocker_cc + * \brief a computationally efficient controllable DC blocker + * + * \ingroup filter_blk + * + * This block implements a computationally efficient DC blocker that produces + * a tighter notch filter around DC for a smaller group delay than an + * equivalent FIR filter or using a single pole IIR filter (though the IIR + * filter is computationally cheaper). + * + * The block defaults to using a delay line of length 32 and the long form + * of the filter. Optionally, the delay line length can be changed to alter + * the width of the DC notch (longer lines will decrease the width). + * + * The long form of the filter produces a nearly flat response outside of + * the notch but at the cost of a group delay of 2D-2. + * + * The short form of the filter does not have as flat a response in the + * passband but has a group delay of only D-1 and is cheaper to compute. + * + * The theory behind this block can be found in the paper: + * + * <B><EM>R. Yates, "DC Blocker Algorithms," IEEE Signal Processing Magazine, + * Mar. 2008, pp 132-134.</EM></B> + * + * \param D (int) the length of the delay line + * \param long_form (bool) whether to use long (true, default) or short form + */ + static sptr make(int D, bool long_form); + + virtual int group_delay() = 0; + }; + + } /* namespace filter */ +} /* namespace gr */ + +#endif /* INCLUDED_FILTER_DC_BLOCKER_CC_H */ diff --git a/gr-filter/include/filter/dc_blocker_ff.h b/gr-filter/include/filter/dc_blocker_ff.h new file mode 100644 index 000000000..6ab4d5a3d --- /dev/null +++ b/gr-filter/include/filter/dc_blocker_ff.h @@ -0,0 +1,76 @@ +/* -*- c++ -*- */ +/* + * Copyright 2011,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_FILTER_DC_BLOCKER_FF_H +#define INCLUDED_FILTER_DC_BLOCKER_FF_H + +#include <filter/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace filter { + + class FILTER_API dc_blocker_ff : virtual public gr_sync_block + { + public: + + // gr::filter::dc_blocker_ff::sptr + typedef boost::shared_ptr<dc_blocker_ff> sptr; + + /*! + * \class dc_blocker_ff + * \brief a computationally efficient controllable DC blocker + * + * \ingroup filter_blk + * + * This block implements a computationally efficient DC blocker that produces + * a tighter notch filter around DC for a smaller group delay than an + * equivalent FIR filter or using a single pole IIR filter (though the IIR + * filter is computationally cheaper). + * + * The block defaults to using a delay line of length 32 and the long form + * of the filter. Optionally, the delay line length can be changed to alter + * the width of the DC notch (longer lines will decrease the width). + * + * The long form of the filter produces a nearly flat response outside of + * the notch but at the cost of a group delay of 2D-2. + * + * The short form of the filter does not have as flat a response in the + * passband but has a group delay of only D-1 and is cheaper to compute. + * + * The theory behind this block can be found in the paper: + * + * <B><EM>R. Yates, "DC Blocker Algorithms," IEEE Signal Processing Magazine, + * Mar. 2008, pp 132-134.</EM></B> + * + * \param D (int) the length of the delay line + * \param long_form (bool) whether to use long (true, default) or short form + */ + static sptr make(int D, bool long_form=true); + + virtual int group_delay() = 0; + }; + + } /* namespace filter */ +} /* namespace gr */ + +#endif /* INCLUDED_FILTER_DC_BLOCKER_FF_H */ diff --git a/gr-filter/include/filter/fft_filter.h b/gr-filter/include/filter/fft_filter.h new file mode 100644 index 000000000..8c7d6cf78 --- /dev/null +++ b/gr-filter/include/filter/fft_filter.h @@ -0,0 +1,171 @@ +/* -*- c++ -*- */ +/* + * Copyright 2010,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_FILTER_FFT_FILTER_H +#define INCLUDED_FILTER_FFT_FILTER_H + +#include <filter/api.h> +#include <vector> +#include <gr_complex.h> +#include <fft/fft.h> + +namespace gr { + namespace filter { + namespace kernel { + /*! + * \brief Fast FFT filter with float input, float output and float taps + * \ingroup filter_blk + */ + class FILTER_API fft_filter_fff + { + private: + int d_ntaps; + int d_nsamples; + int d_fftsize; // fftsize = ntaps + nsamples - 1 + int d_decimation; + fft::fft_real_fwd *d_fwdfft; // forward "plan" + fft::fft_real_rev *d_invfft; // inverse "plan" + int d_nthreads; // number of FFTW threads to use + std::vector<float> d_tail; // state carried between blocks for overlap-add + std::vector<float> d_new_taps; + gr_complex *d_xformed_taps; // Fourier xformed taps + + void compute_sizes(int ntaps); + int tailsize() const { return d_ntaps - 1; } + + public: + /*! + * \brief Construct an FFT filter for float vectors with the given taps and decimation rate. + * + * This is the basic implementation for performing FFT filter for fast convolution + * in other blocks for complex vectors (such as fft_filter_ccc). + * + * \param decimation The decimation rate of the filter (int) + * \param taps The filter taps (complex) + * \param nthreads The number of threads for the FFT to use (int) + */ + fft_filter_fff(int decimation, + const std::vector<float> &taps, + int nthreads=1); + + ~fft_filter_fff(); + + /*! + * \brief Set new taps for the filter. + * + * Sets new taps and resets the class properties to handle different sizes + * \param taps The filter taps (complex) + */ + int set_taps(const std::vector<float> &taps); + + /*! + * \brief Set number of threads to use. + */ + void set_nthreads(int n); + + /*! + * \brief Get number of threads being used. + */ + int nthreads() const; + + /*! + * \brief Perform the filter operation + * + * \param nitems The number of items to produce + * \param input The input vector to be filtered + * \param output The result of the filter operation + */ + int filter(int nitems, const float *input, float *output); + }; + + + /*! + * \brief Fast FFT filter with gr_complex input, gr_complex output and gr_complex taps + * \ingroup filter_blk + */ + class FILTER_API fft_filter_ccc + { + private: + int d_ntaps; + int d_nsamples; + int d_fftsize; // fftsize = ntaps + nsamples - 1 + int d_decimation; + fft::fft_complex *d_fwdfft; // forward "plan" + fft::fft_complex *d_invfft; // inverse "plan" + int d_nthreads; // number of FFTW threads to use + std::vector<gr_complex> d_tail; // state carried between blocks for overlap-add + std::vector<gr_complex> d_new_taps; + gr_complex *d_xformed_taps; // Fourier xformed taps + + void compute_sizes(int ntaps); + int tailsize() const { return d_ntaps - 1; } + + public: + /*! + * \brief Construct an FFT filter for complex vectors with the given taps and decimation rate. + * + * This is the basic implementation for performing FFT filter for fast convolution + * in other blocks for complex vectors (such as fft_filter_ccc). + * + * \param decimation The decimation rate of the filter (int) + * \param taps The filter taps (complex) + * \param nthreads The number of threads for the FFT to use (int) + */ + fft_filter_ccc(int decimation, + const std::vector<gr_complex> &taps, + int nthreads=1); + + ~fft_filter_ccc(); + + /*! + * \brief Set new taps for the filter. + * + * Sets new taps and resets the class properties to handle different sizes + * \param taps The filter taps (complex) + */ + int set_taps(const std::vector<gr_complex> &taps); + + /*! + * \brief Set number of threads to use. + */ + void set_nthreads(int n); + + /*! + * \brief Get number of threads being used. + */ + int nthreads() const; + + /*! + * \brief Perform the filter operation + * + * \param nitems The number of items to produce + * \param input The input vector to be filtered + * \param output The result of the filter operation + */ + int filter(int nitems, const gr_complex *input, gr_complex *output); + }; + + } /* namespace kernel */ + } /* namespace filter */ +} /* namespace gr */ + +#endif /* INCLUDED_FILTER_FFT_FILTER_H */ diff --git a/gr-filter/include/filter/fft_filter_ccc.h b/gr-filter/include/filter/fft_filter_ccc.h new file mode 100644 index 000000000..acec93277 --- /dev/null +++ b/gr-filter/include/filter/fft_filter_ccc.h @@ -0,0 +1,86 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_FILTER_FFT_FILTER_CCC_H +#define INCLUDED_FILTER_FFT_FILTER_CCC_H + +#include <filter/api.h> +#include <gr_sync_decimator.h> + +namespace gr { + namespace filter { + + class FILTER_API fft_filter_ccc : virtual public gr_sync_decimator + { + public: + // gr::filter::fft_filter_ccc::sptr + typedef boost::shared_ptr<fft_filter_ccc> sptr; + + /*! + * \brief Fast FFT filter with gr_complex input, gr_complex output and gr_complex taps + * \ingroup filter_blk + * + * This block implements a complex decimating filter using the + * fast convolution method via an FFT. The decimation factor is + * an interger that is greater than or equal to 1. + * + * The filter takes a set of complex (or real) taps to use in + * the filtering operation. These taps can be defined as + * anything that satisfies the user's filtering needs. For + * standard filters such as lowpass, highpass, bandpass, etc., + * the filter.firdes and filter.optfir classes provide + * convenient generating methods. + * + * This filter is implemented by using the FFTW package to + * perform the required FFTs. An optional argument, nthreads, + * may be passed to the constructor (or set using the + * set_nthreads member function) to split the FFT among N number + * of threads. This can improve performance on very large FFTs + * (that is, if the number of taps used is very large) if you + * have enough threads/cores to support it. + * + * \param decimation >= 1 + * \param taps complex filter taps + * \param nthreads number of threads for the FFT to use + */ + static sptr make(int decimation, + const std::vector<gr_complex> &taps, + int nthreads=1); + + virtual void set_taps(const std::vector<gr_complex> &taps) = 0; + virtual std::vector<gr_complex> taps() const = 0; + + /*! + * \brief Set number of threads to use. + */ + virtual void set_nthreads(int n) = 0; + + /*! + * \brief Get number of threads being used. + */ + virtual int nthreads() const = 0; + }; + + } /* namespace filter */ +} /* namespace gr */ + +#endif /* INCLUDED_FILTER_FFT_FILTER_CCC_H */ diff --git a/gr-filter/include/filter/fft_filter_fff.h b/gr-filter/include/filter/fft_filter_fff.h new file mode 100644 index 000000000..d8140325f --- /dev/null +++ b/gr-filter/include/filter/fft_filter_fff.h @@ -0,0 +1,86 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_FILTER_FFT_FILTER_FFF_H +#define INCLUDED_FILTER_FFT_FILTER_FFF_H + +#include <filter/api.h> +#include <gr_sync_decimator.h> + +namespace gr { + namespace filter { + + class FILTER_API fft_filter_fff : virtual public gr_sync_decimator + { + public: + // gr::filter::fft_filter_fff::sptr + typedef boost::shared_ptr<fft_filter_fff> sptr; + + /*! + * \brief Fast FFT filter with float input, float output and float taps + * \ingroup filter_blk + * + * This block implements a real-value decimating filter using + * the fast convolution method via an FFT. The decimation factor + * is an interger that is greater than or equal to 1. + * + * The filter takes a set of real-valued taps to use in + * the filtering operation. These taps can be defined as + * anything that satisfies the user's filtering needs. For + * standard filters such as lowpass, highpass, bandpass, etc., + * the filter.firdes and filter.optfir classes provide + * convenient generating methods. + * + * This filter is implemented by using the FFTW package to + * perform the required FFTs. An optional argument, nthreads, + * may be passed to the constructor (or set using the + * set_nthreads member function) to split the FFT among N number + * of threads. This can improve performance on very large FFTs + * (that is, if the number of taps used is very large) if you + * have enough threads/cores to support it. + * + * \param decimation >= 1 + * \param taps float filter taps + * \param nthreads number of threads for the FFT to use + */ + static sptr make(int decimation, + const std::vector<float> &taps, + int nthreads=1); + + virtual void set_taps(const std::vector<float> &taps) = 0; + virtual std::vector<float> taps() const = 0; + + /*! + * \brief Set number of threads to use. + */ + virtual void set_nthreads(int n) = 0; + + /*! + * \brief Get number of threads being used. + */ + virtual int nthreads() const = 0; + }; + + } /* namespace filter */ +} /* namespace gr */ + +#endif /* INCLUDED_FILTER_FFT_FILTER_FFF_H */ diff --git a/gr-filter/include/filter/filter_delay_fc.h b/gr-filter/include/filter/filter_delay_fc.h new file mode 100644 index 000000000..8a84a6a0e --- /dev/null +++ b/gr-filter/include/filter/filter_delay_fc.h @@ -0,0 +1,65 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_FILTER_FILTER_DELAY_FC_H +#define INCLUDED_FILTER_FILTER_DELAY_FC_H + +#include <filter/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace filter { + + class FILTER_API filter_delay_fc : virtual public gr_sync_block + { + public: + + // gr::filter::filter_delay_fc::sptr + typedef boost::shared_ptr<filter_delay_fc> sptr; + + /*! + * \brief Filter-Delay Combination Block. + * \ingroup filter_blk + * + * The block takes one or two float stream and outputs a complex + * stream. + * + * If only one float stream is input, the real output is a + * delayed version of this input and the imaginary output is the + * filtered output. + * + * If two floats are connected to the input, then the real + * output is the delayed version of the first input, and the + * imaginary output is the filtered output. + * + * The delay in the real path accounts for the group delay + * introduced by the filter in the imaginary path. The filter + * taps needs to be calculated before initializing this block. + * + */ + static sptr make(const std::vector<float> &taps); + }; + + } /* namespace filter */ +} /* namespace gr */ + +#endif /* INCLUDED_FILTER_FILTER_DELAY_FC_H */ diff --git a/gr-filter/include/filter/fir_filter.h b/gr-filter/include/filter/fir_filter.h new file mode 100644 index 000000000..e86111268 --- /dev/null +++ b/gr-filter/include/filter/fir_filter.h @@ -0,0 +1,222 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2010,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_FILTER_FIR_FILTER_H +#define INCLUDED_FILTER_FIR_FILTER_H + +#include <filter/api.h> +#include <vector> +#include <gr_complex.h> + +namespace gr { + namespace filter { + namespace kernel { + + class FILTER_API fir_filter_fff + { + public: + fir_filter_fff(int decimation, + const std::vector<float> &taps); + ~fir_filter_fff(); + + void set_taps(const std::vector<float> &taps); + std::vector<float> taps() const; + unsigned int ntaps() const; + + float filter(const float input[]); + void filterN(float output[], + const float input[], + unsigned long n); + void filterNdec(float output[], + const float input[], + unsigned long n, + unsigned int decimate); + + protected: + std::vector<float> d_taps; + unsigned int d_ntaps; + float **d_aligned_taps; + float *d_output; + int d_align; + int d_naligned; + }; + + /**************************************************************/ + + class FILTER_API fir_filter_ccf + { + public: + fir_filter_ccf(int decimation, + const std::vector<float> &taps); + ~fir_filter_ccf(); + + void set_taps(const std::vector<float> &taps); + std::vector<float> taps() const; + unsigned int ntaps() const; + + gr_complex filter(const gr_complex input[]); + void filterN(gr_complex output[], + const gr_complex input[], + unsigned long n); + void filterNdec(gr_complex output[], + const gr_complex input[], + unsigned long n, + unsigned int decimate); + + protected: + std::vector<float> d_taps; + unsigned int d_ntaps; + float **d_aligned_taps; + gr_complex *d_output; + int d_align; + int d_naligned; + }; + + /**************************************************************/ + + class FILTER_API fir_filter_fcc + { + public: + fir_filter_fcc(int decimation, + const std::vector<gr_complex> &taps); + ~fir_filter_fcc(); + + void set_taps(const std::vector<gr_complex> &taps); + std::vector<gr_complex> taps() const; + unsigned int ntaps() const; + + gr_complex filter(const float input[]); + void filterN(gr_complex output[], + const float input[], + unsigned long n); + void filterNdec(gr_complex output[], + const float input[], + unsigned long n, + unsigned int decimate); + + protected: + std::vector<gr_complex> d_taps; + unsigned int d_ntaps; + gr_complex **d_aligned_taps; + gr_complex *d_output; + int d_align; + int d_naligned; + }; + + /**************************************************************/ + + class FILTER_API fir_filter_ccc + { + public: + fir_filter_ccc(int decimation, + const std::vector<gr_complex> &taps); + ~fir_filter_ccc(); + + void set_taps(const std::vector<gr_complex> &taps); + std::vector<gr_complex> taps() const; + unsigned int ntaps() const; + + gr_complex filter(const gr_complex input[]); + void filterN(gr_complex output[], + const gr_complex input[], + unsigned long n); + void filterNdec(gr_complex output[], + const gr_complex input[], + unsigned long n, + unsigned int decimate); + + protected: + std::vector<gr_complex> d_taps; + unsigned int d_ntaps; + gr_complex **d_aligned_taps; + gr_complex *d_output; + int d_align; + int d_naligned; + }; + + /**************************************************************/ + + class FILTER_API fir_filter_scc + { + public: + fir_filter_scc(int decimation, + const std::vector<gr_complex> &taps); + ~fir_filter_scc(); + + void set_taps(const std::vector<gr_complex> &taps); + std::vector<gr_complex> taps() const; + unsigned int ntaps() const; + + gr_complex filter(const short input[]); + void filterN(gr_complex output[], + const short input[], + unsigned long n); + void filterNdec(gr_complex output[], + const short input[], + unsigned long n, + unsigned int decimate); + + protected: + std::vector<gr_complex> d_taps; + unsigned int d_ntaps; + gr_complex **d_aligned_taps; + gr_complex *d_output; + int d_align; + int d_naligned; + }; + + /**************************************************************/ + + class FILTER_API fir_filter_fsf + { + public: + fir_filter_fsf(int decimation, + const std::vector<float> &taps); + ~fir_filter_fsf(); + + void set_taps(const std::vector<float> &taps); + std::vector<float> taps() const; + unsigned int ntaps() const; + + short filter(const float input[]); + void filterN(short output[], + const float input[], + unsigned long n); + void filterNdec(short output[], + const float input[], + unsigned long n, + unsigned int decimate); + + protected: + std::vector<float> d_taps; + unsigned int d_ntaps; + float **d_aligned_taps; + short *d_output; + int d_align; + int d_naligned; + }; + + } /* namespace kernel */ + } /* namespace filter */ +} /* namespace gr */ + +#endif /* INCLUDED_FILTER_FIR_FILTER_H */ diff --git a/gr-filter/include/filter/fir_filter_XXX.h.t b/gr-filter/include/filter/fir_filter_XXX.h.t new file mode 100644 index 000000000..98e82f510 --- /dev/null +++ b/gr-filter/include/filter/fir_filter_XXX.h.t @@ -0,0 +1,82 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +/* @WARNING@ */ + +#ifndef @GUARD_NAME@ +#define @GUARD_NAME@ + +#include <filter/api.h> +#include <gr_sync_decimator.h> + +namespace gr { + namespace filter { + + /*! + * \brief FIR filter with @I_TYPE@ input, @O_TYPE@ output, and @TAP_TYPE@ taps + * \ingroup filter_blk + * + * The fir_filter_XXX blocks create finite impulse response + * (FIR) filters that perform the convolution in the time + * domain: + * + * \code + * out = 0 + * for i in ntaps: + * out += input[n-i] * taps[i] + * \endcode + * + * The taps are a C++ vector (or Python list) of values of the + * type specified by the third letter in the block's suffix. For + * this block, the value is of type @TAP_TYPE@. Taps can be + * created using the firdes or optfir tools. + * + * These versions of the filter can also act as down-samplers + * (or decimators) by specifying an integer value for \p + * decimation. + * + */ + class FILTER_API @BASE_NAME@ : virtual public gr_sync_decimator + { + public: + + // gr::filter::@BASE_NAME@::sptr + typedef boost::shared_ptr<@BASE_NAME@> sptr; + + /*! + * \brief FIR filter with @I_TYPE@ input, @O_TYPE@ output, and @TAP_TYPE@ taps + * \ingroup filter_blk + * + * \param decimation set the integer decimation rate + * \param taps a vector/list of taps of type @TAP_TYPE@ + */ + static sptr make(int decimation, + const std::vector<@TAP_TYPE@> &taps); + + virtual void set_taps(const std::vector<@TAP_TYPE@> &taps) = 0; + virtual std::vector<@TAP_TYPE@> taps() const = 0; + }; + + } /* namespace filter */ +} /* namespace gr */ + +#endif /* @GUARD_NAME@ */ diff --git a/gr-filter/include/filter/fir_filter_with_buffer.h b/gr-filter/include/filter/fir_filter_with_buffer.h new file mode 100644 index 000000000..007eae3fa --- /dev/null +++ b/gr-filter/include/filter/fir_filter_with_buffer.h @@ -0,0 +1,326 @@ +/* -*- c++ -*- */ +/* + * Copyright 2010,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_FILTER_FIR_FILTER_WITH_BUFFER_H +#define INCLUDED_FILTER_FIR_FILTER_WITH_BUFFER_H + +#include <filter/api.h> +#include <vector> +#include <gr_complex.h> + +namespace gr { + namespace filter { + namespace kernel { + + /*! + * \brief FIR with internal buffer for float input, float output and float taps. + * \ingroup filter + */ + class FILTER_API fir_filter_with_buffer_fff + { + private: + std::vector<float> d_taps; + unsigned int d_ntaps; + float *d_buffer_ptr; + float *d_buffer; + unsigned int d_idx; + float **d_aligned_taps; + float *d_output; + int d_align; + int d_naligned; + + public: + + // CONSTRUCTORS + + /*! + * \brief construct new FIR with given taps. + * + * Note that taps must be in forward order, e.g., coefficient 0 is + * stored in new_taps[0], coefficient 1 is stored in + * new_taps[1], etc. + */ + fir_filter_with_buffer_fff(const std::vector<float> &taps); + + ~fir_filter_with_buffer_fff(); + + // MANIPULATORS + + /*! + * \brief compute a single output value. + * + * \p input is a single input value of the filter type + * + * \returns the filtered input value. + */ + float filter(float input); + + /*! + * \brief compute a single output value; designed for decimating filters. + * + * \p input is a single input value of the filter type. The value of dec is the + * decimating value of the filter, so input[] must have dec valid values. + * The filter pushes dec number of items onto the circ. buffer before computing + * a single output. + * + * \returns the filtered input value. + */ + float filter(const float input[], unsigned long dec); + + /*! + * \brief compute an array of N output values. + * + * \p input must have (n - 1 + ntaps()) valid entries. + * input[0] .. input[n - 1 + ntaps() - 1] are referenced to compute the output values. + */ + void filterN(float output[], + const float input[], + unsigned long n); + + /*! + * \brief compute an array of N output values, decimating the input + * + * \p input must have (decimate * (n - 1) + ntaps()) valid entries. + * input[0] .. input[decimate * (n - 1) + ntaps() - 1] are referenced to + * compute the output values. + */ + void filterNdec(float output[], const float input[], + unsigned long n, unsigned long decimate); + + // ACCESSORS + + /*! + * \return number of taps in filter. + */ + unsigned int ntaps() const { return d_ntaps; } + + /*! + * \brief install \p new_taps as the current taps. + */ + void set_taps(const std::vector<float> &taps); + + /*! + * \return current taps + */ + std::vector<float> taps() const; + }; + + + /**************************************************************/ + + + /*! + * \brief FIR with internal buffer for gr_complex input, gr_complex output and gr_complex taps. + * \ingroup filter + */ + class FILTER_API fir_filter_with_buffer_ccc + { + private: + std::vector<gr_complex> d_taps; + unsigned int d_ntaps; + gr_complex *d_buffer_ptr; + gr_complex *d_buffer; + unsigned int d_idx; + gr_complex **d_aligned_taps; + gr_complex *d_output; + int d_align; + int d_naligned; + + public: + + // CONSTRUCTORS + + /*! + * \brief construct new FIR with given taps. + * + * Note that taps must be in forward order, e.g., coefficient 0 is + * stored in new_taps[0], coefficient 1 is stored in + * new_taps[1], etc. + */ + fir_filter_with_buffer_ccc(const std::vector<gr_complex> &taps); + + ~fir_filter_with_buffer_ccc(); + + // MANIPULATORS + + /*! + * \brief compute a single output value. + * + * \p input is a single input value of the filter type + * + * \returns the filtered input value. + */ + gr_complex filter(gr_complex input); + + /*! + * \brief compute a single output value; designed for decimating filters. + * + * \p input is a single input value of the filter type. The value of dec is the + * decimating value of the filter, so input[] must have dec valid values. + * The filter pushes dec number of items onto the circ. buffer before computing + * a single output. + * + * \returns the filtered input value. + */ + gr_complex filter(const gr_complex input[], unsigned long dec); + + /*! + * \brief compute an array of N output values. + * + * \p input must have (n - 1 + ntaps()) valid entries. + * input[0] .. input[n - 1 + ntaps() - 1] are referenced to compute the output values. + */ + void filterN(gr_complex output[], + const gr_complex input[], + unsigned long n); + + /*! + * \brief compute an array of N output values, decimating the input + * + * \p input must have (decimate * (n - 1) + ntaps()) valid entries. + * input[0] .. input[decimate * (n - 1) + ntaps() - 1] are referenced to + * compute the output values. + */ + void filterNdec(gr_complex output[], const gr_complex input[], + unsigned long n, unsigned long decimate); + + // ACCESSORS + + /*! + * \return number of taps in filter. + */ + unsigned int ntaps() const { return d_ntaps; } + + /*! + * \brief install \p new_taps as the current taps. + */ + void set_taps(const std::vector<gr_complex> &taps); + + /*! + * \return current taps + */ + std::vector<gr_complex> taps() const; + }; + + + /**************************************************************/ + + + /*! + * \brief FIR with internal buffer for gr_complex input, gr_complex output and gr_complex taps. + * \ingroup filter + */ + class FILTER_API fir_filter_with_buffer_ccf + { + private: + std::vector<float> d_taps; + unsigned int d_ntaps; + gr_complex *d_buffer_ptr; + gr_complex *d_buffer; + unsigned int d_idx; + float **d_aligned_taps; + gr_complex *d_output; + int d_align; + int d_naligned; + + public: + + // CONSTRUCTORS + + /*! + * \brief construct new FIR with given taps. + * + * Note that taps must be in forward order, e.g., coefficient 0 is + * stored in new_taps[0], coefficient 1 is stored in + * new_taps[1], etc. + */ + fir_filter_with_buffer_ccf(const std::vector<float> &taps); + + ~fir_filter_with_buffer_ccf(); + + // MANIPULATORS + + /*! + * \brief compute a single output value. + * + * \p input is a single input value of the filter type + * + * \returns the filtered input value. + */ + gr_complex filter(gr_complex input); + + /*! + * \brief compute a single output value; designed for decimating filters. + * + * \p input is a single input value of the filter type. The value of dec is the + * decimating value of the filter, so input[] must have dec valid values. + * The filter pushes dec number of items onto the circ. buffer before computing + * a single output. + * + * \returns the filtered input value. + */ + gr_complex filter(const gr_complex input[], unsigned long dec); + + /*! + * \brief compute an array of N output values. + * + * \p input must have (n - 1 + ntaps()) valid entries. + * input[0] .. input[n - 1 + ntaps() - 1] are referenced to compute the output values. + */ + void filterN(gr_complex output[], + const gr_complex input[], + unsigned long n); + + /*! + * \brief compute an array of N output values, decimating the input + * + * \p input must have (decimate * (n - 1) + ntaps()) valid entries. + * input[0] .. input[decimate * (n - 1) + ntaps() - 1] are referenced to + * compute the output values. + */ + void filterNdec(gr_complex output[], const gr_complex input[], + unsigned long n, unsigned long decimate); + + // ACCESSORS + + /*! + * \return number of taps in filter. + */ + unsigned int ntaps() const { return d_ntaps; } + + /*! + * \brief install \p new_taps as the current taps. + */ + void set_taps(const std::vector<float> &taps); + + /*! + * \return current taps + */ + std::vector<float> taps() const; + }; + + + } /* namespace kernel */ + } /* namespace filter */ +} /* namespace gr */ + +#endif /* INCLUDED_FILTER_FIR_FILTER_WITH_BUFFER_H */ diff --git a/gr-filter/include/filter/firdes.h b/gr-filter/include/filter/firdes.h new file mode 100644 index 000000000..172563ea0 --- /dev/null +++ b/gr-filter/include/filter/firdes.h @@ -0,0 +1,378 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002,2008,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef _FILTER_FIRDES_H_ +#define _FILTER_FIRDES_H_ + +#include <filter/api.h> +#include <vector> +#include <cmath> +#include <gr_complex.h> + +namespace gr { + namespace filter { + + /*! + * \brief Finite Impulse Response (FIR) filter design functions. + * \ingroup filter_design + */ + + class FILTER_API firdes { + public: + + enum win_type { + WIN_HAMMING = 0, // max attenuation 53 dB + WIN_HANN = 1, // max attenuation 44 dB + WIN_BLACKMAN = 2, // max attenuation 74 dB + WIN_RECTANGULAR = 3, + WIN_KAISER = 4, // max attenuation a function of beta, google it + WIN_BLACKMAN_hARRIS = 5, + WIN_BLACKMAN_HARRIS = 5, // alias for capitalization consistency + }; + + + // ... class methods ... + + /*! + * \brief use "window method" to design a low-pass FIR filter + * + * \p gain: overall gain of filter (typically 1.0) + * \p sampling_freq: sampling freq (Hz) + * \p cutoff_freq: center of transition band (Hz) + * \p transition_width: width of transition band (Hz). + * The normalized width of the transition + * band is what sets the number of taps + * required. Narrow --> more taps + * \p window_type: What kind of window to use. Determines + * maximum attenuation and passband ripple. + * \p beta: parameter for Kaiser window + */ + static std::vector<float> + low_pass(double gain, + double sampling_freq, + double cutoff_freq, // Hz center of transition band + double transition_width, // Hz width of transition band + win_type window = WIN_HAMMING, + double beta = 6.76); // used only with Kaiser + + /*! + * \brief use "window method" to design a low-pass FIR filter + * + * \p gain: overall gain of filter (typically 1.0) + * \p sampling_freq: sampling freq (Hz) + * \p cutoff_freq: center of transition band (Hz) + * \p transition_width: width of transition band (Hz). + * \p attenuation_dB required stopband attenuation + * The normalized width of the transition + * band and the required stop band + * attenuation is what sets the number of taps + * required. Narrow --> more taps + * More attenuatin --> more taps + * \p window_type: What kind of window to use. Determines + * maximum attenuation and passband ripple. + * \p beta: parameter for Kaiser window + */ + + static std::vector<float> + low_pass_2(double gain, + double sampling_freq, + double cutoff_freq, // Hz beginning transition band + double transition_width, // Hz width of transition band + double attenuation_dB, // out of band attenuation dB + win_type window = WIN_HAMMING, + double beta = 6.76); // used only with Kaiser + + /*! + * \brief use "window method" to design a high-pass FIR filter + * + * \p gain: overall gain of filter (typically 1.0) + * \p sampling_freq: sampling freq (Hz) + * \p cutoff_freq: center of transition band (Hz) + * \p transition_width: width of transition band (Hz). + * The normalized width of the transition + * band is what sets the number of taps + * required. Narrow --> more taps + * \p window_type: What kind of window to use. Determines + * maximum attenuation and passband ripple. + * \p beta: parameter for Kaiser window + */ + + static std::vector<float> + high_pass(double gain, + double sampling_freq, + double cutoff_freq, // Hz center of transition band + double transition_width, // Hz width of transition band + win_type window = WIN_HAMMING, + double beta = 6.76); // used only with Kaiser + + /*! + * \brief use "window method" to design a high-pass FIR filter + * + * \p gain: overall gain of filter (typically 1.0) + * \p sampling_freq: sampling freq (Hz) + * \p cutoff_freq: center of transition band (Hz) + * \p transition_width: width of transition band (Hz). + * \p attenuation_dB out of band attenuation + * The normalized width of the transition + * band and the required stop band + * attenuation is what sets the number of taps + * required. Narrow --> more taps + * More attenuation --> more taps + * \p window_type: What kind of window to use. Determines + * maximum attenuation and passband ripple. + * \p beta: parameter for Kaiser window + */ + + static std::vector<float> + high_pass_2(double gain, + double sampling_freq, + double cutoff_freq, // Hz center of transition band + double transition_width, // Hz width of transition band + double attenuation_dB, // out of band attenuation dB + win_type window = WIN_HAMMING, + double beta = 6.76); // used only with Kaiser + + /*! + * \brief use "window method" to design a band-pass FIR filter + * + * \p gain: overall gain of filter (typically 1.0) + * \p sampling_freq: sampling freq (Hz) + * \p low_cutoff_freq: center of transition band (Hz) + * \p high_cutoff_freq: center of transition band (Hz) + * \p transition_width: width of transition band (Hz). + * The normalized width of the transition + * band is what sets the number of taps + * required. Narrow --> more taps + * \p window_type: What kind of window to use. Determines + * maximum attenuation and passband ripple. + * \p beta: parameter for Kaiser window + */ + static std::vector<float> + band_pass(double gain, + double sampling_freq, + double low_cutoff_freq, // Hz center of transition band + double high_cutoff_freq, // Hz center of transition band + double transition_width, // Hz width of transition band + win_type window = WIN_HAMMING, + double beta = 6.76); // used only with Kaiser + + /*! + * \brief use "window method" to design a band-pass FIR filter + * + * \p gain: overall gain of filter (typically 1.0) + * \p sampling_freq: sampling freq (Hz) + * \p low_cutoff_freq: center of transition band (Hz) + * \p high_cutoff_freq: center of transition band (Hz) + * \p transition_width: width of transition band (Hz). + * \p attenuation_dB out of band attenuation + * The normalized width of the transition + * band and the required stop band + * attenuation is what sets the number of taps + * required. Narrow --> more taps + * More attenuation --> more taps + * \p window_type: What kind of window to use. Determines + * maximum attenuation and passband ripple. + * \p beta: parameter for Kaiser window + */ + + static std::vector<float> + band_pass_2(double gain, + double sampling_freq, + double low_cutoff_freq, // Hz beginning transition band + double high_cutoff_freq, // Hz beginning transition band + double transition_width, // Hz width of transition band + double attenuation_dB, // out of band attenuation dB + win_type window = WIN_HAMMING, + double beta = 6.76); // used only with Kaiser + + /*! + * \brief use "window method" to design a complex band-pass FIR filter + * + * \p gain: overall gain of filter (typically 1.0) + * \p sampling_freq: sampling freq (Hz) + * \p low_cutoff_freq: center of transition band (Hz) + * \p high_cutoff_freq: center of transition band (Hz) + * \p transition_width: width of transition band (Hz). + * The normalized width of the transition + * band is what sets the number of taps + * required. Narrow --> more taps + * \p window_type: What kind of window to use. Determines + * maximum attenuation and passband ripple. + * \p beta: parameter for Kaiser window + */ + static std::vector<gr_complex> + complex_band_pass(double gain, + double sampling_freq, + double low_cutoff_freq, // Hz center of transition band + double high_cutoff_freq, // Hz center of transition band + double transition_width, // Hz width of transition band + win_type window = WIN_HAMMING, + double beta = 6.76); // used only with Kaiser + + /*! + * \brief use "window method" to design a complex band-pass FIR filter + * + * \p gain: overall gain of filter (typically 1.0) + * \p sampling_freq: sampling freq (Hz) + * \p low_cutoff_freq: center of transition band (Hz) + * \p high_cutoff_freq: center of transition band (Hz) + * \p transition_width: width of transition band (Hz). + * \p attenuation_dB out of band attenuation + * The normalized width of the transition + * band and the required stop band + * attenuation is what sets the number of taps + * required. Narrow --> more taps + * More attenuation --> more taps + * \p window_type: What kind of window to use. Determines + * maximum attenuation and passband ripple. + * \p beta: parameter for Kaiser window + */ + + static std::vector<gr_complex> + complex_band_pass_2(double gain, + double sampling_freq, + double low_cutoff_freq, // Hz beginning transition band + double high_cutoff_freq, // Hz beginning transition band + double transition_width, // Hz width of transition band + double attenuation_dB, // out of band attenuation dB + win_type window = WIN_HAMMING, + double beta = 6.76); // used only with Kaiser + + /*! + * \brief use "window method" to design a band-reject FIR filter + * + * \p gain: overall gain of filter (typically 1.0) + * \p sampling_freq: sampling freq (Hz) + * \p low_cutoff_freq: center of transition band (Hz) + * \p high_cutoff_freq: center of transition band (Hz) + * \p transition_width: width of transition band (Hz). + * The normalized width of the transition + * band is what sets the number of taps + * required. Narrow --> more taps + * \p window_type: What kind of window to use. Determines + * maximum attenuation and passband ripple. + * \p beta: parameter for Kaiser window + */ + + static std::vector<float> + band_reject(double gain, + double sampling_freq, + double low_cutoff_freq, // Hz center of transition band + double high_cutoff_freq, // Hz center of transition band + double transition_width, // Hz width of transition band + win_type window = WIN_HAMMING, + double beta = 6.76); // used only with Kaiser + + /*! + * \brief use "window method" to design a band-reject FIR filter + * + * \p gain: overall gain of filter (typically 1.0) + * \p sampling_freq: sampling freq (Hz) + * \p low_cutoff_freq: center of transition band (Hz) + * \p high_cutoff_freq: center of transition band (Hz) + * \p transition_width: width of transition band (Hz). + * \p attenuation_dB out of band attenuation + * The normalized width of the transition + * band and the required stop band + * attenuation is what sets the number of taps + * required. Narrow --> more taps + * More attenuation --> more taps + * \p window_type: What kind of window to use. Determines + * maximum attenuation and passband ripple. + * \p beta: parameter for Kaiser window + */ + + static std::vector<float> + band_reject_2(double gain, + double sampling_freq, + double low_cutoff_freq, // Hz beginning transition band + double high_cutoff_freq, // Hz beginning transition band + double transition_width, // Hz width of transition band + double attenuation_dB, // out of band attenuation dB + win_type window = WIN_HAMMING, + double beta = 6.76); // used only with Kaiser + + /*!\brief design a Hilbert Transform Filter + * + * \p ntaps: Number of taps, must be odd + * \p window_type: What kind of window to use + * \p beta: Only used for Kaiser + */ + static std::vector<float> + hilbert(unsigned int ntaps = 19, + win_type windowtype = WIN_RECTANGULAR, + double beta = 6.76); + + /*! + * \brief design a Root Cosine FIR Filter (do we need a window?) + * + * \p gain: overall gain of filter (typically 1.0) + * \p sampling_freq: sampling freq (Hz) + * \p symbol rate: symbol rate, must be a factor of sample rate + * \p alpha: excess bandwidth factor + * \p ntaps: number of taps + */ + static std::vector<float> + root_raised_cosine(double gain, + double sampling_freq, + double symbol_rate, // Symbol rate, NOT bitrate (unless BPSK) + double alpha, // Excess Bandwidth Factor + int ntaps); + + /*! + * \brief design a Gaussian filter + * + * \p gain: overall gain of filter (typically 1.0) + * \p symbols per bit: symbol rate, must be a factor of sample rate + * \p ntaps: number of taps + */ + static std::vector<float> + gaussian(double gain, + double spb, + double bt, // Bandwidth to bitrate ratio + int ntaps); + + // window functions ... + static std::vector<float> window (win_type type, int ntaps, double beta); + + private: + static double bessi0(double x); + static void sanity_check_1f(double sampling_freq, double f1, + double transition_width); + static void sanity_check_2f(double sampling_freq, double f1, double f2, + double transition_width); + static void sanity_check_2f_c(double sampling_freq, double f1, double f2, + double transition_width); + + static int compute_ntaps(double sampling_freq, + double transition_width, + win_type window_type, double beta); + + static int compute_ntaps_windes(double sampling_freq, + double transition_width, + double attenuation_dB); + }; + + } /* namespace filter */ +} /* namespace gr */ + +#endif /* _FILTER_FIRDES_H_ */ diff --git a/gr-filter/include/filter/fractional_interpolator_cc.h b/gr-filter/include/filter/fractional_interpolator_cc.h new file mode 100644 index 000000000..bb0e18932 --- /dev/null +++ b/gr-filter/include/filter/fractional_interpolator_cc.h @@ -0,0 +1,60 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2007,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_FRACTIONAL_INTERPOLATOR_CC_H +#define INCLUDED_FRACTIONAL_INTERPOLATOR_CC_H + +#include <filter/api.h> +#include <gr_block.h> + +namespace gr { + namespace filter { + + /*! + * \brief Interpolating MMSE filter with complex input, complex output + * \ingroup filter_blk + */ + class FILTER_API fractional_interpolator_cc : virtual public gr_block + { + public: + // gr::filter::fractional_interpolator_cc::sptr + typedef boost::shared_ptr<fractional_interpolator_cc> sptr; + + /*! + * \brief Build the interpolating MMSE filter (complex input, complex output) + * + * \param phase_shift The phase shift of the output signal to the input + * \param interp_ratio The interpolation ratio = input_rate / output_rate. + */ + static sptr make(float phase_shift, + float interp_ratio); + + virtual float mu() const = 0; + virtual float interp_ratio() const = 0; + virtual void set_mu (float mu) = 0; + virtual void set_interp_ratio(float interp_ratio) = 0; + }; + + } /* namespace filter */ +} /* namespace gr */ + +#endif /* INCLUDED_FRACTIONAL_INTERPOLATOR_FF_H */ diff --git a/gr-filter/include/filter/fractional_interpolator_ff.h b/gr-filter/include/filter/fractional_interpolator_ff.h new file mode 100644 index 000000000..fc43c3457 --- /dev/null +++ b/gr-filter/include/filter/fractional_interpolator_ff.h @@ -0,0 +1,60 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2007,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_FRACTIONAL_INTERPOLATOR_FF_H +#define INCLUDED_FRACTIONAL_INTERPOLATOR_FF_H + +#include <filter/api.h> +#include <gr_block.h> + +namespace gr { + namespace filter { + + /*! + * \brief Interpolating MMSE filter with float input, float output + * \ingroup filter_blk + */ + class FILTER_API fractional_interpolator_ff : virtual public gr_block + { + public: + // gr::filter::fractional_interpolator_ff::sptr + typedef boost::shared_ptr<fractional_interpolator_ff> sptr; + + /*! + * \brief Build the interpolating MMSE filter (float input, float output) + * + * \param phase_shift The phase shift of the output signal to the input + * \param interp_ratio The interpolation ratio = input_rate / output_rate. + */ + static sptr make(float phase_shift, + float interp_ratio); + + virtual float mu() const = 0; + virtual float interp_ratio() const = 0; + virtual void set_mu (float mu) = 0; + virtual void set_interp_ratio(float interp_ratio) = 0; + }; + + } /* namespace filter */ +} /* namespace gr */ + +#endif /* INCLUDED_FRACTIONAL_INTERPOLATOR_FF_H */ diff --git a/gr-filter/include/filter/freq_xlating_fir_filter_XXX.h.t b/gr-filter/include/filter/freq_xlating_fir_filter_XXX.h.t new file mode 100644 index 000000000..88e15f823 --- /dev/null +++ b/gr-filter/include/filter/freq_xlating_fir_filter_XXX.h.t @@ -0,0 +1,90 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002,2004,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +/* + * WARNING: This file is automatically generated by cmake. + * Any changes made to this file will be overwritten. + */ + +#ifndef @GUARD_NAME@ +#define @GUARD_NAME@ + +#include <filter/api.h> +#include <gr_sync_decimator.h> +#include <gr_rotator.h> + +namespace gr { + namespace filter { + + + /*! + * \brief FIR filter combined with frequency translation with + * @I_TYPE@ input, @O_TYPE@ output and @TAP_TYPE@ taps + * + * \ingroup filter_blk + * + * This class efficiently combines a frequency translation + * (typically "down conversion") with a FIR filter (typically + * low-pass) and decimation. It is ideally suited for a "channel + * selection filter" and can be efficiently used to select and + * decimate a narrow band signal out of wide bandwidth input. + * + * Uses a single input array to produce a single output array. + * Additional inputs and/or outputs are ignored. + */ + class FILTER_API @BASE_NAME@ : virtual public gr_sync_decimator + { + public: + // gr::filter::@BASE_NAME@::sptr + typedef boost::shared_ptr<@BASE_NAME@> sptr; + + /*! + * \brief FIR filter with @I_TYPE@ input, @O_TYPE@ output, and + * @TAP_TYPE@ taps that also frequency translates a signal from + * \p center_freq. + * + * Construct a FIR filter with the given taps and a composite + * frequency translation that shifts center_freq down to zero + * Hz. The frequency translation logically comes before the + * filtering operation. + * + * \param decimation set the integer decimation rate + * \param taps a vector/list of taps of type @TAP_TYPE@ + * \param center_freq Center frequency of signal to down convert from (Hz) + * \param sampling_freq Sampling rate of signal (in Hz) + */ + static sptr make(int decimation, + const std::vector<@TAP_TYPE@> &taps, + double center_freq, + double sampling_freq); + + virtual void set_center_freq(double center_freq) = 0; + virtual double center_freq() const = 0; + + virtual void set_taps(const std::vector<@TAP_TYPE@> &taps) = 0; + virtual std::vector<@TAP_TYPE@> taps() const = 0; + }; + + } /* namespace filter */ +} /* namespace gr */ + +#endif /* @GUARD_NAME@ */ diff --git a/gr-filter/include/filter/hilbert_fc.h b/gr-filter/include/filter/hilbert_fc.h new file mode 100644 index 000000000..de7cd82b6 --- /dev/null +++ b/gr-filter/include/filter/hilbert_fc.h @@ -0,0 +1,53 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_FILTER_HILBERT_FC_H +#define INCLUDED_FILTER_HILBERT_FC_H + +#include <filter/api.h> +#include <gr_sync_block.h> +#include <gr_types.h> + +namespace gr { + namespace filter { + + class FILTER_API hilbert_fc : virtual public gr_sync_block + { + public: + // gr::filter::hilbert_fc::sptr + typedef boost::shared_ptr<hilbert_fc> sptr; + + /*! + * \brief Hilbert transformer. + * \ingroup filter_blk + * + * real output is input appropriately delayed. + * imaginary output is hilbert filtered (90 degree phase shift) + * version of input. + */ + static sptr make(unsigned int ntaps); + }; + + } /* namespace filter */ +} /* namespace gr */ + +#endif /* INCLUDED_FILTER_HILBERT_FC_H */ diff --git a/gr-filter/include/filter/iir_filter.h b/gr-filter/include/filter/iir_filter.h new file mode 100644 index 000000000..667acec35 --- /dev/null +++ b/gr-filter/include/filter/iir_filter.h @@ -0,0 +1,183 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_IIR_FILTER_H +#define INCLUDED_IIR_FILTER_H + +#include <filter/api.h> +#include <vector> +#include <stdexcept> + +namespace gr { + namespace filter { + namespace kernel { + + /*! + * \brief base class template for Infinite Impulse Response filter (IIR) + */ + template<class i_type, class o_type, class tap_type> + class iir_filter + { + public: + /*! + * \brief Construct an IIR with the given taps. + * + * This filter uses the Direct Form I implementation, where + * \p fftaps contains the feed-forward taps, and \p fbtaps the feedback ones. + * + * \p fftaps and \p fbtaps must have equal numbers of taps + * + * The input and output satisfy a difference equation of the form + + \f[ + y[n] - \sum_{k=1}^{M} a_k y[n-k] = \sum_{k=0}^{N} b_k x[n-k] + \f] + + * with the corresponding rational system function + + \f[ + H(z) = \frac{\sum_{k=0}^{N} b_k z^{-k}}{1 - \sum_{k=1}^{M} a_k z^{-k}} + \f] + + * Note that some texts define the system function with a + in + * the denominator. If you're using that convention, you'll + * need to negate the feedback taps. + */ + iir_filter(const std::vector<tap_type>& fftaps, + const std::vector<tap_type>& fbtaps) throw (std::invalid_argument) + { + set_taps(fftaps, fbtaps); + } + + iir_filter() : d_latest_n(0),d_latest_m(0) { } + + ~iir_filter() {} + + /*! + * \brief compute a single output value. + * \returns the filtered input value. + */ + o_type filter(const i_type input); + + /*! + * \brief compute an array of N output values. + * \p input must have N valid entries. + */ + void filter_n(o_type output[], const i_type input[], long n); + + /*! + * \return number of taps in filter. + */ + unsigned ntaps_ff() const { return d_fftaps.size(); } + unsigned ntaps_fb() const { return d_fbtaps.size(); } + + /*! + * \brief install new taps. + */ + void set_taps(const std::vector<tap_type> &fftaps, + const std::vector<tap_type> &fbtaps) throw (std::invalid_argument) + { + d_latest_n = 0; + d_latest_m = 0; + d_fftaps = fftaps; + d_fbtaps = fbtaps; + + int n = fftaps.size(); + int m = fbtaps.size(); + d_prev_input.resize(2 * n); + d_prev_output.resize(2 * m); + + for(int i = 0; i < 2 * n; i++) { + d_prev_input[i] = 0; + } + for(int i = 0; i < 2 * m; i++) { + d_prev_output[i] = 0; + } + } + + protected: + std::vector<tap_type> d_fftaps; + std::vector<tap_type> d_fbtaps; + int d_latest_n; + int d_latest_m; + std::vector<tap_type> d_prev_output; + std::vector<i_type> d_prev_input; + }; + + // + // general case. We may want to specialize this + // + template<class i_type, class o_type, class tap_type> + o_type + iir_filter<i_type, o_type, tap_type>::filter(const i_type input) + { + tap_type acc; + unsigned i = 0; + unsigned n = ntaps_ff(); + unsigned m = ntaps_fb(); + + if(n == 0) + return (o_type)0; + + int latest_n = d_latest_n; + int latest_m = d_latest_m; + + acc = d_fftaps[0] * input; + for(i = 1; i < n; i ++) + acc += (d_fftaps[i] * d_prev_input[latest_n + i]); + for(i = 1; i < m; i ++) + acc += (d_fbtaps[i] * d_prev_output[latest_m + i]); + + // store the values twice to avoid having to handle wrap-around in the loop + d_prev_output[latest_m] = acc; + d_prev_output[latest_m+m] = acc; + d_prev_input[latest_n] = input; + d_prev_input[latest_n+n] = input; + + latest_n--; + latest_m--; + if(latest_n < 0) + latest_n += n; + if(latest_m < 0) + latest_m += m; + + d_latest_m = latest_m; + d_latest_n = latest_n; + return (o_type)acc; + } + + template<class i_type, class o_type, class tap_type> + void + iir_filter<i_type, o_type, tap_type>::filter_n(o_type output[], + const i_type input[], + long n) + { + for(int i = 0; i < n; i++) + output[i] = filter(input[i]); + } + + } /* namespace kernel */ + } /* namespace filter */ +} /* namespace gr */ + +#endif /* INCLUDED_IIR_FILTER_H */ + diff --git a/gr-filter/include/filter/iir_filter_ffd.h b/gr-filter/include/filter/iir_filter_ffd.h new file mode 100644 index 000000000..04dd1e776 --- /dev/null +++ b/gr-filter/include/filter/iir_filter_ffd.h @@ -0,0 +1,82 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_IIR_FILTER_FFD_H +#define INCLUDED_IIR_FILTER_FFD_H + +#include <filter/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace filter { + + /*! + * \brief IIR filter with float input, float output and double taps + * \ingroup filter_blk + * + * This filter uses the Direct Form I implementation, where + * \p fftaps contains the feed-forward taps, and \p fbtaps the feedback ones. + * + * + * The input and output satisfy a difference equation of the form + \htmlonly + \f{ + y[n] - \sum_{k=1}^{M} a_k y[n-k] = \sum_{k=0}^{N} b_k x[n-k] + \f} + \endhtmlonly + + \xmlonly + y[n] - \sum_{k=1}^{M} a_k y[n-k] = \sum_{k=0}^{N} b_k x[n-k] + \endxmlonly + + * with the corresponding rational system function + \htmlonly + \f{ + H(z) = \ frac{\sum_{k=0}^{M} b_k z^{-k}}{1 - \sum_{k=1}^{N} a_k z^{-k}} + \f} + \endhtmlonly + + \xmlonly + H(z) = \ frac{\sum_{k=0}^{M} b_k z^{-k}}{1 - \sum_{k=1}^{N} a_k z^{-k}} + \endxmlonly + + * Note that some texts define the system function with a + in the + * denominator. If you're using that convention, you'll need to + * negate the feedback taps. + */ + class FILTER_API iir_filter_ffd : virtual public gr_sync_block + { + public: + // gr::filter::iir_filter_ffd::sptr + typedef boost::shared_ptr<iir_filter_ffd> sptr; + + static sptr make(const std::vector<double> &fftaps, + const std::vector<double> &fbtaps); + + virtual void set_taps(const std::vector<double> &fftaps, + const std::vector<double> &fbtaps) = 0; + }; + + } /* namespace filter */ +} /* namespace gr */ + +#endif /* INCLUDED_IIR_FILTER_FFD_H */ diff --git a/gr-filter/include/filter/interp_fir_filter_XXX.h.t b/gr-filter/include/filter/interp_fir_filter_XXX.h.t new file mode 100644 index 000000000..b66c9f643 --- /dev/null +++ b/gr-filter/include/filter/interp_fir_filter_XXX.h.t @@ -0,0 +1,81 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +/* @WARNING@ */ + +#ifndef @GUARD_NAME@ +#define @GUARD_NAME@ + +#include <filter/api.h> +#include <gr_sync_interpolator.h> + +namespace gr { + namespace filter { + + /*! + * \brief Interpolating FIR filter with @I_TYPE@ input, @O_TYPE@ output and @TAP_TYPE@ taps + * \ingroup filter_blk + * + * The fir_filter_XXX blocks create finite impulse response + * (FIR) filters that perform the convolution in the time + * domain: + * + * \code + * out = 0 + * for i in ntaps: + * out += input[n-i] * taps[i] + * \endcode + * + * The taps are a C++ vector (or Python list) of values of the + * type specified by the third letter in the block's suffix. For + * this block, the value is of type @TAP_TYPE@. Taps can be + * created using the firdes or optfir tools. + * + * These versions of the filter can also act as up-samplers + * (or interpolators) by specifying an integer value for \p + * interpolation. + * + */ + class FILTER_API @BASE_NAME@ : virtual public gr_sync_interpolator + { + public: + // gr::filter::@BASE_NAME@::sptr + typedef boost::shared_ptr<@BASE_NAME@> sptr; + + /*! + * \brief Interpolating FIR filter with @I_TYPE@ input, @O_TYPE@ output, and @TAP_TYPE@ taps + * \ingroup filter_blk + * + * \param interpolation set the integer interpolation rate + * \param taps a vector/list of taps of type @TAP_TYPE@ + */ + static sptr make(unsigned interpolation, + const std::vector<@TAP_TYPE@> &taps); + + virtual void set_taps(const std::vector<@TAP_TYPE@> &taps) = 0; + virtual std::vector<@TAP_TYPE@> taps() const = 0; + }; + + } /* namespace filter */ +} /* namespace gr */ + +#endif /* @GUARD_NAME@ */ diff --git a/gr-filter/include/filter/interpolator_taps.h b/gr-filter/include/filter/interpolator_taps.h new file mode 100644 index 000000000..a232edd38 --- /dev/null +++ b/gr-filter/include/filter/interpolator_taps.h @@ -0,0 +1,140 @@ +/* + * This file was machine generated by gen_interpolator_taps. + * DO NOT EDIT BY HAND. + */ + +static const int NTAPS = 8; +static const int NSTEPS = 128; + +static const float taps[NSTEPS+1][NTAPS] = { + // -4 -3 -2 -1 0 1 2 3 mu + { 0.00000e+00, 0.00000e+00, 0.00000e+00, 0.00000e+00, 1.00000e+00, 0.00000e+00, 0.00000e+00, 0.00000e+00 }, // 0/128 + { -1.54700e-04, 8.53777e-04, -2.76968e-03, 7.89295e-03, 9.98534e-01, -5.41054e-03, 1.24642e-03, -1.98993e-04 }, // 1/128 + { -3.09412e-04, 1.70888e-03, -5.55134e-03, 1.58840e-02, 9.96891e-01, -1.07209e-02, 2.47942e-03, -3.96391e-04 }, // 2/128 + { -4.64053e-04, 2.56486e-03, -8.34364e-03, 2.39714e-02, 9.95074e-01, -1.59305e-02, 3.69852e-03, -5.92100e-04 }, // 3/128 + { -6.18544e-04, 3.42130e-03, -1.11453e-02, 3.21531e-02, 9.93082e-01, -2.10389e-02, 4.90322e-03, -7.86031e-04 }, // 4/128 + { -7.72802e-04, 4.27773e-03, -1.39548e-02, 4.04274e-02, 9.90917e-01, -2.60456e-02, 6.09305e-03, -9.78093e-04 }, // 5/128 + { -9.26747e-04, 5.13372e-03, -1.67710e-02, 4.87921e-02, 9.88580e-01, -3.09503e-02, 7.26755e-03, -1.16820e-03 }, // 6/128 + { -1.08030e-03, 5.98883e-03, -1.95925e-02, 5.72454e-02, 9.86071e-01, -3.57525e-02, 8.42626e-03, -1.35627e-03 }, // 7/128 + { -1.23337e-03, 6.84261e-03, -2.24178e-02, 6.57852e-02, 9.83392e-01, -4.04519e-02, 9.56876e-03, -1.54221e-03 }, // 8/128 + { -1.38589e-03, 7.69462e-03, -2.52457e-02, 7.44095e-02, 9.80543e-01, -4.50483e-02, 1.06946e-02, -1.72594e-03 }, // 9/128 + { -1.53777e-03, 8.54441e-03, -2.80746e-02, 8.31162e-02, 9.77526e-01, -4.95412e-02, 1.18034e-02, -1.90738e-03 }, // 10/128 + { -1.68894e-03, 9.39154e-03, -3.09033e-02, 9.19033e-02, 9.74342e-01, -5.39305e-02, 1.28947e-02, -2.08645e-03 }, // 11/128 + { -1.83931e-03, 1.02356e-02, -3.37303e-02, 1.00769e-01, 9.70992e-01, -5.82159e-02, 1.39681e-02, -2.26307e-03 }, // 12/128 + { -1.98880e-03, 1.10760e-02, -3.65541e-02, 1.09710e-01, 9.67477e-01, -6.23972e-02, 1.50233e-02, -2.43718e-03 }, // 13/128 + { -2.13733e-03, 1.19125e-02, -3.93735e-02, 1.18725e-01, 9.63798e-01, -6.64743e-02, 1.60599e-02, -2.60868e-03 }, // 14/128 + { -2.28483e-03, 1.27445e-02, -4.21869e-02, 1.27812e-01, 9.59958e-01, -7.04471e-02, 1.70776e-02, -2.77751e-03 }, // 15/128 + { -2.43121e-03, 1.35716e-02, -4.49929e-02, 1.36968e-01, 9.55956e-01, -7.43154e-02, 1.80759e-02, -2.94361e-03 }, // 16/128 + { -2.57640e-03, 1.43934e-02, -4.77900e-02, 1.46192e-01, 9.51795e-01, -7.80792e-02, 1.90545e-02, -3.10689e-03 }, // 17/128 + { -2.72032e-03, 1.52095e-02, -5.05770e-02, 1.55480e-01, 9.47477e-01, -8.17385e-02, 2.00132e-02, -3.26730e-03 }, // 18/128 + { -2.86289e-03, 1.60193e-02, -5.33522e-02, 1.64831e-01, 9.43001e-01, -8.52933e-02, 2.09516e-02, -3.42477e-03 }, // 19/128 + { -3.00403e-03, 1.68225e-02, -5.61142e-02, 1.74242e-01, 9.38371e-01, -8.87435e-02, 2.18695e-02, -3.57923e-03 }, // 20/128 + { -3.14367e-03, 1.76185e-02, -5.88617e-02, 1.83711e-01, 9.33586e-01, -9.20893e-02, 2.27664e-02, -3.73062e-03 }, // 21/128 + { -3.28174e-03, 1.84071e-02, -6.15931e-02, 1.93236e-01, 9.28650e-01, -9.53307e-02, 2.36423e-02, -3.87888e-03 }, // 22/128 + { -3.41815e-03, 1.91877e-02, -6.43069e-02, 2.02814e-01, 9.23564e-01, -9.84679e-02, 2.44967e-02, -4.02397e-03 }, // 23/128 + { -3.55283e-03, 1.99599e-02, -6.70018e-02, 2.12443e-01, 9.18329e-01, -1.01501e-01, 2.53295e-02, -4.16581e-03 }, // 24/128 + { -3.68570e-03, 2.07233e-02, -6.96762e-02, 2.22120e-01, 9.12947e-01, -1.04430e-01, 2.61404e-02, -4.30435e-03 }, // 25/128 + { -3.81671e-03, 2.14774e-02, -7.23286e-02, 2.31843e-01, 9.07420e-01, -1.07256e-01, 2.69293e-02, -4.43955e-03 }, // 26/128 + { -3.94576e-03, 2.22218e-02, -7.49577e-02, 2.41609e-01, 9.01749e-01, -1.09978e-01, 2.76957e-02, -4.57135e-03 }, // 27/128 + { -4.07279e-03, 2.29562e-02, -7.75620e-02, 2.51417e-01, 8.95936e-01, -1.12597e-01, 2.84397e-02, -4.69970e-03 }, // 28/128 + { -4.19774e-03, 2.36801e-02, -8.01399e-02, 2.61263e-01, 8.89984e-01, -1.15113e-01, 2.91609e-02, -4.82456e-03 }, // 29/128 + { -4.32052e-03, 2.43930e-02, -8.26900e-02, 2.71144e-01, 8.83893e-01, -1.17526e-01, 2.98593e-02, -4.94589e-03 }, // 30/128 + { -4.44107e-03, 2.50946e-02, -8.52109e-02, 2.81060e-01, 8.77666e-01, -1.19837e-01, 3.05345e-02, -5.06363e-03 }, // 31/128 + { -4.55932e-03, 2.57844e-02, -8.77011e-02, 2.91006e-01, 8.71305e-01, -1.22047e-01, 3.11866e-02, -5.17776e-03 }, // 32/128 + { -4.67520e-03, 2.64621e-02, -9.01591e-02, 3.00980e-01, 8.64812e-01, -1.24154e-01, 3.18153e-02, -5.28823e-03 }, // 33/128 + { -4.78866e-03, 2.71272e-02, -9.25834e-02, 3.10980e-01, 8.58189e-01, -1.26161e-01, 3.24205e-02, -5.39500e-03 }, // 34/128 + { -4.89961e-03, 2.77794e-02, -9.49727e-02, 3.21004e-01, 8.51437e-01, -1.28068e-01, 3.30021e-02, -5.49804e-03 }, // 35/128 + { -5.00800e-03, 2.84182e-02, -9.73254e-02, 3.31048e-01, 8.44559e-01, -1.29874e-01, 3.35600e-02, -5.59731e-03 }, // 36/128 + { -5.11376e-03, 2.90433e-02, -9.96402e-02, 3.41109e-01, 8.37557e-01, -1.31581e-01, 3.40940e-02, -5.69280e-03 }, // 37/128 + { -5.21683e-03, 2.96543e-02, -1.01915e-01, 3.51186e-01, 8.30432e-01, -1.33189e-01, 3.46042e-02, -5.78446e-03 }, // 38/128 + { -5.31716e-03, 3.02507e-02, -1.04150e-01, 3.61276e-01, 8.23188e-01, -1.34699e-01, 3.50903e-02, -5.87227e-03 }, // 39/128 + { -5.41467e-03, 3.08323e-02, -1.06342e-01, 3.71376e-01, 8.15826e-01, -1.36111e-01, 3.55525e-02, -5.95620e-03 }, // 40/128 + { -5.50931e-03, 3.13987e-02, -1.08490e-01, 3.81484e-01, 8.08348e-01, -1.37426e-01, 3.59905e-02, -6.03624e-03 }, // 41/128 + { -5.60103e-03, 3.19495e-02, -1.10593e-01, 3.91596e-01, 8.00757e-01, -1.38644e-01, 3.64044e-02, -6.11236e-03 }, // 42/128 + { -5.68976e-03, 3.24843e-02, -1.12650e-01, 4.01710e-01, 7.93055e-01, -1.39767e-01, 3.67941e-02, -6.18454e-03 }, // 43/128 + { -5.77544e-03, 3.30027e-02, -1.14659e-01, 4.11823e-01, 7.85244e-01, -1.40794e-01, 3.71596e-02, -6.25277e-03 }, // 44/128 + { -5.85804e-03, 3.35046e-02, -1.16618e-01, 4.21934e-01, 7.77327e-01, -1.41727e-01, 3.75010e-02, -6.31703e-03 }, // 45/128 + { -5.93749e-03, 3.39894e-02, -1.18526e-01, 4.32038e-01, 7.69305e-01, -1.42566e-01, 3.78182e-02, -6.37730e-03 }, // 46/128 + { -6.01374e-03, 3.44568e-02, -1.20382e-01, 4.42134e-01, 7.61181e-01, -1.43313e-01, 3.81111e-02, -6.43358e-03 }, // 47/128 + { -6.08674e-03, 3.49066e-02, -1.22185e-01, 4.52218e-01, 7.52958e-01, -1.43968e-01, 3.83800e-02, -6.48585e-03 }, // 48/128 + { -6.15644e-03, 3.53384e-02, -1.23933e-01, 4.62289e-01, 7.44637e-01, -1.44531e-01, 3.86247e-02, -6.53412e-03 }, // 49/128 + { -6.22280e-03, 3.57519e-02, -1.25624e-01, 4.72342e-01, 7.36222e-01, -1.45004e-01, 3.88454e-02, -6.57836e-03 }, // 50/128 + { -6.28577e-03, 3.61468e-02, -1.27258e-01, 4.82377e-01, 7.27714e-01, -1.45387e-01, 3.90420e-02, -6.61859e-03 }, // 51/128 + { -6.34530e-03, 3.65227e-02, -1.28832e-01, 4.92389e-01, 7.19116e-01, -1.45682e-01, 3.92147e-02, -6.65479e-03 }, // 52/128 + { -6.40135e-03, 3.68795e-02, -1.30347e-01, 5.02377e-01, 7.10431e-01, -1.45889e-01, 3.93636e-02, -6.68698e-03 }, // 53/128 + { -6.45388e-03, 3.72167e-02, -1.31800e-01, 5.12337e-01, 7.01661e-01, -1.46009e-01, 3.94886e-02, -6.71514e-03 }, // 54/128 + { -6.50285e-03, 3.75341e-02, -1.33190e-01, 5.22267e-01, 6.92808e-01, -1.46043e-01, 3.95900e-02, -6.73929e-03 }, // 55/128 + { -6.54823e-03, 3.78315e-02, -1.34515e-01, 5.32164e-01, 6.83875e-01, -1.45993e-01, 3.96678e-02, -6.75943e-03 }, // 56/128 + { -6.58996e-03, 3.81085e-02, -1.35775e-01, 5.42025e-01, 6.74865e-01, -1.45859e-01, 3.97222e-02, -6.77557e-03 }, // 57/128 + { -6.62802e-03, 3.83650e-02, -1.36969e-01, 5.51849e-01, 6.65779e-01, -1.45641e-01, 3.97532e-02, -6.78771e-03 }, // 58/128 + { -6.66238e-03, 3.86006e-02, -1.38094e-01, 5.61631e-01, 6.56621e-01, -1.45343e-01, 3.97610e-02, -6.79588e-03 }, // 59/128 + { -6.69300e-03, 3.88151e-02, -1.39150e-01, 5.71370e-01, 6.47394e-01, -1.44963e-01, 3.97458e-02, -6.80007e-03 }, // 60/128 + { -6.71985e-03, 3.90083e-02, -1.40136e-01, 5.81063e-01, 6.38099e-01, -1.44503e-01, 3.97077e-02, -6.80032e-03 }, // 61/128 + { -6.74291e-03, 3.91800e-02, -1.41050e-01, 5.90706e-01, 6.28739e-01, -1.43965e-01, 3.96469e-02, -6.79662e-03 }, // 62/128 + { -6.76214e-03, 3.93299e-02, -1.41891e-01, 6.00298e-01, 6.19318e-01, -1.43350e-01, 3.95635e-02, -6.78902e-03 }, // 63/128 + { -6.77751e-03, 3.94578e-02, -1.42658e-01, 6.09836e-01, 6.09836e-01, -1.42658e-01, 3.94578e-02, -6.77751e-03 }, // 64/128 + { -6.78902e-03, 3.95635e-02, -1.43350e-01, 6.19318e-01, 6.00298e-01, -1.41891e-01, 3.93299e-02, -6.76214e-03 }, // 65/128 + { -6.79662e-03, 3.96469e-02, -1.43965e-01, 6.28739e-01, 5.90706e-01, -1.41050e-01, 3.91800e-02, -6.74291e-03 }, // 66/128 + { -6.80032e-03, 3.97077e-02, -1.44503e-01, 6.38099e-01, 5.81063e-01, -1.40136e-01, 3.90083e-02, -6.71985e-03 }, // 67/128 + { -6.80007e-03, 3.97458e-02, -1.44963e-01, 6.47394e-01, 5.71370e-01, -1.39150e-01, 3.88151e-02, -6.69300e-03 }, // 68/128 + { -6.79588e-03, 3.97610e-02, -1.45343e-01, 6.56621e-01, 5.61631e-01, -1.38094e-01, 3.86006e-02, -6.66238e-03 }, // 69/128 + { -6.78771e-03, 3.97532e-02, -1.45641e-01, 6.65779e-01, 5.51849e-01, -1.36969e-01, 3.83650e-02, -6.62802e-03 }, // 70/128 + { -6.77557e-03, 3.97222e-02, -1.45859e-01, 6.74865e-01, 5.42025e-01, -1.35775e-01, 3.81085e-02, -6.58996e-03 }, // 71/128 + { -6.75943e-03, 3.96678e-02, -1.45993e-01, 6.83875e-01, 5.32164e-01, -1.34515e-01, 3.78315e-02, -6.54823e-03 }, // 72/128 + { -6.73929e-03, 3.95900e-02, -1.46043e-01, 6.92808e-01, 5.22267e-01, -1.33190e-01, 3.75341e-02, -6.50285e-03 }, // 73/128 + { -6.71514e-03, 3.94886e-02, -1.46009e-01, 7.01661e-01, 5.12337e-01, -1.31800e-01, 3.72167e-02, -6.45388e-03 }, // 74/128 + { -6.68698e-03, 3.93636e-02, -1.45889e-01, 7.10431e-01, 5.02377e-01, -1.30347e-01, 3.68795e-02, -6.40135e-03 }, // 75/128 + { -6.65479e-03, 3.92147e-02, -1.45682e-01, 7.19116e-01, 4.92389e-01, -1.28832e-01, 3.65227e-02, -6.34530e-03 }, // 76/128 + { -6.61859e-03, 3.90420e-02, -1.45387e-01, 7.27714e-01, 4.82377e-01, -1.27258e-01, 3.61468e-02, -6.28577e-03 }, // 77/128 + { -6.57836e-03, 3.88454e-02, -1.45004e-01, 7.36222e-01, 4.72342e-01, -1.25624e-01, 3.57519e-02, -6.22280e-03 }, // 78/128 + { -6.53412e-03, 3.86247e-02, -1.44531e-01, 7.44637e-01, 4.62289e-01, -1.23933e-01, 3.53384e-02, -6.15644e-03 }, // 79/128 + { -6.48585e-03, 3.83800e-02, -1.43968e-01, 7.52958e-01, 4.52218e-01, -1.22185e-01, 3.49066e-02, -6.08674e-03 }, // 80/128 + { -6.43358e-03, 3.81111e-02, -1.43313e-01, 7.61181e-01, 4.42134e-01, -1.20382e-01, 3.44568e-02, -6.01374e-03 }, // 81/128 + { -6.37730e-03, 3.78182e-02, -1.42566e-01, 7.69305e-01, 4.32038e-01, -1.18526e-01, 3.39894e-02, -5.93749e-03 }, // 82/128 + { -6.31703e-03, 3.75010e-02, -1.41727e-01, 7.77327e-01, 4.21934e-01, -1.16618e-01, 3.35046e-02, -5.85804e-03 }, // 83/128 + { -6.25277e-03, 3.71596e-02, -1.40794e-01, 7.85244e-01, 4.11823e-01, -1.14659e-01, 3.30027e-02, -5.77544e-03 }, // 84/128 + { -6.18454e-03, 3.67941e-02, -1.39767e-01, 7.93055e-01, 4.01710e-01, -1.12650e-01, 3.24843e-02, -5.68976e-03 }, // 85/128 + { -6.11236e-03, 3.64044e-02, -1.38644e-01, 8.00757e-01, 3.91596e-01, -1.10593e-01, 3.19495e-02, -5.60103e-03 }, // 86/128 + { -6.03624e-03, 3.59905e-02, -1.37426e-01, 8.08348e-01, 3.81484e-01, -1.08490e-01, 3.13987e-02, -5.50931e-03 }, // 87/128 + { -5.95620e-03, 3.55525e-02, -1.36111e-01, 8.15826e-01, 3.71376e-01, -1.06342e-01, 3.08323e-02, -5.41467e-03 }, // 88/128 + { -5.87227e-03, 3.50903e-02, -1.34699e-01, 8.23188e-01, 3.61276e-01, -1.04150e-01, 3.02507e-02, -5.31716e-03 }, // 89/128 + { -5.78446e-03, 3.46042e-02, -1.33189e-01, 8.30432e-01, 3.51186e-01, -1.01915e-01, 2.96543e-02, -5.21683e-03 }, // 90/128 + { -5.69280e-03, 3.40940e-02, -1.31581e-01, 8.37557e-01, 3.41109e-01, -9.96402e-02, 2.90433e-02, -5.11376e-03 }, // 91/128 + { -5.59731e-03, 3.35600e-02, -1.29874e-01, 8.44559e-01, 3.31048e-01, -9.73254e-02, 2.84182e-02, -5.00800e-03 }, // 92/128 + { -5.49804e-03, 3.30021e-02, -1.28068e-01, 8.51437e-01, 3.21004e-01, -9.49727e-02, 2.77794e-02, -4.89961e-03 }, // 93/128 + { -5.39500e-03, 3.24205e-02, -1.26161e-01, 8.58189e-01, 3.10980e-01, -9.25834e-02, 2.71272e-02, -4.78866e-03 }, // 94/128 + { -5.28823e-03, 3.18153e-02, -1.24154e-01, 8.64812e-01, 3.00980e-01, -9.01591e-02, 2.64621e-02, -4.67520e-03 }, // 95/128 + { -5.17776e-03, 3.11866e-02, -1.22047e-01, 8.71305e-01, 2.91006e-01, -8.77011e-02, 2.57844e-02, -4.55932e-03 }, // 96/128 + { -5.06363e-03, 3.05345e-02, -1.19837e-01, 8.77666e-01, 2.81060e-01, -8.52109e-02, 2.50946e-02, -4.44107e-03 }, // 97/128 + { -4.94589e-03, 2.98593e-02, -1.17526e-01, 8.83893e-01, 2.71144e-01, -8.26900e-02, 2.43930e-02, -4.32052e-03 }, // 98/128 + { -4.82456e-03, 2.91609e-02, -1.15113e-01, 8.89984e-01, 2.61263e-01, -8.01399e-02, 2.36801e-02, -4.19774e-03 }, // 99/128 + { -4.69970e-03, 2.84397e-02, -1.12597e-01, 8.95936e-01, 2.51417e-01, -7.75620e-02, 2.29562e-02, -4.07279e-03 }, // 100/128 + { -4.57135e-03, 2.76957e-02, -1.09978e-01, 9.01749e-01, 2.41609e-01, -7.49577e-02, 2.22218e-02, -3.94576e-03 }, // 101/128 + { -4.43955e-03, 2.69293e-02, -1.07256e-01, 9.07420e-01, 2.31843e-01, -7.23286e-02, 2.14774e-02, -3.81671e-03 }, // 102/128 + { -4.30435e-03, 2.61404e-02, -1.04430e-01, 9.12947e-01, 2.22120e-01, -6.96762e-02, 2.07233e-02, -3.68570e-03 }, // 103/128 + { -4.16581e-03, 2.53295e-02, -1.01501e-01, 9.18329e-01, 2.12443e-01, -6.70018e-02, 1.99599e-02, -3.55283e-03 }, // 104/128 + { -4.02397e-03, 2.44967e-02, -9.84679e-02, 9.23564e-01, 2.02814e-01, -6.43069e-02, 1.91877e-02, -3.41815e-03 }, // 105/128 + { -3.87888e-03, 2.36423e-02, -9.53307e-02, 9.28650e-01, 1.93236e-01, -6.15931e-02, 1.84071e-02, -3.28174e-03 }, // 106/128 + { -3.73062e-03, 2.27664e-02, -9.20893e-02, 9.33586e-01, 1.83711e-01, -5.88617e-02, 1.76185e-02, -3.14367e-03 }, // 107/128 + { -3.57923e-03, 2.18695e-02, -8.87435e-02, 9.38371e-01, 1.74242e-01, -5.61142e-02, 1.68225e-02, -3.00403e-03 }, // 108/128 + { -3.42477e-03, 2.09516e-02, -8.52933e-02, 9.43001e-01, 1.64831e-01, -5.33522e-02, 1.60193e-02, -2.86289e-03 }, // 109/128 + { -3.26730e-03, 2.00132e-02, -8.17385e-02, 9.47477e-01, 1.55480e-01, -5.05770e-02, 1.52095e-02, -2.72032e-03 }, // 110/128 + { -3.10689e-03, 1.90545e-02, -7.80792e-02, 9.51795e-01, 1.46192e-01, -4.77900e-02, 1.43934e-02, -2.57640e-03 }, // 111/128 + { -2.94361e-03, 1.80759e-02, -7.43154e-02, 9.55956e-01, 1.36968e-01, -4.49929e-02, 1.35716e-02, -2.43121e-03 }, // 112/128 + { -2.77751e-03, 1.70776e-02, -7.04471e-02, 9.59958e-01, 1.27812e-01, -4.21869e-02, 1.27445e-02, -2.28483e-03 }, // 113/128 + { -2.60868e-03, 1.60599e-02, -6.64743e-02, 9.63798e-01, 1.18725e-01, -3.93735e-02, 1.19125e-02, -2.13733e-03 }, // 114/128 + { -2.43718e-03, 1.50233e-02, -6.23972e-02, 9.67477e-01, 1.09710e-01, -3.65541e-02, 1.10760e-02, -1.98880e-03 }, // 115/128 + { -2.26307e-03, 1.39681e-02, -5.82159e-02, 9.70992e-01, 1.00769e-01, -3.37303e-02, 1.02356e-02, -1.83931e-03 }, // 116/128 + { -2.08645e-03, 1.28947e-02, -5.39305e-02, 9.74342e-01, 9.19033e-02, -3.09033e-02, 9.39154e-03, -1.68894e-03 }, // 117/128 + { -1.90738e-03, 1.18034e-02, -4.95412e-02, 9.77526e-01, 8.31162e-02, -2.80746e-02, 8.54441e-03, -1.53777e-03 }, // 118/128 + { -1.72594e-03, 1.06946e-02, -4.50483e-02, 9.80543e-01, 7.44095e-02, -2.52457e-02, 7.69462e-03, -1.38589e-03 }, // 119/128 + { -1.54221e-03, 9.56876e-03, -4.04519e-02, 9.83392e-01, 6.57852e-02, -2.24178e-02, 6.84261e-03, -1.23337e-03 }, // 120/128 + { -1.35627e-03, 8.42626e-03, -3.57525e-02, 9.86071e-01, 5.72454e-02, -1.95925e-02, 5.98883e-03, -1.08030e-03 }, // 121/128 + { -1.16820e-03, 7.26755e-03, -3.09503e-02, 9.88580e-01, 4.87921e-02, -1.67710e-02, 5.13372e-03, -9.26747e-04 }, // 122/128 + { -9.78093e-04, 6.09305e-03, -2.60456e-02, 9.90917e-01, 4.04274e-02, -1.39548e-02, 4.27773e-03, -7.72802e-04 }, // 123/128 + { -7.86031e-04, 4.90322e-03, -2.10389e-02, 9.93082e-01, 3.21531e-02, -1.11453e-02, 3.42130e-03, -6.18544e-04 }, // 124/128 + { -5.92100e-04, 3.69852e-03, -1.59305e-02, 9.95074e-01, 2.39714e-02, -8.34364e-03, 2.56486e-03, -4.64053e-04 }, // 125/128 + { -3.96391e-04, 2.47942e-03, -1.07209e-02, 9.96891e-01, 1.58840e-02, -5.55134e-03, 1.70888e-03, -3.09412e-04 }, // 126/128 + { -1.98993e-04, 1.24642e-03, -5.41054e-03, 9.98534e-01, 7.89295e-03, -2.76968e-03, 8.53777e-04, -1.54700e-04 }, // 127/128 + { 0.00000e+00, 0.00000e+00, 0.00000e+00, 1.00000e+00, 0.00000e+00, 0.00000e+00, 0.00000e+00, 0.00000e+00 }, // 128/128 +}; diff --git a/gr-filter/include/filter/mmse_fir_interpolator_cc.h b/gr-filter/include/filter/mmse_fir_interpolator_cc.h new file mode 100644 index 000000000..0436b4a0f --- /dev/null +++ b/gr-filter/include/filter/mmse_fir_interpolator_cc.h @@ -0,0 +1,79 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002,2007,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ +#ifndef _GRI_MMSE_FIR_INTERPOLATOR_CC_H_ +#define _GRI_MMSE_FIR_INTERPOLATOR_CC_H_ + +#include <filter/api.h> +#include <filter/fir_filter.h> +#include <gr_complex.h> +#include <vector> + +namespace gr { + namespace filter { + + /*! + * \brief Compute intermediate samples between signal samples x(k*Ts) + * \ingroup filter_primitive + * + * This implements a Mininum Mean Squared Error interpolator with + * 8 taps. It is suitable for signals where the bandwidth of + * interest B = 1/(4*Ts) Where Ts is the time between samples. + * + * Although mu, the fractional delay, is specified as a float, it + * is actually quantized. 0.0 <= mu <= 1.0. That is, mu is + * quantized in the interpolate method to 32nd's of a sample. + * + * For more information, in the GNU Radio source code, see: + * \li gnuradio-core/src/gen_interpolator_taps/README + * \li gnuradio-core/src/gen_interpolator_taps/praxis.txt + */ + + class FILTER_API mmse_fir_interpolator_cc + { + public: + mmse_fir_interpolator_cc(); + ~mmse_fir_interpolator_cc(); + + unsigned ntaps() const; + unsigned nsteps() const; + + /*! + * \brief compute a single interpolated output value. + * + * \p input must have ntaps() valid entries and be 8-byte aligned. + * input[0] .. input[ntaps() - 1] are referenced to compute the output value. + * \throws std::invalid_argument if input is not 8-byte aligned. + * + * \p mu must be in the range [0, 1] and specifies the fractional delay. + * + * \returns the interpolated input value. + */ + gr_complex interpolate(const gr_complex input[], float mu) const; + + protected: + std::vector<kernel::fir_filter_ccf *> filters; + }; + + } /* namespace filter */ +} /* namespace gr */ + +#endif /* _MMSE_FIR_INTERPOLATOR_CC_H_ */ diff --git a/gr-filter/include/filter/mmse_fir_interpolator_ff.h b/gr-filter/include/filter/mmse_fir_interpolator_ff.h new file mode 100644 index 000000000..4353aa94f --- /dev/null +++ b/gr-filter/include/filter/mmse_fir_interpolator_ff.h @@ -0,0 +1,76 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef _MMSE_FIR_INTERPOLATOR_FF_H_ +#define _MMSE_FIR_INTERPOLATOR_FF_H_ + +#include <filter/api.h> +#include <filter/fir_filter.h> +#include <vector> + +namespace gr { + namespace filter { + + /*! + * \brief Compute intermediate samples between signal samples x(k*Ts) + * \ingroup filter_primitive + * + * This implements a Mininum Mean Squared Error interpolator with + * 8 taps. It is suitable for signals where the bandwidth of + * interest B = 1/(4*Ts) Where Ts is the time between samples. + * + * Although mu, the fractional delay, is specified as a float, it + * is actually quantized. 0.0 <= mu <= 1.0. That is, mu is + * quantized in the interpolate method to 32nd's of a sample. + * + * For more information, in the GNU Radio source code, see: + * \li gnuradio-core/src/gen_interpolator_taps/README + * \li gnuradio-core/src/gen_interpolator_taps/praxis.txt + */ + class FILTER_API mmse_fir_interpolator_ff + { + public: + mmse_fir_interpolator_ff(); + ~mmse_fir_interpolator_ff(); + + unsigned ntaps() const; + unsigned nsteps() const; + + /*! + * \brief compute a single interpolated output value. + * \p input must have ntaps() valid entries. + * input[0] .. input[ntaps() - 1] are referenced to compute the output value. + * + * \p mu must be in the range [0, 1] and specifies the fractional delay. + * + * \returns the interpolated input value. + */ + float interpolate(const float input[], float mu) const; + + protected: + std::vector<kernel::fir_filter_fff*> filters; + }; + + } /* namespace filter */ +} /* namespace gr */ + +#endif /* _MMSE_FIR_INTERPOLATOR_FF_H_ */ diff --git a/gr-filter/include/filter/pfb_arb_resampler_ccf.h b/gr-filter/include/filter/pfb_arb_resampler_ccf.h new file mode 100644 index 000000000..a154e055a --- /dev/null +++ b/gr-filter/include/filter/pfb_arb_resampler_ccf.h @@ -0,0 +1,151 @@ +/* -*- c++ -*- */ +/* + * Copyright 2009,2010,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + + +#ifndef INCLUDED_PFB_ARB_RESAMPLER_CCF_H +#define INCLUDED_PFB_ARB_RESAMPLER_CCF_H + +#include <filter/api.h> +#include <gr_block.h> + +namespace gr { + namespace filter { + + /*! + * \class pfb_arb_resampler_ccf + * + * \brief Polyphase filterbank arbitrary resampler with + * gr_complex input, gr_complex output and float taps + * + * \ingroup filter_blk + * \ingroup pfb_blk + * + * This block takes in a signal stream and performs arbitrary + * resampling. The resampling rate can be any real number + * <EM>r</EM>. The resampling is done by constructing <EM>N</EM> + * filters where <EM>N</EM> is the interpolation rate. We then + * calculate <EM>D</EM> where <EM>D = floor(N/r)</EM>. + * + * Using <EM>N</EM> and <EM>D</EM>, we can perform rational + * resampling where <EM>N/D</EM> is a rational number close to the + * input rate <EM>r</EM> where we have <EM>N</EM> filters and we + * cycle through them as a polyphase filterbank with a stride of + * <EM>D</EM> so that <EM>i+1 = (i + D) % N</EM>. + * + * To get the arbitrary rate, we want to interpolate between two + * points. For each value out, we take an output from the current + * filter, <EM>i</EM>, and the next filter <EM>i+1</EM> and then + * linearly interpolate between the two based on the real + * resampling rate we want. + * + * The linear interpolation only provides us with an approximation + * to the real sampling rate specified. The error is a + * quantization error between the two filters we used as our + * interpolation points. To this end, the number of filters, + * <EM>N</EM>, used determines the quantization error; the larger + * <EM>N</EM>, the smaller the noise. You can design for a + * specified noise floor by setting the filter size (parameters + * <EM>filter_size</EM>). The size defaults to 32 filters, which + * is about as good as most implementations need. + * + * The trick with designing this filter is in how to specify the + * taps of the prototype filter. Like the PFB interpolator, the + * taps are specified using the interpolated filter rate. In this + * case, that rate is the input sample rate multiplied by the + * number of filters in the filterbank, which is also the + * interpolation rate. All other values should be relative to this + * rate. + * + * For example, for a 32-filter arbitrary resampler and using the + * GNU Radio's firdes utility to build the filter, we build a + * low-pass filter with a sampling rate of <EM>fs</EM>, a 3-dB + * bandwidth of <EM>BW</EM> and a transition bandwidth of + * <EM>TB</EM>. We can also specify the out-of-band attenuation to + * use, <EM>ATT</EM>, and the filter window function (a + * Blackman-harris window in this case). The first input is the + * gain of the filter, which we specify here as the interpolation + * rate (<EM>32</EM>). + * + * <B><EM>self._taps = filter.firdes.low_pass_2(32, 32*fs, BW, TB, + * attenuation_dB=ATT, window=filter.firdes.WIN_BLACKMAN_hARRIS)</EM></B> + * + * The theory behind this block can be found in Chapter 7.5 of + * the following book. + * + * <B><EM>f. harris, "Multirate Signal Processing for Communication + * Systems", Upper Saddle River, NJ: Prentice Hall, Inc. 2004.</EM></B> + */ + + class FILTER_API pfb_arb_resampler_ccf : virtual public gr_block + { + public: + // gr::filter::pfb_arb_resampler_ccf::sptr + typedef boost::shared_ptr<pfb_arb_resampler_ccf> sptr; + + /*! + * Build the polyphase filterbank arbitray resampler. + * \param rate (float) Specifies the resampling rate to use + * \param taps (vector/list of floats) The prototype filter to populate the filterbank. The taps + * should be generated at the filter_size sampling rate. + * \param filter_size (unsigned int) The number of filters in the filter bank. This is directly + * related to quantization noise introduced during the resampling. + * Defaults to 32 filters. + */ + static sptr make(float rate, + const std::vector<float> &taps, + unsigned int filter_size=32); + /*! + * Resets the filterbank's filter taps with the new prototype filter + * \param taps (vector/list of floats) The prototype filter to populate the filterbank. + */ + virtual void set_taps(const std::vector<float> &taps) = 0; + + /*! + * Return a vector<vector<>> of the filterbank taps + */ + virtual std::vector<std::vector<float> > taps() const = 0; + + /*! + * Print all of the filterbank taps to screen. + */ + virtual void print_taps() = 0; + + /*! + * Sets the resampling rate of the block. + */ + virtual void set_rate (float rate) = 0; + + /*! + * Sets the current phase offset in radians (0 to 2pi). + */ + virtual void set_phase(float ph) = 0; + + /*! + * Gets the current phase of the resampler in radians (2 to 2pi). + */ + virtual float phase() const = 0; + }; + + } /* namespace filter */ +} /* namespace gr */ + +#endif /* INCLUDED_PFB_ARB_RESAMPLER_CCF_H */ diff --git a/gr-filter/include/filter/pfb_arb_resampler_fff.h b/gr-filter/include/filter/pfb_arb_resampler_fff.h new file mode 100644 index 000000000..38dcc7132 --- /dev/null +++ b/gr-filter/include/filter/pfb_arb_resampler_fff.h @@ -0,0 +1,152 @@ +/* -*- c++ -*- */ +/* + * Copyright 2009-2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + + +#ifndef INCLUDED_PFB_ARB_RESAMPLER_FFF_H +#define INCLUDED_PFB_ARB_RESAMPLER_FFF_H + +#include <filter/api.h> +#include <gr_block.h> + +namespace gr { + namespace filter { + + /*! + * \class pfb_arb_resampler_fff + * + * \brief Polyphase filterbank arbitrary resampler with + * float input, float output and float taps + * + * \ingroup filter_blk + * \ingroup pfb_blk + * + * This block takes in a signal stream and performs arbitrary + * resampling. The resampling rate can be any real number + * <EM>r</EM>. The resampling is done by constructing <EM>N</EM> + * filters where <EM>N</EM> is the interpolation rate. We then + * calculate <EM>D</EM> where <EM>D = floor(N/r)</EM>. + * + * Using <EM>N</EM> and <EM>D</EM>, we can perform rational + * resampling where <EM>N/D</EM> is a rational number close to the + * input rate <EM>r</EM> where we have <EM>N</EM> filters and we + * cycle through them as a polyphase filterbank with a stride of + * <EM>D</EM> so that <EM>i+1 = (i + D) % N</EM>. + * + * To get the arbitrary rate, we want to interpolate between two + * points. For each value out, we take an output from the current + * filter, <EM>i</EM>, and the next filter <EM>i+1</EM> and then + * linearly interpolate between the two based on the real + * resampling rate we want. + * + * The linear interpolation only provides us with an approximation + * to the real sampling rate specified. The error is a + * quantization error between the two filters we used as our + * interpolation points. To this end, the number of filters, + * <EM>N</EM>, used determines the quantization error; the larger + * <EM>N</EM>, the smaller the noise. You can design for a + * specified noise floor by setting the filter size (parameters + * <EM>filter_size</EM>). The size defaults to 32 filters, which + * is about as good as most implementations need. + * + * The trick with designing this filter is in how to specify the + * taps of the prototype filter. Like the PFB interpolator, the + * taps are specified using the interpolated filter rate. In this + * case, that rate is the input sample rate multiplied by the + * number of filters in the filterbank, which is also the + * interpolation rate. All other values should be relative to this + * rate. + * + * For example, for a 32-filter arbitrary resampler and using the + * GNU Radio's firdes utility to build the filter, we build a + * low-pass filter with a sampling rate of <EM>fs</EM>, a 3-dB + * bandwidth of <EM>BW</EM> and a transition bandwidth of + * <EM>TB</EM>. We can also specify the out-of-band attenuation to + * use, <EM>ATT</EM>, and the filter window function (a + * Blackman-harris window in this case). The first input is the + * gain of the filter, which we specify here as the interpolation + * rate (<EM>32</EM>). + * + * <B><EM>self._taps = filter.firdes.low_pass_2(32, 32*fs, BW, TB, + * attenuation_dB=ATT, window=filter.firdes.WIN_BLACKMAN_hARRIS)</EM></B> + * + * The theory behind this block can be found in Chapter 7.5 of the + * following book. + * + * <B><EM>f. harris, "Multirate Signal Processing for Communication + * Systems", Upper Saddle River, NJ: Prentice Hall, Inc. 2004.</EM></B> + */ + + class FILTER_API pfb_arb_resampler_fff : virtual public gr_block + { + public: + // gr::filter::pfb_arb_resampler_fff::sptr + typedef boost::shared_ptr<pfb_arb_resampler_fff> sptr; + + /*! + * Build the polyphase filterbank arbitray resampler. + * \param rate (float) Specifies the resampling rate to use + * \param taps (vector/list of floats) The prototype filter to populate the filterbank. The taps + * should be generated at the filter_size sampling rate. + * \param filter_size (unsigned int) The number of filters in the filter bank. This is directly + * related to quantization noise introduced during the resampling. + * Defaults to 32 filters. + */ + static sptr make(float rate, + const std::vector<float> &taps, + unsigned int filter_size=32); + + /*! + * Resets the filterbank's filter taps with the new prototype filter + * \param taps (vector/list of floats) The prototype filter to populate the filterbank. + */ + virtual void set_taps(const std::vector<float> &taps) = 0; + + /*! + * Return a vector<vector<>> of the filterbank taps + */ + virtual std::vector<std::vector<float> > taps() const = 0; + + /*! + * Print all of the filterbank taps to screen. + */ + virtual void print_taps() = 0; + + /*! + * Sets the resampling rate of the block. + */ + virtual void set_rate (float rate) = 0; + + /*! + * Sets the current phase offset in radians (0 to 2pi). + */ + virtual void set_phase(float ph) = 0; + + /*! + * Gets the current phase of the resampler in radians (2 to 2pi). + */ + virtual float phase() const = 0; + }; + + } /* namespace filter */ +} /* namespace gr */ + +#endif /* INCLUDED_PFB_ARB_RESAMPLER_FFF_H */ diff --git a/gr-filter/include/filter/pfb_channelizer_ccf.h b/gr-filter/include/filter/pfb_channelizer_ccf.h new file mode 100644 index 000000000..2ff83b5e7 --- /dev/null +++ b/gr-filter/include/filter/pfb_channelizer_ccf.h @@ -0,0 +1,204 @@ +/* -*- c++ -*- */ +/* + * Copyright 2009,2010,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + + +#ifndef INCLUDED_FILTER_PFB_CHANNELIZER_CCF_H +#define INCLUDED_FILTER_PFB_CHANNELIZER_CCF_H + +#include <filter/api.h> +#include <gr_block.h> + +namespace gr { + namespace filter { + + /*! + * \class pfb_channelizer_ccf + * + * \brief Polyphase filterbank channelizer with + * gr_complex input, gr_complex output and float taps + * + * \ingroup filter_blk + * \ingroup pfb_blk + * + * This block takes in complex inputs and channelizes it to <EM>M</EM> + * channels of equal bandwidth. Each of the resulting channels is + * decimated to the new rate that is the input sampling rate + * <EM>fs</EM> divided by the number of channels, <EM>M</EM>. + * + * The PFB channelizer code takes the taps generated above and builds + * a set of filters. The set contains <EM>M</EM> number of filters + * and each filter contains ceil(taps.size()/decim) number of taps. + * Each tap from the filter prototype is sequentially inserted into + * the next filter. When all of the input taps are used, the remaining + * filters in the filterbank are filled out with 0's to make sure each + * filter has the same number of taps. + * + * Each filter operates using the gr_fir filter classs of GNU Radio, + * which takes the input stream at <EM>i</EM> and performs the inner + * product calculation to <EM>i+(n-1)</EM> where <EM>n</EM> is the + * number of filter taps. To efficiently handle this in the GNU Radio + * structure, each filter input must come from its own input + * stream. So the channelizer must be provided with <EM>M</EM> streams + * where the input stream has been deinterleaved. This is most easily + * done using the gr_stream_to_streams block. + * + * The output is then produced as a vector, where index <EM>i</EM> in + * the vector is the next sample from the <EM>i</EM>th channel. This + * is most easily handled by sending the output to a + * gr_vector_to_streams block to handle the conversion and passing + * <EM>M</EM> streams out. + * + * The input and output formatting is done using a hier_block2 called + * pfb_channelizer_ccf. This can take in a single stream and outputs + * <EM>M</EM> streams based on the behavior described above. + * + * The filter's taps should be based on the input sampling rate. + * + * For example, using the GNU Radio's firdes utility to building + * filters, we build a low-pass filter with a sampling rate of + * <EM>fs</EM>, a 3-dB bandwidth of <EM>BW</EM> and a transition + * bandwidth of <EM>TB</EM>. We can also specify the out-of-band + * attenuation to use, <EM>ATT</EM>, and the filter window + * function (a Blackman-harris window in this case). The first input + * is the gain of the filter, which we specify here as unity. + * + * <B><EM>self._taps = filter.firdes.low_pass_2(1, fs, BW, TB, + * attenuation_dB=ATT, window=filter.firdes.WIN_BLACKMAN_hARRIS)</EM></B> + * + * The filter output can also be overs ampled. The over sampling rate + * is the ratio of the the actual output sampling rate to the normal + * output sampling rate. It must be rationally related to the number + * of channels as N/i for i in [1,N], which gives an outputsample rate + * of [fs/N, fs] where fs is the input sample rate and N is the number + * of channels. + * + * For example, for 6 channels with fs = 6000 Hz, the normal rate is + * 6000/6 = 1000 Hz. Allowable oversampling rates are 6/6, 6/5, 6/4, + * 6/3, 6/2, and 6/1 where the output sample rate of a 6/1 oversample + * ratio is 6000 Hz, or 6 times the normal 1000 Hz. A rate of 6/5 = 1.2, + * so the output rate would be 1200 Hz. + * + * The theory behind this block can be found in Chapter 6 of + * the following book. + * + * <B><EM>f. harris, "Multirate Signal Processing for Communication + * Systems," Upper Saddle River, NJ: Prentice Hall, Inc. 2004.</EM></B> + * + */ + + class FILTER_API pfb_channelizer_ccf : virtual public gr_block + { + public: + // gr::filter::pfb_channelizer_ccf::sptr + typedef boost::shared_ptr<pfb_channelizer_ccf> sptr; + + /*! + * Build the polyphase filterbank decimator. + * \param numchans (unsigned integer) Specifies the number of + * channels <EM>M</EM> + * \param taps (vector/list of floats) The prototype filter to + * populate the filterbank. + * \param oversample_rate (float) The over sampling rate is the + * ratio of the the actual output + * sampling rate to the normal + * output sampling rate. It must + * be rationally related to the + * number of channels as N/i for + * i in [1,N], which gives an + * outputsample rate of [fs/N, + * fs] where fs is the input + * sample rate and N is the + * number of channels. + * + * For example, for 6 channels + * with fs = 6000 Hz, the normal + * rateis 6000/6 = 1000 + * Hz. Allowable oversampling + * rates are 6/6, 6/5, 6/4, 6/3, + * 6/2, and 6/1 where the output + * sample rate of a 6/1 + * oversample ratio is 6000 Hz, + * or 6 times the normal 1000 Hz. + */ + static sptr make(unsigned int numchans, + const std::vector<float> &taps, + float oversample_rate); + + /*! + * Resets the filterbank's filter taps with the new prototype filter + * \param taps (vector/list of floats) The prototype filter to populate the filterbank. + */ + virtual void set_taps(const std::vector<float> &taps) = 0; + + /*! + * Print all of the filterbank taps to screen. + */ + virtual void print_taps() = 0; + + /*! + * Return a vector<vector<>> of the filterbank taps + */ + virtual std::vector<std::vector<float> > taps() const = 0; + + /*! + * Set the channel map. Channels are numbers as: + * + * N/2+1 | ... | N-1 | 0 | 1 | 2 | ... | N/2 + * <------------------- 0 --------------------> + * freq + * + * So output stream 0 comes from channel 0, etc. Setting a new + * channel map allows the user to specify which channel in frequency + * he/she wants to got to which output stream. + * + * The map should have the same number of elements as the number + * of output connections from the block. The minimum value of + * the map is 0 (for the 0th channel) and the maximum number is + * N-1 where N is the number of channels. + * + * We specify M as the number of output connections made where M + * <= N, so only M out of N channels are driven to an output + * stream. The number of items in the channel map should be at + * least M long. If there are more channels specified, any value + * in the map over M-1 will be ignored. If the size of the map + * is less than M the behavior is unknown (we don't wish to + * check every entry into the work function). + * + * This means that if the channelizer is splitting the signal up + * into N channels but only M channels are specified in the map + * (where M <= N), then M output streams must be connected and + * the map and the channel numbers used must be less than + * N-1. Output channel number can be reused, too. By default, + * the map is [0...M-1] with M = N. + */ + virtual void set_channel_map(const std::vector<int> &map) = 0; + + /*! + * Gets the current channel map. + */ + virtual std::vector<int> channel_map() const = 0; + }; + + } /* namespace filter */ +} /* namespace gr */ + +#endif /* INCLUDED_FILTER_PFB_CHANNELIZER_CCF_H */ diff --git a/gr-filter/include/filter/pfb_decimator_ccf.h b/gr-filter/include/filter/pfb_decimator_ccf.h new file mode 100644 index 000000000..bf9d0d950 --- /dev/null +++ b/gr-filter/include/filter/pfb_decimator_ccf.h @@ -0,0 +1,131 @@ +/* -*- c++ -*- */ +/* + * Copyright 2009,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + + +#ifndef INCLUDED_PFB_DECIMATOR_CCF_H +#define INCLUDED_PFB_DECIMATOR_CCF_H + +#include <filter/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace filter { + + /*! + * \class pfb_decimator_ccf + * \brief Polyphase filterbank bandpass decimator with gr_complex + * input, gr_complex output and float taps + * + * \ingroup filter_blk + * \ingroup pfb_blk + * + * This block takes in a signal stream and performs interger down- + * sampling (decimation) with a polyphase filterbank. The first + * input is the integer specifying how much to decimate by. The + * second input is a vector (Python list) of floating-point taps + * of the prototype filter. The third input specifies the channel + * to extract. By default, the zeroth channel is used, which is + * the baseband channel (first Nyquist zone). + * + * The <EM>channel</EM> parameter specifies which channel to use + * since this class is capable of bandpass decimation. Given a + * complex input stream at a sampling rate of <EM>fs</EM> and a + * decimation rate of <EM>decim</EM>, the input frequency domain + * is split into <EM>decim</EM> channels that represent the + * Nyquist zones. Using the polyphase filterbank, we can select + * any one of these channels to decimate. + * + * The output signal will be the basebanded and decimated signal + * from that channel. This concept is very similar to the PFB + * channelizer (see #gr_pfb_channelizer_ccf) where only a single + * channel is extracted at a time. + * + * The filter's taps should be based on the sampling rate before + * decimation. + * + * For example, using the GNU Radio's firdes utility to building + * filters, we build a low-pass filter with a sampling rate of + * <EM>fs</EM>, a 3-dB bandwidth of <EM>BW</EM> and a transition + * bandwidth of <EM>TB</EM>. We can also specify the out-of-band + * attenuation to use, <EM>ATT</EM>, and the filter window + * function (a Blackman-harris window in this case). The first + * input is the gain of the filter, which we specify here as + * unity. + * + * <B><EM>self._taps = filter.firdes.low_pass_2(1, fs, BW, TB, + * attenuation_dB=ATT, window=filter.firdes.WIN_BLACKMAN_hARRIS)</EM></B> + * + * The PFB decimator code takes the taps generated above and + * builds a set of filters. The set contains <EM>decim</EM> number + * of filters and each filter contains ceil(taps.size()/decim) + * number of taps. Each tap from the filter prototype is + * sequentially inserted into the next filter. When all of the + * input taps are used, the remaining filters in the filterbank + * are filled out with 0's to make sure each filter has the same + * number of taps. + * + * The theory behind this block can be found in Chapter 6 of + * the following book. + * + * <B><EM>f. harris, "Multirate Signal Processing for Communication + * Systems," Upper Saddle River, NJ: Prentice Hall, Inc. 2004.</EM></B> + */ + + class FILTER_API pfb_decimator_ccf : virtual public gr_sync_block + { + public: + // gr::filter::pfb_decimator_ccf::sptr + typedef boost::shared_ptr<pfb_decimator_ccf> sptr; + + /*! + * Build the polyphase filterbank decimator. + * \param decim (unsigned integer) Specifies the decimation rate to use + * \param taps (vector/list of floats) The prototype filter to populate the filterbank. + * \param channel (unsigned integer) Selects the channel to return [default=0]. + */ + static sptr make(unsigned int decim, + const std::vector<float> &taps, + unsigned int channel); + + /*! + * Resets the filterbank's filter taps with the new prototype filter + * \param taps (vector/list of floats) The prototype filter to populate the filterbank. + */ + virtual void set_taps(const std::vector<float> &taps) = 0; + + /*! + * Return a vector<vector<>> of the filterbank taps + */ + virtual std::vector<std::vector<float> > taps() const = 0; + + /*! + * Print all of the filterbank taps to screen. + */ + virtual void print_taps() = 0; + + //virtual void set_channel(unsigned int channel) = 0; + }; + + } /* namespace filter */ +} /* namespace gr */ + +#endif /* INCLUDED_PFB_DECIMATOR_CCF_H */ diff --git a/gr-filter/include/filter/pfb_interpolator_ccf.h b/gr-filter/include/filter/pfb_interpolator_ccf.h new file mode 100644 index 000000000..df28ab64d --- /dev/null +++ b/gr-filter/include/filter/pfb_interpolator_ccf.h @@ -0,0 +1,118 @@ +/* -*- c++ -*- */ +/* + * Copyright 2009,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + + +#ifndef INCLUDED_PFB_INTERPOLATOR_CCF_H +#define INCLUDED_PFB_INTERPOLATOR_CCF_H + +#include <filter/api.h> +#include <gr_sync_interpolator.h> + +namespace gr { + namespace filter { + + /*! + * \class gr_pfb_interpolator_ccf + * + * \brief Polyphase filterbank interpolator with gr_complex input, + * gr_complex output and float taps + * + * \ingroup filter_blk + * \ingroup pfb_blk + * + * This block takes in a signal stream and performs interger up- + * sampling (interpolation) with a polyphase filterbank. The first + * input is the integer specifying how much to interpolate by. The + * second input is a vector (Python list) of floating-point taps + * of the prototype filter. + * + * The filter's taps should be based on the interpolation rate + * specified. That is, the bandwidth specified is relative to the + * bandwidth after interpolation. + * + * For example, using the GNU Radio's firdes utility to building + * filters, we build a low-pass filter with a sampling rate of + * <EM>fs</EM>, a 3-dB bandwidth of <EM>BW</EM> and a transition + * bandwidth of <EM>TB</EM>. We can also specify the out-of-band + * attenuation to use, ATT, and the filter window function (a + * Blackman-harris window in this case). The first input is the + * gain, which is also specified as the interpolation rate so that + * the output levels are the same as the input (this creates an + * overall increase in power). + * + * <B><EM>self._taps = filter.firdes.low_pass_2(interp, interp*fs, BW, TB, + * attenuation_dB=ATT, window=filter.firdes.WIN_BLACKMAN_hARRIS)</EM></B> + * + * The PFB interpolator code takes the taps generated above and + * builds a set of filters. The set contains <EM>interp</EM> + * number of filters and each filter contains + * ceil(taps.size()/interp) number of taps. Each tap from the + * filter prototype is sequentially inserted into the next + * filter. When all of the input taps are used, the remaining + * filters in the filterbank are filled out with 0's to make sure + * each filter has the same number of taps. + * + * The theory behind this block can be found in Chapter 7.1 of the + * following book. + * + * <B><EM>f. harris, "Multirate Signal Processing for Communication + * Systems</EM>," Upper Saddle River, NJ: Prentice Hall, + * Inc. 2004.</EM></B> + */ + + class FILTER_API pfb_interpolator_ccf : virtual public gr_sync_interpolator + { + public: + // gr::filter::pfb_interpolator_ccf::sptr + typedef boost::shared_ptr<pfb_interpolator_ccf> sptr; + + /*! + * Build the polyphase filterbank interpolator. + * \param interp (unsigned integer) Specifies the interpolation rate to use + * \param taps (vector/list of floats) The prototype filter to populate the filterbank. The taps + * should be generated at the interpolated sampling rate. + */ + static sptr make(unsigned int interp, + const std::vector<float> &taps); + + /*! + * Resets the filterbank's filter taps with the new prototype filter + * \param taps (vector/list of floats) The prototype filter to populate the filterbank. + * The taps should be generated at the interpolated sampling rate. + */ + virtual void set_taps(const std::vector<float> &taps) = 0; + + /*! + * Return a vector<vector<>> of the filterbank taps + */ + virtual std::vector<std::vector<float> > taps() const = 0; + + /*! + * Print all of the filterbank taps to screen. + */ + virtual void print_taps() = 0; + }; + + } /* namespace filter */ +} /* namespace gr */ + +#endif /* INCLUDED_FILTER_PFB_INTERPOLATOR_CCF_H */ diff --git a/gr-filter/include/filter/pfb_synthesizer_ccf.h b/gr-filter/include/filter/pfb_synthesizer_ccf.h new file mode 100644 index 000000000..faa16990c --- /dev/null +++ b/gr-filter/include/filter/pfb_synthesizer_ccf.h @@ -0,0 +1,107 @@ +/* -*- c++ -*- */ +/* + * Copyright 2010,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + + +#ifndef INCLUDED_PFB_SYNTHESIZER_CCF_H +#define INCLUDED_PFB_SYNTHESIZER_CCF_H + +#include <filter/api.h> +#include <gr_sync_interpolator.h> + +namespace gr { + namespace filter { + + /*! + * \class pfb_synthesizer_ccf + * + * \brief Polyphase synthesis filterbank with + * gr_complex input, gr_complex output and float taps + * + * \ingroup filter_blk + * \ingroup pfb_blk + */ + + class FILTER_API pfb_synthesizer_ccf : virtual public gr_sync_interpolator + { + public: + // gr::filter::pfb_synthesizer_ccf::sptr + typedef boost::shared_ptr<pfb_synthesizer_ccf> sptr; + + /*! + * Build the polyphase synthesis filterbank. + * \param numchans (unsigned integer) Specifies the number of + * channels <EM>M</EM> + * \param taps (vector/list of floats) The prototype filter to + * populate the filterbank. + * \param twox (bool) use 2x oversampling or not (default is no) + */ + static sptr make(unsigned int numchans, + const std::vector<float> &taps, + bool twox=false); + + /*! + * Resets the filterbank's filter taps with the new prototype filter + * \param taps (vector/list of floats) The prototype filter to + * populate the filterbank. + */ + virtual void set_taps(const std::vector<float> &taps) = 0; + + /*! + * Print all of the filterbank taps to screen. + */ + virtual void print_taps() = 0; + + /*! + * Return a vector<vector<>> of the filterbank taps + */ + virtual std::vector<std::vector<float> > taps() const = 0; + + /*! + * Set the channel map. Channels are numbers as: + * N/2+1 | ... | N-1 | 0 | 1 | 2 | ... | N/2 + * <------------------- 0 --------------------> + * freq + * + * So input stream 0 goes to channel 0, etc. Setting a new channel + * map allows the user to specify where in frequency he/she wants + * the input stream to go. This is especially useful to avoid + * putting signals into the channels on the edge of the spectrum + * which can either wrap around (in the case of odd number of + * channels) and be affected by filter rolloff in the transmitter. + * + * The map must be at least the number of streams being sent to the + * block. Less and the algorithm will not have enough data to + * properly setup the buffers. Any more channels specified will be + * ignored. + */ + virtual void set_channel_map(const std::vector<int> &map) = 0; + + /*! + * Gets the current channel map. + */ + virtual std::vector<int> channel_map() const = 0; + }; + + } /* namespace filter */ +} /* namespace gr */ + +#endif /* INCLUDED_PFB_SYNTHESIZER_CCF_H */ diff --git a/gr-filter/include/filter/pm_remez.h b/gr-filter/include/filter/pm_remez.h new file mode 100644 index 000000000..a57e9e276 --- /dev/null +++ b/gr-filter/include/filter/pm_remez.h @@ -0,0 +1,72 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_FILTER_PM_REMEZ_H +#define INCLUDED_FILTER_PM_REMEZ_H + +#include <filter/api.h> +#include <gr_types.h> +#include <string> +#include <stdexcept> + +namespace gr { + namespace filter { + /*! + * \brief Parks-McClellan FIR filter design using Remez algorithm. + * + * \ingroup filter_design + * + * Calculates the optimal (in the Chebyshev/minimax sense) FIR + * filter inpulse reponse given a set of band edges, the desired + * reponse on those bands, and the weight given to the error in + * those bands. + * + * \param order filter order (number of taps in the returned filter - 1) + * \param bands frequency at the band edges [ b1 e1 b2 e2 b3 e3 ...] + * \param ampl desired amplitude at the band edges [ a(b1) a(e1) a(b2) a(e2) ...] + * \param error_weight weighting applied to each band (usually 1) + * \param filter_type one of "bandpass", "hilbert" or "differentiator" + * \param grid_density determines how accurately the filter will be constructed. \ + * The minimum value is 16; higher values are slower to compute. + * + * Frequency is in the range [0, 1], with 1 being the Nyquist + * frequency (Fs/2) + * + * \returns vector of computed taps + * + * \throws std::runtime_error if args are invalid or calculation + * fails to converge. + */ + + FILTER_API std::vector<double> + pm_remez(int order, + const std::vector<double> &bands, + const std::vector<double> &l, + const std::vector<double> &error_weight, + const std::string filter_type = "bandpass", + int grid_density = 16 + ) throw (std::runtime_error); + + } /* namespace filter */ +} /* namespace gr */ + +#endif /* INCLUDED_FILTER_PM_REMEZ_H */ diff --git a/gr-filter/include/filter/polyphase_filterbank.h b/gr-filter/include/filter/polyphase_filterbank.h new file mode 100644 index 000000000..33e9522e1 --- /dev/null +++ b/gr-filter/include/filter/polyphase_filterbank.h @@ -0,0 +1,148 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + + +#ifndef INCLUDED_FILTER_POLYPHASE_FILTERBANK_H +#define INCLUDED_FILTER_POLYPHASE_FILTERBANK_H + +#include <filter/api.h> +#include <filter/fir_filter.h> +#include <fft/fft.h> + +namespace gr { + namespace filter { + namespace kernel { + + /*! + * \class polyphase_filterbank + * + * \brief Polyphase filterbank parent class + * + * \ingroup filter_blk + * \ingroup pfb_blk + * + * This block takes in complex inputs and channelizes it to + * <EM>M</EM> channels of equal bandwidth. Each of the resulting + * channels is decimated to the new rate that is the input + * sampling rate <EM>fs</EM> divided by the number of channels, + * <EM>M</EM>. + * + * The PFB channelizer code takes the taps generated above and + * builds a set of filters. The set contains <EM>M</EM> number + * of filters and each filter contains ceil(taps.size()/decim) + * number of taps. Each tap from the filter prototype is + * sequentially inserted into the next filter. When all of the + * input taps are used, the remaining filters in the filterbank + * are filled out with 0's to make sure each filter has the same + * number of taps. + * + * Each filter operates using the gr_fir filter classs of GNU + * Radio, which takes the input stream at <EM>i</EM> and + * performs the inner product calculation to <EM>i+(n-1)</EM> + * where <EM>n</EM> is the number of filter taps. To efficiently + * handle this in the GNU Radio structure, each filter input + * must come from its own input stream. So the channelizer must + * be provided with <EM>M</EM> streams where the input stream + * has been deinterleaved. This is most easily done using the + * gr_stream_to_streams block. + * + * The output is then produced as a vector, where index + * <EM>i</EM> in the vector is the next sample from the + * <EM>i</EM>th channel. This is most easily handled by sending + * the output to a gr_vector_to_streams block to handle the + * conversion and passing <EM>M</EM> streams out. + * + * The input and output formatting is done using a hier_block2 + * called pfb_channelizer_ccf. This can take in a single stream + * and outputs <EM>M</EM> streams based on the behavior + * described above. + * + * The filter's taps should be based on the input sampling rate. + * + * For example, using the GNU Radio's firdes utility to building + * filters, we build a low-pass filter with a sampling rate of + * <EM>fs</EM>, a 3-dB bandwidth of <EM>BW</EM> and a transition + * bandwidth of <EM>TB</EM>. We can also specify the out-of-band + * attenuation to use, <EM>ATT</EM>, and the filter window + * function (a Blackman-harris window in this case). The first + * input is the gain of the filter, which we specify here as + * unity. + * + * <B><EM>self._taps = filter.firdes.low_pass_2(1, fs, BW, TB, + * attenuation_dB=ATT, window=filter.firdes.WIN_BLACKMAN_hARRIS)</EM></B> + * + * More on the theory of polyphase filterbanks can be found in + * the following book. + * + * <B><EM>f. harris, "Multirate Signal Processing for + * Communication Systems," Upper Saddle River, NJ: + * Prentice Hall, Inc. 2004.</EM></B> + * + */ + + class FILTER_API polyphase_filterbank + { + protected: + unsigned int d_nfilts; + std::vector<kernel::fir_filter_ccf*> d_filters; + std::vector< std::vector<float> > d_taps; + unsigned int d_taps_per_filter; + fft::fft_complex *d_fft; + + public: + /*! + * Build the polyphase filterbank decimator. + * \param nfilts (unsigned integer) Specifies the number of + * channels <EM>M</EM> + * \param taps (vector/list of floats) The prototype filter to + * populate the filterbank. + */ + polyphase_filterbank(unsigned int nfilts, + const std::vector<float> &taps); + + ~polyphase_filterbank(); + + /*! + * Update the filterbank's filter taps from a prototype + * filter. + * + * \param taps (vector/list of floats) The prototype filter to + * populate the filterbank. + */ + void set_taps(const std::vector<float> &taps); + + /*! + * Print all of the filterbank taps to screen. + */ + void print_taps(); + + /*! + * Return a vector<vector<>> of the filterbank taps + */ + std::vector<std::vector<float> > taps() const; + }; + + } /* namespace kernel */ + } /* namespace filter */ +} /* namespace gr */ + +#endif /* INCLUDED_FILTER_POLYPHASE_FILTERBANK_H */ diff --git a/gr-filter/include/filter/rational_resampler_base_XXX.h.t b/gr-filter/include/filter/rational_resampler_base_XXX.h.t new file mode 100644 index 000000000..e47a16ec6 --- /dev/null +++ b/gr-filter/include/filter/rational_resampler_base_XXX.h.t @@ -0,0 +1,61 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +/* @WARNING@ */ + +#ifndef @GUARD_NAME@ +#define @GUARD_NAME@ + +#include <filter/api.h> +#include <gr_block.h> + + +namespace gr { + namespace filter { + + /*! + * \brief Rational Resampling Polyphase FIR filter with @I_TYPE@ + * input, @O_TYPE@ output and @TAP_TYPE@ taps. + * + *\ingroup filter_blk + */ + class FILTER_API @NAME@ : virtual public gr_block + { + public: + // gr::filter::@BASE_NAME@::sptr + typedef boost::shared_ptr<@BASE_NAME@> sptr; + + static sptr make(unsigned interpolation, + unsigned decimation, + const std::vector<@TAP_TYPE@> &taps); + + virtual unsigned interpolation() const = 0; + virtual unsigned decimation() const = 0; + + virtual void set_taps(const std::vector<@TAP_TYPE@> &taps) = 0; + virtual std::vector<@TAP_TYPE@> taps() const = 0; + }; + + } /* namespace filter */ +} /* namespace gr */ + +#endif /* @GUARD_NAME@ */ diff --git a/gr-filter/include/filter/single_pole_iir.h b/gr-filter/include/filter/single_pole_iir.h new file mode 100644 index 000000000..10d1b4791 --- /dev/null +++ b/gr-filter/include/filter/single_pole_iir.h @@ -0,0 +1,200 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002,2006,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_SINGLE_POLE_IIR_H +#define INCLUDED_SINGLE_POLE_IIR_H + +#include <filter/api.h> +#include <stdexcept> +#include <gr_complex.h> + +namespace gr { + namespace filter { + + /*! + * \brief class template for single pole IIR filter + */ + template<class o_type, class i_type, class tap_type> + class single_pole_iir + { + public: + /*! + * \brief construct new single pole IIR with given alpha + * + * computes y(i) = (1-alpha) * y(i-1) + alpha * x(i) + */ + single_pole_iir(tap_type alpha = 1.0) + { + d_prev_output = 0; + set_taps(alpha); + } + + /*! + * \brief compute a single output value. + * \returns the filtered input value. + */ + o_type filter(const i_type input); + + /*! + * \brief compute an array of N output values. + * \p input must have n valid entries. + */ + void filterN(o_type output[], const i_type input[], unsigned long n); + + /*! + * \brief install \p alpha as the current taps. + */ + void set_taps(tap_type alpha) + { + if(alpha < 0 || alpha > 1) + throw std::out_of_range("Alpha must be in [0, 1]\n"); + + d_alpha = alpha; + d_one_minus_alpha = 1.0 - alpha; + } + + //! reset state to zero + void reset() + { + d_prev_output = 0; + } + + o_type prev_output() const { return d_prev_output; } + + protected: + tap_type d_alpha; + tap_type d_one_minus_alpha; + o_type d_prev_output; + }; + + // + // general case. We may want to specialize this + // + template<class o_type, class i_type, class tap_type> + o_type + single_pole_iir<o_type, i_type, tap_type>::filter(const i_type input) + { + o_type output; + + output = d_alpha * input + d_one_minus_alpha * d_prev_output; + d_prev_output = output; + + return (o_type) output; + } + + + template<class o_type, class i_type, class tap_type> + void + single_pole_iir<o_type, i_type, tap_type>::filterN(o_type output[], + const i_type input[], + unsigned long n) + { + for(unsigned i = 0; i < n; i++) + output[i] = filter(input[i]); + } + + + // + // Specialized case for gr_complex output and double taps + // We need to have a gr_complexd type for the calculations and prev_output variable (in stead of double) + + template<class i_type> + class single_pole_iir<gr_complex, i_type, double> + { + public: + /*! + * \brief construct new single pole IIR with given alpha + * + * computes y(i) = (1-alpha) * y(i-1) + alpha * x(i) + */ + single_pole_iir(double alpha = 1.0) + { + d_prev_output = 0; + set_taps(alpha); + } + + /*! + * \brief compute a single output value. + * \returns the filtered input value. + */ + gr_complex filter(const i_type input); + + /*! + * \brief compute an array of N output values. + * \p input must have n valid entries. + */ + void filterN(gr_complex output[], const i_type input[], unsigned long n); + + /*! + * \brief install \p alpha as the current taps. + */ + void set_taps(double alpha) + { + if(alpha < 0 || alpha > 1) + throw std::out_of_range("Alpha must be in [0, 1]\n"); + + d_alpha = alpha; + d_one_minus_alpha = 1.0 - alpha; + } + + //! reset state to zero + void reset() + { + d_prev_output = 0; + } + + gr_complexd prev_output() const { return d_prev_output; } + + protected: + double d_alpha; + double d_one_minus_alpha; + gr_complexd d_prev_output; + }; + + template< class i_type> + gr_complex + single_pole_iir<gr_complex, i_type, double>::filter(const i_type input) + { + gr_complexd output; + + output = d_alpha * (gr_complexd)input + d_one_minus_alpha * d_prev_output; + d_prev_output = output; + + return (gr_complex) output; + } + + //Do we need to specialize this, although it is the same as the general case? + + template<class i_type> + void + single_pole_iir<gr_complex, i_type, double>::filterN(gr_complex output[], + const i_type input[], + unsigned long n) + { + for(unsigned i = 0; i < n; i++) + output[i] = filter(input[i]); + } + + } /* namespace filter */ +} /* namespace gr */ + +#endif /* INCLUDED_SINGLE_POLE_IIR_H */ diff --git a/gr-filter/include/filter/single_pole_iir_filter_cc.h b/gr-filter/include/filter/single_pole_iir_filter_cc.h new file mode 100644 index 000000000..82febe8ec --- /dev/null +++ b/gr-filter/include/filter/single_pole_iir_filter_cc.h @@ -0,0 +1,78 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004-2006,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_SINGLE_POLE_IIR_FILTER_CC_H +#define INCLUDED_SINGLE_POLE_IIR_FILTER_CC_H + +#include <filter/api.h> +#include <filter/single_pole_iir.h> +#include <gr_sync_block.h> +#include <gr_complex.h> + +namespace gr { + namespace filter { + + /*! + * \brief single pole IIR filter with complex input, complex output + * \ingroup filter_blk + * + * The input and output satisfy a difference equation of the form + \htmlonly + \f{ + y[n] - (1-alpha) y[n-1] = alpha x[n] + \f} + \endhtmlonly + + \xmlonly + y[n] - (1-alpha) y[n-1] = alpha x[n] + \endxmlonly + + * with the corresponding rational system function + \htmlonly + \f{ + H(z) = \frac{alpha}{1 - (1-alpha) z^{-1}} + \f} + \endhtmlonly + + \xmlonly + H(z) = \ frac{alpha}{1 - (1-alpha) z^{-1}} + \endxmlonly + + * Note that some texts define the system function with a + in the + * denominator. If you're using that convention, you'll need to + * negate the feedback tap. + */ + class FILTER_API single_pole_iir_filter_cc : virtual public gr_sync_block + { + public: + // gr::filter::single_pole_iir_filter_cc::sptr + typedef boost::shared_ptr<single_pole_iir_filter_cc> sptr; + + static sptr make(double alpha, unsigned int vlen=1); + + virtual void set_taps(double alpha) = 0; + }; + + } /* namespace filter */ +} /* namespace gr */ + +#endif /* INCLUDED_SINGLE_POLE_IIR_FILTER_CC_H */ diff --git a/gr-filter/include/filter/single_pole_iir_filter_ff.h b/gr-filter/include/filter/single_pole_iir_filter_ff.h new file mode 100644 index 000000000..d85688db8 --- /dev/null +++ b/gr-filter/include/filter/single_pole_iir_filter_ff.h @@ -0,0 +1,78 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2005 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_SINGLE_POLE_IIR_FILTER_FF_H +#define INCLUDED_SINGLE_POLE_IIR_FILTER_FF_H + +#include <filter/api.h> +#include <filter/single_pole_iir.h> +#include <gr_sync_block.h> +#include <gr_complex.h> + +namespace gr { + namespace filter { + + /*! + * \brief single pole IIR filter with float input, float output + * \ingroup filter_blk + * + * The input and output satisfy a difference equation of the form + \htmlonly + \f{ + y[n] - (1-alpha) y[n-1] = alpha x[n] + \f} + \endhtmlonly + + \xmlonly + y[n] - (1-alpha) y[n-1] = alpha x[n] + \endxmlonly + + * with the corresponding rational system function + \htmlonly + \f{ + H(z) = \frac{alpha}{1 - (1-alpha) z^{-1}} + \f} + \endhtmlonly + + \xmlonly + H(z) = \ frac{alpha}{1 - (1-alpha) z^{-1}} + \endxmlonly + + * Note that some texts define the system function with a + in the + * denominator. If you're using that convention, you'll need to + * negate the feedback tap. + */ + class FILTER_API single_pole_iir_filter_ff : virtual public gr_sync_block + { + public: + // gr::filter::single_pole_iir_filter_ff::sptr + typedef boost::shared_ptr<single_pole_iir_filter_ff> sptr; + + static sptr make(double alpha, unsigned int vlen=1); + + virtual void set_taps (double alpha) = 0; + }; + + } /* namespace filter */ +} /* namespace gr */ + +#endif /* INCLUDED_SINGLE_POLE_IIR_FILTER_FF_H */ |