diff options
author | Tom Rondeau <tom@trondeau.com> | 2013-11-18 20:25:23 -0500 |
---|---|---|
committer | Tom Rondeau <tom@trondeau.com> | 2013-11-18 21:18:39 -0500 |
commit | d04a3d340145ed14a64cf1e0e0615cab806ab357 (patch) | |
tree | da51f734678f54ba76fa27e4cc76d12014e92958 /gr-fft | |
parent | 38ecfe9a63f3b35359930bfb04ca2929f42f6658 (diff) |
filter: remove use of magic numbers for calculating number of taps in firdes filters.
New way uses known max attenuation values for the windows to estimate the number of taps used in a filter. This produces smaller filters but needed QA code with pre-defined values updated.
Diffstat (limited to 'gr-fft')
-rw-r--r-- | gr-fft/include/gnuradio/fft/window.h | 42 | ||||
-rw-r--r-- | gr-fft/lib/window.cc | 19 |
2 files changed, 50 insertions, 11 deletions
diff --git a/gr-fft/include/gnuradio/fft/window.h b/gr-fft/include/gnuradio/fft/window.h index 4a7fb44ff9..92f62c64cb 100644 --- a/gr-fft/include/gnuradio/fft/window.h +++ b/gr-fft/include/gnuradio/fft/window.h @@ -35,19 +35,41 @@ namespace gr { public: enum win_type { - WIN_NONE = -1, //!< don't use a window - WIN_HAMMING = 0, //!< Hamming window; max attenuation 53 dB - WIN_HANN = 1, //!< Hann window; max attenuation 44 dB - WIN_BLACKMAN = 2, //!< Blackman window; max attenuation 74 dB - WIN_RECTANGULAR = 3, //!< Basic rectangular window - WIN_KAISER = 4, //!< Kaiser window; max attenuation a function of beta, google it - WIN_BLACKMAN_hARRIS = 5, //!< Blackman-harris window - WIN_BLACKMAN_HARRIS = 5, //!< alias to WIN_BLACKMAN_hARRIS for capitalization consistency - WIN_BARTLETT = 6, //!< Barlett (triangular) window - WIN_FLATTOP = 7, //!< flat top window; useful in FFTs + WIN_HAMMING = 0, //!< Hamming window; max attenuation 53 dB + WIN_HANN = 1, //!< Hann window; max attenuation 44 dB + WIN_BLACKMAN = 2, //!< Blackman window; max attenuation 74 dB + WIN_RECTANGULAR = 3, //!< Basic rectangular window; max attenuation 21 dB + WIN_KAISER = 4, //!< Kaiser window; max attenuation see window::max_attenuation + WIN_BLACKMAN_hARRIS = 5, //!< Blackman-harris window; max attenuation 92 dB + WIN_BLACKMAN_HARRIS = 5, //!< alias to WIN_BLACKMAN_hARRIS for capitalization consistency + WIN_BARTLETT = 6, //!< Barlett (triangular) window; max attenuation 26 dB + WIN_FLATTOP = 7, //!< flat top window; useful in FFTs; max attenuation 93 dB }; /*! + * \brief Given a window::win_type, this tells you the maximum + * attenuation you can expect. + * + * \details + * For most windows, this is a set value. For the Kaiser window, + * the attenuation is based on the value of beta. The actual + * relationship is a piece-wise exponential relationship to + * calculate beta from the desired attenuation and can be found + * on page 542 of Oppenheim and Schafer (Discrete-Time Signal + * Processing, 3rd edition). To simplify this function to solve + * for A given beta, we use a linear form that is exact for + * attenuation >= 50 dB. + * + * For an attenuation of 50 dB, beta = 4.55. + * + * For an attenuation of 70 dB, beta = 6.76. + * + * \param type The window::win_type enumeration of the window type. + * \param beta Beta value only used for the Kaiser window. + */ + static double max_attenuation(win_type type, double beta=6.76); + + /*! * \brief Helper function to build cosine-based windows. 3-coefficient version. */ static std::vector<float> coswindow(int ntaps, float c0, float c1, float c2); diff --git a/gr-fft/lib/window.cc b/gr-fft/lib/window.cc index 1610b46f5d..015e2d9943 100644 --- a/gr-fft/lib/window.cc +++ b/gr-fft/lib/window.cc @@ -74,7 +74,24 @@ namespace gr { return 1.0/(ntaps >> 1); } - std::vector<float> + double + window::max_attenuation(win_type type, double beta) + { + switch(type) { + case(WIN_HAMMING): return 53; break; + case(WIN_HANN): return 44; break; + case(WIN_BLACKMAN): return 74; break; + case(WIN_RECTANGULAR): return 21; break; + case(WIN_KAISER): return (beta/0.1102 + 8.7); break; + case(WIN_BLACKMAN_hARRIS): return 92; break; + case(WIN_BARTLETT): return 27; break; + case(WIN_FLATTOP): return 93; break; + default: + throw std::out_of_range("window::max_attenuation: unknown window type provided."); + } + } + + std::vector<float> window::coswindow(int ntaps, float c0, float c1, float c2) { std::vector<float> taps(ntaps); |