summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rondeau <trondeau@vt.edu>2013-02-17 11:04:02 -0500
committerTom Rondeau <trondeau@vt.edu>2013-02-17 11:04:02 -0500
commit9ca6c72a04991a0ec41afcc04b60a85eae52e921 (patch)
tree88c22d2fff68e2e8c3d3b46ce5c7556e2e4f5a95
parentf8175a626bb477d92b0d46164d30399e12e2ac09 (diff)
parent226bb6ad1f524b3556f3fc2be83a6093875e50f0 (diff)
Merge branch 'next' of gnuradio.org:gnuradio into next
-rw-r--r--gnuradio-core/src/examples/ctrlport/pfb_sync_test-qt.grc183
-rw-r--r--gnuradio-core/src/lib/runtime/gr_block.cc125
-rw-r--r--gnuradio-core/src/lib/runtime/gr_block.h41
-rw-r--r--gnuradio-core/src/lib/runtime/gr_block.i9
-rw-r--r--gnuradio-core/src/lib/runtime/gr_block_detail.cc137
-rw-r--r--gnuradio-core/src/lib/runtime/gr_block_detail.h15
-rw-r--r--gnuradio-core/src/python/gnuradio/ctrlport/GrDataPlotter.py156
-rwxr-xr-xgnuradio-core/src/python/gnuradio/ctrlport/gr-ctrlport-monitor24
-rw-r--r--gr-channels/examples/channel_tone_response.grc762
-rw-r--r--gr-channels/grc/CMakeLists.txt1
-rw-r--r--gr-channels/grc/channels_block_tree.xml1
-rw-r--r--gr-channels/grc/channels_fading_model.xml75
-rw-r--r--gr-channels/include/channels/CMakeLists.txt1
-rw-r--r--gr-channels/include/channels/fading_model.h75
-rw-r--r--gr-channels/lib/CMakeLists.txt1
-rw-r--r--gr-channels/lib/fading_model_impl.cc207
-rw-r--r--gr-channels/lib/fading_model_impl.h94
-rw-r--r--gr-channels/lib/sincostable.h30
-rw-r--r--gr-channels/python/qa_fading_model.py62
-rw-r--r--gr-channels/swig/channels_swig.i3
-rw-r--r--gr-filter/lib/pfb_synthesizer_ccf_impl.cc52
-rw-r--r--gr-qtgui/grc/qtgui_const_sink_x.xml10
-rw-r--r--gr-qtgui/grc/qtgui_freq_sink_x.xml16
-rw-r--r--gr-qtgui/grc/qtgui_time_raster_x.xml12
-rw-r--r--gr-qtgui/grc/qtgui_time_sink_x.xml10
-rw-r--r--gr-qtgui/grc/qtgui_waterfall_sink_x.xml10
-rw-r--r--gr-qtgui/include/qtgui/const_sink_c.h1
-rw-r--r--gr-qtgui/include/qtgui/freq_sink_c.h1
-rw-r--r--gr-qtgui/include/qtgui/freq_sink_f.h1
-rw-r--r--gr-qtgui/include/qtgui/time_raster_sink_b.h5
-rw-r--r--gr-qtgui/include/qtgui/time_raster_sink_f.h5
-rw-r--r--gr-qtgui/include/qtgui/time_sink_c.h1
-rw-r--r--gr-qtgui/include/qtgui/time_sink_f.h1
-rw-r--r--gr-qtgui/lib/FrequencyDisplayPlot.cc2
-rw-r--r--gr-qtgui/lib/TimeRasterDisplayPlot.cc71
-rw-r--r--gr-qtgui/lib/TimeRasterDisplayPlot.h1
-rw-r--r--gr-qtgui/lib/const_sink_c_impl.cc8
-rw-r--r--gr-qtgui/lib/const_sink_c_impl.h1
-rw-r--r--gr-qtgui/lib/constellationdisplayform.cc21
-rw-r--r--gr-qtgui/lib/constellationdisplayform.h2
-rw-r--r--gr-qtgui/lib/displayform.cc6
-rw-r--r--gr-qtgui/lib/displayform.h3
-rw-r--r--gr-qtgui/lib/freq_sink_c_impl.cc8
-rw-r--r--gr-qtgui/lib/freq_sink_c_impl.h1
-rw-r--r--gr-qtgui/lib/freq_sink_f_impl.cc8
-rw-r--r--gr-qtgui/lib/freq_sink_f_impl.h1
-rw-r--r--gr-qtgui/lib/freqdisplayform.cc25
-rw-r--r--gr-qtgui/lib/freqdisplayform.h3
-rw-r--r--gr-qtgui/lib/timeRasterGlobalData.cc18
-rw-r--r--gr-qtgui/lib/timeRasterGlobalData.h3
-rw-r--r--gr-qtgui/lib/time_raster_sink_b_impl.cc27
-rw-r--r--gr-qtgui/lib/time_raster_sink_b_impl.h5
-rw-r--r--gr-qtgui/lib/time_raster_sink_f_impl.cc30
-rw-r--r--gr-qtgui/lib/time_raster_sink_f_impl.h5
-rw-r--r--gr-qtgui/lib/time_sink_c_impl.cc8
-rw-r--r--gr-qtgui/lib/time_sink_c_impl.h1
-rw-r--r--gr-qtgui/lib/time_sink_f_impl.cc8
-rw-r--r--gr-qtgui/lib/time_sink_f_impl.h1
-rw-r--r--gr-qtgui/lib/timedisplayform.cc22
-rw-r--r--gr-qtgui/lib/timedisplayform.h2
-rw-r--r--gr-qtgui/lib/timerasterdisplayform.cc11
-rw-r--r--gr-qtgui/lib/timerasterdisplayform.h2
-rw-r--r--gr-qtgui/lib/waterfall_sink_c_impl.cc2
-rw-r--r--gr-qtgui/lib/waterfall_sink_f_impl.cc2
-rw-r--r--gr-qtgui/lib/waterfalldisplayform.cc10
-rw-r--r--gr-qtgui/lib/waterfalldisplayform.h3
66 files changed, 2234 insertions, 214 deletions
diff --git a/gnuradio-core/src/examples/ctrlport/pfb_sync_test-qt.grc b/gnuradio-core/src/examples/ctrlport/pfb_sync_test-qt.grc
index 2dadddb6df..5891500860 100644
--- a/gnuradio-core/src/examples/ctrlport/pfb_sync_test-qt.grc
+++ b/gnuradio-core/src/examples/ctrlport/pfb_sync_test-qt.grc
@@ -1,6 +1,6 @@
<?xml version='1.0' encoding='ASCII'?>
<flow_graph>
- <timestamp>Wed Feb 6 17:01:06 2013</timestamp>
+ <timestamp>Thu Feb 14 15:27:16 2013</timestamp>
<block>
<key>options</key>
<param>
@@ -161,76 +161,6 @@
</param>
</block>
<block>
- <key>gr_file_source</key>
- <param>
- <key>id</key>
- <value>gr_file_source_0</value>
- </param>
- <param>
- <key>_enabled</key>
- <value>True</value>
- </param>
- <param>
- <key>file</key>
- <value>/dev/urandom</value>
- </param>
- <param>
- <key>type</key>
- <value>byte</value>
- </param>
- <param>
- <key>repeat</key>
- <value>True</value>
- </param>
- <param>
- <key>vlen</key>
- <value>1</value>
- </param>
- <param>
- <key>_coordinate</key>
- <value>(228, 56)</value>
- </param>
- <param>
- <key>_rotation</key>
- <value>0</value>
- </param>
- </block>
- <block>
- <key>gr_packed_to_unpacked_xx</key>
- <param>
- <key>id</key>
- <value>gr_packed_to_unpacked_xx_0</value>
- </param>
- <param>
- <key>_enabled</key>
- <value>True</value>
- </param>
- <param>
- <key>type</key>
- <value>byte</value>
- </param>
- <param>
- <key>bits_per_chunk</key>
- <value>8</value>
- </param>
- <param>
- <key>endianness</key>
- <value>gr.GR_MSB_FIRST</value>
- </param>
- <param>
- <key>num_ports</key>
- <value>1</value>
- </param>
- <param>
- <key>_coordinate</key>
- <value>(408, 56)</value>
- </param>
- <param>
- <key>_rotation</key>
- <value>0</value>
- </param>
- </block>
- <block>
<key>variable</key>
<param>
<key>id</key>
@@ -709,6 +639,111 @@
<value>0</value>
</param>
</block>
+ <block>
+ <key>gr_file_source</key>
+ <param>
+ <key>id</key>
+ <value>gr_file_source_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>file</key>
+ <value>/dev/urandom</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>byte</value>
+ </param>
+ <param>
+ <key>repeat</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>vlen</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(228, 56)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>gr_vector_source_x</key>
+ <param>
+ <key>id</key>
+ <value>gr_vector_source_x_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>byte</value>
+ </param>
+ <param>
+ <key>vector</key>
+ <value>0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50</value>
+ </param>
+ <param>
+ <key>repeat</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>vlen</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(235, 126)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>gr_packed_to_unpacked_xx</key>
+ <param>
+ <key>id</key>
+ <value>gr_packed_to_unpacked_xx_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>byte</value>
+ </param>
+ <param>
+ <key>bits_per_chunk</key>
+ <value>8</value>
+ </param>
+ <param>
+ <key>endianness</key>
+ <value>gr.GR_MSB_FIRST</value>
+ </param>
+ <param>
+ <key>num_ports</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(408, 56)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
<connection>
<source_block_id>gr_packed_to_unpacked_xx_0</source_block_id>
<sink_block_id>gr_throttle_0</sink_block_id>
@@ -769,4 +804,10 @@
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
+ <connection>
+ <source_block_id>gr_vector_source_x_0</source_block_id>
+ <sink_block_id>gr_packed_to_unpacked_xx_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
</flow_graph>
diff --git a/gnuradio-core/src/lib/runtime/gr_block.cc b/gnuradio-core/src/lib/runtime/gr_block.cc
index 83bbea37e6..c736d0f058 100644
--- a/gnuradio-core/src/lib/runtime/gr_block.cc
+++ b/gnuradio-core/src/lib/runtime/gr_block.cc
@@ -283,6 +283,17 @@ gr_block::pc_noutput_items()
}
float
+gr_block::pc_noutput_items_var()
+{
+ if(d_detail) {
+ return d_detail->pc_noutput_items_var();
+ }
+ else {
+ return 0;
+ }
+}
+
+float
gr_block::pc_nproduced()
{
if(d_detail) {
@@ -294,6 +305,17 @@ gr_block::pc_nproduced()
}
float
+gr_block::pc_nproduced_var()
+{
+ if(d_detail) {
+ return d_detail->pc_nproduced_var();
+ }
+ else {
+ return 0;
+ }
+}
+
+float
gr_block::pc_input_buffers_full(int which)
{
if(d_detail) {
@@ -304,6 +326,17 @@ gr_block::pc_input_buffers_full(int which)
}
}
+float
+gr_block::pc_input_buffers_full_var(int which)
+{
+ if(d_detail) {
+ return d_detail->pc_input_buffers_full_var(static_cast<size_t>(which));
+ }
+ else {
+ return 0;
+ }
+}
+
std::vector<float>
gr_block::pc_input_buffers_full()
{
@@ -315,6 +348,17 @@ gr_block::pc_input_buffers_full()
}
}
+std::vector<float>
+gr_block::pc_input_buffers_full_var()
+{
+ if(d_detail) {
+ return d_detail->pc_input_buffers_full_var();
+ }
+ else {
+ return std::vector<float>(1,0);
+ }
+}
+
float
gr_block::pc_output_buffers_full(int which)
{
@@ -326,6 +370,17 @@ gr_block::pc_output_buffers_full(int which)
}
}
+float
+gr_block::pc_output_buffers_full_var(int which)
+{
+ if(d_detail) {
+ return d_detail->pc_output_buffers_full_var(static_cast<size_t>(which));
+ }
+ else {
+ return 0;
+ }
+}
+
std::vector<float>
gr_block::pc_output_buffers_full()
{
@@ -337,6 +392,17 @@ gr_block::pc_output_buffers_full()
}
}
+std::vector<float>
+gr_block::pc_output_buffers_full_var()
+{
+ if(d_detail) {
+ return d_detail->pc_output_buffers_full_var();
+ }
+ else {
+ return std::vector<float>(1,0);
+ }
+}
+
float
gr_block::pc_work_time()
{
@@ -348,6 +414,25 @@ gr_block::pc_work_time()
}
}
+float
+gr_block::pc_work_time_var()
+{
+ if(d_detail) {
+ return d_detail->pc_work_time_var();
+ }
+ else {
+ return 0;
+ }
+}
+
+void
+gr_block::reset_perf_counters()
+{
+ if(d_detail) {
+ d_detail->reset_perf_counters();
+ }
+}
+
void
gr_block::setup_pc_rpc()
{
@@ -355,33 +440,63 @@ gr_block::setup_pc_rpc()
#ifdef GR_CTRLPORT
d_rpc_vars.push_back(
rpcbasic_sptr(new rpcbasic_register_get<gr_block, float>(
- alias(), "noutput_items", &gr_block::pc_noutput_items,
+ alias(), "avg noutput_items", &gr_block::pc_noutput_items,
pmt::mp(0), pmt::mp(32768), pmt::mp(0),
"", "Average noutput items", RPC_PRIVLVL_MIN, DISPTIMESERIESF)));
d_rpc_vars.push_back(
rpcbasic_sptr(new rpcbasic_register_get<gr_block, float>(
- alias(), "nproduced", &gr_block::pc_nproduced,
+ alias(), "var noutput_items", &gr_block::pc_noutput_items_var,
+ pmt::mp(0), pmt::mp(32768), pmt::mp(0),
+ "", "Var. noutput items", RPC_PRIVLVL_MIN, DISPTIMESERIESF)));
+
+ d_rpc_vars.push_back(
+ rpcbasic_sptr(new rpcbasic_register_get<gr_block, float>(
+ alias(), "avg nproduced", &gr_block::pc_nproduced,
pmt::mp(0), pmt::mp(32768), pmt::mp(0),
"", "Average items produced", RPC_PRIVLVL_MIN, DISPTIMESERIESF)));
d_rpc_vars.push_back(
rpcbasic_sptr(new rpcbasic_register_get<gr_block, float>(
- alias(), "work time", &gr_block::pc_work_time,
+ alias(), "var nproduced", &gr_block::pc_nproduced_var,
+ pmt::mp(0), pmt::mp(32768), pmt::mp(0),
+ "", "Var. items produced", RPC_PRIVLVL_MIN, DISPTIMESERIESF)));
+
+ d_rpc_vars.push_back(
+ rpcbasic_sptr(new rpcbasic_register_get<gr_block, float>(
+ alias(), "avg work time", &gr_block::pc_work_time,
pmt::mp(0), pmt::mp(1e9), pmt::mp(0),
"", "Average clock cycles in call to work", RPC_PRIVLVL_MIN, DISPTIMESERIESF)));
d_rpc_vars.push_back(
+ rpcbasic_sptr(new rpcbasic_register_get<gr_block, float>(
+ alias(), "var work time", &gr_block::pc_work_time_var,
+ pmt::mp(0), pmt::mp(1e9), pmt::mp(0),
+ "", "Var. clock cycles in call to work", RPC_PRIVLVL_MIN, DISPTIMESERIESF)));
+
+ d_rpc_vars.push_back(
rpcbasic_sptr(new rpcbasic_register_get<gr_block, std::vector<float> >(
- alias(), "input \% full", &gr_block::pc_input_buffers_full,
+ alias(), "avg input \% full", &gr_block::pc_input_buffers_full,
pmt::make_c32vector(0,0), pmt::make_c32vector(0,1), pmt::make_c32vector(0,0),
"", "Average of how full input buffers are", RPC_PRIVLVL_MIN, DISPTIMESERIESF)));
d_rpc_vars.push_back(
rpcbasic_sptr(new rpcbasic_register_get<gr_block, std::vector<float> >(
- alias(), "output \% full", &gr_block::pc_output_buffers_full,
+ alias(), "var input \% full", &gr_block::pc_input_buffers_full_var,
+ pmt::make_c32vector(0,0), pmt::make_c32vector(0,1), pmt::make_c32vector(0,0),
+ "", "Var. of how full input buffers are", RPC_PRIVLVL_MIN, DISPTIMESERIESF)));
+
+ d_rpc_vars.push_back(
+ rpcbasic_sptr(new rpcbasic_register_get<gr_block, std::vector<float> >(
+ alias(), "avg output \% full", &gr_block::pc_output_buffers_full,
pmt::make_c32vector(0,0), pmt::make_c32vector(0,1), pmt::make_c32vector(0,0),
"", "Average of how full output buffers are", RPC_PRIVLVL_MIN, DISPTIMESERIESF)));
+
+ d_rpc_vars.push_back(
+ rpcbasic_sptr(new rpcbasic_register_get<gr_block, std::vector<float> >(
+ alias(), "var output \% full", &gr_block::pc_output_buffers_full_var,
+ pmt::make_c32vector(0,0), pmt::make_c32vector(0,1), pmt::make_c32vector(0,0),
+ "", "Var. of how full output buffers are", RPC_PRIVLVL_MIN, DISPTIMESERIESF)));
#endif /* GR_CTRLPORT */
}
diff --git a/gnuradio-core/src/lib/runtime/gr_block.h b/gnuradio-core/src/lib/runtime/gr_block.h
index 8b8851ee92..034f6136d9 100644
--- a/gnuradio-core/src/lib/runtime/gr_block.h
+++ b/gnuradio-core/src/lib/runtime/gr_block.h
@@ -383,29 +383,58 @@ class GR_CORE_API gr_block : public gr_basic_block {
float pc_noutput_items();
/*!
+ * \brief Gets variance of noutput_items performance counter.
+ */
+ float pc_noutput_items_var();
+
+ /*!
* \brief Gets average num items produced performance counter.
*/
float pc_nproduced();
/*!
- * \brief Gets average average fullness of \p which input buffer.
+ * \brief Gets variance of num items produced performance counter.
+ */
+ float pc_nproduced_var();
+
+ /*!
+ * \brief Gets average fullness of \p which input buffer.
*/
float pc_input_buffers_full(int which);
/*!
+ * \brief Gets variance of fullness of \p which input buffer.
+ */
+ float pc_input_buffers_full_var(int which);
+
+ /*!
* \brief Gets average fullness of all input buffers.
*/
std::vector<float> pc_input_buffers_full();
/*!
+ * \brief Gets variance of fullness of all input buffers.
+ */
+ std::vector<float> pc_input_buffers_full_var();
+
+ /*!
* \brief Gets average fullness of \p which input buffer.
*/
float pc_output_buffers_full(int which);
/*!
+ * \brief Gets variance of fullness of \p which input buffer.
+ */
+ float pc_output_buffers_full_var(int which);
+
+ /*!
* \brief Gets average fullness of all output buffers.
*/
std::vector<float> pc_output_buffers_full();
+ /*!
+ * \brief Gets variance of fullness of all output buffers.
+ */
+ std::vector<float> pc_output_buffers_full_var();
/*!
* \brief Gets average clock cycles spent in work.
@@ -413,6 +442,16 @@ class GR_CORE_API gr_block : public gr_basic_block {
float pc_work_time();
/*!
+ * \brief Gets average clock cycles spent in work.
+ */
+ float pc_work_time_var();
+
+ /*!
+ * \brief Resets the performance counters
+ */
+ void reset_perf_counters();
+
+ /*!
* \brief Sets up export of perf. counters to ControlPort. Only
* called by the scheduler.
*/
diff --git a/gnuradio-core/src/lib/runtime/gr_block.i b/gnuradio-core/src/lib/runtime/gr_block.i
index c016f2c28e..a80f64d027 100644
--- a/gnuradio-core/src/lib/runtime/gr_block.i
+++ b/gnuradio-core/src/lib/runtime/gr_block.i
@@ -68,13 +68,20 @@ class gr_block : public gr_basic_block {
// Methods to access performance counters
float pc_noutput_items();
+ float pc_noutput_items_var();
float pc_nproduced();
+ float pc_nproduced_var();
float pc_input_buffers_full(int which);
+ float pc_input_buffers_full_var(int which);
std::vector<float> pc_input_buffers_full();
+ std::vector<float> pc_input_buffers_full_var();
float pc_output_buffers_full(int which);
+ float pc_output_buffers_full_var(int which);
std::vector<float> pc_output_buffers_full();
+ std::vector<float> pc_output_buffers_full_var();
float pc_work_time();
-
+ float pc_work_time_var();
+
// Methods to manage processor affinity.
void set_processor_affinity(const gr_vector_uint &mask);
void unset_processor_affinity();
diff --git a/gnuradio-core/src/lib/runtime/gr_block_detail.cc b/gnuradio-core/src/lib/runtime/gr_block_detail.cc
index b151bd96d2..c05b7b96a0 100644
--- a/gnuradio-core/src/lib/runtime/gr_block_detail.cc
+++ b/gnuradio-core/src/lib/runtime/gr_block_detail.cc
@@ -41,10 +41,17 @@ gr_block_detail::gr_block_detail (unsigned int ninputs, unsigned int noutputs)
d_ninputs (ninputs), d_noutputs (noutputs),
d_input (ninputs), d_output (noutputs),
d_done (false),
- d_avg_noutput_items(0), d_avg_nproduced(0),
+ d_avg_noutput_items(0),
+ d_var_noutput_items(0),
+ d_avg_nproduced(0),
+ d_var_nproduced(0),
d_avg_input_buffers_full(ninputs, 0),
+ d_var_input_buffers_full(ninputs, 0),
d_avg_output_buffers_full(noutputs, 0),
- d_avg_work_time(0)
+ d_var_output_buffers_full(noutputs, 0),
+ d_avg_work_time(0),
+ d_var_work_time(0),
+ d_pc_counter(0)
{
s_ncurrently_allocated++;
}
@@ -235,27 +242,68 @@ gr_block_detail::start_perf_counters()
void
gr_block_detail::stop_perf_counters(int noutput_items, int nproduced)
{
- float alpha = 0.05;
- float beta = 1.0-alpha;
-
d_end_of_work = gruel::high_res_timer_now();
gruel::high_res_timer_type diff = d_end_of_work - d_start_of_work;
- d_avg_work_time = beta*d_avg_work_time + alpha*diff;
-
- d_avg_nproduced = beta*d_avg_nproduced + alpha*nproduced;
- d_avg_noutput_items = beta*d_avg_noutput_items + alpha*noutput_items;
- for(size_t i=0; i < d_input.size(); i++) {
- float pfull = static_cast<float>(d_input[i]->items_available()) /
- static_cast<float>(d_input[i]->max_possible_items_available());
- d_avg_input_buffers_full[i] = beta*d_avg_input_buffers_full[i] + alpha*pfull;
+ if(d_pc_counter == 0) {
+ d_avg_work_time = diff;
+ d_var_work_time = 0;
+ d_avg_nproduced = nproduced;
+ d_var_nproduced = 0;
+ d_avg_noutput_items = noutput_items;
+ d_var_noutput_items = 0;
+ for(size_t i=0; i < d_input.size(); i++) {
+ float pfull = static_cast<float>(d_input[i]->items_available()) /
+ static_cast<float>(d_input[i]->max_possible_items_available());
+ d_avg_input_buffers_full[i] = pfull;
+ d_var_input_buffers_full[i] = 0;
+ }
+ for(size_t i=0; i < d_output.size(); i++) {
+ float pfull = 1.0f - static_cast<float>(d_output[i]->space_available()) /
+ static_cast<float>(d_output[i]->bufsize());
+ d_avg_output_buffers_full[i] = pfull;
+ d_var_output_buffers_full[i] = 0;
+ }
}
+ else {
+ float d = diff - d_avg_work_time;
+ d_avg_work_time = d_avg_work_time + d/d_pc_counter;
+ d_var_work_time = d_var_work_time + d*d;
+
+ d = nproduced - d_avg_nproduced;
+ d_avg_nproduced = d_avg_nproduced + d/d_pc_counter;
+ d_var_nproduced = d_var_nproduced + d*d;
+
+ d = noutput_items - d_avg_noutput_items;
+ d_avg_noutput_items = d_avg_noutput_items + d/d_pc_counter;
+ d_var_noutput_items = d_var_noutput_items + d*d;
+
+ for(size_t i=0; i < d_input.size(); i++) {
+ float pfull = static_cast<float>(d_input[i]->items_available()) /
+ static_cast<float>(d_input[i]->max_possible_items_available());
+
+ d = pfull - d_avg_input_buffers_full[i];
+ d_avg_input_buffers_full[i] = d_avg_input_buffers_full[i] + d/d_pc_counter;
+ d_var_input_buffers_full[i] = d_var_input_buffers_full[i] + d*d;
+ }
- for(size_t i=0; i < d_output.size(); i++) {
- float pfull = 1.0f - static_cast<float>(d_output[i]->space_available()) /
- static_cast<float>(d_output[i]->bufsize());
- d_avg_output_buffers_full[i] = beta*d_avg_output_buffers_full[i] + alpha*pfull;
+ for(size_t i=0; i < d_output.size(); i++) {
+ float pfull = 1.0f - static_cast<float>(d_output[i]->space_available()) /
+ static_cast<float>(d_output[i]->bufsize());
+
+ d = pfull - d_avg_output_buffers_full[i];
+ d_avg_output_buffers_full[i] = d_avg_output_buffers_full[i] + d/d_pc_counter;
+ d_var_output_buffers_full[i] = d_var_output_buffers_full[i] + d*d;
+ }
}
+
+ d_pc_counter++;
+}
+
+void
+gr_block_detail::reset_perf_counters()
+{
+ d_pc_counter = 0;
}
float
@@ -305,3 +353,58 @@ gr_block_detail::pc_work_time()
{
return d_avg_work_time;
}
+
+
+float
+gr_block_detail::pc_noutput_items_var()
+{
+ return d_var_noutput_items/(d_pc_counter-1);
+}
+
+float
+gr_block_detail::pc_nproduced_var()
+{
+ return d_var_nproduced/(d_pc_counter-1);
+}
+
+float
+gr_block_detail::pc_input_buffers_full_var(size_t which)
+{
+ if(which < d_avg_input_buffers_full.size())
+ return d_var_input_buffers_full[which]/(d_pc_counter-1);
+ else
+ return 0;
+}
+
+std::vector<float>
+gr_block_detail::pc_input_buffers_full_var()
+{
+ std::vector<float> var(d_avg_input_buffers_full.size(), 0);
+ for(size_t i = 0; i < d_avg_input_buffers_full.size(); i++)
+ var[i] = d_avg_input_buffers_full[i]/(d_pc_counter-1);
+ return var;
+}
+
+float
+gr_block_detail::pc_output_buffers_full_var(size_t which)
+{
+ if(which < d_avg_output_buffers_full.size())
+ return d_var_output_buffers_full[which]/(d_pc_counter-1);
+ else
+ return 0;
+}
+
+std::vector<float>
+gr_block_detail::pc_output_buffers_full_var()
+{
+ std::vector<float> var(d_avg_output_buffers_full.size(), 0);
+ for(size_t i = 0; i < d_avg_output_buffers_full.size(); i++)
+ var[i] = d_avg_output_buffers_full[i]/(d_pc_counter-1);
+ return var;
+}
+
+float
+gr_block_detail::pc_work_time_var()
+{
+ return d_var_work_time/(d_pc_counter-1);
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_block_detail.h b/gnuradio-core/src/lib/runtime/gr_block_detail.h
index dd8be71c9c..32a01e763a 100644
--- a/gnuradio-core/src/lib/runtime/gr_block_detail.h
+++ b/gnuradio-core/src/lib/runtime/gr_block_detail.h
@@ -173,6 +173,7 @@ class GR_CORE_API gr_block_detail {
void start_perf_counters();
void stop_perf_counters(int noutput_items, int nproduced);
+ void reset_perf_counters();
// Calls to get performance counter items
float pc_noutput_items();
@@ -183,6 +184,14 @@ class GR_CORE_API gr_block_detail {
std::vector<float> pc_output_buffers_full();
float pc_work_time();
+ float pc_noutput_items_var();
+ float pc_nproduced_var();
+ float pc_input_buffers_full_var(size_t which);
+ std::vector<float> pc_input_buffers_full_var();
+ float pc_output_buffers_full_var(size_t which);
+ std::vector<float> pc_output_buffers_full_var();
+ float pc_work_time_var();
+
gr_tpb_detail d_tpb; // used by thread-per-block scheduler
int d_produce_or;
@@ -197,11 +206,17 @@ class GR_CORE_API gr_block_detail {
// Performance counters
float d_avg_noutput_items;
+ float d_var_noutput_items;
float d_avg_nproduced;
+ float d_var_nproduced;
std::vector<float> d_avg_input_buffers_full;
+ std::vector<float> d_var_input_buffers_full;
std::vector<float> d_avg_output_buffers_full;
+ std::vector<float> d_var_output_buffers_full;
gruel::high_res_timer_type d_start_of_work, d_end_of_work;
float d_avg_work_time;
+ float d_var_work_time;
+ float d_pc_counter;
gr_block_detail (unsigned int ninputs, unsigned int noutputs);
diff --git a/gnuradio-core/src/python/gnuradio/ctrlport/GrDataPlotter.py b/gnuradio-core/src/python/gnuradio/ctrlport/GrDataPlotter.py
index f33160aca2..e2844b8bad 100644
--- a/gnuradio-core/src/python/gnuradio/ctrlport/GrDataPlotter.py
+++ b/gnuradio-core/src/python/gnuradio/ctrlport/GrDataPlotter.py
@@ -46,9 +46,7 @@ class GrDataPlotterC(gr.top_block):
self.thr = gr.throttle(gr.sizeof_gr_complex, rate)
self.snk = qtgui.time_sink_c(self._npts, samp_rate,
self._name, 1)
-
- if(pmin is not None or not pmax is None):
- self.snk.set_y_axis(pmin, pmax)
+ self.snk.enable_autoscale(True)
self.connect(self.src, self.thr, (self.snk, 0))
@@ -121,9 +119,7 @@ class GrDataPlotterF(gr.top_block):
self.thr = gr.throttle(gr.sizeof_float, rate)
self.snk = qtgui.time_sink_f(self._npts, samp_rate,
self._name, 1)
-
- if(pmin is not None or not pmax is None):
- self.snk.set_y_axis(pmin, pmax)
+ self.snk.enable_autoscale(True)
self.connect(self.src, self.thr, (self.snk, 0))
@@ -191,10 +187,7 @@ class GrDataPlotterConst(gr.top_block):
self.thr = gr.throttle(gr.sizeof_gr_complex, rate)
self.snk = qtgui.const_sink_c(self._npts,
self._name, 1)
-
- if(pmin is not None or not pmax is None):
- self.snk.set_x_axis(pmin, pmax)
- self.snk.set_y_axis(pmin, pmax)
+ self.snk.enable_autoscale(True)
self.connect(self.src, self.thr, (self.snk, 0))
@@ -268,9 +261,7 @@ class GrDataPlotterPsdC(gr.top_block):
self.snk = qtgui.freq_sink_c(self._fftsize, self._wintype,
self._fc, self._samp_rate,
self._name, 1)
-
- if(pmin is not None or not pmax is None):
- self.snk.set_y_axis(pmin, pmax)
+ self.snk.enable_autoscale(True)
self.connect(self.src, self.thr, (self.snk, 0))
@@ -343,9 +334,7 @@ class GrDataPlotterPsdF(gr.top_block):
self.snk = qtgui.freq_sink_f(self._fftsize, self._wintype,
self._fc, self._samp_rate,
self._name, 1)
-
- if(pmin is not None or not pmax is None):
- self.snk.set_y_axis(pmin, pmax)
+ self.snk.enable_autoscale(True)
self.connect(self.src, self.thr, (self.snk, 0))
@@ -401,6 +390,141 @@ class GrDataPlotterPsdF(gr.top_block):
self.src.set_data(self._last_data)
+class GrTimeRasterF(gr.top_block):
+ def __init__(self, name, rate, pmin=None, pmax=None):
+ gr.top_block.__init__(self)
+
+ self._name = name
+ self._npts = 100
+ self._rows = 100
+ samp_rate = 1.0
+
+ self._last_data = self._npts*[0,]
+ self._data_len = 0
+
+ self.src = gr.vector_source_f([])
+ self.thr = gr.throttle(gr.sizeof_float, rate)
+ self.snk = qtgui.time_raster_sink_f(samp_rate, self._npts, self._rows,
+ [], [], self._name, 1)
+
+ self.connect(self.src, self.thr, (self.snk, 0))
+
+ self.py_window = sip.wrapinstance(self.snk.pyqwidget(), QtGui.QWidget)
+
+ def __del__(self):
+ pass
+
+ def qwidget(self):
+ return self.py_window
+
+ def name(self):
+ return self._name
+
+ def update(self, data):
+ # Ask GUI if there has been a change in nsamps
+ npts = int(self.snk.num_cols())
+ if(self._npts != npts):
+
+ # Adjust buffers to accomodate new settings
+ if(npts < self._npts):
+ if(self._data_len < npts):
+ self._last_data = self._last_data[0:npts]
+ else:
+ self._last_data = self._last_data[self._data_len-npts:self._data_len]
+ self._data_len = npts
+ else:
+ self._last_data += (npts - self._npts)*[0,]
+ self._npts = npts
+ self.snk.reset()
+
+ # Update the plot data depending on type
+ if(type(data) == list):
+ if(len(data) > self._npts):
+ self.src.set_data(data)
+ self._last_data = data[-self._npts:]
+ else:
+ newdata = self._last_data[-(self._npts-len(data)):]
+ newdata += data
+ self.src.set_data(newdata)
+ self._last_data = newdata
+
+ else: # single value update
+ if(self._data_len < self._npts):
+ self._last_data[self._data_len] = data
+ self._data_len += 1
+ else:
+ self._last_data = self._last_data[1:]
+ self._last_data.append(data)
+ self.src.set_data(self._last_data)
+
+class GrTimeRasterB(gr.top_block):
+ def __init__(self, name, rate, pmin=None, pmax=None):
+ gr.top_block.__init__(self)
+
+ self._name = name
+ self._npts = 100
+ self._rows = 100
+ samp_rate = 1.0
+
+ self._last_data = self._npts*[0,]
+ self._data_len = 0
+
+ self.src = gr.vector_source_b([])
+ self.thr = gr.throttle(gr.sizeof_char, rate)
+ self.snk = qtgui.time_raster_sink_b(samp_rate, self._npts, self._rows,
+ [], [], self._name, 1)
+
+ self.connect(self.src, self.thr, (self.snk, 0))
+
+ self.py_window = sip.wrapinstance(self.snk.pyqwidget(), QtGui.QWidget)
+
+ def __del__(self):
+ pass
+
+ def qwidget(self):
+ return self.py_window
+
+ def name(self):
+ return self._name
+
+ def update(self, data):
+ # Ask GUI if there has been a change in nsamps
+ npts = self.snk.num_cols()
+ if(self._npts != npts):
+
+ # Adjust buffers to accomodate new settings
+ if(npts < self._npts):
+ if(self._data_len < npts):
+ self._last_data = self._last_data[0:npts]
+ else:
+ self._last_data = self._last_data[self._data_len-npts:self._data_len]
+ self._data_len = npts
+ else:
+ self._last_data += (npts - self._npts)*[0,]
+ self._npts = npts
+ self.snk.reset()
+
+ # Update the plot data depending on type
+ if(type(data) == list):
+ if(len(data) > self._npts):
+ self.src.set_data(data)
+ self._last_data = data[-self._npts:]
+ else:
+ newdata = self._last_data[-(self._npts-len(data)):]
+ newdata += data
+ self.src.set_data(newdata)
+ self._last_data = newdata
+
+ else: # single value update
+ if(self._data_len < self._npts):
+ self._last_data[self._data_len] = data
+ self._data_len += 1
+ else:
+ self._last_data = self._last_data[1:]
+ self._last_data.append(data)
+ self.src.set_data(self._last_data)
+
+
class GrDataPlotterValueTable:
def __init__(self, uid, parent, x, y, xsize, ysize,
headers=['Statistic Key ( Source Block :: Stat Name ) ',
diff --git a/gnuradio-core/src/python/gnuradio/ctrlport/gr-ctrlport-monitor b/gnuradio-core/src/python/gnuradio/ctrlport/gr-ctrlport-monitor
index b51888527b..ec31be209f 100755
--- a/gnuradio-core/src/python/gnuradio/ctrlport/gr-ctrlport-monitor
+++ b/gnuradio-core/src/python/gnuradio/ctrlport/gr-ctrlport-monitor
@@ -133,6 +133,12 @@ class MAINWindow(QtGui.QMainWindow):
def newPlotterPsdCProxy():
self.newPlotPsdC(key, uid, title)
+ def newPlotterRasterFProxy():
+ self.newPlotRasterF(key, uid, title, pmin, pmax)
+
+ def newPlotterRasterBProxy():
+ self.newPlotRasterB(key, uid, title, pmin, pmax)
+
menu = QtGui.QMenu(self)
menu.setTitle("Item Actions")
menu.setTearOffEnabled(False)
@@ -140,14 +146,14 @@ class MAINWindow(QtGui.QMainWindow):
# object properties
menu.addAction("Properties", newUpdaterProxy)
- # displays available if not complex
+ # displays available
menu.addAction("Plot Time", newPlotterFProxy)
- menu.addAction("Plot PSD", newPlotterPsdFProxy)
-
- # displays available if complex
menu.addAction("Plot Time (cpx)", newPlotterCProxy)
- menu.addAction("Plot Constellation", newPlotterConstProxy)
+ menu.addAction("Plot PSD", newPlotterPsdFProxy)
menu.addAction("Plot PSD cpx", newPlotterPsdCProxy)
+ menu.addAction("Plot Constellation", newPlotterConstProxy)
+ menu.addAction("Plot Raster (real)", newPlotterRasterFProxy)
+ #menu.addAction("Plot Raster (bits)", newPlotterRasterBProxy)
menu.popup(QtGui.QCursor.pos())
@@ -222,6 +228,14 @@ class MAINWindow(QtGui.QMainWindow):
plot = GrDataPlotterPsdC(tag, 32e6, pmin, pmax)
self.createPlot(plot, uid, title)
+ def newPlotRasterF(self, tag, uid, title="", pmin=None, pmax=None):
+ plot = GrTimeRasterF(tag, 32e6, pmin, pmax)
+ self.createPlot(plot, uid, title)
+
+ def newPlotRasterB(self, tag, uid, title="", pmin=None, pmax=None):
+ plot = GrTimeRasterB(tag, 32e6, pmin, pmax)
+ self.createPlot(plot, uid, title)
+
def update(self, knobs, uid):
#sys.stderr.write("KNOB KEYS: {0}\n".format(knobs.keys()))
for plot in self.plots[uid]:
diff --git a/gr-channels/examples/channel_tone_response.grc b/gr-channels/examples/channel_tone_response.grc
new file mode 100644
index 0000000000..bd02f6000a
--- /dev/null
+++ b/gr-channels/examples/channel_tone_response.grc
@@ -0,0 +1,762 @@
+<?xml version='1.0' encoding='ASCII'?>
+<flow_graph>
+ <timestamp>Fri Feb 15 15:13:55 2013</timestamp>
+ <block>
+ <key>import</key>
+ <param>
+ <key>id</key>
+ <value>import_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>import</key>
+ <value>import math</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(181, 10)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>samp_rate</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>100e3</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(273, 10)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>ctrlport_monitor</key>
+ <param>
+ <key>id</key>
+ <value>ctrlport_monitor_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>en</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(374, 10)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>qtgui_freq_sink_x</key>
+ <param>
+ <key>id</key>
+ <value>qtgui_freq_sink_x_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>complex</value>
+ </param>
+ <param>
+ <key>name</key>
+ <value>QT GUI Plot</value>
+ </param>
+ <param>
+ <key>fftsize</key>
+ <value>1024</value>
+ </param>
+ <param>
+ <key>wintype</key>
+ <value>firdes.WIN_BLACKMAN_hARRIS</value>
+ </param>
+ <param>
+ <key>fc</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>bw</key>
+ <value>samp_rate</value>
+ </param>
+ <param>
+ <key>ymin</key>
+ <value>-140</value>
+ </param>
+ <param>
+ <key>ymax</key>
+ <value>10</value>
+ </param>
+ <param>
+ <key>nconnections</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>update_time</key>
+ <value>0.10</value>
+ </param>
+ <param>
+ <key>gui_hint</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(1011, 21)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>channels_channel_model</key>
+ <param>
+ <key>id</key>
+ <value>channels_channel_model_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>noise_voltage</key>
+ <value>math.pow(10,n/10.0)</value>
+ </param>
+ <param>
+ <key>freq_offset</key>
+ <value>cfo</value>
+ </param>
+ <param>
+ <key>epsilon</key>
+ <value>fso</value>
+ </param>
+ <param>
+ <key>taps</key>
+ <value>1.0 + 1.0j</value>
+ </param>
+ <param>
+ <key>seed</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(737, 106)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>analog_sig_source_x</key>
+ <param>
+ <key>id</key>
+ <value>analog_sig_source_x_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>complex</value>
+ </param>
+ <param>
+ <key>samp_rate</key>
+ <value>samp_rate</value>
+ </param>
+ <param>
+ <key>waveform</key>
+ <value>analog.GR_COS_WAVE</value>
+ </param>
+ <param>
+ <key>freq</key>
+ <value>samp_rate/4</value>
+ </param>
+ <param>
+ <key>amp</key>
+ <value>math.pow(10,amp/10)</value>
+ </param>
+ <param>
+ <key>offset</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(12, 106)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>gr_throttle</key>
+ <param>
+ <key>id</key>
+ <value>gr_throttle_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>complex</value>
+ </param>
+ <param>
+ <key>samples_per_second</key>
+ <value>samp_rate</value>
+ </param>
+ <param>
+ <key>vlen</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(218, 138)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>qtgui_waterfall_sink_x</key>
+ <param>
+ <key>id</key>
+ <value>qtgui_waterfall_sink_x_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>complex</value>
+ </param>
+ <param>
+ <key>name</key>
+ <value>QT GUI Plot</value>
+ </param>
+ <param>
+ <key>fftsize</key>
+ <value>1024</value>
+ </param>
+ <param>
+ <key>wintype</key>
+ <value>firdes.WIN_BLACKMAN_hARRIS</value>
+ </param>
+ <param>
+ <key>fc</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>bw</key>
+ <value>samp_rate</value>
+ </param>
+ <param>
+ <key>update_time</key>
+ <value>0.10</value>
+ </param>
+ <param>
+ <key>gui_hint</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(1011, 130)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable_qtgui_range</key>
+ <param>
+ <key>id</key>
+ <value>amp</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>label</key>
+ <value>Sine Amplitude (dB)</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>start</key>
+ <value>-100</value>
+ </param>
+ <param>
+ <key>stop</key>
+ <value>100</value>
+ </param>
+ <param>
+ <key>step</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>widget</key>
+ <value>counter_slider</value>
+ </param>
+ <param>
+ <key>orient</key>
+ <value>Qt.Horizontal</value>
+ </param>
+ <param>
+ <key>min_len</key>
+ <value>200</value>
+ </param>
+ <param>
+ <key>gui_hint</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(785, 227)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable_qtgui_range</key>
+ <param>
+ <key>id</key>
+ <value>fso</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>label</key>
+ <value>Sampling Frequency Relative Offset</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>start</key>
+ <value>0.9</value>
+ </param>
+ <param>
+ <key>stop</key>
+ <value>1.1</value>
+ </param>
+ <param>
+ <key>step</key>
+ <value>.001</value>
+ </param>
+ <param>
+ <key>widget</key>
+ <value>counter_slider</value>
+ </param>
+ <param>
+ <key>orient</key>
+ <value>Qt.Horizontal</value>
+ </param>
+ <param>
+ <key>min_len</key>
+ <value>200</value>
+ </param>
+ <param>
+ <key>gui_hint</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(621, 227)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable_qtgui_range</key>
+ <param>
+ <key>id</key>
+ <value>n</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>label</key>
+ <value>Noise Level (dB)</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>-12</value>
+ </param>
+ <param>
+ <key>start</key>
+ <value>-30</value>
+ </param>
+ <param>
+ <key>stop</key>
+ <value>30</value>
+ </param>
+ <param>
+ <key>step</key>
+ <value>.5</value>
+ </param>
+ <param>
+ <key>widget</key>
+ <value>counter_slider</value>
+ </param>
+ <param>
+ <key>orient</key>
+ <value>Qt.Horizontal</value>
+ </param>
+ <param>
+ <key>min_len</key>
+ <value>200</value>
+ </param>
+ <param>
+ <key>gui_hint</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(342, 226)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable_qtgui_range</key>
+ <param>
+ <key>id</key>
+ <value>fD</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>label</key>
+ <value>Max Doppler Frequency (Hz)</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>125</value>
+ </param>
+ <param>
+ <key>start</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>stop</key>
+ <value>1000</value>
+ </param>
+ <param>
+ <key>step</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>widget</key>
+ <value>counter_slider</value>
+ </param>
+ <param>
+ <key>orient</key>
+ <value>Qt.Horizontal</value>
+ </param>
+ <param>
+ <key>min_len</key>
+ <value>200</value>
+ </param>
+ <param>
+ <key>gui_hint</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(13, 226)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable_qtgui_range</key>
+ <param>
+ <key>id</key>
+ <value>cfo</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>label</key>
+ <value>Frequency Offset</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>start</key>
+ <value>-20e3</value>
+ </param>
+ <param>
+ <key>stop</key>
+ <value>20e3</value>
+ </param>
+ <param>
+ <key>step</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>widget</key>
+ <value>counter_slider</value>
+ </param>
+ <param>
+ <key>orient</key>
+ <value>Qt.Horizontal</value>
+ </param>
+ <param>
+ <key>min_len</key>
+ <value>200</value>
+ </param>
+ <param>
+ <key>gui_hint</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(480, 225)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable_qtgui_range</key>
+ <param>
+ <key>id</key>
+ <value>K</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>label</key>
+ <value>K (Rician Factor)</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>4</value>
+ </param>
+ <param>
+ <key>start</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>stop</key>
+ <value>30</value>
+ </param>
+ <param>
+ <key>step</key>
+ <value>.1</value>
+ </param>
+ <param>
+ <key>widget</key>
+ <value>counter_slider</value>
+ </param>
+ <param>
+ <key>orient</key>
+ <value>Qt.Horizontal</value>
+ </param>
+ <param>
+ <key>min_len</key>
+ <value>200</value>
+ </param>
+ <param>
+ <key>gui_hint</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(195, 226)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>options</key>
+ <param>
+ <key>id</key>
+ <value>channel_tone_response</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>title</key>
+ <value>Channel Tone Response</value>
+ </param>
+ <param>
+ <key>author</key>
+ <value></value>
+ </param>
+ <param>
+ <key>description</key>
+ <value></value>
+ </param>
+ <param>
+ <key>window_size</key>
+ <value>1280, 1024</value>
+ </param>
+ <param>
+ <key>generate_options</key>
+ <value>qt_gui</value>
+ </param>
+ <param>
+ <key>category</key>
+ <value>Custom</value>
+ </param>
+ <param>
+ <key>run_options</key>
+ <value>prompt</value>
+ </param>
+ <param>
+ <key>run</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>pre_hook</key>
+ <value>None</value>
+ </param>
+ <param>
+ <key>post_hook</key>
+ <value>None</value>
+ </param>
+ <param>
+ <key>realtime_scheduling</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(10, 10)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>channels_fading_model</key>
+ <param>
+ <key>id</key>
+ <value>channels_fading_model_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>N</key>
+ <value>8</value>
+ </param>
+ <param>
+ <key>fDTs</key>
+ <value>fD/samp_rate</value>
+ </param>
+ <param>
+ <key>LOS</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>K</key>
+ <value>K</value>
+ </param>
+ <param>
+ <key>seed</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(415, 106)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <connection>
+ <source_block_id>channels_channel_model_0</source_block_id>
+ <sink_block_id>qtgui_waterfall_sink_x_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>channels_channel_model_0</source_block_id>
+ <sink_block_id>qtgui_freq_sink_x_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>channels_fading_model_0</source_block_id>
+ <sink_block_id>channels_channel_model_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>gr_throttle_0</source_block_id>
+ <sink_block_id>channels_fading_model_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>analog_sig_source_x_0</source_block_id>
+ <sink_block_id>gr_throttle_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+</flow_graph>
diff --git a/gr-channels/grc/CMakeLists.txt b/gr-channels/grc/CMakeLists.txt
index 9e77fcc4ef..cbbf75901c 100644
--- a/gr-channels/grc/CMakeLists.txt
+++ b/gr-channels/grc/CMakeLists.txt
@@ -20,6 +20,7 @@
install(FILES
channels_block_tree.xml
channels_channel_model.xml
+ channels_fading_model.xml
DESTINATION ${GRC_BLOCKS_DIR}
COMPONENT "channels_python"
)
diff --git a/gr-channels/grc/channels_block_tree.xml b/gr-channels/grc/channels_block_tree.xml
index 587eebb6e9..efa808fd53 100644
--- a/gr-channels/grc/channels_block_tree.xml
+++ b/gr-channels/grc/channels_block_tree.xml
@@ -31,5 +31,6 @@
<cat>
<name>Channel Models</name>
<block>channels_channel_model</block>
+ <block>channels_fading_model</block>
</cat>
</cat>
diff --git a/gr-channels/grc/channels_fading_model.xml b/gr-channels/grc/channels_fading_model.xml
new file mode 100644
index 0000000000..2b68cfa2ec
--- /dev/null
+++ b/gr-channels/grc/channels_fading_model.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Fading Model
+###################################################
+ -->
+<block>
+ <name>Fading Model</name>
+ <key>channels_fading_model</key>
+ <import>from gnuradio import channels</import>
+ <make>channels.fading_model( $N, $fDTs, $LOS, $K, $seed )</make>
+ <callback>set_fDTs($fDTs)</callback>
+ <callback>set_K($K)</callback>
+ <param>
+ <name>Num Sinusoids (SoS model)</name>
+ <key>N</key>
+ <value>8</value>
+ <type>int</type>
+ </param>
+ <param>
+ <name>Normalized Max Doppler (fD*Ts)</name>
+ <key>fDTs</key>
+ <value>10.0/samp_rate</value>
+ <type>real</type>
+ </param>
+ <param>
+ <name>LOS Model</name>
+ <key>LOS</key>
+ <type>enum</type>
+ <option>
+ <name>Rayleigh/NLOS</name>
+ <key>False</key>
+ <opt>hide_K:all</opt>
+ </option>
+ <option>
+ <name>Rician/LOS</name>
+ <key>True</key>
+ <opt>hide_K:</opt>
+ </option>
+ </param>
+ <param>
+ <name>Rician factor (K)</name>
+ <key>K</key>
+ <value>4.0</value>
+ <type>real</type>
+ <hide>$LOS.hide_K</hide>
+ </param>
+ <param>
+ <name>Seed</name>
+ <key>seed</key>
+ <value>0</value>
+ <type>int</type>
+ </param>
+
+ <sink>
+ <name>in</name>
+ <type>complex</type>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>complex</type>
+ </source>
+ <doc>
+ This algorithm implements the method described in
+ Compact Rayleigh and Rician fading simulator based on random walk processes
+ A. Alimohammad S.F. Fard B.F. Cockburn C. Schlegel
+ 26th November 2008
+
+ int d_N=8; // number of sinusoids
+ float d_fDTs=0.01 // normalized maximum doppler frequency (f_doppler / f_samprate)
+ float d_K=4; // Rician factor (ratio of the specular power to the scattered power)
+ bool d_LOS=true; // LOS path exists? chooses Rician (LOS) vs Rayleigh (NLOS) model.
+ int seed=0; // noise seed
+ </doc>
+</block>
diff --git a/gr-channels/include/channels/CMakeLists.txt b/gr-channels/include/channels/CMakeLists.txt
index a913b96819..c0c70e2b00 100644
--- a/gr-channels/include/channels/CMakeLists.txt
+++ b/gr-channels/include/channels/CMakeLists.txt
@@ -23,6 +23,7 @@
install(FILES
api.h
channel_model.h
+ fading_model.h
DESTINATION ${GR_INCLUDE_DIR}/gnuradio/channels
COMPONENT "channels_devel"
)
diff --git a/gr-channels/include/channels/fading_model.h b/gr-channels/include/channels/fading_model.h
new file mode 100644
index 0000000000..651b087eb7
--- /dev/null
+++ b/gr-channels/include/channels/fading_model.h
@@ -0,0 +1,75 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2013 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_CHANNELS_FADING_MODEL_H
+#define INCLUDED_CHANNELS_FADING_MODEL_H
+
+#include <channels/api.h>
+#include <gr_sync_block.h>
+#include <gr_types.h>
+
+namespace gr {
+ namespace channels {
+
+ /*!
+ * \brief fading simulator
+ * \ingroup misc_blk
+ *
+ * This block implements a basic fading model simulator that can
+ * be used to help evaluate, design, and test various signals,
+ * waveforms, and algorithms.
+ *
+ */
+ class CHANNELS_API fading_model : virtual public gr_sync_block
+ {
+ public:
+ // gr::channels::channel_model::sptr
+ typedef boost::shared_ptr<fading_model> sptr;
+
+ /*! \brief Build the channel simulator.
+ *
+ * \param N The number of sinusiods to use in simulating the channel 8 is a good value
+ * \param fDTs normalized maximum doppler frequency, fD * Ts
+ * \param LOS include Line-of-Site path? selects between Rayleigh (NLOS) and Rician (LOS) models
+ * \param K Rician factor (ratio of the specular power to the scattered power)
+ * \param seed a random number to seed the noise generators
+ */
+ static sptr make(unsigned int N,
+ float fDTs=0.01,
+ bool LOS=true,
+ float K=4,
+ int seed=0);
+
+ virtual float fDTs() = 0;
+ virtual float K() = 0;
+ virtual float step() = 0;
+
+ virtual void set_fDTs(float fDTs) = 0;
+ virtual void set_K(float K) = 0;
+ virtual void set_step(float step) = 0;
+
+ };
+
+ } /* namespace channels */
+} /* namespace gr */
+
+#endif /* INCLUDED_CHANNELS_FADING_MODEL_H */
diff --git a/gr-channels/lib/CMakeLists.txt b/gr-channels/lib/CMakeLists.txt
index f895f25806..fe28d41672 100644
--- a/gr-channels/lib/CMakeLists.txt
+++ b/gr-channels/lib/CMakeLists.txt
@@ -44,6 +44,7 @@ endif(ENABLE_GR_CTRLPORT)
########################################################################
list(APPEND channels_sources
channel_model_impl.cc
+ fading_model_impl.cc
)
list(APPEND channels_libs
diff --git a/gr-channels/lib/fading_model_impl.cc b/gr-channels/lib/fading_model_impl.cc
new file mode 100644
index 0000000000..709c1c5713
--- /dev/null
+++ b/gr-channels/lib/fading_model_impl.cc
@@ -0,0 +1,207 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2013 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.
+ */
+
+#include "fading_model_impl.h"
+#include <gr_io_signature.h>
+#include <iostream>
+
+#include <boost/format.hpp>
+#include <boost/random.hpp>
+
+#include <gr_fxpt.h>
+#include <sincostable.h>
+
+
+// FASTSINCOS: 0 = slow native, 1 = gr_fxpt impl, 2 = sincostable.h
+#define FASTSINCOS 2
+
+
+namespace gr {
+ namespace channels {
+
+ fading_model::sptr
+ fading_model::make( unsigned int N, float fDTs, bool LOS, float K, int seed )
+ {
+ return gnuradio::get_initial_sptr
+ (new fading_model_impl( N, fDTs, LOS, K, seed));
+ }
+
+ // Block constructor
+ fading_model_impl::fading_model_impl( unsigned int N, float fDTs, bool LOS, float K, int seed )
+ : gr_sync_block("fading_model",
+ gr_make_io_signature(1, 1, sizeof(gr_complex)),
+ gr_make_io_signature(1, 1, sizeof(gr_complex))),
+ seed_1((int)seed),
+ dist_1(-M_PI, M_PI),
+ rv_1( seed_1, dist_1 ), // U(-pi,pi)
+
+ seed_2((int)seed+1),
+ dist_2(0, 1),
+ rv_2( seed_2, dist_2 ), // U(0,1)
+
+ d_N(N),
+ d_fDTs(fDTs),
+ d_theta(rv_1()),
+ d_theta_los(rv_1()),
+ d_step( powf(0.00125*fDTs, 1.1) ), // max step size approximated from Table 2
+ d_m(0),
+ d_K(K),
+ d_LOS(LOS),
+
+ d_psi(d_N+1, 0),
+ d_phi(d_N+1, 0),
+
+ d_table(8*1024),
+
+ scale_sin(sqrtf(2.0/d_N)),
+ scale_los(sqrtf(d_K)/sqrtf(d_K+1)),
+ scale_nlos(1/sqrtf(d_K+1))
+ {
+ // generate initial phase values
+ for(int i=0; i<d_N+1; i++){
+ d_psi[i] = rv_1();
+ d_phi[i] = rv_1();
+ }
+ }
+
+ fading_model_impl::~fading_model_impl()
+ {
+ }
+
+ void
+ fading_model_impl::setup_rpc()
+ {
+#ifdef GR_CTRLPORT
+ add_rpc_variable(
+ rpcbasic_sptr(new rpcbasic_register_get<fading_model, float >(
+ alias(), "fDTs",
+ &fading_model::fDTs,
+ pmt::mp(0), pmt::mp(1), pmt::mp(0.01),
+ "Hz*Sec", "normalized maximum doppler frequency (fD*Ts)",
+ RPC_PRIVLVL_MIN, DISPTIMESERIESF)));
+ add_rpc_variable(
+ rpcbasic_sptr(new rpcbasic_register_set<fading_model, float >(
+ alias(), "fDTs",
+ &fading_model::set_fDTs,
+ pmt::mp(0), pmt::mp(1), pmt::mp(0.01),
+ "Hz*Sec", "normalized maximum doppler frequency (fD*Ts)",
+ RPC_PRIVLVL_MIN, DISPTIMESERIESF)));
+
+ add_rpc_variable(
+ rpcbasic_sptr(new rpcbasic_register_get<fading_model, float >(
+ alias(), "K",
+ &fading_model::K,
+ pmt::mp(0), pmt::mp(8), pmt::mp(4),
+ "Ratio", "Rician factor (ratio of the specular power to the scattered power)",
+ RPC_PRIVLVL_MIN, DISPTIMESERIESF)));
+ add_rpc_variable(
+ rpcbasic_sptr(new rpcbasic_register_set<fading_model, float >(
+ alias(), "K",
+ &fading_model::set_K,
+ pmt::mp(0), pmt::mp(8), pmt::mp(4),
+ "Ratio", "Rician factor (ratio of the specular power to the scattered power)",
+ RPC_PRIVLVL_MIN, DISPTIMESERIESF)));
+
+ add_rpc_variable(
+ rpcbasic_sptr(new rpcbasic_register_get<fading_model, float >(
+ alias(), "step",
+ &fading_model::step,
+ pmt::mp(0), pmt::mp(8), pmt::mp(4),
+ "radians", "Maximum step size for random walk angle per sample",
+ RPC_PRIVLVL_MIN, DISPTIMESERIESF)));
+ add_rpc_variable(
+ rpcbasic_sptr(new rpcbasic_register_set<fading_model, float >(
+ alias(), "step",
+ &fading_model::set_step,
+ pmt::mp(0), pmt::mp(1), pmt::mp(0.00001),
+ "radians", "Maximum step size for random walk angle per sample",
+ RPC_PRIVLVL_MIN, DISPTIMESERIESF)));
+
+#endif /* GR_CTRLPORT */
+ }
+
+ void
+ fading_model_impl::update_theta()
+ {
+ d_theta += (d_step*rv_2());
+ if(d_theta > M_PI){
+ d_theta = M_PI; d_step = -d_step;
+ } else if(d_theta < -M_PI){
+ d_theta = -M_PI; d_step = -d_step;
+ }
+ }
+
+ int
+ fading_model_impl::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ const gr_complex* in = (const gr_complex*) input_items[0];
+ gr_complex* out = (gr_complex*) output_items[0];
+
+ for(int i=0; i<noutput_items; i++){
+ gr_complex H(0,0);
+
+ for(int n=1; n<d_N; n++){
+ float alpha_n = (2*M_PI*n - M_PI + d_theta)/4*d_N;
+#if FASTSINCOS == 1
+ float s_i = scale_sin*gr_fxpt::cos(gr_fxpt::float_to_fixed(2*M_PI*d_fDTs*d_m*gr_fxpt::cos(gr_fxpt::float_to_fixed(alpha_n))+d_psi[n+1]));
+ float s_q = scale_sin*gr_fxpt::cos(gr_fxpt::float_to_fixed(2*M_PI*d_fDTs*d_m*gr_fxpt::sin(gr_fxpt::float_to_fixed(alpha_n))+d_phi[n+1]));
+#elif FASTSINCOS == 2
+ float s_i = scale_sin*d_table.cos(2*M_PI*d_fDTs*d_m*d_table.cos(alpha_n)+d_psi[n+1]);
+ float s_q = scale_sin*d_table.cos(2*M_PI*d_fDTs*d_m*d_table.sin(alpha_n)+d_phi[n+1]);
+
+#else
+ float s_i = scale_sin*cos(2*M_PI*d_fDTs*d_m*cos(alpha_n)+d_psi[n+1]);
+ float s_q = scale_sin*cos(2*M_PI*d_fDTs*d_m*sin(alpha_n)+d_phi[n+1]);
+#endif
+
+ H += gr_complex(s_i, s_q);
+ }
+
+ if(d_LOS){
+#if FASTSINCOS == 1
+ float los_i = gr_fxpt::cos(gr_fxpt::float_to_fixed(2*M_PI*d_fDTs*d_m*gr_fxpt::cos(gr_fxpt::float_to_fixed(d_theta_los)) + d_psi[0]));
+ float los_q = gr_fxpt::sin(gr_fxpt::float_to_fixed(2*M_PI*d_fDTs*d_m*gr_fxpt::cos(gr_fxpt::float_to_fixed(d_theta_los)) + d_psi[0]));
+#elif FASTSINCOS == 2
+ float los_i = d_table.cos(2*M_PI*d_fDTs*d_m*d_table.cos(d_theta_los) + d_psi[0]);
+ float los_q = d_table.sin(2*M_PI*d_fDTs*d_m*d_table.cos(d_theta_los) + d_psi[0]);
+#else
+ float los_i = cos(2*M_PI*d_fDTs*d_m*cos(d_theta_los) + d_psi[0]);
+ float los_q = sin(2*M_PI*d_fDTs*d_m*cos(d_theta_los) + d_psi[0]);
+#endif
+
+ H = H*scale_nlos + gr_complex(los_i,los_q)*scale_los;
+ }
+
+ out[i] = in[i]*H;
+ d_m++;
+ update_theta();
+
+ }
+
+ return noutput_items;
+ }
+
+
+ } /* namespace channels */
+} /* namespace gr */
diff --git a/gr-channels/lib/fading_model_impl.h b/gr-channels/lib/fading_model_impl.h
new file mode 100644
index 0000000000..5c2d7f3877
--- /dev/null
+++ b/gr-channels/lib/fading_model_impl.h
@@ -0,0 +1,94 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2013 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_CHANNELS_CHANNEL_MODEL_IMPL_H
+#define INCLUDED_CHANNELS_CHANNEL_MODEL_IMPL_H
+
+#include <gr_sync_block.h>
+#include <channels/fading_model.h>
+
+//#include <iostream>
+#include <boost/format.hpp>
+#include <boost/random.hpp>
+
+#include <gr_fxpt.h>
+#include <sincostable.h>
+
+namespace gr {
+ namespace channels {
+
+ class CHANNELS_API fading_model_impl : public fading_model
+ {
+ private:
+ // initial theta variate generator
+ boost::mt19937 seed_1;
+ boost::uniform_real<> dist_1; // U(-pi,pi)
+ boost::variate_generator<boost::mt19937&, boost::uniform_real<> > rv_1;
+
+ // random walk variate
+ boost::mt19937 seed_2;
+ boost::uniform_real<> dist_2; // U(-pi,pi)
+ boost::variate_generator<boost::mt19937&, boost::uniform_real<> > rv_2;
+
+ int d_N; // number of sinusoids
+ float d_fDTs; // normalized maximum doppler frequency
+ double d_theta; // random walk variable (RWP)
+ float d_theta_los;
+ float d_step; // maximum random walk step size
+ uint64_t d_m; // sample counter
+
+ float d_K; // Rician factor (ratio of the specular power to the scattered power)
+ bool d_LOS; // LOS path exists? chooses Rician (LOS) vs Rayleigh (NLOS) model.
+
+ std::vector<float> d_psi; // in-phase initial phase
+ std::vector<float> d_phi; // quadrature initial phase
+
+ std::vector<float> d_costable;
+
+ sincostable d_table;
+
+ float scale_sin, scale_los, scale_nlos;
+
+ void update_theta();
+
+ public:
+ fading_model_impl(unsigned int N, float fDTs, bool LOS, float K, int seed);
+ ~fading_model_impl();
+ void setup_rpc();
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ virtual float fDTs(){ return d_fDTs; }
+ virtual float K(){ return d_K; }
+ virtual float step(){ return d_step; }
+
+ virtual void set_fDTs(float fDTs){ d_fDTs = fDTs; d_step = powf(0.00125*fDTs, 1.1); }
+ virtual void set_K(float K){ d_K = K; scale_los = sqrtf(d_K)/sqrtf(d_K+1); scale_nlos = (1/sqrtf(d_K+1)); }
+ virtual void set_step(float step){ d_step = step; }
+
+ };
+
+ } /* namespace channels */
+} /* namespace gr */
+
+#endif /* INCLUDED_CHANNELS_CHANNEL_MODEL_IMPL_H */
diff --git a/gr-channels/lib/sincostable.h b/gr-channels/lib/sincostable.h
new file mode 100644
index 0000000000..ca4bc4688b
--- /dev/null
+++ b/gr-channels/lib/sincostable.h
@@ -0,0 +1,30 @@
+#ifndef SINCOSTABLE_H
+#define SINCOSTABLE_H
+
+#include <math.h>
+
+class sincostable {
+ std::vector<float> d_cos;
+ size_t d_sz;
+ float d_scale;
+ public:
+ sincostable(size_t tbl_size) :
+ d_cos(tbl_size,1),
+ d_sz(tbl_size),
+ d_scale(tbl_size/(M_PI*2))
+ {
+ for(size_t i=0; i<tbl_size; i++){
+ d_cos[i] = ::cos(2*M_PI*i/tbl_size);
+ }
+ }
+ const float sin(float x){
+ int idx = (((int)(x*d_scale)) + d_sz - d_sz/4 )% d_sz;
+ return d_cos[idx];
+ }
+ const float cos(float x){
+ int idx = (((int)(x*d_scale)) + d_sz) % d_sz;
+ return d_cos[idx];
+ }
+};
+
+#endif
diff --git a/gr-channels/python/qa_fading_model.py b/gr-channels/python/qa_fading_model.py
new file mode 100644
index 0000000000..e8a066ccb5
--- /dev/null
+++ b/gr-channels/python/qa_fading_model.py
@@ -0,0 +1,62 @@
+#!/usr/bin/env python
+#
+# 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.
+#
+
+from gnuradio import gr, gr_unittest
+import analog_swig as analog
+import channels_swig as channels
+import math
+
+class test_fading_model(gr_unittest.TestCase):
+
+ def setUp(self):
+ self.tb = gr.top_block()
+
+ def tearDown(self):
+ self.tb = None
+
+ def test_000(self):
+ N = 1000 # number of samples to use
+ fs = 1000 # baseband sampling rate
+ freq = 100
+
+ fDTs = 0.01
+ K = 4
+ signal = analog.sig_source_c(fs, analog.GR_SIN_WAVE, freq, 1)
+ head = gr.head(gr.sizeof_gr_complex, N)
+ op = channels.fading_model(8, fDTs=fDTs, LOS=True,
+ K=K, seed=0)
+ snk = gr.vector_sink_c()
+ snk1 = gr.vector_sink_c()
+
+ self.assertAlmostEqual(K, op.K(), 4)
+ self.assertAlmostEqual(fDTs, op.fDTs(), 4)
+
+ #self.tb.connect(signal, head, op, snk)
+ #self.tb.connect(op, snk1)
+ #self.tb.run()
+
+ #dst_data = snk.data()
+ #exp_data = snk1.data()
+ #self.assertComplexTuplesAlmostEqual(exp_data, dst_data, 5)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_fading_model, "test_fading_model.xml")
diff --git a/gr-channels/swig/channels_swig.i b/gr-channels/swig/channels_swig.i
index 364f8d0fbd..fb284a74bd 100644
--- a/gr-channels/swig/channels_swig.i
+++ b/gr-channels/swig/channels_swig.i
@@ -29,8 +29,11 @@
%{
#include "channels/channel_model.h"
+#include "channels/fading_model.h"
%}
%include "channels/channel_model.h"
+%include "channels/fading_model.h"
GR_SWIG_BLOCK_MAGIC2(channels, channel_model);
+GR_SWIG_BLOCK_MAGIC2(channels, fading_model);
diff --git a/gr-filter/lib/pfb_synthesizer_ccf_impl.cc b/gr-filter/lib/pfb_synthesizer_ccf_impl.cc
index 9dd519d57c..f89b48b125 100644
--- a/gr-filter/lib/pfb_synthesizer_ccf_impl.cc
+++ b/gr-filter/lib/pfb_synthesizer_ccf_impl.cc
@@ -47,8 +47,8 @@ namespace gr {
: gr_sync_interpolator("pfb_synthesizer_ccf",
gr_make_io_signature(1, numchans, sizeof(gr_complex)),
gr_make_io_signature(1, 1, sizeof(gr_complex)),
- numchans),
- d_updated (false), d_numchans(numchans), d_state(0)
+ (twox ? numchans/2 : numchans)),
+ d_updated(false), d_numchans(numchans), d_state(0)
{
// set up 2x multiplier; if twox==True, set to 2, otherwise to 1
d_twox = (twox ? 2 : 1);
@@ -56,12 +56,12 @@ namespace gr {
throw std::invalid_argument("pfb_synthesizer_ccf: number of channels must be even for 2x oversampling.\n");
}
- d_filters = std::vector<kernel::fir_filter_with_buffer_ccf*>(d_twox*d_numchans);
- d_channel_map.resize(d_twox*d_numchans);
+ d_filters = std::vector<kernel::fir_filter_with_buffer_ccf*>(d_numchans);
+ d_channel_map.resize(d_numchans);
// Create a FIR filter for each channel and zero out the taps
- std::vector<float> vtaps(0, d_twox*d_numchans);
- for(unsigned int i = 0; i < d_twox*d_numchans; i++) {
+ std::vector<float> vtaps(0, d_numchans);
+ for(unsigned int i = 0; i < d_numchans; i++) {
d_filters[i] = new kernel::fir_filter_with_buffer_ccf(vtaps);
d_channel_map[i] = i;
}
@@ -70,15 +70,15 @@ namespace gr {
set_taps(taps);
// Create the IFFT to handle the input channel rotations
- d_fft = new fft::fft_complex(d_twox*d_numchans, false);
- memset(d_fft->get_inbuf(), 0, d_twox*d_numchans*sizeof(gr_complex));
+ d_fft = new fft::fft_complex(d_numchans, false);
+ memset(d_fft->get_inbuf(), 0, d_numchans*sizeof(gr_complex));
set_output_multiple(d_numchans);
}
pfb_synthesizer_ccf_impl::~pfb_synthesizer_ccf_impl()
{
- for(unsigned int i = 0; i < d_twox*d_numchans; i++) {
+ for(unsigned int i = 0; i < d_numchans; i++) {
delete d_filters[i];
}
}
@@ -137,11 +137,11 @@ namespace gr {
unsigned int i,j;
int state = 0;
- unsigned int ntaps = taps.size();
+ unsigned int ntaps = 2*taps.size();
d_taps_per_filter = (unsigned int)ceil((double)ntaps/(double)d_numchans);
// Create d_numchan vectors to store each channel's taps
- d_taps.resize(d_twox*d_numchans);
+ d_taps.resize(d_numchans);
// Make a vector of the taps plus fill it out with 0's to fill
// each polyphase filter with exactly d_taps_per_filter
@@ -152,29 +152,30 @@ namespace gr {
}
// Partition the filter
- for(i = 0; i < d_numchans; i++) {
+ unsigned int halfchans = d_numchans/2;
+ for(i = 0; i < halfchans; i++) {
// Each channel uses all d_taps_per_filter with 0's if not enough taps to fill out
d_taps[i] = std::vector<float>(d_taps_per_filter, 0);
- d_taps[d_numchans+i] = std::vector<float>(d_taps_per_filter, 0);
+ d_taps[halfchans+i] = std::vector<float>(d_taps_per_filter, 0);
state = 0;
for(j = 0; j < d_taps_per_filter; j++) {
// add taps to channels in reverse order
// Zero out every other tap
if(state == 0) {
- d_taps[i][j] = tmp_taps[i + j*d_numchans];
- d_taps[d_numchans + i][j] = 0;
+ d_taps[i][j] = tmp_taps[i + j*halfchans];
+ d_taps[halfchans + i][j] = 0;
state = 1;
}
else {
d_taps[i][j] = 0;
- d_taps[d_numchans + i][j] = tmp_taps[i + j*d_numchans];
+ d_taps[halfchans + i][j] = tmp_taps[i + j*halfchans];
state = 0;
}
}
// Build a filter for each channel and add it's taps to it
d_filters[i]->set_taps(d_taps[i]);
- d_filters[d_numchans + i]->set_taps(d_taps[d_numchans + i]);
+ d_filters[halfchans + i]->set_taps(d_taps[halfchans + i]);
}
}
@@ -182,7 +183,7 @@ namespace gr {
pfb_synthesizer_ccf_impl::print_taps()
{
unsigned int i, j;
- for(i = 0; i < d_twox*d_numchans; i++) {
+ for(i = 0; i < d_numchans; i++) {
printf("filter[%d]: [", i);
for(j = 0; j < d_taps_per_filter; j++) {
printf(" %.4e", d_taps[i][j]);
@@ -204,13 +205,13 @@ namespace gr {
if(map.size() > 0) {
unsigned int max = (unsigned int)*std::max_element(map.begin(), map.end());
- if(max >= d_twox*d_numchans) {
+ if(max >= d_numchans) {
throw std::invalid_argument("gr_pfb_synthesizer_ccf::set_channel_map: map range out of bounds.\n");
}
d_channel_map = map;
// Zero out fft buffer so that unused channels are always 0
- memset(d_fft->get_inbuf(), 0,d_twox*d_numchans*sizeof(gr_complex));
+ memset(d_fft->get_inbuf(), 0, d_numchans*sizeof(gr_complex));
}
}
@@ -258,7 +259,8 @@ namespace gr {
// Algorithm for oversampling by 2x
else {
- for(n = 0; n < noutput_items/d_numchans; n++) {
+ unsigned int halfchans = d_numchans/2;
+ for(n = 0; n < noutput_items/halfchans; n++) {
for(i = 0; i < ninputs; i++) {
in = (gr_complex*)input_items[i];
d_fft->get_inbuf()[d_channel_map[i]] = in[n];
@@ -270,13 +272,13 @@ namespace gr {
// Output is sum of two filters, but the input buffer to the filters must be circularly
// shifted by numchans every time through, done by using d_state to determine which IFFT
// buffer position to pull from.
- for(i = 0; i < d_numchans; i++) {
- out[i] = d_filters[i]->filter(d_fft->get_outbuf()[d_state*d_numchans+i]);
- out[i] += d_filters[d_numchans+i]->filter(d_fft->get_outbuf()[(d_state^1)*d_numchans+i]);
+ for(i = 0; i < halfchans; i++) {
+ out[i] = d_filters[i]->filter(d_fft->get_outbuf()[d_state*halfchans+i]);
+ out[i] += d_filters[halfchans+i]->filter(d_fft->get_outbuf()[(d_state^1)*halfchans+i]);
}
d_state ^= 1;
- out += d_numchans;
+ out += halfchans;
}
}
diff --git a/gr-qtgui/grc/qtgui_const_sink_x.xml b/gr-qtgui/grc/qtgui_const_sink_x.xml
index 31b13fe136..c751c89437 100644
--- a/gr-qtgui/grc/qtgui_const_sink_x.xml
+++ b/gr-qtgui/grc/qtgui_const_sink_x.xml
@@ -16,12 +16,13 @@ qtgui.$(type.fcn)(
$name, \#name
$nconnections \#number of inputs
)
+self.$(id).set_update_time($update_time)
self.$(id).set_y_axis($ymin, $ymax)
self.$(id).set_x_axis($xmin, $xmax)
self._$(id)_win = sip.wrapinstance(self.$(id).pyqwidget(), Qt.QWidget)
$(gui_hint()($win))</make>
<callback>set_resize($width, $height)</callback>
- <callback>set_update_time($t)</callback>
+ <callback>set_update_time($update_time)</callback>
<callback>set_title($which, $title)</callback>
<callback>set_color($which, $color)</callback>
<param>
@@ -80,6 +81,13 @@ $(gui_hint()($win))</make>
<hide>part</hide>
</param>
<param>
+ <name>Update Period</name>
+ <key>update_time</key>
+ <value>0.10</value>
+ <type>real</type>
+ <hide>part</hide>
+ </param>
+ <param>
<name>GUI Hint</name>
<key>gui_hint</key>
<value></value>
diff --git a/gr-qtgui/grc/qtgui_freq_sink_x.xml b/gr-qtgui/grc/qtgui_freq_sink_x.xml
index 0844a7cbc9..ce229b03de 100644
--- a/gr-qtgui/grc/qtgui_freq_sink_x.xml
+++ b/gr-qtgui/grc/qtgui_freq_sink_x.xml
@@ -20,11 +20,12 @@ qtgui.$(type.fcn)(
$name, \#name
$nconnections \#number of inputs
)
+self.$(id).set_update_time($update_time)
self.$(id).set_y_axis($ymin, $ymax)
self._$(id)_win = sip.wrapinstance(self.$(id).pyqwidget(), Qt.QWidget)
$(gui_hint()($win))</make>
<callback>set_frequency_range($fc, $bw)</callback>
- <callback>set_update_time($t)</callback>
+ <callback>set_update_time($update_time)</callback>
<callback>set_title($which, $title)</callback>
<callback>set_color($which, $color)</callback>
<param>
@@ -91,12 +92,6 @@ $(gui_hint()($win))</make>
<type>real</type>
</param>
<param>
- <name>Update Rate</name>
- <key>rate</key>
- <value>10</value>
- <type>real</type>
- </param>
- <param>
<name>Y min</name>
<key>ymin</key>
<value>-140</value>
@@ -118,6 +113,13 @@ $(gui_hint()($win))</make>
<hide>part</hide>
</param>
<param>
+ <name>Update Period</name>
+ <key>update_time</key>
+ <value>0.10</value>
+ <type>real</type>
+ <hide>part</hide>
+ </param>
+ <param>
<name>GUI Hint</name>
<key>gui_hint</key>
<value></value>
diff --git a/gr-qtgui/grc/qtgui_time_raster_x.xml b/gr-qtgui/grc/qtgui_time_raster_x.xml
index e50810f29a..7d880ab084 100644
--- a/gr-qtgui/grc/qtgui_time_raster_x.xml
+++ b/gr-qtgui/grc/qtgui_time_raster_x.xml
@@ -20,13 +20,14 @@ qtgui.$(type.fcn)(
$name,
$nconnections,
)
+self.$(id).set_update_time($update_time)
self._$(id)_win = sip.wrapinstance(self.$(id).pyqwidget(), Qt.QWidget)
$(gui_hint()($win))</make>
<callback>set_num_rows($nrows)</callback>
<callback>set_num_cols($ncols)</callback>
<callback>set_multiplier($mult)</callback>
<callback>set_offset($offset)</callback>
- <callback>set_update_time($t)</callback>
+ <callback>set_update_time($update_time)</callback>
<callback>set_title($which, $title)</callback>
<callback>set_color($which, $color)</callback>
<param>
@@ -46,7 +47,7 @@ $(gui_hint()($win))</make>
<param>
<name>Sample Rate</name>
<key>samp_rate</key>
- <value>1</value>
+ <value>samp_rate</value>
<type>real</type>
</param>
<param>
@@ -81,10 +82,11 @@ $(gui_hint()($win))</make>
<hide>part</hide>
</param>
<param>
- <name>Update Rate</name>
- <key>rate</key>
- <value>10</value>
+ <name>Update Period</name>
+ <key>update_time</key>
+ <value>0.10</value>
<type>real</type>
+ <hide>part</hide>
</param>
<param>
<name>GUI Hint</name>
diff --git a/gr-qtgui/grc/qtgui_time_sink_x.xml b/gr-qtgui/grc/qtgui_time_sink_x.xml
index 7b15aa840a..b02555b733 100644
--- a/gr-qtgui/grc/qtgui_time_sink_x.xml
+++ b/gr-qtgui/grc/qtgui_time_sink_x.xml
@@ -18,11 +18,12 @@ qtgui.$(type.fcn)(
$name, \#name
$nconnections \#number of inputs
)
+self.$(id).set_update_time($update_time)
self.$(id).set_y_axis($ymin, $ymax)
self._$(id)_win = sip.wrapinstance(self.$(id).pyqwidget(), Qt.QWidget)
$(gui_hint()($win))</make>
<callback>set_time_domain_axis($min, $max)</callback>
- <callback>set_update_time($t)</callback>
+ <callback>set_update_time($update_time)</callback>
<callback>set_title($which, $title)</callback>
<callback>set_color($which, $color)</callback>
<callback>set_y_axis($ymin, $ymax)</callback>
@@ -75,6 +76,13 @@ $(gui_hint()($win))</make>
<hide>part</hide>
</param>
<param>
+ <name>Update Period</name>
+ <key>update_time</key>
+ <value>0.10</value>
+ <type>real</type>
+ <hide>part</hide>
+ </param>
+ <param>
<name>GUI Hint</name>
<key>gui_hint</key>
<value></value>
diff --git a/gr-qtgui/grc/qtgui_waterfall_sink_x.xml b/gr-qtgui/grc/qtgui_waterfall_sink_x.xml
index 47de5b593c..d49b4db224 100644
--- a/gr-qtgui/grc/qtgui_waterfall_sink_x.xml
+++ b/gr-qtgui/grc/qtgui_waterfall_sink_x.xml
@@ -19,10 +19,11 @@ qtgui.$(type.fcn)(
$bw, \#bw
$name, \#name
)
+self.$(id).set_update_time($update_time)
self._$(id)_win = sip.wrapinstance(self.$(id).pyqwidget(), Qt.QWidget)
$(gui_hint()($win))</make>
<callback>set_frequency_range($fc, $bw)</callback>
- <callback>set_update_time($t)</callback>
+ <callback>set_update_time($update_time)</callback>
<callback>set_title($which, $title)</callback>
<callback>set_color($which, $color)</callback>
<param>
@@ -89,10 +90,11 @@ $(gui_hint()($win))</make>
<type>real</type>
</param>
<param>
- <name>Update Rate</name>
- <key>rate</key>
- <value>10</value>
+ <name>Update Period</name>
+ <key>update_time</key>
+ <value>0.10</value>
<type>real</type>
+ <hide>part</hide>
</param>
<param>
<name>GUI Hint</name>
diff --git a/gr-qtgui/include/qtgui/const_sink_c.h b/gr-qtgui/include/qtgui/const_sink_c.h
index 9a9783bed4..e0c358bcad 100644
--- a/gr-qtgui/include/qtgui/const_sink_c.h
+++ b/gr-qtgui/include/qtgui/const_sink_c.h
@@ -84,6 +84,7 @@ namespace gr {
virtual void set_size(int width, int height) = 0;
virtual void enable_menu(bool en=true) = 0;
+ virtual void enable_autoscale(bool en) = 0;
virtual int nsamps() const = 0;
virtual void reset() = 0;
diff --git a/gr-qtgui/include/qtgui/freq_sink_c.h b/gr-qtgui/include/qtgui/freq_sink_c.h
index 37a12440a0..79d3f2e8f0 100644
--- a/gr-qtgui/include/qtgui/freq_sink_c.h
+++ b/gr-qtgui/include/qtgui/freq_sink_c.h
@@ -100,6 +100,7 @@ namespace gr {
virtual void enable_menu(bool en=true) = 0;
virtual void enable_grid(bool en=true) = 0;
+ virtual void enable_autoscale(bool en=true) = 0;
virtual void reset() = 0;
QApplication *d_qApplication;
diff --git a/gr-qtgui/include/qtgui/freq_sink_f.h b/gr-qtgui/include/qtgui/freq_sink_f.h
index 4682f73c10..131801f531 100644
--- a/gr-qtgui/include/qtgui/freq_sink_f.h
+++ b/gr-qtgui/include/qtgui/freq_sink_f.h
@@ -99,6 +99,7 @@ namespace gr {
virtual void enable_menu(bool en=true) = 0;
virtual void enable_grid(bool en=true) = 0;
+ virtual void enable_autoscale(bool en=true) = 0;
virtual void reset() = 0;
QApplication *d_qApplication;
diff --git a/gr-qtgui/include/qtgui/time_raster_sink_b.h b/gr-qtgui/include/qtgui/time_raster_sink_b.h
index 51de65c9cf..1b65646b81 100644
--- a/gr-qtgui/include/qtgui/time_raster_sink_b.h
+++ b/gr-qtgui/include/qtgui/time_raster_sink_b.h
@@ -86,11 +86,16 @@ namespace gr {
virtual void set_num_rows(double rows) = 0;
virtual void set_num_cols(double cols) = 0;
+ virtual double num_rows() = 0;
+ virtual double num_cols() = 0;
+
virtual void set_multiplier(const std::vector<float> &mult) = 0;
virtual void set_offset(const std::vector<float> &offset) = 0;
virtual void set_intensity_range(float min, float max) = 0;
+ virtual void reset() = 0;
+
QApplication *d_qApplication;
};
diff --git a/gr-qtgui/include/qtgui/time_raster_sink_f.h b/gr-qtgui/include/qtgui/time_raster_sink_f.h
index 075b4239cc..1ae4d79bda 100644
--- a/gr-qtgui/include/qtgui/time_raster_sink_f.h
+++ b/gr-qtgui/include/qtgui/time_raster_sink_f.h
@@ -83,11 +83,16 @@ namespace gr {
virtual void set_num_rows(double rows) = 0;
virtual void set_num_cols(double cols) = 0;
+ virtual double num_rows() = 0;
+ virtual double num_cols() = 0;
+
virtual void set_multiplier(const std::vector<float> &mult) = 0;
virtual void set_offset(const std::vector<float> &offset) = 0;
virtual void set_intensity_range(float min, float max) = 0;
+ virtual void reset() = 0;
+
QApplication *d_qApplication;
};
diff --git a/gr-qtgui/include/qtgui/time_sink_c.h b/gr-qtgui/include/qtgui/time_sink_c.h
index ef72f7df58..c6a9a5f4f3 100644
--- a/gr-qtgui/include/qtgui/time_sink_c.h
+++ b/gr-qtgui/include/qtgui/time_sink_c.h
@@ -89,6 +89,7 @@ namespace gr {
virtual void enable_menu(bool en=true) = 0;
virtual void enable_grid(bool en=true) = 0;
+ virtual void enable_autoscale(bool en=true) = 0;
virtual void toggle_stem_plot() = 0;
virtual int nsamps() const = 0;
virtual void reset() = 0;
diff --git a/gr-qtgui/include/qtgui/time_sink_f.h b/gr-qtgui/include/qtgui/time_sink_f.h
index 6f689e7b60..c17d60c820 100644
--- a/gr-qtgui/include/qtgui/time_sink_f.h
+++ b/gr-qtgui/include/qtgui/time_sink_f.h
@@ -87,6 +87,7 @@ namespace gr {
virtual void enable_menu(bool en=true) = 0;
virtual void enable_grid(bool en=true) = 0;
+ virtual void enable_autoscale(bool en=true) = 0;
virtual void toggle_stem_plot() = 0;
virtual int nsamps() const = 0;
virtual void reset() = 0;
diff --git a/gr-qtgui/lib/FrequencyDisplayPlot.cc b/gr-qtgui/lib/FrequencyDisplayPlot.cc
index a04a9886d4..e279155544 100644
--- a/gr-qtgui/lib/FrequencyDisplayPlot.cc
+++ b/gr-qtgui/lib/FrequencyDisplayPlot.cc
@@ -393,7 +393,7 @@ FrequencyDisplayPlot::plotNewData(const double* dataPoints,
plotNewData(vecDataPoints, numDataPoints, noiseFloorAmplitude,
peakFrequency, peakAmplitude, timeInterval);
}
-
+
void
FrequencyDisplayPlot::clearMaxData()
{
diff --git a/gr-qtgui/lib/TimeRasterDisplayPlot.cc b/gr-qtgui/lib/TimeRasterDisplayPlot.cc
index 84ec31f6ef..537a7e4ef7 100644
--- a/gr-qtgui/lib/TimeRasterDisplayPlot.cc
+++ b/gr-qtgui/lib/TimeRasterDisplayPlot.cc
@@ -93,15 +93,41 @@ private:
double _rows;
};
+class TimePrecisionClass
+{
+public:
+ TimePrecisionClass(const int timePrecision)
+ {
+ _timePrecision = timePrecision;
+ }
+
+ virtual ~TimePrecisionClass()
+ {
+ }
+
+ virtual unsigned int getTimePrecision() const
+ {
+ return _timePrecision;
+ }
+
+ virtual void setTimePrecision(const unsigned int newPrecision)
+ {
+ _timePrecision = newPrecision;
+ }
+protected:
+ unsigned int _timePrecision;
+};
/***********************************************************************
* Widget to provide mouse pointer coordinate text
**********************************************************************/
-class TimeRasterZoomer: public QwtPlotZoomer, public TimeScaleData
+class TimeRasterZoomer: public QwtPlotZoomer, public TimePrecisionClass,
+ public TimeScaleData
{
public:
- TimeRasterZoomer(QwtPlotCanvas* canvas, double rows, double cols)
- : QwtPlotZoomer(canvas), TimeScaleData(),
+ TimeRasterZoomer(QwtPlotCanvas* canvas, double rows, double cols,
+ const unsigned int timePrecision)
+ : QwtPlotZoomer(canvas), TimePrecisionClass(timePrecision), TimeScaleData(),
d_rows(static_cast<double>(rows)), d_cols(static_cast<double>(cols))
{
setTrackerMode(QwtPicker::AlwaysOn);
@@ -139,8 +165,9 @@ protected:
double x = dp.x() * getSecondsPerLine();
//double y = dp.y() * getSecondsPerLine() * d_cols;
double y = floor(d_rows - dp.y());
- QwtText t(QString("%1 s, %2")
- .arg(x, 0, 'f', 2)
+ QwtText t(QString("%1 %2, %3")
+ .arg(x, 0, 'f', getTimePrecision())
+ .arg(_unitType.c_str())
.arg(y, 0, 'f', 0));
return t;
}
@@ -171,13 +198,6 @@ TimeRasterDisplayPlot::TimeRasterDisplayPlot(int nplots,
setAxisScaleDraw(QwtPlot::xBottom, new QwtXScaleDraw());
setAxisScaleDraw(QwtPlot::yLeft, new QwtYScaleDraw());
- double sec_per_samp = 1.0/d_samp_rate;
- QwtYScaleDraw* yScale = (QwtYScaleDraw*)axisScaleDraw(QwtPlot::yLeft);
- yScale->setRows(d_rows);
-
- QwtXScaleDraw* xScale = (QwtXScaleDraw*)axisScaleDraw(QwtPlot::xBottom);
- xScale->setSecondsPerLine(sec_per_samp);
-
for(int i = 0; i < _nplots; i++) {
d_data.push_back(new TimeRasterData(d_rows, d_cols));
d_raster.push_back(new PlotTimeRaster("Raster"));
@@ -200,7 +220,7 @@ TimeRasterDisplayPlot::TimeRasterDisplayPlot(int nplots,
// MidButton for the panning
// RightButton: zoom out by 1
// Ctrl+RighButton: zoom out to full size
- _zoomer = new TimeRasterZoomer(canvas(), d_rows, d_cols);
+ _zoomer = new TimeRasterZoomer(canvas(), d_rows, d_cols, 0);
#if QWT_VERSION < 0x060000
_zoomer->setSelectionFlags(QwtPicker::RectSelection | QwtPicker::DragSelection);
#endif
@@ -238,22 +258,32 @@ TimeRasterDisplayPlot::reset()
d_data[i]->reset();
}
- setAxisScale(QwtPlot::xBottom, 0, d_rows);
- setAxisScale(QwtPlot::yLeft, 0, d_cols);
+ // Update zoomer/picker text units
+ std::string strunits[4] = {"sec", "ms", "us", "ns"};
+ double units10 = floor(log10(d_samp_rate));
+ double units3 = std::max(floor(units10/3), 0.0);
+ double units = pow(10, (units10-fmod(units10, 3.0)));
+ int iunit = static_cast<int>(units3);
+
+ double sec_per_samp = units/d_samp_rate;
- double sec_per_samp = 1.0/d_samp_rate;
QwtYScaleDraw* yScale = (QwtYScaleDraw*)axisScaleDraw(QwtPlot::yLeft);
yScale->setRows(d_rows);
QwtXScaleDraw* xScale = (QwtXScaleDraw*)axisScaleDraw(QwtPlot::xBottom);
xScale->setSecondsPerLine(sec_per_samp);
+ setAxisTitle(QwtPlot::xBottom, QString("Time (%1)")
+ .arg(strunits[iunit].c_str()));
+ xScale->initiateUpdate();
// Load up the new base zoom settings
if(_zoomer) {
+ double display_units = 4;
((TimeRasterZoomer*)_zoomer)->setColumns(d_cols);
((TimeRasterZoomer*)_zoomer)->setRows(d_rows);
((TimeRasterZoomer*)_zoomer)->setSecondsPerLine(sec_per_samp);
- //((TimeRasterZoomer*)_zoomer)-sSetUnitType(strunits);
+ ((TimeRasterZoomer*)_zoomer)->setTimePrecision(display_units);
+ ((TimeRasterZoomer*)_zoomer)->setUnitType(strunits[iunit]);
QwtDoubleRect newSize = _zoomer->zoomBase();
newSize.setLeft(0);
@@ -287,6 +317,13 @@ TimeRasterDisplayPlot::setAlpha(int which, int alpha)
d_raster[which]->setAlpha(alpha);
}
+void
+TimeRasterDisplayPlot::setSampleRate(double samprate)
+{
+ d_samp_rate = samprate;
+ reset();
+}
+
double
TimeRasterDisplayPlot::numRows() const
{
diff --git a/gr-qtgui/lib/TimeRasterDisplayPlot.h b/gr-qtgui/lib/TimeRasterDisplayPlot.h
index 3e0ac1cfdb..fca9672b91 100644
--- a/gr-qtgui/lib/TimeRasterDisplayPlot.h
+++ b/gr-qtgui/lib/TimeRasterDisplayPlot.h
@@ -54,6 +54,7 @@ public:
void setNumRows(double rows);
void setNumCols(double cols);
void setAlpha(int which, int alpha);
+ void setSampleRate(double samprate);
double numRows() const;
double numCols() const;
diff --git a/gr-qtgui/lib/const_sink_c_impl.cc b/gr-qtgui/lib/const_sink_c_impl.cc
index 2490e9a618..9b01d1659e 100644
--- a/gr-qtgui/lib/const_sink_c_impl.cc
+++ b/gr-qtgui/lib/const_sink_c_impl.cc
@@ -104,7 +104,6 @@ namespace gr {
d_main_gui->setNPoints(d_size);
// initialize update time to 10 times a second
set_update_time(0.1);
- d_last_time = 0;
}
void
@@ -146,6 +145,7 @@ namespace gr {
gruel::high_res_timer_type tps = gruel::high_res_timer_tps();
d_update_time = t * tps;
d_main_gui->setUpdateTime(t);
+ d_last_time = 0;
}
void
@@ -284,6 +284,12 @@ namespace gr {
}
void
+ const_sink_c_impl::enable_autoscale(bool en)
+ {
+ d_main_gui->autoScale(en);
+ }
+
+ void
const_sink_c_impl::reset()
{
d_index = 0;
diff --git a/gr-qtgui/lib/const_sink_c_impl.h b/gr-qtgui/lib/const_sink_c_impl.h
index 3e90d00429..81cdb9881f 100644
--- a/gr-qtgui/lib/const_sink_c_impl.h
+++ b/gr-qtgui/lib/const_sink_c_impl.h
@@ -92,6 +92,7 @@ namespace gr {
int nsamps() const;
void enable_menu(bool en);
+ void enable_autoscale(bool en);
void reset();
int work(int noutput_items,
diff --git a/gr-qtgui/lib/constellationdisplayform.cc b/gr-qtgui/lib/constellationdisplayform.cc
index 361c5a71c9..9fa22cb306 100644
--- a/gr-qtgui/lib/constellationdisplayform.cc
+++ b/gr-qtgui/lib/constellationdisplayform.cc
@@ -122,3 +122,24 @@ ConstellationDisplayForm::autoScale()
getPlot()->setAutoScale(_autoscale_state);
getPlot()->replot();
}
+
+void
+ConstellationDisplayForm::autoScale(bool en)
+{
+ if(en) {
+ _autoscale_act->setText(tr("Auto Scale Off"));
+ _autoscale_state = true;
+ }
+ else {
+ _autoscale_act->setText(tr("Auto Scale On"));
+ _autoscale_state = false;
+ }
+
+ getPlot()->setAutoScale(_autoscale_state);
+ getPlot()->replot();
+}
+
+void
+ConstellationDisplayForm::setSampleRate(const QString &samprate)
+{
+}
diff --git a/gr-qtgui/lib/constellationdisplayform.h b/gr-qtgui/lib/constellationdisplayform.h
index d9779515a1..f9f8dab175 100644
--- a/gr-qtgui/lib/constellationdisplayform.h
+++ b/gr-qtgui/lib/constellationdisplayform.h
@@ -46,9 +46,11 @@ public slots:
void customEvent(QEvent * e);
void setNPoints(const int);
+ void setSampleRate(const QString &samprate);
void setYaxis(double min, double max);
void setXaxis(double min, double max);
void autoScale();
+ void autoScale(bool en);
private slots:
void newData(const QEvent*);
diff --git a/gr-qtgui/lib/displayform.cc b/gr-qtgui/lib/displayform.cc
index 444fa95858..e4a70c209a 100644
--- a/gr-qtgui/lib/displayform.cc
+++ b/gr-qtgui/lib/displayform.cc
@@ -98,6 +98,12 @@ DisplayForm::DisplayForm(int nplots, QWidget* parent)
_menu->addMenu(_lines_menu[i]);
}
+ _samp_rate_act = new PopupMenu("Sample Rate", this);
+ _samp_rate_act->setStatusTip(tr("Set Sample Rate"));
+ connect(_samp_rate_act, SIGNAL(whichTrigger(QString)),
+ this, SLOT(setSampleRate(QString)));
+ _menu->addAction(_samp_rate_act);
+
_autoscale_act = new QAction("Auto Scale On", this);
_autoscale_act->setStatusTip(tr("Autoscale Plot"));
connect(_autoscale_act, SIGNAL(triggered()), this, SLOT(autoScale()));
diff --git a/gr-qtgui/lib/displayform.h b/gr-qtgui/lib/displayform.h
index bd64407863..14f385796b 100644
--- a/gr-qtgui/lib/displayform.h
+++ b/gr-qtgui/lib/displayform.h
@@ -71,6 +71,8 @@ public slots:
QwtSymbol::Style lineMarker(int which);
int markerAlpha(int which);
+ virtual void setSampleRate(const QString &rate) = 0;
+
void setStop(bool on);
void setStop();
@@ -117,6 +119,7 @@ protected:
QList<LineMarkerMenu*> _line_marker_menu;
QList<MarkerAlphaMenu*> _marker_alpha_menu;
+ PopupMenu *_samp_rate_act;
QAction *_save_act;
QTimer *d_displayTimer;
diff --git a/gr-qtgui/lib/freq_sink_c_impl.cc b/gr-qtgui/lib/freq_sink_c_impl.cc
index 78d7431b20..3755df0552 100644
--- a/gr-qtgui/lib/freq_sink_c_impl.cc
+++ b/gr-qtgui/lib/freq_sink_c_impl.cc
@@ -128,7 +128,6 @@ namespace gr {
// initialize update time to 10 times a second
set_update_time(0.1);
- d_last_time = 0;
}
void
@@ -209,6 +208,7 @@ namespace gr {
gruel::high_res_timer_type tps = gruel::high_res_timer_tps();
d_update_time = t * tps;
d_main_gui->setUpdateTime(t);
+ d_last_time = 0;
}
void
@@ -314,6 +314,12 @@ namespace gr {
}
void
+ freq_sink_c_impl::enable_autoscale(bool en)
+ {
+ d_main_gui->autoScale(en);
+ }
+
+ void
freq_sink_c_impl::reset()
{
d_index = 0;
diff --git a/gr-qtgui/lib/freq_sink_c_impl.h b/gr-qtgui/lib/freq_sink_c_impl.h
index 77a625eb13..0567b914c8 100644
--- a/gr-qtgui/lib/freq_sink_c_impl.h
+++ b/gr-qtgui/lib/freq_sink_c_impl.h
@@ -116,6 +116,7 @@ namespace gr {
void enable_menu(bool en);
void enable_grid(bool en);
+ void enable_autoscale(bool en);
void reset();
int work(int noutput_items,
diff --git a/gr-qtgui/lib/freq_sink_f_impl.cc b/gr-qtgui/lib/freq_sink_f_impl.cc
index 457235df6f..807be83948 100644
--- a/gr-qtgui/lib/freq_sink_f_impl.cc
+++ b/gr-qtgui/lib/freq_sink_f_impl.cc
@@ -128,7 +128,6 @@ namespace gr {
// initialize update time to 10 times a second
set_update_time(0.1);
- d_last_time = 0;
}
void
@@ -209,6 +208,7 @@ namespace gr {
gruel::high_res_timer_type tps = gruel::high_res_timer_tps();
d_update_time = t * tps;
d_main_gui->setUpdateTime(t);
+ d_last_time = 0;
}
void
@@ -314,6 +314,12 @@ namespace gr {
}
void
+ freq_sink_f_impl::enable_autoscale(bool en)
+ {
+ d_main_gui->autoScale(en);
+ }
+
+ void
freq_sink_f_impl::reset()
{
d_index = 0;
diff --git a/gr-qtgui/lib/freq_sink_f_impl.h b/gr-qtgui/lib/freq_sink_f_impl.h
index d0a6b2c14b..b79127f3dd 100644
--- a/gr-qtgui/lib/freq_sink_f_impl.h
+++ b/gr-qtgui/lib/freq_sink_f_impl.h
@@ -115,6 +115,7 @@ namespace gr {
void enable_menu(bool en);
void enable_grid(bool en);
+ void enable_autoscale(bool en);
void reset();
int work(int noutput_items,
diff --git a/gr-qtgui/lib/freqdisplayform.cc b/gr-qtgui/lib/freqdisplayform.cc
index 50c5a9d258..9015b79618 100644
--- a/gr-qtgui/lib/freqdisplayform.cc
+++ b/gr-qtgui/lib/freqdisplayform.cc
@@ -111,6 +111,12 @@ FreqDisplayForm::getFFTWindowType() const
}
void
+FreqDisplayForm::setSampleRate(const QString &samprate)
+{
+ setFrequencyRange(_center_freq, samprate.toDouble());
+}
+
+void
FreqDisplayForm::setFFTSize(const int newsize)
{
_fftsize = newsize;
@@ -141,6 +147,9 @@ FreqDisplayForm::setFrequencyRange(const double centerfreq,
double units = pow(10, (units10-fmod(units10, 3.0)));
int iunit = static_cast<int>(units3);
+ _center_freq = centerfreq;
+ _samp_rate = bandwidth;
+
getPlot()->setFrequencyRange(centerfreq, bandwidth,
units, strunits[iunit]);
}
@@ -166,3 +175,19 @@ FreqDisplayForm::autoScale()
getPlot()->setAutoScale(_autoscale_state);
getPlot()->replot();
}
+
+void
+FreqDisplayForm::autoScale(bool en)
+{
+ if(en) {
+ _autoscale_act->setText(tr("Auto Scale Off"));
+ _autoscale_state = true;
+ }
+ else {
+ _autoscale_act->setText(tr("Auto Scale On"));
+ _autoscale_state = false;
+ }
+
+ getPlot()->setAutoScale(_autoscale_state);
+ getPlot()->replot();
+}
diff --git a/gr-qtgui/lib/freqdisplayform.h b/gr-qtgui/lib/freqdisplayform.h
index 93967a23c3..f635fb5f33 100644
--- a/gr-qtgui/lib/freqdisplayform.h
+++ b/gr-qtgui/lib/freqdisplayform.h
@@ -48,6 +48,7 @@ class FreqDisplayForm : public DisplayForm
public slots:
void customEvent(QEvent *e);
+ void setSampleRate(const QString &samprate);
void setFFTSize(const int);
void setFFTAverage(const float);
void setFFTWindowType(const gr::filter::firdes::win_type);
@@ -56,6 +57,7 @@ public slots:
const double bandwidth);
void setYaxis(double min, double max);
void autoScale();
+ void autoScale(bool en);
private slots:
void newData(const QEvent *updateEvent);
@@ -64,6 +66,7 @@ private:
uint64_t _numRealDataPoints;
QIntValidator* _intValidator;
+ double _samp_rate, _center_freq;
int _fftsize;
float _fftavg;
gr::filter::firdes::win_type _fftwintype;
diff --git a/gr-qtgui/lib/timeRasterGlobalData.cc b/gr-qtgui/lib/timeRasterGlobalData.cc
index 10ba7ececc..556196f644 100644
--- a/gr-qtgui/lib/timeRasterGlobalData.cc
+++ b/gr-qtgui/lib/timeRasterGlobalData.cc
@@ -65,7 +65,8 @@ TimeRasterData::~TimeRasterData()
void TimeRasterData::reset()
{
d_resid = 0;
- memset(d_data, 0x0, d_totalitems*sizeof(double));
+ d_nitems = 0;
+ memset(d_data, 0x0, d_data_size*sizeof(double));
}
void TimeRasterData::copy(const TimeRasterData* rhs)
@@ -93,7 +94,6 @@ void TimeRasterData::copy(const TimeRasterData* rhs)
#endif
reset();
- setDataBuffer(rhs->getDataBuffer());
#if QWT_VERSION < 0x060000
setRange(rhs->range());
@@ -231,22 +231,10 @@ TimeRasterData::addData(const double* data,
d_nitems += cols;
}
else {
- memmove(d_data, &d_data[cols], d_totalitems*sizeof(double));
memcpy(&d_data[d_nitems], data, cols*sizeof(double));
+ memmove(d_data, &d_data[cols], d_totalitems*sizeof(double));
}
}
}
-double*
-TimeRasterData::getDataBuffer() const
-{
- return d_data;
-}
-
-void
-TimeRasterData::setDataBuffer(const double* newData)
-{
- memcpy(d_data, newData, d_totalitems*sizeof(double));
-}
-
#endif /* TIMERASTER_GLOBAL_DATA_CPP */
diff --git a/gr-qtgui/lib/timeRasterGlobalData.h b/gr-qtgui/lib/timeRasterGlobalData.h
index 7b450c033b..0a414432d1 100644
--- a/gr-qtgui/lib/timeRasterGlobalData.h
+++ b/gr-qtgui/lib/timeRasterGlobalData.h
@@ -56,9 +56,6 @@ public:
virtual void addData(const double*, const int);
- virtual double* getDataBuffer()const;
- virtual void setDataBuffer(const double*);
-
void incrementResidual();
protected:
diff --git a/gr-qtgui/lib/time_raster_sink_b_impl.cc b/gr-qtgui/lib/time_raster_sink_b_impl.cc
index 46d60ba3f5..e79b2f1ff4 100644
--- a/gr-qtgui/lib/time_raster_sink_b_impl.cc
+++ b/gr-qtgui/lib/time_raster_sink_b_impl.cc
@@ -124,7 +124,6 @@ namespace gr {
// initialize update time to 10 times a second
set_update_time(0.1);
- d_last_time = 0;
}
void
@@ -154,6 +153,7 @@ namespace gr {
gruel::high_res_timer_type tps = gruel::high_res_timer_tps();
d_update_time = t * tps;
d_main_gui->setUpdateTime(t);
+ d_last_time = 0;
}
void
@@ -210,6 +210,18 @@ namespace gr {
d_main_gui->setNumCols(cols);
}
+ double
+ time_raster_sink_b_impl::num_rows()
+ {
+ return d_main_gui->numRows();
+ }
+
+ double
+ time_raster_sink_b_impl::num_cols()
+ {
+ return d_main_gui->numCols();
+ }
+
void
time_raster_sink_b_impl::set_multiplier(const std::vector<float> &mult)
{
@@ -252,6 +264,12 @@ namespace gr {
d_main_gui->setIntensityRange(min, max);
}
+ void
+ time_raster_sink_b_impl::reset()
+ {
+ d_index = 0;
+ }
+
int
time_raster_sink_b_impl::work(int noutput_items,
gr_vector_const_void_star &input_items,
@@ -298,8 +316,11 @@ namespace gr {
d_tmpflt, resid);
}
- d_qApplication->postEvent(d_main_gui,
- new TimeRasterUpdateEvent(d_residbufs, d_icols));
+ if(gruel::high_res_timer_now() - d_last_time > d_update_time) {
+ d_last_time = gruel::high_res_timer_now();
+ d_qApplication->postEvent(d_main_gui,
+ new TimeRasterUpdateEvent(d_residbufs, d_icols));
+ }
d_index = 0;
j += resid;
diff --git a/gr-qtgui/lib/time_raster_sink_b_impl.h b/gr-qtgui/lib/time_raster_sink_b_impl.h
index 248eb8dd67..1997bacd93 100644
--- a/gr-qtgui/lib/time_raster_sink_b_impl.h
+++ b/gr-qtgui/lib/time_raster_sink_b_impl.h
@@ -88,11 +88,16 @@ namespace gr {
void set_num_rows(double rows);
void set_num_cols(double cols);
+ double num_rows();
+ double num_cols();
+
void set_multiplier(const std::vector<float> &mult);
void set_offset(const std::vector<float> &offset);
void set_intensity_range(float min, float max);
+ void reset();
+
int work(int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items);
diff --git a/gr-qtgui/lib/time_raster_sink_f_impl.cc b/gr-qtgui/lib/time_raster_sink_f_impl.cc
index be1e66da12..61d1436529 100644
--- a/gr-qtgui/lib/time_raster_sink_f_impl.cc
+++ b/gr-qtgui/lib/time_raster_sink_f_impl.cc
@@ -122,7 +122,6 @@ namespace gr {
// initialize update time to 10 times a second
set_update_time(0.1);
- d_last_time = 0;
}
void
@@ -152,6 +151,7 @@ namespace gr {
gruel::high_res_timer_type tps = gruel::high_res_timer_tps();
d_update_time = t * tps;
d_main_gui->setUpdateTime(t);
+ d_last_time = 0;
}
void
@@ -208,6 +208,18 @@ namespace gr {
d_main_gui->setNumCols(cols);
}
+ double
+ time_raster_sink_f_impl::num_rows()
+ {
+ return d_main_gui->numRows();
+ }
+
+ double
+ time_raster_sink_f_impl::num_cols()
+ {
+ return d_main_gui->numCols();
+ }
+
void
time_raster_sink_f_impl::set_multiplier(const std::vector<float> &mult)
{
@@ -250,6 +262,12 @@ namespace gr {
d_main_gui->setIntensityRange(min, max);
}
+ void
+ time_raster_sink_f_impl::reset()
+ {
+ d_index = 0;
+ }
+
int
time_raster_sink_f_impl::work(int noutput_items,
gr_vector_const_void_star &input_items,
@@ -258,7 +276,7 @@ namespace gr {
int n=0, j=0, idx=0;
const float *in = (const float*)input_items[0];
- unsigned int cols = d_main_gui->numCols();
+ double cols = d_main_gui->numCols();
if(d_cols != cols) {
d_cols = cols;
d_index = 0;
@@ -294,8 +312,12 @@ namespace gr {
d_tmpflt, resid);
}
- d_qApplication->postEvent(d_main_gui,
- new TimeRasterUpdateEvent(d_residbufs, d_cols));
+ // Update the plot if its time
+ if(gruel::high_res_timer_now() - d_last_time > d_update_time) {
+ d_last_time = gruel::high_res_timer_now();
+ d_qApplication->postEvent(d_main_gui,
+ new TimeRasterUpdateEvent(d_residbufs, d_cols));
+ }
d_index = 0;
j += resid;
diff --git a/gr-qtgui/lib/time_raster_sink_f_impl.h b/gr-qtgui/lib/time_raster_sink_f_impl.h
index c14a5c1147..9c00ac89ba 100644
--- a/gr-qtgui/lib/time_raster_sink_f_impl.h
+++ b/gr-qtgui/lib/time_raster_sink_f_impl.h
@@ -87,11 +87,16 @@ namespace gr {
void set_num_rows(double rows);
void set_num_cols(double cols);
+ double num_rows();
+ double num_cols();
+
void set_multiplier(const std::vector<float> &mult);
void set_offset(const std::vector<float> &offset);
void set_intensity_range(float min, float max);
+ void reset();
+
int work(int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items);
diff --git a/gr-qtgui/lib/time_sink_c_impl.cc b/gr-qtgui/lib/time_sink_c_impl.cc
index 46db6315eb..c6fe4ae168 100644
--- a/gr-qtgui/lib/time_sink_c_impl.cc
+++ b/gr-qtgui/lib/time_sink_c_impl.cc
@@ -103,7 +103,6 @@ namespace gr {
// initialize update time to 10 times a second
set_update_time(0.1);
- d_last_time = 0;
}
void
@@ -139,6 +138,7 @@ namespace gr {
gruel::high_res_timer_type tps = gruel::high_res_timer_tps();
d_update_time = t * tps;
d_main_gui->setUpdateTime(t);
+ d_last_time = 0;
}
void
@@ -288,6 +288,12 @@ namespace gr {
}
void
+ time_sink_c_impl::enable_autoscale(bool en)
+ {
+ d_main_gui->autoScale(en);
+ }
+
+ void
time_sink_c_impl::toggle_stem_plot()
{
d_main_gui->setStem();
diff --git a/gr-qtgui/lib/time_sink_c_impl.h b/gr-qtgui/lib/time_sink_c_impl.h
index bccb7b1197..6e35844c59 100644
--- a/gr-qtgui/lib/time_sink_c_impl.h
+++ b/gr-qtgui/lib/time_sink_c_impl.h
@@ -93,6 +93,7 @@ namespace gr {
void enable_menu(bool en);
void enable_grid(bool en);
+ void enable_autoscale(bool en);
void toggle_stem_plot();
void reset();
diff --git a/gr-qtgui/lib/time_sink_f_impl.cc b/gr-qtgui/lib/time_sink_f_impl.cc
index 06854c71e7..329af89dde 100644
--- a/gr-qtgui/lib/time_sink_f_impl.cc
+++ b/gr-qtgui/lib/time_sink_f_impl.cc
@@ -103,7 +103,6 @@ namespace gr {
// initialize update time to 10 times a second
set_update_time(0.1);
- d_last_time = 0;
}
void
@@ -139,6 +138,7 @@ namespace gr {
gruel::high_res_timer_type tps = gruel::high_res_timer_tps();
d_update_time = t * tps;
d_main_gui->setUpdateTime(t);
+ d_last_time = 0;
}
void
@@ -294,6 +294,12 @@ namespace gr {
}
void
+ time_sink_f_impl::enable_autoscale(bool en)
+ {
+ d_main_gui->autoScale(en);
+ }
+
+ void
time_sink_f_impl::reset()
{
d_index = 0;
diff --git a/gr-qtgui/lib/time_sink_f_impl.h b/gr-qtgui/lib/time_sink_f_impl.h
index b6aafb19b7..f15841429b 100644
--- a/gr-qtgui/lib/time_sink_f_impl.h
+++ b/gr-qtgui/lib/time_sink_f_impl.h
@@ -93,6 +93,7 @@ namespace gr {
void enable_menu(bool en);
void enable_grid(bool en);
+ void enable_autoscale(bool en);
void toggle_stem_plot();
void reset();
diff --git a/gr-qtgui/lib/timedisplayform.cc b/gr-qtgui/lib/timedisplayform.cc
index 7bc30aee7a..8fe149a61a 100644
--- a/gr-qtgui/lib/timedisplayform.cc
+++ b/gr-qtgui/lib/timedisplayform.cc
@@ -89,6 +89,12 @@ TimeDisplayForm::customEvent(QEvent * e)
}
void
+TimeDisplayForm::setSampleRate(const QString &samprate)
+{
+ setSampleRate(samprate.toDouble());
+}
+
+void
TimeDisplayForm::setSampleRate(const double samprate)
{
if(samprate > 0) {
@@ -145,3 +151,19 @@ TimeDisplayForm::autoScale()
getPlot()->setAutoScale(_autoscale_state);
getPlot()->replot();
}
+
+void
+TimeDisplayForm::autoScale(bool en)
+{
+ if(en) {
+ _autoscale_act->setText(tr("Auto Scale Off"));
+ _autoscale_state = true;
+ }
+ else {
+ _autoscale_act->setText(tr("Auto Scale On"));
+ _autoscale_state = false;
+ }
+
+ getPlot()->setAutoScale(_autoscale_state);
+ getPlot()->replot();
+}
diff --git a/gr-qtgui/lib/timedisplayform.h b/gr-qtgui/lib/timedisplayform.h
index 5734d3b1e5..8c5682cde2 100644
--- a/gr-qtgui/lib/timedisplayform.h
+++ b/gr-qtgui/lib/timedisplayform.h
@@ -46,10 +46,12 @@ public slots:
void customEvent(QEvent * e);
void setSampleRate(const double samprate);
+ void setSampleRate(const QString &samprate);
void setYaxis(double min, double max);
void setNPoints(const int);
void setStem(bool trig=false);
void autoScale();
+ void autoScale(bool en);
private slots:
void newData(const QEvent*);
diff --git a/gr-qtgui/lib/timerasterdisplayform.cc b/gr-qtgui/lib/timerasterdisplayform.cc
index 1fbad090ca..2f9c8aaf0f 100644
--- a/gr-qtgui/lib/timerasterdisplayform.cc
+++ b/gr-qtgui/lib/timerasterdisplayform.cc
@@ -72,10 +72,7 @@ TimeRasterDisplayForm::TimeRasterDisplayForm(int nplots,
_lines_menu[i]->addMenu(_marker_alpha_menu[i]);
}
- QAction *autoscale_act = new QAction("Auto Scale", this);
- autoscale_act->setStatusTip(tr("Autoscale intensity range"));
- connect(autoscale_act, SIGNAL(triggered()), this, SLOT(autoScale()));
- _menu->addAction(autoscale_act);
+ _autoscale_act->setText(tr("Auto Scale"));
PopupMenu *colsmenu = new PopupMenu("Num. Columns", this);
_menu->addAction(colsmenu);
@@ -173,6 +170,12 @@ TimeRasterDisplayForm::setNumCols(QString cols)
}
void
+TimeRasterDisplayForm::setSampleRate(const QString &rate)
+{
+ getPlot()->setSampleRate(rate.toDouble());
+}
+
+void
TimeRasterDisplayForm::setColorMap(int which,
const int newType,
const QColor lowColor,
diff --git a/gr-qtgui/lib/timerasterdisplayform.h b/gr-qtgui/lib/timerasterdisplayform.h
index e136f5faf8..e28183ffcb 100644
--- a/gr-qtgui/lib/timerasterdisplayform.h
+++ b/gr-qtgui/lib/timerasterdisplayform.h
@@ -58,6 +58,8 @@ public slots:
void setNumRows(QString rows);
void setNumCols(QString cols);
+ void setSampleRate(const QString &rate);
+
void setIntensityRange(const double minIntensity,
const double maxIntensity);
diff --git a/gr-qtgui/lib/waterfall_sink_c_impl.cc b/gr-qtgui/lib/waterfall_sink_c_impl.cc
index e182d3c141..617d6b5442 100644
--- a/gr-qtgui/lib/waterfall_sink_c_impl.cc
+++ b/gr-qtgui/lib/waterfall_sink_c_impl.cc
@@ -127,7 +127,6 @@ namespace gr {
// initialize update time to 10 times a second
set_update_time(0.1);
- d_last_time = 0;
}
void
@@ -215,6 +214,7 @@ namespace gr {
gruel::high_res_timer_type tps = gruel::high_res_timer_tps();
d_update_time = t * tps;
d_main_gui->setUpdateTime(t);
+ d_last_time = 0;
}
void
diff --git a/gr-qtgui/lib/waterfall_sink_f_impl.cc b/gr-qtgui/lib/waterfall_sink_f_impl.cc
index d59319fd27..a17f73a248 100644
--- a/gr-qtgui/lib/waterfall_sink_f_impl.cc
+++ b/gr-qtgui/lib/waterfall_sink_f_impl.cc
@@ -126,7 +126,6 @@ namespace gr {
// initialize update time to 10 times a second
set_update_time(0.1);
- d_last_time = 0;
}
void
@@ -214,6 +213,7 @@ namespace gr {
gruel::high_res_timer_type tps = gruel::high_res_timer_tps();
d_update_time = t * tps;
d_main_gui->setUpdateTime(t);
+ d_last_time = 0;
}
void
diff --git a/gr-qtgui/lib/waterfalldisplayform.cc b/gr-qtgui/lib/waterfalldisplayform.cc
index d45af04248..d8160d0d85 100644
--- a/gr-qtgui/lib/waterfalldisplayform.cc
+++ b/gr-qtgui/lib/waterfalldisplayform.cc
@@ -37,6 +37,9 @@ WaterfallDisplayForm::WaterfallDisplayForm(int nplots, QWidget* parent)
_layout->addWidget(_displayPlot, 0, 0);
setLayout(_layout);
+ _center_freq = 0;
+ _samp_rate = 0;
+
_numRealDataPoints = 1024;
_fftsize = 1024;
_fftavg = 1.0;
@@ -178,6 +181,12 @@ WaterfallDisplayForm::getMaxIntensity(int which)
}
void
+WaterfallDisplayForm::setSampleRate(const QString &samprate)
+{
+ setFrequencyRange(_center_freq, samprate.toDouble());
+}
+
+void
WaterfallDisplayForm::setFFTSize(const int newsize)
{
_fftsize = newsize;
@@ -205,6 +214,7 @@ WaterfallDisplayForm::setFrequencyRange(const double centerfreq,
double units = pow(10, (units10-fmod(units10, 3.0)));
int iunit = static_cast<int>(units3);
+ _center_freq = centerfreq;
_samp_rate = bandwidth;
_time_per_slice = (1.0/bandwidth)*_fftsize;
diff --git a/gr-qtgui/lib/waterfalldisplayform.h b/gr-qtgui/lib/waterfalldisplayform.h
index a6add831fd..aba64bda57 100644
--- a/gr-qtgui/lib/waterfalldisplayform.h
+++ b/gr-qtgui/lib/waterfalldisplayform.h
@@ -55,6 +55,7 @@ class WaterfallDisplayForm : public DisplayForm
public slots:
void customEvent(QEvent *e);
+ void setSampleRate(const QString &samprate);
void setFFTSize(const int);
void setFFTAverage(const float);
void setFFTWindowType(const gr::filter::firdes::win_type);
@@ -81,7 +82,7 @@ private:
uint64_t _numRealDataPoints;
QIntValidator* _intValidator;
- double _samp_rate;
+ double _samp_rate, _center_freq;
double _time_per_slice;
int _fftsize;
float _fftavg;