diff options
author | Martin Braun <martin.braun@ettus.com> | 2020-08-13 17:47:12 +0200 |
---|---|---|
committer | mormj <34754695+mormj@users.noreply.github.com> | 2020-08-17 12:04:35 -0400 |
commit | fdf04c1d1697f884fe0305881a59dfd3ded77c10 (patch) | |
tree | 1ac67415410b99b64d8dfeaa49b79bbe56b810f0 | |
parent | df17aeb1ae0dc9407c1b15c4329b6331dca59e8e (diff) |
qtgui: freq_sink: Allow normalization of window functions
When switching between window functions in a live FFT GUI session, the
difference in power of the window functions is notable. This allows
asserting the 'normalize' argument of fft::window::build() by setting a
bit in the window type during construction,, or by calling a new API
call: set_fft_window_normalized().
Note: The choice to use an unused bit to set the normalization comes
from an attempt to keep the API backward compatible. Adding a new
argument to the make call would require reordering the make arguments.
This feature allows changing window types without signal power varying
due to window power differences.
Note that this does not affect scalloping loss, or processing loss from
the window. For example, the peak value of a sine tone will still vary
for different windows, because different windows distribute the power
differently, and most window functions move power to the sidelobes.
-rw-r--r-- | gr-qtgui/grc/qtgui_freq_sink_x.block.yml | 12 | ||||
-rw-r--r-- | gr-qtgui/include/gnuradio/qtgui/freq_sink_c.h | 8 | ||||
-rw-r--r-- | gr-qtgui/include/gnuradio/qtgui/freq_sink_f.h | 8 | ||||
-rw-r--r-- | gr-qtgui/lib/freq_sink_c_impl.cc | 14 | ||||
-rw-r--r-- | gr-qtgui/lib/freq_sink_c_impl.h | 2 | ||||
-rw-r--r-- | gr-qtgui/lib/freq_sink_f_impl.cc | 12 | ||||
-rw-r--r-- | gr-qtgui/lib/freq_sink_f_impl.h | 2 | ||||
-rw-r--r-- | gr-qtgui/python/qtgui/bindings/docstrings/freq_sink_c_pydoc_template.h | 3 | ||||
-rw-r--r-- | gr-qtgui/python/qtgui/bindings/docstrings/freq_sink_f_pydoc_template.h | 3 | ||||
-rw-r--r-- | gr-qtgui/python/qtgui/bindings/freq_sink_c_python.cc | 5 | ||||
-rw-r--r-- | gr-qtgui/python/qtgui/bindings/freq_sink_f_python.cc | 5 |
11 files changed, 67 insertions, 7 deletions
diff --git a/gr-qtgui/grc/qtgui_freq_sink_x.block.yml b/gr-qtgui/grc/qtgui_freq_sink_x.block.yml index 6a117266c6..543f730e94 100644 --- a/gr-qtgui/grc/qtgui_freq_sink_x.block.yml +++ b/gr-qtgui/grc/qtgui_freq_sink_x.block.yml @@ -26,8 +26,8 @@ parameters: - id: freqhalf label: Spectrum Width dtype: enum - default: 'True' - options: ['True', 'False'] + default: True + options: [True, False] option_labels: [Full, Half] hide: ${ ('part' if type == "float" or type == "msg_float" else 'all') } - id: wintype @@ -39,6 +39,13 @@ parameters: option_labels: [Blackman-harris, Hamming, Hann, Blackman, Rectangular, Kaiser, Flat-top] hide: part +- id: norm_window + label: Normalize Window Power + dtype: enum + default: 'False' + options: ['True', 'False'] + option_labels: [Yes, No] + hide: ${ ('none' if norm_window == 'True' else 'part') } - id: fc label: Center Frequency (Hz) dtype: real @@ -417,6 +424,7 @@ templates: self.${id}.set_fft_average(${average}) self.${id}.enable_axis_labels(${axislabels}) self.${id}.enable_control_panel(${ctrlpanel}) + self.${id}.set_fft_window_normalized(${norm_window}) % if legend == "False": self.${id}.disable_legend() diff --git a/gr-qtgui/include/gnuradio/qtgui/freq_sink_c.h b/gr-qtgui/include/gnuradio/qtgui/freq_sink_c.h index 0612f33ccd..717426d5aa 100644 --- a/gr-qtgui/include/gnuradio/qtgui/freq_sink_c.h +++ b/gr-qtgui/include/gnuradio/qtgui/freq_sink_c.h @@ -83,7 +83,11 @@ public: * \param fftsize size of the FFT to compute and display. If using * the PDU message port to plot samples, the length of * each PDU must be a multiple of the FFT size. - * \param wintype type of window to apply (see gr::fft::window::win_type) + * \param wintype type of window to apply (see gr::fft::window::win_type). + * By setting bit 16 to one, this block will normalize the window + * before applying it. This allows switching between windows without + * sacrifying signal power due to tapering, but it will also amplify + * some samples. See also set_fft_window_normalized(). * \param fc center frequency of signal (use for x-axis labels) * \param bw bandwidth of signal (used to set x-axis labels) * \param name title for the plot @@ -116,6 +120,8 @@ public: virtual float fft_average() const = 0; virtual void set_fft_window(const gr::fft::window::win_type win) = 0; virtual gr::fft::window::win_type fft_window() = 0; + //! If true, normalize window to unit power + virtual void set_fft_window_normalized(const bool enable) = 0; virtual void set_frequency_range(const double centerfreq, const double bandwidth) = 0; virtual void set_y_axis(double min, double max) = 0; diff --git a/gr-qtgui/include/gnuradio/qtgui/freq_sink_f.h b/gr-qtgui/include/gnuradio/qtgui/freq_sink_f.h index 499dca91cf..45793e5130 100644 --- a/gr-qtgui/include/gnuradio/qtgui/freq_sink_f.h +++ b/gr-qtgui/include/gnuradio/qtgui/freq_sink_f.h @@ -83,7 +83,11 @@ public: * \param fftsize size of the FFT to compute and display. If using * the PDU message port to plot samples, the length of * each PDU must be a multiple of the FFT size. - * \param wintype type of window to apply (see gr::fft::window::win_type) + * \param wintype type of window to apply (see gr::fft::window::win_type). + * By setting bit 16 to one, this block will normalize the window + * before applying it. This allows switching between windows without + * sacrifying signal power due to tapering, but it will also amplify + * some samples. See also set_fft_window_normalized(). * \param fc center frequency of signal (use for x-axis labels) * \param bw bandwidth of signal (used to set x-axis labels) * \param name title for the plot @@ -116,6 +120,8 @@ public: virtual float fft_average() const = 0; virtual void set_fft_window(const gr::fft::window::win_type win) = 0; virtual gr::fft::window::win_type fft_window() = 0; + //! If true, normalize window to unit power + virtual void set_fft_window_normalized(const bool enable) = 0; virtual void set_frequency_range(const double centerfreq, const double bandwidth) = 0; virtual void set_y_axis(double min, double max) = 0; diff --git a/gr-qtgui/lib/freq_sink_c_impl.cc b/gr-qtgui/lib/freq_sink_c_impl.cc index 48fd681b74..8ba0c67bc3 100644 --- a/gr-qtgui/lib/freq_sink_c_impl.cc +++ b/gr-qtgui/lib/freq_sink_c_impl.cc @@ -20,6 +20,9 @@ #include <qwt_symbol.h> #include <volk/volk.h> +#include <boost/range/adaptor/transformed.hpp> +#include <boost/range/numeric.hpp> + #include <string.h> #include <algorithm> @@ -51,7 +54,8 @@ freq_sink_c_impl::freq_sink_c_impl(int fftsize, d_fftsize(fftsize), d_fft_shift(fftsize), d_fftavg(1.0), - d_wintype((fft::window::win_type)(wintype)), + d_wintype((fft::window::win_type)(wintype & 0xFF)), + d_window_normalize(wintype & (1 << 15)), d_center_freq(fc), d_bandwidth(bw), d_name(name), @@ -208,6 +212,12 @@ void freq_sink_c_impl::set_fft_window(const fft::window::win_type win) fft::window::win_type freq_sink_c_impl::fft_window() { return d_wintype; } +void freq_sink_c_impl::set_fft_window_normalized(const bool enable) +{ + d_window_normalize = enable; + buildwindow(); +} + void freq_sink_c_impl::set_frequency_range(const double centerfreq, const double bandwidth) { @@ -408,7 +418,7 @@ void freq_sink_c_impl::buildwindow() { d_window.clear(); if (d_wintype != fft::window::WIN_NONE) { - d_window = fft::window::build(d_wintype, d_fftsize); + d_window = fft::window::build(d_wintype, d_fftsize, 6.76, d_window_normalize); } } diff --git a/gr-qtgui/lib/freq_sink_c_impl.h b/gr-qtgui/lib/freq_sink_c_impl.h index d11d52d267..8d36a529c0 100644 --- a/gr-qtgui/lib/freq_sink_c_impl.h +++ b/gr-qtgui/lib/freq_sink_c_impl.h @@ -32,6 +32,7 @@ private: float d_fftavg; fft::window::win_type d_wintype; std::vector<float> d_window; + bool d_window_normalize = false; //<! If true, window functions will be normalized double d_center_freq; double d_bandwidth; const std::string d_name; @@ -114,6 +115,7 @@ public: float fft_average() const; void set_fft_window(const fft::window::win_type win); fft::window::win_type fft_window(); + void set_fft_window_normalized(const bool enable); void set_frequency_range(const double centerfreq, const double bandwidth); void set_y_axis(double min, double max); diff --git a/gr-qtgui/lib/freq_sink_f_impl.cc b/gr-qtgui/lib/freq_sink_f_impl.cc index 167e26c0af..3bc5f705e4 100644 --- a/gr-qtgui/lib/freq_sink_f_impl.cc +++ b/gr-qtgui/lib/freq_sink_f_impl.cc @@ -20,6 +20,9 @@ #include <qwt_symbol.h> #include <volk/volk.h> +#include <boost/range/adaptor/transformed.hpp> +#include <boost/range/numeric.hpp> + #include <string.h> namespace gr { @@ -52,6 +55,7 @@ freq_sink_f_impl::freq_sink_f_impl(int fftsize, d_fft_shift(fftsize), d_fftavg(1.0), d_wintype((fft::window::win_type)(wintype)), + d_window_normalize(wintype & (1 << 15)), d_center_freq(fc), d_bandwidth(bw), d_name(name), @@ -208,6 +212,12 @@ void freq_sink_f_impl::set_fft_window(const fft::window::win_type win) fft::window::win_type freq_sink_f_impl::fft_window() { return d_wintype; } +void freq_sink_f_impl::set_fft_window_normalized(const bool enable) +{ + d_window_normalize = enable; + buildwindow(); +} + void freq_sink_f_impl::set_frequency_range(const double centerfreq, const double bandwidth) { @@ -411,7 +421,7 @@ void freq_sink_f_impl::buildwindow() { d_window.clear(); if (d_wintype != fft::window::WIN_NONE) { - d_window = fft::window::build(d_wintype, d_fftsize); + d_window = fft::window::build(d_wintype, d_fftsize, 6.76, d_window_normalize); } } diff --git a/gr-qtgui/lib/freq_sink_f_impl.h b/gr-qtgui/lib/freq_sink_f_impl.h index 9207212c4d..bd1ee14799 100644 --- a/gr-qtgui/lib/freq_sink_f_impl.h +++ b/gr-qtgui/lib/freq_sink_f_impl.h @@ -32,6 +32,7 @@ private: float d_fftavg; fft::window::win_type d_wintype; std::vector<float> d_window; + bool d_window_normalize = false; //<! If true, window functions will be normalized double d_center_freq; double d_bandwidth; const std::string d_name; @@ -114,6 +115,7 @@ public: float fft_average() const; void set_fft_window(const fft::window::win_type win); fft::window::win_type fft_window(); + void set_fft_window_normalized(const bool enable); void set_frequency_range(const double centerfreq, const double bandwidth); void set_y_axis(double min, double max); diff --git a/gr-qtgui/python/qtgui/bindings/docstrings/freq_sink_c_pydoc_template.h b/gr-qtgui/python/qtgui/bindings/docstrings/freq_sink_c_pydoc_template.h index e0f09db46c..3134354a9a 100644 --- a/gr-qtgui/python/qtgui/bindings/docstrings/freq_sink_c_pydoc_template.h +++ b/gr-qtgui/python/qtgui/bindings/docstrings/freq_sink_c_pydoc_template.h @@ -54,6 +54,9 @@ static const char* __doc_gr_qtgui_freq_sink_c_set_fft_window = R"doc()doc"; static const char* __doc_gr_qtgui_freq_sink_c_fft_window = R"doc()doc"; +static const char* __doc_gr_qtgui_freq_sink_c_set_fft_window_normalized = R"doc()doc"; + + static const char* __doc_gr_qtgui_freq_sink_c_set_frequency_range = R"doc()doc"; diff --git a/gr-qtgui/python/qtgui/bindings/docstrings/freq_sink_f_pydoc_template.h b/gr-qtgui/python/qtgui/bindings/docstrings/freq_sink_f_pydoc_template.h index 3c5e2ce3d7..be6020de4a 100644 --- a/gr-qtgui/python/qtgui/bindings/docstrings/freq_sink_f_pydoc_template.h +++ b/gr-qtgui/python/qtgui/bindings/docstrings/freq_sink_f_pydoc_template.h @@ -54,6 +54,9 @@ static const char* __doc_gr_qtgui_freq_sink_f_set_fft_window = R"doc()doc"; static const char* __doc_gr_qtgui_freq_sink_f_fft_window = R"doc()doc"; +static const char* __doc_gr_qtgui_freq_sink_f_set_fft_window_normalized = R"doc()doc"; + + static const char* __doc_gr_qtgui_freq_sink_f_set_frequency_range = R"doc()doc"; diff --git a/gr-qtgui/python/qtgui/bindings/freq_sink_c_python.cc b/gr-qtgui/python/qtgui/bindings/freq_sink_c_python.cc index f1e4c1b8f0..597072bb68 100644 --- a/gr-qtgui/python/qtgui/bindings/freq_sink_c_python.cc +++ b/gr-qtgui/python/qtgui/bindings/freq_sink_c_python.cc @@ -102,6 +102,11 @@ void bind_freq_sink_c(py::module& m) .def("fft_window", &freq_sink_c::fft_window, D(freq_sink_c, fft_window)) + .def("set_fft_window_normalized", + &freq_sink_c::set_fft_window_normalized, + D(freq_sink_c, set_fft_window_normalized)) + + .def("set_frequency_range", &freq_sink_c::set_frequency_range, py::arg("centerfreq"), diff --git a/gr-qtgui/python/qtgui/bindings/freq_sink_f_python.cc b/gr-qtgui/python/qtgui/bindings/freq_sink_f_python.cc index d753986f61..5ea96f3fe7 100644 --- a/gr-qtgui/python/qtgui/bindings/freq_sink_f_python.cc +++ b/gr-qtgui/python/qtgui/bindings/freq_sink_f_python.cc @@ -102,6 +102,11 @@ void bind_freq_sink_f(py::module& m) .def("fft_window", &freq_sink_f::fft_window, D(freq_sink_f, fft_window)) + .def("set_fft_window_normalized", + &freq_sink_f::set_fft_window_normalized, + D(freq_sink_f, set_fft_window_normalized)) + + .def("set_frequency_range", &freq_sink_f::set_frequency_range, py::arg("centerfreq"), |