summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rondeau <tom@trondeau.com>2013-11-07 12:28:01 -0500
committerTom Rondeau <tom@trondeau.com>2013-11-07 12:28:01 -0500
commitd800bc32c3d93364e0c34ff60f01f97b64ec30f4 (patch)
tree6c8529ea67c897da8bfe4edb7deba1de95154aed
parent73d26d6c7129cf2f84ca8b37896e2ecf8c8f3973 (diff)
qtgui: improved handling of qtgui time plotting. Simpler work function. Triggering now handled better, including better delay functionality.
-rw-r--r--gr-qtgui/examples/qtgui_tags_viewing.grc682
-rw-r--r--gr-qtgui/lib/TimeDomainDisplayPlot.cc22
-rw-r--r--gr-qtgui/lib/time_sink_c_impl.cc374
-rw-r--r--gr-qtgui/lib/time_sink_c_impl.h15
-rw-r--r--gr-qtgui/lib/time_sink_f_impl.cc369
-rw-r--r--gr-qtgui/lib/time_sink_f_impl.h17
6 files changed, 785 insertions, 694 deletions
diff --git a/gr-qtgui/examples/qtgui_tags_viewing.grc b/gr-qtgui/examples/qtgui_tags_viewing.grc
index c77e34565d..296641d5cb 100644
--- a/gr-qtgui/examples/qtgui_tags_viewing.grc
+++ b/gr-qtgui/examples/qtgui_tags_viewing.grc
@@ -1,6 +1,6 @@
<?xml version='1.0' encoding='ASCII'?>
<flow_graph>
- <timestamp>Fri Nov 1 18:04:05 2013</timestamp>
+ <timestamp>Wed Nov 6 11:52:40 2013</timestamp>
<block>
<key>options</key>
<param>
@@ -153,10 +153,10 @@
</param>
</block>
<block>
- <key>blocks_add_xx</key>
+ <key>blocks_delay</key>
<param>
<key>id</key>
- <value>blocks_add_xx_1</value>
+ <value>blocks_delay_0</value>
</param>
<param>
<key>_enabled</key>
@@ -167,8 +167,12 @@
<value>complex</value>
</param>
<param>
- <key>num_inputs</key>
- <value>2</value>
+ <key>delay</key>
+ <value>1000</value>
+ </param>
+ <param>
+ <key>num_ports</key>
+ <value>1</value>
</param>
<param>
<key>vlen</key>
@@ -184,7 +188,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(707, 176)</value>
+ <value>(300, 240)</value>
</param>
<param>
<key>_rotation</key>
@@ -192,10 +196,10 @@
</param>
</block>
<block>
- <key>analog_fastnoise_source_x</key>
+ <key>blocks_tags_strobe</key>
<param>
<key>id</key>
- <value>analog_fastnoise_source_x_0</value>
+ <value>blocks_tags_strobe_0</value>
</param>
<param>
<key>_enabled</key>
@@ -206,20 +210,16 @@
<value>complex</value>
</param>
<param>
- <key>noise_type</key>
- <value>analog.GR_GAUSSIAN</value>
- </param>
- <param>
- <key>amp</key>
- <value>0.004</value>
+ <key>value</key>
+ <value>pmt.intern("TEST")</value>
</param>
<param>
- <key>seed</key>
- <value>0</value>
+ <key>nsamps</key>
+ <value>10000</value>
</param>
<param>
- <key>samples</key>
- <value>8192</value>
+ <key>vlen</key>
+ <value>1</value>
</param>
<param>
<key>affinity</key>
@@ -231,7 +231,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(350, 39)</value>
+ <value>(16, 232)</value>
</param>
<param>
<key>_rotation</key>
@@ -239,109 +239,46 @@
</param>
</block>
<block>
- <key>variable_qtgui_range</key>
+ <key>analog_fastnoise_source_x</key>
<param>
<key>id</key>
- <value>ntaps</value>
+ <value>analog_fastnoise_source_x_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>label</key>
- <value>Num Taps</value>
- </param>
- <param>
- <key>value</key>
- <value>30</value>
- </param>
- <param>
- <key>start</key>
- <value>1</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>
+ <key>type</key>
+ <value>complex</value>
</param>
<param>
- <key>gui_hint</key>
- <value></value>
+ <key>noise_type</key>
+ <value>analog.GR_GAUSSIAN</value>
</param>
<param>
- <key>_coordinate</key>
- <value>(899, 430)</value>
+ <key>amp</key>
+ <value>0.004</value>
</param>
<param>
- <key>_rotation</key>
+ <key>seed</key>
<value>0</value>
</param>
- </block>
- <block>
- <key>variable_qtgui_range</key>
- <param>
- <key>id</key>
- <value>delay</value>
- </param>
- <param>
- <key>_enabled</key>
- <value>True</value>
- </param>
<param>
- <key>label</key>
- <value>Delay</value>
+ <key>samples</key>
+ <value>8192</value>
</param>
<param>
- <key>value</key>
- <value>20</value>
+ <key>affinity</key>
+ <value></value>
</param>
<param>
- <key>start</key>
+ <key>minoutbuf</key>
<value>0</value>
</param>
<param>
- <key>stop</key>
- <value>200</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>(762, 428)</value>
+ <value>(350, 39)</value>
</param>
<param>
<key>_rotation</key>
@@ -364,7 +301,7 @@
</param>
<param>
<key>vector</key>
- <value>[0.85+0.5j,] + (10000-1)*[0,]</value>
+ <value>[0.85+0.5j, 0.85, 0.85, 0.85+0.5j] + (10000-4)*[0,]</value>
</param>
<param>
<key>tags</key>
@@ -388,7 +325,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(13, 133)</value>
+ <value>(13, 132)</value>
</param>
<param>
<key>_rotation</key>
@@ -396,10 +333,10 @@
</param>
</block>
<block>
- <key>blocks_throttle</key>
+ <key>blocks_add_xx</key>
<param>
<key>id</key>
- <value>blocks_throttle_0</value>
+ <value>blocks_add_xx_0</value>
</param>
<param>
<key>_enabled</key>
@@ -410,8 +347,8 @@
<value>complex</value>
</param>
<param>
- <key>samples_per_second</key>
- <value>50e3</value>
+ <key>num_inputs</key>
+ <value>2</value>
</param>
<param>
<key>vlen</key>
@@ -427,7 +364,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(266, 149)</value>
+ <value>(482, 193)</value>
</param>
<param>
<key>_rotation</key>
@@ -435,30 +372,22 @@
</param>
</block>
<block>
- <key>blocks_vector_source_x</key>
+ <key>blocks_add_xx</key>
<param>
<key>id</key>
- <value>blocks_vector_source_x_0_0_0</value>
+ <value>blocks_add_xx_1</value>
</param>
<param>
<key>_enabled</key>
- <value>False</value>
+ <value>True</value>
</param>
<param>
<key>type</key>
- <value>float</value>
- </param>
- <param>
- <key>vector</key>
- <value>1000*[0,] + [0.5,] + (10000-1000-1)*[0,]</value>
- </param>
- <param>
- <key>tags</key>
- <value>tagged_streams.make_lengthtags((128,), (1000,), "second stream")</value>
+ <value>complex</value>
</param>
<param>
- <key>repeat</key>
- <value>True</value>
+ <key>num_inputs</key>
+ <value>2</value>
</param>
<param>
<key>vlen</key>
@@ -474,7 +403,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(14, 512)</value>
+ <value>(707, 176)</value>
</param>
<param>
<key>_rotation</key>
@@ -482,30 +411,22 @@
</param>
</block>
<block>
- <key>blocks_vector_source_x</key>
+ <key>blocks_throttle</key>
<param>
<key>id</key>
- <value>blocks_vector_source_x_0_1</value>
+ <value>blocks_throttle_0</value>
</param>
<param>
<key>_enabled</key>
- <value>False</value>
+ <value>True</value>
</param>
<param>
<key>type</key>
- <value>float</value>
- </param>
- <param>
- <key>vector</key>
- <value>[-0.85,] + (10000-1)*[0,]</value>
- </param>
- <param>
- <key>tags</key>
- <value>tagged_streams.make_lengthtags((1024,), (0,), "testing tags")</value>
+ <value>complex</value>
</param>
<param>
- <key>repeat</key>
- <value>True</value>
+ <key>samples_per_second</key>
+ <value>50e3</value>
</param>
<param>
<key>vlen</key>
@@ -521,7 +442,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(14, 421)</value>
+ <value>(266, 149)</value>
</param>
<param>
<key>_rotation</key>
@@ -529,38 +450,54 @@
</param>
</block>
<block>
- <key>blocks_throttle</key>
+ <key>variable_qtgui_range</key>
<param>
<key>id</key>
- <value>blocks_throttle_0_0</value>
+ <value>ntaps</value>
</param>
<param>
<key>_enabled</key>
- <value>False</value>
+ <value>True</value>
</param>
<param>
- <key>type</key>
- <value>float</value>
+ <key>label</key>
+ <value>Num Taps</value>
</param>
<param>
- <key>samples_per_second</key>
- <value>samp_rate</value>
+ <key>value</key>
+ <value>30</value>
</param>
<param>
- <key>vlen</key>
+ <key>start</key>
<value>1</value>
</param>
<param>
- <key>affinity</key>
- <value></value>
+ <key>stop</key>
+ <value>100</value>
</param>
<param>
- <key>minoutbuf</key>
- <value>0</value>
+ <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>(264, 437)</value>
+ <value>(936, 392)</value>
</param>
<param>
<key>_rotation</key>
@@ -571,15 +508,15 @@
<key>qtgui_time_sink_x</key>
<param>
<key>id</key>
- <value>qtgui_time_sink_x_0_0</value>
+ <value>qtgui_time_sink_x_0_1_0</value>
</param>
<param>
<key>_enabled</key>
- <value>False</value>
+ <value>True</value>
</param>
<param>
<key>type</key>
- <value>float</value>
+ <value>complex</value>
</param>
<param>
<key>name</key>
@@ -587,7 +524,7 @@
</param>
<param>
<key>size</key>
- <value>18000</value>
+ <value>5100</value>
</param>
<param>
<key>srate</key>
@@ -595,23 +532,23 @@
</param>
<param>
<key>ymin</key>
- <value>-1</value>
+ <value>-0.1</value>
</param>
<param>
<key>ymax</key>
- <value>1</value>
+ <value>1.5</value>
</param>
<param>
<key>nconnections</key>
- <value>2</value>
+ <value>1</value>
</param>
<param>
<key>update_time</key>
- <value>0.10</value>
+ <value>0.001</value>
</param>
<param>
<key>tr_mode</key>
- <value>qtgui.TRIG_MODE_FREE</value>
+ <value>qtgui.TRIG_MODE_TAG</value>
</param>
<param>
<key>tr_slope</key>
@@ -619,11 +556,11 @@
</param>
<param>
<key>tr_level</key>
- <value>0.0</value>
+ <value>.5</value>
</param>
<param>
<key>tr_delay</key>
- <value>0</value>
+ <value>0.06</value>
</param>
<param>
<key>tr_chan</key>
@@ -631,7 +568,7 @@
</param>
<param>
<key>tr_tag</key>
- <value>""</value>
+ <value>strobe</value>
</param>
<param>
<key>entags</key>
@@ -639,7 +576,7 @@
</param>
<param>
<key>gui_hint</key>
- <value></value>
+ <value>1,1,1,1</value>
</param>
<param>
<key>affinity</key>
@@ -647,7 +584,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(474, 467)</value>
+ <value>(857, 173)</value>
</param>
<param>
<key>_rotation</key>
@@ -702,10 +639,10 @@
</param>
</block>
<block>
- <key>blocks_tags_strobe</key>
+ <key>qtgui_time_sink_x</key>
<param>
<key>id</key>
- <value>blocks_tags_strobe_0</value>
+ <value>qtgui_time_sink_x_0</value>
</param>
<param>
<key>_enabled</key>
@@ -716,71 +653,72 @@
<value>complex</value>
</param>
<param>
- <key>value</key>
- <value>pmt.intern("TEST")</value>
+ <key>name</key>
+ <value>QT GUI Plot</value>
</param>
<param>
- <key>nsamps</key>
- <value>10000</value>
+ <key>size</key>
+ <value>18000</value>
</param>
<param>
- <key>vlen</key>
- <value>1</value>
+ <key>srate</key>
+ <value>samp_rate</value>
</param>
<param>
- <key>affinity</key>
- <value></value>
+ <key>ymin</key>
+ <value>-0.1</value>
</param>
<param>
- <key>minoutbuf</key>
- <value>0</value>
+ <key>ymax</key>
+ <value>1.5</value>
</param>
<param>
- <key>_coordinate</key>
- <value>(16, 232)</value>
+ <key>nconnections</key>
+ <value>2</value>
</param>
<param>
- <key>_rotation</key>
- <value>0</value>
+ <key>update_time</key>
+ <value>0.10</value>
</param>
- </block>
- <block>
- <key>blocks_delay</key>
<param>
- <key>id</key>
- <value>blocks_delay_0</value>
+ <key>tr_mode</key>
+ <value>qtgui.TRIG_MODE_NORM</value>
</param>
<param>
- <key>_enabled</key>
- <value>True</value>
+ <key>tr_slope</key>
+ <value>qtgui.TRIG_SLOPE_POS</value>
</param>
<param>
- <key>type</key>
- <value>complex</value>
+ <key>tr_level</key>
+ <value>0.1</value>
</param>
<param>
- <key>delay</key>
- <value>1000</value>
+ <key>tr_delay</key>
+ <value>0</value>
</param>
<param>
- <key>num_ports</key>
- <value>1</value>
+ <key>tr_chan</key>
+ <value>0</value>
</param>
<param>
- <key>vlen</key>
- <value>1</value>
+ <key>tr_tag</key>
+ <value>""</value>
</param>
<param>
- <key>affinity</key>
+ <key>entags</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>gui_hint</key>
<value></value>
</param>
<param>
- <key>minoutbuf</key>
- <value>0</value>
+ <key>affinity</key>
+ <value></value>
</param>
<param>
<key>_coordinate</key>
- <value>(300, 240)</value>
+ <value>(860, 298)</value>
</param>
<param>
<key>_rotation</key>
@@ -788,10 +726,10 @@
</param>
</block>
<block>
- <key>blocks_add_xx</key>
+ <key>fir_filter_xxx</key>
<param>
<key>id</key>
- <value>blocks_add_xx_0</value>
+ <value>fir_filter_xxx_0</value>
</param>
<param>
<key>_enabled</key>
@@ -799,15 +737,19 @@
</param>
<param>
<key>type</key>
- <value>complex</value>
+ <value>ccc</value>
</param>
<param>
- <key>num_inputs</key>
- <value>2</value>
+ <key>decim</key>
+ <value>1</value>
</param>
<param>
- <key>vlen</key>
- <value>1</value>
+ <key>taps</key>
+ <value>int(ntaps)*[1,]+[1,]</value>
+ </param>
+ <param>
+ <key>samp_delay</key>
+ <value>int(ntaps)</value>
</param>
<param>
<key>affinity</key>
@@ -819,7 +761,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(482, 193)</value>
+ <value>(660, 76)</value>
</param>
<param>
<key>_rotation</key>
@@ -827,10 +769,10 @@
</param>
</block>
<block>
- <key>blocks_delay</key>
+ <key>qtgui_time_sink_x</key>
<param>
<key>id</key>
- <value>blocks_delay_0_0</value>
+ <value>qtgui_time_sink_x_0_1</value>
</param>
<param>
<key>_enabled</key>
@@ -841,71 +783,72 @@
<value>complex</value>
</param>
<param>
- <key>delay</key>
- <value>int(delay)</value>
+ <key>name</key>
+ <value>QT GUI Plot</value>
</param>
<param>
- <key>num_ports</key>
- <value>1</value>
+ <key>size</key>
+ <value>1000</value>
</param>
<param>
- <key>vlen</key>
- <value>1</value>
+ <key>srate</key>
+ <value>samp_rate</value>
</param>
<param>
- <key>affinity</key>
- <value></value>
+ <key>ymin</key>
+ <value>-0.1</value>
</param>
<param>
- <key>minoutbuf</key>
- <value>0</value>
+ <key>ymax</key>
+ <value>4.5</value>
</param>
<param>
- <key>_coordinate</key>
- <value>(890, 44)</value>
+ <key>nconnections</key>
+ <value>2</value>
</param>
<param>
- <key>_rotation</key>
- <value>0</value>
+ <key>update_time</key>
+ <value>0.10</value>
</param>
- </block>
- <block>
- <key>fir_filter_xxx</key>
<param>
- <key>id</key>
- <value>fir_filter_xxx_0</value>
+ <key>tr_mode</key>
+ <value>qtgui.TRIG_MODE_NORM</value>
</param>
<param>
- <key>_enabled</key>
- <value>True</value>
+ <key>tr_slope</key>
+ <value>qtgui.TRIG_SLOPE_POS</value>
</param>
<param>
- <key>type</key>
- <value>ccc</value>
+ <key>tr_level</key>
+ <value>.1</value>
</param>
<param>
- <key>decim</key>
- <value>1</value>
+ <key>tr_delay</key>
+ <value>0.015</value>
</param>
<param>
- <key>taps</key>
- <value>int(ntaps)*[1,]+[1,]</value>
+ <key>tr_chan</key>
+ <value>0</value>
</param>
<param>
- <key>samp_delay</key>
- <value>int(ntaps)</value>
+ <key>tr_tag</key>
+ <value>""</value>
</param>
<param>
- <key>affinity</key>
- <value></value>
+ <key>entags</key>
+ <value>True</value>
</param>
<param>
- <key>minoutbuf</key>
- <value>0</value>
+ <key>gui_hint</key>
+ <value>1,0,1,1</value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
</param>
<param>
<key>_coordinate</key>
- <value>(660, 76)</value>
+ <value>(1072, 77)</value>
</param>
<param>
<key>_rotation</key>
@@ -916,15 +859,15 @@
<key>qtgui_time_sink_x</key>
<param>
<key>id</key>
- <value>qtgui_time_sink_x_0_1_0</value>
+ <value>qtgui_time_sink_x_0_0</value>
</param>
<param>
<key>_enabled</key>
- <value>True</value>
+ <value>False</value>
</param>
<param>
<key>type</key>
- <value>complex</value>
+ <value>float</value>
</param>
<param>
<key>name</key>
@@ -932,7 +875,7 @@
</param>
<param>
<key>size</key>
- <value>18000</value>
+ <value>1024</value>
</param>
<param>
<key>srate</key>
@@ -940,15 +883,15 @@
</param>
<param>
<key>ymin</key>
- <value>-0.1</value>
+ <value>-1</value>
</param>
<param>
<key>ymax</key>
- <value>1.5</value>
+ <value>1</value>
</param>
<param>
<key>nconnections</key>
- <value>1</value>
+ <value>2</value>
</param>
<param>
<key>update_time</key>
@@ -956,7 +899,7 @@
</param>
<param>
<key>tr_mode</key>
- <value>qtgui.TRIG_MODE_NORM</value>
+ <value>qtgui.TRIG_MODE_TAG</value>
</param>
<param>
<key>tr_slope</key>
@@ -964,7 +907,7 @@
</param>
<param>
<key>tr_level</key>
- <value>.1</value>
+ <value>0.0</value>
</param>
<param>
<key>tr_delay</key>
@@ -972,11 +915,11 @@
</param>
<param>
<key>tr_chan</key>
- <value>0</value>
+ <value>1</value>
</param>
<param>
<key>tr_tag</key>
- <value>""</value>
+ <value>second stream</value>
</param>
<param>
<key>entags</key>
@@ -984,7 +927,7 @@
</param>
<param>
<key>gui_hint</key>
- <value>1,1,1,1</value>
+ <value></value>
</param>
<param>
<key>affinity</key>
@@ -992,7 +935,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(857, 173)</value>
+ <value>(475, 444)</value>
</param>
<param>
<key>_rotation</key>
@@ -1000,86 +943,93 @@
</param>
</block>
<block>
- <key>qtgui_time_sink_x</key>
+ <key>blocks_vector_source_x</key>
<param>
<key>id</key>
- <value>qtgui_time_sink_x_0_1</value>
+ <value>blocks_vector_source_x_0_0_0</value>
</param>
<param>
<key>_enabled</key>
- <value>True</value>
+ <value>False</value>
</param>
<param>
<key>type</key>
- <value>complex</value>
+ <value>float</value>
</param>
<param>
- <key>name</key>
- <value>QT GUI Plot</value>
+ <key>vector</key>
+ <value>10*[0,] + [0.5,] + (100-10-1)*[0,]</value>
</param>
<param>
- <key>size</key>
- <value>1000</value>
+ <key>tags</key>
+ <value>tagged_streams.make_lengthtags((128,), (110,), "second stream")</value>
</param>
<param>
- <key>srate</key>
- <value>samp_rate</value>
+ <key>repeat</key>
+ <value>True</value>
</param>
<param>
- <key>ymin</key>
- <value>-0.1</value>
+ <key>vlen</key>
+ <value>1</value>
</param>
<param>
- <key>ymax</key>
- <value>1.5</value>
+ <key>affinity</key>
+ <value></value>
</param>
<param>
- <key>nconnections</key>
- <value>2</value>
+ <key>minoutbuf</key>
+ <value>0</value>
</param>
<param>
- <key>update_time</key>
- <value>0.10</value>
+ <key>_coordinate</key>
+ <value>(15, 489)</value>
</param>
<param>
- <key>tr_mode</key>
- <value>qtgui.TRIG_MODE_NORM</value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>blocks_vector_source_x</key>
<param>
- <key>tr_slope</key>
- <value>qtgui.TRIG_SLOPE_POS</value>
+ <key>id</key>
+ <value>blocks_vector_source_x_0_1</value>
</param>
<param>
- <key>tr_level</key>
- <value>.1</value>
+ <key>_enabled</key>
+ <value>False</value>
</param>
<param>
- <key>tr_delay</key>
- <value>0.015</value>
+ <key>type</key>
+ <value>float</value>
</param>
<param>
- <key>tr_chan</key>
- <value>0</value>
+ <key>vector</key>
+ <value>[-0.85,] + (100-1)*[0,]</value>
</param>
<param>
- <key>tr_tag</key>
- <value>""</value>
+ <key>tags</key>
+ <value>tagged_streams.make_lengthtags((1024,), (0,), "testing tags")</value>
</param>
<param>
- <key>entags</key>
+ <key>repeat</key>
<value>True</value>
</param>
<param>
- <key>gui_hint</key>
- <value>1,0,1,1</value>
+ <key>vlen</key>
+ <value>1</value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
<key>_coordinate</key>
- <value>(1072, 77)</value>
+ <value>(15, 398)</value>
</param>
<param>
<key>_rotation</key>
@@ -1087,10 +1037,49 @@
</param>
</block>
<block>
- <key>qtgui_time_sink_x</key>
+ <key>blocks_throttle</key>
<param>
<key>id</key>
- <value>qtgui_time_sink_x_0</value>
+ <value>blocks_throttle_0_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>float</value>
+ </param>
+ <param>
+ <key>samples_per_second</key>
+ <value>samp_rate</value>
+ </param>
+ <param>
+ <key>vlen</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(267, 414)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>blocks_delay</key>
+ <param>
+ <key>id</key>
+ <value>blocks_delay_0_0</value>
</param>
<param>
<key>_enabled</key>
@@ -1101,72 +1090,83 @@
<value>complex</value>
</param>
<param>
- <key>name</key>
- <value>QT GUI Plot</value>
+ <key>delay</key>
+ <value>int(delay)</value>
</param>
<param>
- <key>size</key>
- <value>18000</value>
+ <key>num_ports</key>
+ <value>1</value>
</param>
<param>
- <key>srate</key>
+ <key>vlen</key>
<value>1</value>
</param>
<param>
- <key>ymin</key>
- <value>-0.1</value>
+ <key>affinity</key>
+ <value></value>
</param>
<param>
- <key>ymax</key>
- <value>1.5</value>
+ <key>minoutbuf</key>
+ <value>0</value>
</param>
<param>
- <key>nconnections</key>
- <value>2</value>
+ <key>_coordinate</key>
+ <value>(890, 44)</value>
</param>
<param>
- <key>update_time</key>
- <value>0.10</value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>variable_qtgui_range</key>
<param>
- <key>tr_mode</key>
- <value>qtgui.TRIG_MODE_NORM</value>
+ <key>id</key>
+ <value>delay</value>
</param>
<param>
- <key>tr_slope</key>
- <value>qtgui.TRIG_SLOPE_POS</value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>tr_level</key>
- <value>.1</value>
+ <key>label</key>
+ <value>Delay</value>
</param>
<param>
- <key>tr_delay</key>
- <value>1000</value>
+ <key>value</key>
+ <value>300</value>
</param>
<param>
- <key>tr_chan</key>
+ <key>start</key>
<value>0</value>
</param>
<param>
- <key>tr_tag</key>
- <value>""</value>
+ <key>stop</key>
+ <value>1000</value>
</param>
<param>
- <key>entags</key>
- <value>True</value>
+ <key>step</key>
+ <value>1</value>
</param>
<param>
- <key>gui_hint</key>
- <value></value>
+ <key>widget</key>
+ <value>counter_slider</value>
</param>
<param>
- <key>affinity</key>
+ <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>(860, 298)</value>
+ <value>(814, 390)</value>
</param>
<param>
<key>_rotation</key>
@@ -1204,18 +1204,6 @@
<sink_key>1</sink_key>
</connection>
<connection>
- <source_block_id>blocks_add_xx_1</source_block_id>
- <sink_block_id>qtgui_time_sink_x_0</sink_block_id>
- <source_key>0</source_key>
- <sink_key>0</sink_key>
- </connection>
- <connection>
- <source_block_id>blocks_add_xx_1</source_block_id>
- <sink_block_id>qtgui_time_sink_x_0_1_0</sink_block_id>
- <source_key>0</source_key>
- <sink_key>0</sink_key>
- </connection>
- <connection>
<source_block_id>blocks_add_xx_0</source_block_id>
<sink_block_id>fir_filter_xxx_0</sink_block_id>
<source_key>0</source_key>
@@ -1240,33 +1228,45 @@
<sink_key>1</sink_key>
</connection>
<connection>
- <source_block_id>blocks_vector_source_x_0_0_0</source_block_id>
- <sink_block_id>qtgui_time_sink_x_0_0</sink_block_id>
+ <source_block_id>blocks_vector_source_x_0_0</source_block_id>
+ <sink_block_id>qtgui_time_sink_x_0</sink_block_id>
<source_key>0</source_key>
<sink_key>1</sink_key>
</connection>
<connection>
- <source_block_id>blocks_vector_source_x_0_1</source_block_id>
- <sink_block_id>blocks_throttle_0_0</sink_block_id>
+ <source_block_id>blocks_tags_strobe_0</source_block_id>
+ <sink_block_id>blocks_delay_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_throttle_0_0</source_block_id>
- <sink_block_id>qtgui_time_sink_x_0_0</sink_block_id>
+ <source_block_id>blocks_add_xx_1</source_block_id>
+ <sink_block_id>qtgui_time_sink_x_0_1_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_tags_strobe_0</source_block_id>
- <sink_block_id>blocks_delay_0</sink_block_id>
+ <source_block_id>blocks_add_xx_1</source_block_id>
+ <sink_block_id>qtgui_time_sink_x_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_vector_source_x_0_0</source_block_id>
- <sink_block_id>qtgui_time_sink_x_0</sink_block_id>
+ <source_block_id>blocks_vector_source_x_0_0_0</source_block_id>
+ <sink_block_id>qtgui_time_sink_x_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>1</sink_key>
</connection>
+ <connection>
+ <source_block_id>blocks_throttle_0_0</source_block_id>
+ <sink_block_id>qtgui_time_sink_x_0_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>blocks_vector_source_x_0_1</source_block_id>
+ <sink_block_id>blocks_throttle_0_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
</flow_graph>
diff --git a/gr-qtgui/lib/TimeDomainDisplayPlot.cc b/gr-qtgui/lib/TimeDomainDisplayPlot.cc
index 052aaf8cf7..adc6baa4a9 100644
--- a/gr-qtgui/lib/TimeDomainDisplayPlot.cc
+++ b/gr-qtgui/lib/TimeDomainDisplayPlot.cc
@@ -255,6 +255,12 @@ TimeDomainDisplayPlot::plotNewData(const std::vector<double*> dataPoints,
std::vector<gr::tag_t>::const_iterator t;
for(t = tag->begin(); t != tag->end(); t++) {
uint64_t offset = (*t).offset;
+
+ // Ignore tag if its offset is outside our plottable vector.
+ if(offset >= (uint64_t)d_numPoints) {
+ continue;
+ }
+
double sample_offset = double(offset)/d_sample_rate;
std::stringstream s;
@@ -265,8 +271,20 @@ TimeDomainDisplayPlot::plotNewData(const std::vector<double*> dataPoints,
// real and imaginary parts and put the tag on that one.
int which = i;
if(cmplx) {
- if(fabs(d_ydata[i][offset]) < fabs(d_ydata[i+1][offset]))
- which = i+1;
+ bool show0 = d_plot_curve[i]->isVisible();
+ bool show1 = d_plot_curve[i+1]->isVisible();
+
+ // If we are showing both streams, select the inptu stream
+ // with the larger value
+ if(show0 && show1) {
+ if(fabs(d_ydata[i][offset]) < fabs(d_ydata[i+1][offset]))
+ which = i+1;
+ }
+ else {
+ // If show0, we keep which = i; otherwise, use i+1.
+ if(show1)
+ which = i+1;
+ }
}
double yval = d_ydata[which][offset];
diff --git a/gr-qtgui/lib/time_sink_c_impl.cc b/gr-qtgui/lib/time_sink_c_impl.cc
index c87a9ee900..fb3ffcd00b 100644
--- a/gr-qtgui/lib/time_sink_c_impl.cc
+++ b/gr-qtgui/lib/time_sink_c_impl.cc
@@ -26,8 +26,6 @@
#include "time_sink_c_impl.h"
#include <gnuradio/io_signature.h>
-#include <gnuradio/block_detail.h>
-#include <gnuradio/buffer.h>
#include <string.h>
#include <volk/volk.h>
#include <gnuradio/fft/fft.h>
@@ -53,16 +51,14 @@ namespace gr {
: sync_block("time_sink_c",
io_signature::make(nconnections, nconnections, sizeof(gr_complex)),
io_signature::make(0, 0, 0)),
- d_size(size), d_samp_rate(samp_rate), d_name(name),
+ d_size(size), d_buffer_size(2*size), d_samp_rate(samp_rate), d_name(name),
d_nconnections(2*nconnections), d_parent(parent)
{
d_main_gui = NULL;
- d_index = 0;
-
- for(int i = 0; i < d_nconnections; i++) {
- d_residbufs.push_back(fft::malloc_double(d_size));
- memset(d_residbufs[i], 0, d_size*sizeof(double));
+ for(int n = 0; n < d_nconnections; n++) {
+ d_buffers.push_back(fft::malloc_double(d_buffer_size));
+ memset(d_buffers[n], 0, d_buffer_size*sizeof(double));
}
// Set alignment properties for VOLK
@@ -74,10 +70,11 @@ namespace gr {
initialize();
- d_size += 1; // trick the next line into updating
- set_nsamps(size);
- set_trigger_mode(TRIG_MODE_AUTO, TRIG_SLOPE_POS, 0, 0, 0);
- d_initial_delay = d_trigger_delay;
+ d_main_gui->setNPoints(d_size); // setup GUI box with size
+ set_trigger_mode(TRIG_MODE_FREE, TRIG_SLOPE_POS, 0, 0, 0);
+
+ set_history(2); // so we can look ahead for the trigger slope
+ declare_sample_delay(1); // delay the tags for a history of 2
}
time_sink_c_impl::~time_sink_c_impl()
@@ -86,8 +83,8 @@ namespace gr {
d_main_gui->close();
// d_main_gui is a qwidget destroyed with its parent
- for(int i = 0; i < d_nconnections; i++) {
- fft::free(d_residbufs[i]);
+ for(int n = 0; n < d_nconnections; n++) {
+ fft::free(d_buffers[n]);
}
}
@@ -202,6 +199,8 @@ namespace gr {
float delay, int channel,
const std::string &tag_key)
{
+ gr::thread::scoped_lock lock(d_mutex);
+
d_trigger_mode = mode;
d_trigger_slope = slope;
d_trigger_level = level;
@@ -211,10 +210,11 @@ namespace gr {
d_triggered = false;
d_trigger_count = 0;
- if(d_trigger_delay >= d_size) {
- GR_LOG_WARN(d_logger, boost::format("Trigger delay (%1%) outside of display range (%2%).") \
- % d_trigger_delay % d_size);
- d_trigger_delay = d_size-1;
+ if((d_trigger_delay < 0) || (d_trigger_delay >= d_size)) {
+ GR_LOG_WARN(d_logger, boost::format("Trigger delay (%1%) outside of display range (0:%2%).") \
+ % (d_trigger_delay/d_samp_rate) % ((d_size-1)/d_samp_rate));
+ d_trigger_delay = std::max(0, std::min(d_size-1, d_trigger_delay));
+ delay = d_trigger_delay/d_samp_rate;
}
d_main_gui->setTriggerMode(d_trigger_mode);
@@ -224,8 +224,7 @@ namespace gr {
d_main_gui->setTriggerChannel(d_trigger_channel);
d_main_gui->setTriggerTagKey(tag_key);
- set_history(d_trigger_delay + 2);
- declare_sample_delay(d_trigger_delay+1);
+ _reset();
}
void
@@ -279,23 +278,31 @@ namespace gr {
void
time_sink_c_impl::set_nsamps(const int newsize)
{
- gr::thread::scoped_lock lock(d_mutex);
-
if(newsize != d_size) {
- // Resize residbuf and replace data
- for(int i = 0; i < d_nconnections; i++) {
- fft::free(d_residbufs[i]);
- d_residbufs[i] = fft::malloc_double(newsize);
-
- memset(d_residbufs[i], 0, newsize*sizeof(double));
- }
+ gr::thread::scoped_lock lock(d_mutex);
// Set new size and reset buffer index
// (throws away any currently held data, but who cares?)
d_size = newsize;
- d_index = 0;
+ d_buffer_size = 2*d_size;
+
+ // Resize buffers and replace data
+ for(int n = 0; n < d_nconnections; n++) {
+ fft::free(d_buffers[n]);
+ d_buffers[n] = fft::malloc_double(d_buffer_size);
+ memset(d_buffers[n], 0, d_buffer_size*sizeof(double));
+ }
+
+ // If delay was set beyond the new boundary, pull it back.
+ if(d_trigger_delay >= d_size) {
+ GR_LOG_WARN(d_logger, boost::format("Trigger delay (%1%) outside of display range (0:%2%). Moving to 50%% point.") \
+ % (d_trigger_delay/d_samp_rate) % ((d_size-1)/d_samp_rate));
+ d_trigger_delay = d_size/2;
+ d_main_gui->setTriggerDelay(d_trigger_delay/d_samp_rate);
+ }
d_main_gui->setNPoints(d_size);
+ _reset();
}
}
@@ -364,7 +371,57 @@ namespace gr {
void
time_sink_c_impl::reset()
{
- d_index = 0;
+ gr::thread::scoped_lock lock(d_mutex);
+ _reset();
+ }
+
+ void
+ time_sink_c_impl::_reset()
+ {
+ // Move the tail of the buffers to the front. This section
+ // represents data that might have to be plotted again if a
+ // trigger occurs and we have a trigger delay set. The tail
+ // section is between (d_end-d_trigger_delay) and d_end.
+ int n;
+ if(d_trigger_delay) {
+ for(n = 0; n < d_nconnections; n++) {
+ memmove(d_buffers[n], &d_buffers[n][d_size-d_trigger_delay], d_trigger_delay*sizeof(double));
+ }
+
+ // Also move the offsets of any tags that occur in the tail
+ // section so they would be plotted again, too.
+ for(n = 0; n < d_nconnections/2; n++) {
+ std::vector<gr::tag_t> tmp_tags;
+ for(size_t t = 0; t < d_tags[n].size(); t++) {
+ if(d_tags[n][t].offset > (d_size - d_trigger_delay)) {
+ d_tags[n][t].offset = d_tags[n][t].offset - (d_size - d_trigger_delay);
+ tmp_tags.push_back(d_tags[n][t]);
+ }
+ }
+ d_tags[n] = tmp_tags;
+ }
+ }
+ // Otherwise, just clear the local list of tags.
+ else {
+ for(n = 0; n < d_nconnections/2; n++) {
+ d_tags[n].clear();
+ }
+ }
+
+ // Reset the start and end indices.
+ d_start = 0;
+ d_end = d_size;
+
+ // Reset the trigger. If in free running mode, ignore the
+ // trigger delay and always set trigger to true.
+ if(d_trigger_mode == TRIG_MODE_FREE) {
+ d_index = 0;
+ d_triggered = true;
+ }
+ else {
+ d_index = d_trigger_delay;
+ d_triggered = false;
+ }
}
void
@@ -375,55 +432,94 @@ namespace gr {
}
void
+ time_sink_c_impl::_adjust_tags(int adj)
+ {
+ for(size_t n = 0; n < d_tags.size(); n++) {
+ for(size_t t = 0; t < d_tags[n].size(); t++) {
+ d_tags[n][t].offset += adj;
+ }
+ }
+ }
+
+ void
time_sink_c_impl::_gui_update_trigger()
{
d_trigger_mode = d_main_gui->getTriggerMode();
d_trigger_slope = d_main_gui->getTriggerSlope();
d_trigger_level = d_main_gui->getTriggerLevel();
d_trigger_channel = d_main_gui->getTriggerChannel();
+ d_trigger_count = 0;
float delayf = d_main_gui->getTriggerDelay();
int delay = static_cast<int>(delayf*d_samp_rate);
if(delay != d_trigger_delay) {
// We restrict the delay to be within the window of time being
- // plotted. This also restrict it to be less than the number
- // of output items since we cannot set the history greater
- // than this. We can probably get around this latter part by
- // not using history and doing more work inside 'work' to keep
- // track of things.
- int maxn;
-
- // If we have built the detail and buffers, we're stuck with
- // the max number of item; otherwise the buffer will be built
- // around this value so we just don't want to go over d_size.
- int correction = 5; // give us a bit of room at the edge.
- block_detail_sptr d = detail();
- if(d) {
- int max_possible = d->input(d_trigger_channel/2)->max_possible_items_available()/2 - d_initial_delay;
- maxn = std::max(1, std::min(max_possible, d_size) - correction);
- }
- else {
- maxn = d_size-correction;
- d_initial_delay = d_trigger_delay; // store this value before we create a d_detail
- }
-
- if(delay > maxn) {
- GR_LOG_WARN(d_logger, boost::format("Trigger delay (%1% / %2% sec) outside of max range (%3% / %4% sec)") \
- % delay % delayf % maxn % (maxn/d_samp_rate));
- delay = maxn - d_initial_delay;
+ // plotted.
+ if((delay < 0) || (delay >= d_size)) {
+ GR_LOG_WARN(d_logger, boost::format("Trigger delay (%1%) outside of display range (0:%2%).") \
+ % (delay/d_samp_rate) % ((d_size-1)/d_samp_rate));
+ delay = std::max(0, std::min(d_size-1, delay));
delayf = delay/d_samp_rate;
}
d_trigger_delay = delay;
d_main_gui->setTriggerDelay(delayf);
- set_history(d_trigger_delay+1);
+ _reset();
}
std::string tagkey = d_main_gui->getTriggerTagKey();
d_trigger_tag_key = pmt::intern(tagkey);
}
+ void
+ time_sink_c_impl::_test_trigger_tags(int nitems)
+ {
+ int trigger_index;
+
+ uint64_t nr = nitems_read(d_trigger_channel/2);
+ std::vector<gr::tag_t> tags;
+ get_tags_in_range(tags, d_trigger_channel/2,
+ nr, nr + nitems,
+ d_trigger_tag_key);
+ if(tags.size() > 0) {
+ d_triggered = true;
+ trigger_index = tags[0].offset - nr;
+ d_start = d_index + trigger_index - d_trigger_delay - 1;
+ d_end = d_start + d_size;
+ d_trigger_count = 0;
+ _adjust_tags(-d_start);
+ }
+ }
+
+ void
+ time_sink_c_impl::_test_trigger_norm(int nitems, gr_vector_const_void_star inputs)
+ {
+ int trigger_index;
+ const gr_complex *in = (const gr_complex*)inputs[d_trigger_channel/2];
+ for(trigger_index = 0; trigger_index < nitems; trigger_index++) {
+ d_trigger_count++;
+
+ // Test if trigger has occurred based on the input stream,
+ // channel number, and slope direction
+ if(_test_trigger_slope(&in[trigger_index])) {
+ d_triggered = true;
+ d_start = d_index + trigger_index - d_trigger_delay;
+ d_end = d_start + d_size;
+ d_trigger_count = 0;
+ _adjust_tags(-d_start);
+ break;
+ }
+ }
+
+ // If using auto trigger mode, trigger periodically even
+ // without a trigger event.
+ if((d_trigger_mode == TRIG_MODE_AUTO) && (d_trigger_count > d_size)) {
+ d_triggered = true;
+ d_trigger_count = 0;
+ }
+ }
+
bool
time_sink_c_impl::_test_trigger_slope(const gr_complex *in) const
{
@@ -449,134 +545,70 @@ namespace gr {
gr_vector_void_star &output_items)
{
int n=0, idx=0;
- int trigger_index=0;
const gr_complex *in;
_npoints_resize();
_gui_update_trigger();
- for(int i=0; i < noutput_items; i+=d_size) {
-
- // If auto or normal trigger, look for the trigger
- trigger_index = i;
- if((d_trigger_mode != TRIG_MODE_FREE) && !d_triggered) {
-
- if(d_trigger_mode == TRIG_MODE_TAG) {
- uint64_t nr = nitems_read(d_trigger_channel/2);
-
- // Look for tags past the delay so we can subtract delay
- // to calculate the trigger_index without it going
- // negative.
- std::vector<gr::tag_t> tags;
- get_tags_in_range(tags, d_trigger_channel/2,
- nr + trigger_index + d_trigger_delay,
- nr + trigger_index + d_trigger_delay + noutput_items,
- d_trigger_tag_key);
- if(tags.size() > 0) {
- d_index = 0;
- d_triggered = true;
- d_trigger_count = 0;
- trigger_index = tags[0].offset - nr - trigger_index - d_trigger_delay;
- break;
- }
- else
- trigger_index = noutput_items;
- }
- else {
- for(; trigger_index < noutput_items; trigger_index++) {
- d_trigger_count++;
-
- // Test if trigger has occurred based on the input stream,
- // channel number, and slope direction
- in = (const gr_complex*)input_items[d_trigger_channel/2];
- if(_test_trigger_slope(&in[trigger_index + d_trigger_delay])) {
- d_triggered = true;
- d_trigger_count = 0;
- break;
- }
- }
-
- // If using auto trigger mode, trigger periodically even
- // without a trigger event.
- if((d_trigger_mode == TRIG_MODE_AUTO) && (d_trigger_count > d_size)) {
- d_triggered = true;
- d_trigger_count = 0;
- }
- }
+ gr::thread::scoped_lock lock(d_mutex);
+
+ int nfill = d_end - d_index; // how much room left in buffers
+ int nitems = std::min(noutput_items, nfill); // num items we can put in buffers
- i = trigger_index;
+ // If auto, normal, or tag trigger, look for the trigger
+ if((d_trigger_mode != TRIG_MODE_FREE) && !d_triggered) {
+ // trigger off a tag key (first one found)
+ if(d_trigger_mode == TRIG_MODE_TAG) {
+ _test_trigger_tags(nitems);
+ }
+ // Normal or Auto trigger
+ else {
+ _test_trigger_norm(nitems, input_items);
}
+ }
- unsigned int datasize = noutput_items - trigger_index;
- unsigned int resid = d_size-d_index;
- idx = 0;
-
- // If we're in trigger mode, test if we have triggered
- if((d_trigger_mode == TRIG_MODE_FREE) || d_triggered) {
- // If we have enough input for one full plot, do it
- if(datasize >= resid) {
- // Fill up residbufs with d_size number of items
- for(n = 0; n < d_nconnections; n+=2) {
- in = (const gr_complex*)input_items[idx];
- volk_32fc_deinterleave_64f_x2_u(&d_residbufs[n][d_index],
- &d_residbufs[n+1][d_index],
- &in[trigger_index], resid);
-
- uint64_t nr = nitems_read(idx);
- std::vector<gr::tag_t> tags;
- get_tags_in_range(tags, idx, nr + trigger_index,
- nr + trigger_index + resid);
- for(size_t t = 0; t < tags.size(); t++) {
- tags[t].offset = tags[t].offset - (nr + trigger_index) + d_index;
- }
- d_tags[idx].insert(d_tags[idx].end(), tags.begin(), tags.end());
-
- idx++;
- }
+ // Copy data into the buffers.
+ for(n = 0; n < d_nconnections; n+=2) {
+ in = (const gr_complex*)input_items[idx];
+ volk_32fc_deinterleave_64f_x2(&d_buffers[n][d_index],
+ &d_buffers[n+1][d_index],
+ &in[0], nitems);
+
+ uint64_t nr = nitems_read(idx);
+ std::vector<gr::tag_t> tags;
+ get_tags_in_range(tags, idx, nr, nr + nitems);
+ for(size_t t = 0; t < tags.size(); t++) {
+ tags[t].offset = tags[t].offset - nr + (d_index-d_start);
+ }
+ d_tags[idx].insert(d_tags[idx].end(), tags.begin(), tags.end());
+ idx++;
+ }
+ d_index += nitems;
- // Update the plot if it's time
- if(gr::high_res_timer_now() - d_last_time > d_update_time) {
- d_last_time = gr::high_res_timer_now();
- d_qApplication->postEvent(d_main_gui,
- new TimeUpdateEvent(d_residbufs, d_size, d_tags));
- }
+ // If we've have a trigger and a full d_size of items in the buffers, plot.
+ if((d_triggered) && (d_index == d_end)) {
+ // Copy data to be plotted to start of buffers.
+ for(n = 0; n < d_nconnections; n++) {
+ memmove(d_buffers[n], &d_buffers[n][d_start], d_size*sizeof(double));
+ }
- d_index = 0;
- trigger_index += resid;
- d_triggered = false;
+ // Plot if we are able to update
+ if(gr::high_res_timer_now() - d_last_time > d_update_time) {
+ d_last_time = gr::high_res_timer_now();
+ d_qApplication->postEvent(d_main_gui,
+ new TimeUpdateEvent(d_buffers, d_size, d_tags));
+ }
- for(n = 0; n < d_nconnections/2; n++) {
- d_tags[n].clear();
- }
- }
+ // We've plotting, so reset the state
+ _reset();
+ }
- // Otherwise, copy what we received into the residbufs for next time
- else {
- for(n = 0; n < d_nconnections; n+=2) {
- in = (const gr_complex*)input_items[idx];
- volk_32fc_deinterleave_64f_x2_u(&d_residbufs[n][d_index],
- &d_residbufs[n+1][d_index],
- &in[trigger_index], datasize);
-
- uint64_t nr = nitems_read(idx);
- std::vector<gr::tag_t> tags;
- get_tags_in_range(tags, idx, nr + trigger_index,
- nr + trigger_index + datasize);
-
- for(size_t t = 0; t < tags.size(); t++) {
- tags[t].offset = tags[t].offset - (nr + trigger_index) + d_index;
- }
- d_tags[idx].insert(d_tags[idx].end(), tags.begin(), tags.end());
-
- idx++;
- }
- d_index += datasize;
- trigger_index += datasize;
- }
- }
+ // If we've filled up the buffers but haven't triggered, reset.
+ if(d_index == d_end) {
+ _reset();
}
- return trigger_index;
+ return nitems;
}
} /* namespace qtgui */
diff --git a/gr-qtgui/lib/time_sink_c_impl.h b/gr-qtgui/lib/time_sink_c_impl.h
index 9353a96802..6fe8c9c2bd 100644
--- a/gr-qtgui/lib/time_sink_c_impl.h
+++ b/gr-qtgui/lib/time_sink_c_impl.h
@@ -38,13 +38,13 @@ namespace gr {
gr::thread::mutex d_mutex;
- int d_size;
+ int d_size, d_buffer_size;
double d_samp_rate;
std::string d_name;
int d_nconnections;
- int d_index;
- std::vector<double*> d_residbufs;
+ int d_index, d_start, d_end;
+ std::vector<double*> d_buffers;
std::vector< std::vector<gr::tag_t> > d_tags;
QWidget *d_parent;
@@ -53,8 +53,6 @@ namespace gr {
gr::high_res_timer_type d_update_time;
gr::high_res_timer_type d_last_time;
- void _npoints_resize();
-
// Members used for triggering scope
trigger_mode d_trigger_mode;
trigger_slope d_trigger_slope;
@@ -66,8 +64,13 @@ namespace gr {
int d_trigger_count;
int d_initial_delay; // used for limiting d_trigger_delay
- bool _test_trigger_slope(const gr_complex *in) const;
+ void _reset();
+ void _npoints_resize();
+ void _adjust_tags(int adj);
void _gui_update_trigger();
+ void _test_trigger_tags(int nitems);
+ void _test_trigger_norm(int nitems, gr_vector_const_void_star inputs);
+ bool _test_trigger_slope(const gr_complex *in) const;
public:
time_sink_c_impl(int size, double samp_rate,
diff --git a/gr-qtgui/lib/time_sink_f_impl.cc b/gr-qtgui/lib/time_sink_f_impl.cc
index e3c385288f..85f9dc4fdd 100644
--- a/gr-qtgui/lib/time_sink_f_impl.cc
+++ b/gr-qtgui/lib/time_sink_f_impl.cc
@@ -53,16 +53,14 @@ namespace gr {
: sync_block("time_sink_f",
io_signature::make(nconnections, nconnections, sizeof(float)),
io_signature::make(0, 0, 0)),
- d_size(size), d_samp_rate(samp_rate), d_name(name),
+ d_size(size), d_buffer_size(2*size), d_samp_rate(samp_rate), d_name(name),
d_nconnections(nconnections), d_parent(parent)
{
d_main_gui = NULL;
- d_index = 0;
-
- for(int i = 0; i < d_nconnections; i++) {
- d_residbufs.push_back(fft::malloc_double(d_size));
- memset(d_residbufs[i], 0, d_size*sizeof(double));
+ for(int n = 0; n < d_nconnections; n++) {
+ d_buffers.push_back(fft::malloc_double(d_buffer_size));
+ memset(d_buffers[n], 0, d_buffer_size*sizeof(double));
}
// Set alignment properties for VOLK
@@ -74,10 +72,11 @@ namespace gr {
initialize();
- d_size += 1; // trick the next line into updating
- set_nsamps(size);
- set_trigger_mode(TRIG_MODE_AUTO, TRIG_SLOPE_POS, 0, 0, 0);
- d_initial_delay = d_trigger_delay;
+ d_main_gui->setNPoints(d_size); // setup GUI box with size
+ set_trigger_mode(TRIG_MODE_FREE, TRIG_SLOPE_POS, 0, 0, 0);
+
+ set_history(2); // so we can look ahead for the trigger slope
+ declare_sample_delay(1); // delay the tags for a history of 2
}
time_sink_f_impl::~time_sink_f_impl()
@@ -86,8 +85,8 @@ namespace gr {
d_main_gui->close();
// d_main_gui is a qwidget destroyed with its parent
- for(int i = 0; i < d_nconnections; i++) {
- fft::free(d_residbufs[i]);
+ for(int n = 0; n < d_nconnections; n++) {
+ fft::free(d_buffers[n]);
}
}
@@ -202,6 +201,8 @@ namespace gr {
float delay, int channel,
const std::string &tag_key)
{
+ gr::thread::scoped_lock lock(d_mutex);
+
d_trigger_mode = mode;
d_trigger_slope = slope;
d_trigger_level = level;
@@ -211,10 +212,11 @@ namespace gr {
d_triggered = false;
d_trigger_count = 0;
- if(d_trigger_delay >= d_size) {
- GR_LOG_WARN(d_logger, boost::format("Trigger delay (%1%) outside of display range (%2%).") \
- % d_trigger_delay % d_size);
- d_trigger_delay = d_size-1;
+ if((d_trigger_delay < 0) || (d_trigger_delay >= d_size)) {
+ GR_LOG_WARN(d_logger, boost::format("Trigger delay (%1%) outside of display range (0:%2%).") \
+ % (d_trigger_delay/d_samp_rate) % ((d_size-1)/d_samp_rate));
+ d_trigger_delay = std::max(0, std::min(d_size-1, d_trigger_delay));
+ delay = d_trigger_delay/d_samp_rate;
}
d_main_gui->setTriggerMode(d_trigger_mode);
@@ -224,8 +226,7 @@ namespace gr {
d_main_gui->setTriggerChannel(d_trigger_channel);
d_main_gui->setTriggerTagKey(tag_key);
- set_history(d_trigger_delay + 2);
- declare_sample_delay(d_trigger_delay+1);
+ _reset();
}
void
@@ -279,23 +280,31 @@ namespace gr {
void
time_sink_f_impl::set_nsamps(const int newsize)
{
- gr::thread::scoped_lock lock(d_mutex);
-
if(newsize != d_size) {
- // Resize residbuf and replace data
- for(int i = 0; i < d_nconnections; i++) {
- fft::free(d_residbufs[i]);
- d_residbufs[i] = fft::malloc_double(newsize);
-
- memset(d_residbufs[i], 0, newsize*sizeof(double));
- }
+ gr::thread::scoped_lock lock(d_mutex);
// Set new size and reset buffer index
// (throws away any currently held data, but who cares?)
d_size = newsize;
- d_index = 0;
+ d_buffer_size = 2*d_size;
+
+ // Resize buffers and replace data
+ for(int n = 0; n < d_nconnections; n++) {
+ fft::free(d_buffers[n]);
+ d_buffers[n] = fft::malloc_double(d_buffer_size);
+ memset(d_buffers[n], 0, d_buffer_size*sizeof(double));
+ }
+
+ // If delay was set beyond the new boundary, pull it back.
+ if(d_trigger_delay >= d_size) {
+ GR_LOG_WARN(d_logger, boost::format("Trigger delay (%1%) outside of display range (0:%2%). Moving to 50%% point.") \
+ % (d_trigger_delay/d_samp_rate) % ((d_size-1)/d_samp_rate));
+ d_trigger_delay = d_size-1;
+ d_main_gui->setTriggerDelay(d_trigger_delay/d_samp_rate);
+ }
d_main_gui->setNPoints(d_size);
+ _reset();
}
}
@@ -364,7 +373,57 @@ namespace gr {
void
time_sink_f_impl::reset()
{
- d_index = 0;
+ gr::thread::scoped_lock lock(d_mutex);
+ _reset();
+ }
+
+ void
+ time_sink_f_impl::_reset()
+ {
+ // Move the tail of the buffers to the front. This section
+ // represents data that might have to be plotted again if a
+ // trigger occurs and we have a trigger delay set. The tail
+ // section is between (d_end-d_trigger_delay) and d_end.
+ int n;
+ if(d_trigger_delay) {
+ for(n = 0; n < d_nconnections; n++) {
+ memmove(d_buffers[n], &d_buffers[n][d_size-d_trigger_delay], d_trigger_delay*sizeof(double));
+ }
+
+ // Also move the offsets of any tags that occur in the tail
+ // section so they would be plotted again, too.
+ for(n = 0; n < d_nconnections; n++) {
+ std::vector<gr::tag_t> tmp_tags;
+ for(size_t t = 0; t < d_tags[n].size(); t++) {
+ if(d_tags[n][t].offset > (d_size - d_trigger_delay)) {
+ d_tags[n][t].offset = d_tags[n][t].offset - (d_size - d_trigger_delay);
+ tmp_tags.push_back(d_tags[n][t]);
+ }
+ }
+ d_tags[n] = tmp_tags;
+ }
+ }
+ // Otherwise, just clear the local list of tags.
+ else {
+ for(n = 0; n < d_nconnections; n++) {
+ d_tags[n].clear();
+ }
+ }
+
+ // Reset the start and end indices.
+ d_start = 0;
+ d_end = d_size;
+
+ // Reset the trigger. If in free running mode, ignore the
+ // trigger delay and always set trigger to true.
+ if(d_trigger_mode == TRIG_MODE_FREE) {
+ d_index = 0;
+ d_triggered = true;
+ }
+ else {
+ d_index = d_trigger_delay;
+ d_triggered = false;
+ }
}
void
@@ -375,55 +434,94 @@ namespace gr {
}
void
+ time_sink_f_impl::_adjust_tags(int adj)
+ {
+ for(size_t n = 0; n < d_tags.size(); n++) {
+ for(size_t t = 0; t < d_tags[n].size(); t++) {
+ d_tags[n][t].offset += adj;
+ }
+ }
+ }
+
+ void
time_sink_f_impl::_gui_update_trigger()
{
d_trigger_mode = d_main_gui->getTriggerMode();
d_trigger_slope = d_main_gui->getTriggerSlope();
d_trigger_level = d_main_gui->getTriggerLevel();
d_trigger_channel = d_main_gui->getTriggerChannel();
+ d_trigger_count = 0;
float delayf = d_main_gui->getTriggerDelay();
int delay = static_cast<int>(delayf*d_samp_rate);
if(delay != d_trigger_delay) {
// We restrict the delay to be within the window of time being
- // plotted. This also restrict it to be less than the number
- // of output items since we cannot set the history greater
- // than this. We can probably get around this latter part by
- // not using history and doing more work inside 'work' to keep
- // track of things.
- int maxn;
-
- // If we have built the detail and buffers, we're stuck with
- // the max number of item; otherwise the buffer will be built
- // around this value so we just don't want to go over d_size.
- int correction = 5; // give us a bit of room at the edge.
- block_detail_sptr d = detail();
- if(d) {
- int max_possible = d->input(d_trigger_channel)->max_possible_items_available()/2 - d_initial_delay;
- maxn = std::max(1, std::min(max_possible, d_size) - correction);
- }
- else {
- maxn = d_size-correction;
- d_initial_delay = d_trigger_delay; // store this value before we create a d_detail
- }
-
- if(delay > maxn) {
- GR_LOG_WARN(d_logger, boost::format("Trigger delay (%1% / %2% sec) outside of max range (%3% / %4% sec)") \
- % delay % delayf % maxn % (maxn/d_samp_rate));
- delay = maxn - d_initial_delay;
+ // plotted.
+ if((delay < 0) || (delay >= d_size)) {
+ GR_LOG_WARN(d_logger, boost::format("Trigger delay (%1%) outside of display range (0:%2%).") \
+ % (delay/d_samp_rate) % ((d_size-1)/d_samp_rate));
+ delay = std::max(0, std::min(d_size-1, delay));
delayf = delay/d_samp_rate;
}
d_trigger_delay = delay;
d_main_gui->setTriggerDelay(delayf);
- set_history(d_trigger_delay+1);
+ _reset();
}
std::string tagkey = d_main_gui->getTriggerTagKey();
d_trigger_tag_key = pmt::intern(tagkey);
}
+ void
+ time_sink_f_impl::_test_trigger_tags(int nitems)
+ {
+ int trigger_index;
+
+ uint64_t nr = nitems_read(d_trigger_channel);
+ std::vector<gr::tag_t> tags;
+ get_tags_in_range(tags, d_trigger_channel,
+ nr, nr + nitems,
+ d_trigger_tag_key);
+ if(tags.size() > 0) {
+ d_triggered = true;
+ trigger_index = tags[0].offset - nr;
+ d_start = d_index + trigger_index - d_trigger_delay - 1;
+ d_end = d_start + d_size;
+ d_trigger_count = 0;
+ _adjust_tags(-d_start);
+ }
+ }
+
+ void
+ time_sink_f_impl::_test_trigger_norm(int nitems, gr_vector_const_void_star inputs)
+ {
+ int trigger_index;
+ const float *in = (const float*)inputs[d_trigger_channel];
+ for(trigger_index = 0; trigger_index < nitems; trigger_index++) {
+ d_trigger_count++;
+
+ // Test if trigger has occurred based on the input stream,
+ // channel number, and slope direction
+ if(_test_trigger_slope(&in[trigger_index])) {
+ d_triggered = true;
+ d_start = d_index + trigger_index - d_trigger_delay;
+ d_end = d_start + d_size;
+ d_trigger_count = 0;
+ _adjust_tags(-d_start);
+ break;
+ }
+ }
+
+ // If using auto trigger mode, trigger periodically even
+ // without a trigger event.
+ if((d_trigger_mode == TRIG_MODE_AUTO) && (d_trigger_count > d_size)) {
+ d_triggered = true;
+ d_trigger_count = 0;
+ }
+ }
+
bool
time_sink_f_impl::_test_trigger_slope(const float *in) const
{
@@ -443,132 +541,69 @@ namespace gr {
gr_vector_void_star &output_items)
{
int n=0, idx=0;
- int trigger_index=0;
const float *in;
_npoints_resize();
_gui_update_trigger();
- for(int i=0; i < noutput_items; i+=d_size) {
-
- // If auto or normal trigger, look for the trigger
- trigger_index = i;
- if((d_trigger_mode != TRIG_MODE_FREE) && !d_triggered) {
-
- if(d_trigger_mode == TRIG_MODE_TAG) {
- uint64_t nr = nitems_read(d_trigger_channel/2);
-
- // Look for tags past the delay so we can subtract delay
- // to calculate the trigger_index without it going
- // negative.
- std::vector<gr::tag_t> tags;
- get_tags_in_range(tags, d_trigger_channel/2,
- nr + trigger_index + d_trigger_delay,
- nr + trigger_index + d_trigger_delay + noutput_items,
- d_trigger_tag_key);
- if(tags.size() > 0) {
- d_index = 0;
- d_triggered = true;
- d_trigger_count = 0;
- trigger_index = tags[0].offset - nr - trigger_index - d_trigger_delay;
- break;
- }
- else
- trigger_index = noutput_items;
- }
- else {
- for(; trigger_index < noutput_items; trigger_index++) {
- d_trigger_count++;
-
- // Test if trigger has occurred based on the input stream,
- // channel number, and slope direction
- in = (const float*)input_items[d_trigger_channel];
- if(_test_trigger_slope(&in[trigger_index + d_trigger_delay])) {
- d_triggered = true;
- d_trigger_count = 0;
- break;
- }
- }
-
- // If using auto trigger mode, trigger periodically even
- // without a trigger event.
- if((d_trigger_mode == TRIG_MODE_AUTO) && (d_trigger_count > d_size)) {
- d_triggered = true;
- d_trigger_count = 0;
- }
- }
-
- i = trigger_index;
- }
-
- unsigned int datasize = noutput_items - trigger_index;
- unsigned int resid = d_size-d_index;
- idx = 0;
-
- // If we're in trigger mode, test if we have triggered
- if((d_trigger_mode == TRIG_MODE_FREE) || d_triggered) {
- // If we have enough input for one full plot, do it
- if(datasize >= resid) {
- // Fill up residbufs with d_size number of items
- for(n = 0; n < d_nconnections; n++) {
- in = (const float*)input_items[idx];
- volk_32f_convert_64f_u(&d_residbufs[n][d_index],
- &in[trigger_index], resid);
-
- uint64_t nr = nitems_read(idx);
- std::vector<gr::tag_t> tags;
- get_tags_in_range(tags, idx, nr + trigger_index,
- nr + trigger_index + resid);
- for(size_t t = 0; t < tags.size(); t++) {
- tags[t].offset = tags[t].offset - (nr + trigger_index) + d_index;
- }
- d_tags[idx].insert(d_tags[idx].end(), tags.begin(), tags.end());
-
- idx++;
- }
+ gr::thread::scoped_lock lock(d_mutex);
- // Update the plot if it's time
- if(gr::high_res_timer_now() - d_last_time > d_update_time) {
- d_last_time = gr::high_res_timer_now();
- d_qApplication->postEvent(d_main_gui,
- new TimeUpdateEvent(d_residbufs, d_size, d_tags));
- }
+ int nfill = d_end - d_index; // how much room left in buffers
+ int nitems = std::min(noutput_items, nfill); // num items we can put in buffers
- d_index = 0;
- trigger_index += resid;
- d_triggered = false;
+ // If auto, normal, or tag trigger, look for the trigger
+ if((d_trigger_mode != TRIG_MODE_FREE) && !d_triggered) {
+ // trigger off a tag key (first one found)
+ if(d_trigger_mode == TRIG_MODE_TAG) {
+ _test_trigger_tags(nitems);
+ }
+ // Normal or Auto trigger
+ else {
+ _test_trigger_norm(nitems, input_items);
+ }
+ }
- for(n = 0; n < d_nconnections; n++) {
- d_tags[n].clear();
- }
- }
+ // Copy data into the buffers.
+ for(n = 0; n < d_nconnections; n++) {
+ in = (const float*)input_items[idx];
+ volk_32f_convert_64f(&d_buffers[n][d_index],
+ &in[0], nitems);
+
+ uint64_t nr = nitems_read(idx);
+ std::vector<gr::tag_t> tags;
+ get_tags_in_range(tags, idx, nr, nr + nitems);
+ for(size_t t = 0; t < tags.size(); t++) {
+ tags[t].offset = tags[t].offset - nr + (d_index-d_start);
+ }
+ d_tags[idx].insert(d_tags[idx].end(), tags.begin(), tags.end());
+ idx++;
+ }
+ d_index += nitems;
- // Otherwise, copy what we received into the residbufs for next time
- else {
- for(n = 0; n < d_nconnections; n++) {
- in = (const float*)input_items[idx];
- volk_32f_convert_64f_u(&d_residbufs[n][d_index],
- &in[trigger_index], datasize);
+ // If we've have a trigger and a full d_size of items in the buffers, plot.
+ if((d_triggered) && (d_index == d_end)) {
+ // Copy data to be plotted to start of buffers.
+ for(n = 0; n < d_nconnections; n++) {
+ memmove(d_buffers[n], &d_buffers[n][d_start], d_size*sizeof(double));
+ }
- uint64_t nr = nitems_read(idx);
- std::vector<gr::tag_t> tags;
- get_tags_in_range(tags, idx, nr + trigger_index,
- nr + trigger_index + datasize);
+ // Plot if we are able to update
+ if(gr::high_res_timer_now() - d_last_time > d_update_time) {
+ d_last_time = gr::high_res_timer_now();
+ d_qApplication->postEvent(d_main_gui,
+ new TimeUpdateEvent(d_buffers, d_size, d_tags));
+ }
- for(size_t t = 0; t < tags.size(); t++) {
- tags[t].offset = tags[t].offset - (nr + trigger_index) + d_index;
- }
- d_tags[idx].insert(d_tags[idx].end(), tags.begin(), tags.end());
+ // We've plotting, so reset the state
+ _reset();
+ }
- idx++;
- }
- d_index += datasize;
- trigger_index += datasize;
- }
- }
+ // If we've filled up the buffers but haven't triggered, reset.
+ if(d_index == d_end) {
+ _reset();
}
- return trigger_index;
+ return nitems;
}
} /* namespace qtgui */
diff --git a/gr-qtgui/lib/time_sink_f_impl.h b/gr-qtgui/lib/time_sink_f_impl.h
index 87ffe39850..7a203b742a 100644
--- a/gr-qtgui/lib/time_sink_f_impl.h
+++ b/gr-qtgui/lib/time_sink_f_impl.h
@@ -38,13 +38,13 @@ namespace gr {
gr::thread::mutex d_mutex;
- int d_size;
+ int d_size, d_buffer_size;
double d_samp_rate;
std::string d_name;
int d_nconnections;
- int d_index;
- std::vector<double*> d_residbufs;
+ int d_index, d_start, d_end;
+ std::vector<double*> d_buffers;
std::vector< std::vector<gr::tag_t> > d_tags;
QWidget *d_parent;
@@ -53,8 +53,6 @@ namespace gr {
gr::high_res_timer_type d_update_time;
gr::high_res_timer_type d_last_time;
- void _npoints_resize();
-
// Members used for triggering scope
trigger_mode d_trigger_mode;
trigger_slope d_trigger_slope;
@@ -66,8 +64,13 @@ namespace gr {
int d_trigger_count;
int d_initial_delay; // used for limiting d_trigger_delay
- bool _test_trigger_slope(const float *in) const;
+ void _reset();
+ void _npoints_resize();
+ void _adjust_tags(int adj);
void _gui_update_trigger();
+ void _test_trigger_tags(int nitems);
+ void _test_trigger_norm(int nitems, gr_vector_const_void_star inputs);
+ bool _test_trigger_slope(const float *in) const;
public:
time_sink_f_impl(int size, double samp_rate,
@@ -90,7 +93,7 @@ namespace gr {
void set_line_width(int which, int width);
void set_line_style(int which, int style);
void set_line_marker(int which, int marker);
- void set_nsamps(const int newsize);
+ void set_nsamps(const int size);
void set_samp_rate(const double samp_rate);
void set_line_alpha(int which, double alpha);
void set_trigger_mode(trigger_mode mode, trigger_slope slope,