commit-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commit-gnuradio] [gnuradio] 01/05: qtgui: adding a trigger for the cons


From: git
Subject: [Commit-gnuradio] [gnuradio] 01/05: qtgui: adding a trigger for the constellation plots. Probably most useful with tags, but normal and auto triggering supported, too.
Date: Fri, 25 Apr 2014 16:44:46 +0000 (UTC)

This is an automated email from the git hooks/post-receive script.

trondeau pushed a commit to branch master
in repository gnuradio.

commit d78d1ce2069ae20c86f9f301d89f303c2ae5942e
Author: Tom Rondeau <address@hidden>
Date:   Thu Apr 24 14:10:26 2014 -0400

    qtgui: adding a trigger for the constellation plots. Probably most useful 
with tags, but normal and auto triggering supported, too.
    
    Updates test_corr_and_sync block to use the time_est tag to trigger 
constellation plot.
---
 gr-digital/examples/demod/test_corr_and_sync.grc   | 176 +++++++------
 gr-qtgui/grc/qtgui_const_sink_x.xml                |  79 ++++++
 gr-qtgui/include/gnuradio/qtgui/const_sink_c.h     |  41 +++-
 .../gnuradio/qtgui/constellationdisplayform.h      |  31 ++-
 gr-qtgui/include/gnuradio/qtgui/time_sink_c.h      |  49 +++-
 gr-qtgui/include/gnuradio/qtgui/time_sink_f.h      |  41 +++-
 gr-qtgui/lib/const_sink_c_impl.cc                  | 272 +++++++++++++++------
 gr-qtgui/lib/const_sink_c_impl.h                   |  27 +-
 gr-qtgui/lib/constellationdisplayform.cc           | 138 ++++++++++-
 gr-qtgui/lib/time_sink_c_impl.cc                   |   2 +-
 10 files changed, 692 insertions(+), 164 deletions(-)

diff --git a/gr-digital/examples/demod/test_corr_and_sync.grc 
b/gr-digital/examples/demod/test_corr_and_sync.grc
index 8701690..496a0be 100644
--- a/gr-digital/examples/demod/test_corr_and_sync.grc
+++ b/gr-digital/examples/demod/test_corr_and_sync.grc
@@ -1,6 +1,6 @@
 <?xml version='1.0' encoding='ASCII'?>
 <flow_graph>
-  <timestamp>Thu Apr 10 15:34:59 2014</timestamp>
+  <timestamp>Thu Apr 24 14:08:23 2014</timestamp>
   <block>
     <key>options</key>
     <param>
@@ -64,30 +64,7 @@
     <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>100000</value>
-    </param>
-    <param>
-      <key>_coordinate</key>
-      <value>(11, 72)</value>
-    </param>
-    <param>
-      <key>_rotation</key>
-      <value>0</value>
-    </param>
-  </block>
-  <block>
-    <key>variable</key>
-    <param>
-      <key>id</key>
-      <value>eb</value>
+      <value>rrc_taps</value>
     </param>
     <param>
       <key>_enabled</key>
@@ -95,11 +72,11 @@
     </param>
     <param>
       <key>value</key>
-      <value>0.35</value>
+      <value>firdes.root_raised_cosine(nfilts, nfilts, 1.0/float(sps), eb, 
5*sps*nfilts)</value>
     </param>
     <param>
       <key>_coordinate</key>
-      <value>(346, 72)</value>
+      <value>(1075, 73)</value>
     </param>
     <param>
       <key>_rotation</key>
@@ -110,7 +87,7 @@
     <key>variable</key>
     <param>
       <key>id</key>
-      <value>matched_filter</value>
+      <value>nfilts</value>
     </param>
     <param>
       <key>_enabled</key>
@@ -118,11 +95,11 @@
     </param>
     <param>
       <key>value</key>
-      <value>firdes.root_raised_cosine(nfilts, nfilts, 1, eb, 
int(11*sps*nfilts))</value>
+      <value>32</value>
     </param>
     <param>
       <key>_coordinate</key>
-      <value>(429, 72)</value>
+      <value>(1074, 9)</value>
     </param>
     <param>
       <key>_rotation</key>
@@ -133,7 +110,7 @@
     <key>variable</key>
     <param>
       <key>id</key>
-      <value>preamble</value>
+      <value>payload_size</value>
     </param>
     <param>
       <key>_enabled</key>
@@ -141,11 +118,11 @@
     </param>
     <param>
       <key>value</key>
-      
<value>[1,-1,1,-1,1,1,-1,-1,1,1,-1,1,1,1,-1,1,1,-1,1,-1,-1,1,-1,-1,1,1,1,-1,-1,-1,1,-1,1,1,1,1,-1,-1,1,-1,1,-1,-1,-1,1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,1,1,1,-1,-1]</value>
+      <value>992</value>
     </param>
     <param>
       <key>_coordinate</key>
-      <value>(279, 8)</value>
+      <value>(101, 73)</value>
     </param>
     <param>
       <key>_rotation</key>
@@ -156,7 +133,7 @@
     <key>variable</key>
     <param>
       <key>id</key>
-      <value>sps</value>
+      <value>gap</value>
     </param>
     <param>
       <key>_enabled</key>
@@ -164,11 +141,11 @@
     </param>
     <param>
       <key>value</key>
-      <value>4</value>
+      <value>20000</value>
     </param>
     <param>
       <key>_coordinate</key>
-      <value>(278, 72)</value>
+      <value>(202, 72)</value>
     </param>
     <param>
       <key>_rotation</key>
@@ -202,7 +179,7 @@
     <key>variable</key>
     <param>
       <key>id</key>
-      <value>gap</value>
+      <value>sps</value>
     </param>
     <param>
       <key>_enabled</key>
@@ -210,11 +187,11 @@
     </param>
     <param>
       <key>value</key>
-      <value>20000</value>
+      <value>4</value>
     </param>
     <param>
       <key>_coordinate</key>
-      <value>(202, 72)</value>
+      <value>(278, 72)</value>
     </param>
     <param>
       <key>_rotation</key>
@@ -225,7 +202,7 @@
     <key>variable</key>
     <param>
       <key>id</key>
-      <value>payload_size</value>
+      <value>preamble</value>
     </param>
     <param>
       <key>_enabled</key>
@@ -233,11 +210,11 @@
     </param>
     <param>
       <key>value</key>
-      <value>992</value>
+      
<value>[1,-1,1,-1,1,1,-1,-1,1,1,-1,1,1,1,-1,1,1,-1,1,-1,-1,1,-1,-1,1,1,1,-1,-1,-1,1,-1,1,1,1,1,-1,-1,1,-1,1,-1,-1,-1,1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,1,1,1,-1,-1]</value>
     </param>
     <param>
       <key>_coordinate</key>
-      <value>(101, 73)</value>
+      <value>(279, 8)</value>
     </param>
     <param>
       <key>_rotation</key>
@@ -248,7 +225,7 @@
     <key>variable</key>
     <param>
       <key>id</key>
-      <value>nfilts</value>
+      <value>matched_filter</value>
     </param>
     <param>
       <key>_enabled</key>
@@ -256,11 +233,11 @@
     </param>
     <param>
       <key>value</key>
-      <value>32</value>
+      <value>firdes.root_raised_cosine(nfilts, nfilts, 1, eb, 
int(11*sps*nfilts))</value>
     </param>
     <param>
       <key>_coordinate</key>
-      <value>(1074, 9)</value>
+      <value>(429, 72)</value>
     </param>
     <param>
       <key>_rotation</key>
@@ -271,7 +248,7 @@
     <key>variable</key>
     <param>
       <key>id</key>
-      <value>rrc_taps</value>
+      <value>eb</value>
     </param>
     <param>
       <key>_enabled</key>
@@ -279,11 +256,11 @@
     </param>
     <param>
       <key>value</key>
-      <value>firdes.root_raised_cosine(nfilts, nfilts, 1.0/float(sps), eb, 
5*sps*nfilts)</value>
+      <value>0.35</value>
     </param>
     <param>
       <key>_coordinate</key>
-      <value>(1075, 73)</value>
+      <value>(346, 72)</value>
     </param>
     <param>
       <key>_rotation</key>
@@ -291,38 +268,22 @@
     </param>
   </block>
   <block>
-    <key>digital_costas_loop_cc</key>
+    <key>variable</key>
     <param>
       <key>id</key>
-      <value>digital_costas_loop_cc_0</value>
+      <value>samp_rate</value>
     </param>
     <param>
       <key>_enabled</key>
       <value>True</value>
     </param>
     <param>
-      <key>w</key>
-      <value>1*3.14/50.0</value>
-    </param>
-    <param>
-      <key>order</key>
-      <value>2</value>
-    </param>
-    <param>
-      <key>affinity</key>
-      <value></value>
-    </param>
-    <param>
-      <key>minoutbuf</key>
-      <value>0</value>
-    </param>
-    <param>
-      <key>maxoutbuf</key>
-      <value>0</value>
+      <key>value</key>
+      <value>100000</value>
     </param>
     <param>
       <key>_coordinate</key>
-      <value>(1091, 303)</value>
+      <value>(11, 72)</value>
     </param>
     <param>
       <key>_rotation</key>
@@ -2611,10 +2572,49 @@
     </param>
   </block>
   <block>
+    <key>digital_costas_loop_cc</key>
+    <param>
+      <key>id</key>
+      <value>digital_costas_loop_cc_0</value>
+    </param>
+    <param>
+      <key>_enabled</key>
+      <value>True</value>
+    </param>
+    <param>
+      <key>w</key>
+      <value>1*3.14/50.0</value>
+    </param>
+    <param>
+      <key>order</key>
+      <value>2</value>
+    </param>
+    <param>
+      <key>affinity</key>
+      <value></value>
+    </param>
+    <param>
+      <key>minoutbuf</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>maxoutbuf</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>_coordinate</key>
+      <value>(1091, 303)</value>
+    </param>
+    <param>
+      <key>_rotation</key>
+      <value>0</value>
+    </param>
+  </block>
+  <block>
     <key>qtgui_const_sink_x</key>
     <param>
       <key>id</key>
-      <value>qtgui_const_sink_x_0_0</value>
+      <value>qtgui_const_sink_x_0</value>
     </param>
     <param>
       <key>_enabled</key>
@@ -2630,7 +2630,7 @@
     </param>
     <param>
       <key>size</key>
-      <value>20000</value>
+      <value>1000</value>
     </param>
     <param>
       <key>autoscale</key>
@@ -2665,6 +2665,26 @@
       <value>0,1,1,1</value>
     </param>
     <param>
+      <key>tr_mode</key>
+      <value>qtgui.TRIG_MODE_TAG</value>
+    </param>
+    <param>
+      <key>tr_slope</key>
+      <value>qtgui.TRIG_SLOPE_POS</value>
+    </param>
+    <param>
+      <key>tr_level</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>tr_chan</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>tr_tag</key>
+      <value>time_est</value>
+    </param>
+    <param>
       <key>label1</key>
       <value></value>
     </param>
@@ -2910,7 +2930,7 @@
     </param>
     <param>
       <key>_coordinate</key>
-      <value>(1399, 291)</value>
+      <value>(1399, 283)</value>
     </param>
     <param>
       <key>_rotation</key>
@@ -2919,12 +2939,6 @@
   </block>
   <connection>
     <source_block_id>digital_costas_loop_cc_0</source_block_id>
-    <sink_block_id>qtgui_const_sink_x_0_0</sink_block_id>
-    <source_key>0</source_key>
-    <sink_key>0</sink_key>
-  </connection>
-  <connection>
-    <source_block_id>digital_costas_loop_cc_0</source_block_id>
     <sink_block_id>qtgui_time_sink_x_0</sink_block_id>
     <source_key>0</source_key>
     <sink_key>0</sink_key>
@@ -3097,4 +3111,10 @@
     <source_key>0</source_key>
     <sink_key>0</sink_key>
   </connection>
+  <connection>
+    <source_block_id>digital_costas_loop_cc_0</source_block_id>
+    <sink_block_id>qtgui_const_sink_x_0</sink_block_id>
+    <source_key>0</source_key>
+    <sink_key>0</sink_key>
+  </connection>
 </flow_graph>
diff --git a/gr-qtgui/grc/qtgui_const_sink_x.xml 
b/gr-qtgui/grc/qtgui_const_sink_x.xml
index 08f9064..3b549e2 100644
--- a/gr-qtgui/grc/qtgui_const_sink_x.xml
+++ b/gr-qtgui/grc/qtgui_const_sink_x.xml
@@ -19,6 +19,7 @@ qtgui.$(type.fcn)(
 self.$(id).set_update_time($update_time)
 self.$(id).set_y_axis($ymin, $ymax)
 self.$(id).set_x_axis($xmin, $xmax)
+self.$(id).set_trigger_mode($tr_mode, $tr_slope, $tr_level, $tr_chan, $tr_tag)
 self.$(id).enable_autoscale($autoscale)
 
 labels = [$label1, $label2, $label3, $label4, $label5,
@@ -51,6 +52,12 @@ $(gui_hint()($win))</make>
   <callback>set_title($which, $title)</callback>
   <callback>set_color($which, $color)</callback>
 
+  <param_tab_order>
+    <tab>General</tab>
+    <tab>Trigger</tab>
+    <tab>Config</tab>
+  </param_tab_order>
+
   <param>
     <name>Type</name>
     <key>type</key>
@@ -137,6 +144,78 @@ $(gui_hint()($win))</make>
     <hide>part</hide>
   </param>
 
+
+  <param>
+    <name>Trigger Mode</name>
+    <key>tr_mode</key>
+    <value>qtgui.TRIG_MODE_FREE</value>
+    <type>enum</type>
+    <hide>part</hide>
+    <option>
+      <name>Free</name>
+      <key>qtgui.TRIG_MODE_FREE</key>
+    </option>
+    <option>
+      <name>Auto</name>
+      <key>qtgui.TRIG_MODE_AUTO</key>
+    </option>
+    <option>
+      <name>Normal</name>
+      <key>qtgui.TRIG_MODE_NORM</key>
+    </option>
+    <option>
+      <name>Tag</name>
+      <key>qtgui.TRIG_MODE_TAG</key>
+    </option>
+    <tab>Trigger</tab>
+  </param>
+
+  <param>
+    <name>Trigger Slope</name>
+    <key>tr_slope</key>
+    <value>qtgui.TRIG_MODE_POS</value>
+    <type>enum</type>
+    <hide>part</hide>
+    <option>
+      <name>Positive</name>
+      <key>qtgui.TRIG_SLOPE_POS</key>
+    </option>
+    <option>
+      <name>Negative</name>
+      <key>qtgui.TRIG_SLOPE_NEG</key>
+    </option>
+    <tab>Trigger</tab>
+  </param>
+
+  <param>
+    <name>Trigger Level</name>
+    <key>tr_level</key>
+    <value>0.0</value>
+    <type>float</type>
+    <hide>part</hide>
+    <tab>Trigger</tab>
+  </param>
+
+  <param>
+    <name>Trigger Channel</name>
+    <key>tr_chan</key>
+    <value>0</value>
+    <type>int</type>
+    <hide>part</hide>
+    <tab>Trigger</tab>
+  </param>
+
+  <param>
+    <name>Trigger Tag Key</name>
+    <key>tr_tag</key>
+    <value>""</value>
+    <type>string</type>
+    <hide>part</hide>
+    <tab>Trigger</tab>
+  </param>
+
+
+
   <param>
     <name>Line 1 Label</name>
     <key>label1</key>
diff --git a/gr-qtgui/include/gnuradio/qtgui/const_sink_c.h 
b/gr-qtgui/include/gnuradio/qtgui/const_sink_c.h
index f413ce9..84f9a87 100644
--- a/gr-qtgui/include/gnuradio/qtgui/const_sink_c.h
+++ b/gr-qtgui/include/gnuradio/qtgui/const_sink_c.h
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2012 Free Software Foundation, Inc.
+ * Copyright 2012,2014 Free Software Foundation, Inc.
  *
  * This file is part of GNU Radio
  *
@@ -28,13 +28,14 @@
 #endif
 
 #include <gnuradio/qtgui/api.h>
+#include <gnuradio/qtgui/trigger_mode.h>
 #include <gnuradio/sync_block.h>
 #include <qapplication.h>
 #include <gnuradio/filter/firdes.h>
 
 namespace gr {
   namespace qtgui {
-    
+
     /*!
      * \brief A graphical sink to display the IQ constellation of multiple 
signals.
      * \ingroup instrumentation_blk
@@ -51,7 +52,7 @@ namespace gr {
       typedef boost::shared_ptr<const_sink_c> sptr;
 
       /*!
-       * \brief Build a complex PSD sink.
+       * \brief Build a constellation plot sink.
        *
        * \param size number of points to plot at once
        * \param name title for the plot
@@ -85,6 +86,40 @@ namespace gr {
       virtual void set_nsamps(const int newsize) = 0;
       virtual void set_line_alpha(int which, double alpha) = 0;
 
+      /*!
+       * Set up a trigger for the sink to know when to start
+       * plotting. Useful to isolate events and avoid noise.
+       *
+       * The trigger modes are Free, Auto, Normal, and Tag (see
+       * gr::qtgui::trigger_mode). The first three are like a normal
+       * oscope trigger function. Free means free running with no
+       * trigger, auto will trigger if the trigger event is seen, but
+       * will still plot otherwise, and normal will hold until the
+       * trigger event is observed. The Tag trigger mode allows us to
+       * trigger off a specific stream tag. The tag trigger is based
+       * only on the name of the tag, so when a tag of the given name
+       * is seen, the trigger is activated.
+       *
+       * In auto and normal mode, we look for the slope of the
+       * magnitude of the signal. As a constellation sink, this only
+       * takes in complex numbers to plot. Given a
+       * gr::qtgui::trigger_slope as either Positive or Negative, if
+       * the magnitude between two samples moves in the given
+       * direction (x[1] > x[0] for Positive or x[1] < x[0] for
+       * Negative), then the trigger is activated.
+       *
+       * \param mode The trigger_mode: free, auto, normal, or tag.
+       * \param slope The trigger_slope: positive or negative. Only
+       *              used for auto and normal modes.
+       * \param level The magnitude of the trigger even for auto or normal 
modes.
+       * \param channel Which input channel to use for the trigger events.
+       * \param tag_key The name (as a string) of the tag to trigger off
+       *                 of if using the tag mode.
+       */
+      virtual void set_trigger_mode(trigger_mode mode, trigger_slope slope,
+                                    float level, int channel,
+                                    const std::string &tag_key="") = 0;
+
       virtual std::string title() = 0;
       virtual std::string line_label(int which) = 0;
       virtual std::string line_color(int which) = 0;
diff --git a/gr-qtgui/include/gnuradio/qtgui/constellationdisplayform.h 
b/gr-qtgui/include/gnuradio/qtgui/constellationdisplayform.h
index fb14388..e75eac9 100644
--- a/gr-qtgui/include/gnuradio/qtgui/constellationdisplayform.h
+++ b/gr-qtgui/include/gnuradio/qtgui/constellationdisplayform.h
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2012 Free Software Foundation, Inc.
+ * Copyright 2012,2014 Free Software Foundation, Inc.
  *
  * This file is part of GNU Radio
  *
@@ -46,6 +46,11 @@ public:
   ConstellationDisplayPlot* getPlot();
 
   int getNPoints() const;
+  gr::qtgui::trigger_mode getTriggerMode() const;
+  gr::qtgui::trigger_slope getTriggerSlope() const;
+  float getTriggerLevel() const;
+  int getTriggerChannel() const;
+  std::string getTriggerTagKey() const;
 
 public slots:
   void customEvent(QEvent * e);
@@ -56,12 +61,36 @@ public slots:
   void setXaxis(double min, double max);
   void autoScale(bool en);
 
+  void updateTrigger(gr::qtgui::trigger_mode mode);
+  void setTriggerMode(gr::qtgui::trigger_mode mode);
+  void setTriggerSlope(gr::qtgui::trigger_slope slope);
+  void setTriggerLevel(QString s);
+  void setTriggerLevel(float level);
+  void setTriggerChannel(int chan);
+  void setTriggerTagKey(QString s);
+  void setTriggerTagKey(const std::string &s);
+
 private slots:
   void newData(const QEvent*);
 
 private:
   QIntValidator* d_int_validator;
   int d_npoints;
+
+  NPointsMenu *d_nptsmenu;
+
+  QMenu *d_triggermenu;
+  TriggerModeMenu *d_tr_mode_menu;
+  TriggerSlopeMenu *d_tr_slope_menu;
+  PopupMenu *d_tr_level_act;
+  TriggerChannelMenu *d_tr_channel_menu;
+  PopupMenu *d_tr_tag_key_act;
+
+  gr::qtgui::trigger_mode d_trig_mode;
+  gr::qtgui::trigger_slope d_trig_slope;
+  float d_trig_level;
+  int d_trig_channel;
+  std::string d_trig_tag_key;
 };
 
 #endif /* CONSTELLATION_DISPLAY_FORM_H */
diff --git a/gr-qtgui/include/gnuradio/qtgui/time_sink_c.h 
b/gr-qtgui/include/gnuradio/qtgui/time_sink_c.h
index 2d52485..8ce6e2e 100644
--- a/gr-qtgui/include/gnuradio/qtgui/time_sink_c.h
+++ b/gr-qtgui/include/gnuradio/qtgui/time_sink_c.h
@@ -34,7 +34,7 @@
 
 namespace gr {
   namespace qtgui {
-    
+
     /*!
      * \brief A graphical sink to display multiple signals in time.
      * \ingroup instrumentation_blk
@@ -88,6 +88,53 @@ namespace gr {
       virtual void set_nsamps(const int newsize) = 0;
       virtual void set_samp_rate(const double samp_rate) = 0;
       virtual void set_line_alpha(int which, double alpha) = 0;
+
+      /*!
+       * Set up a trigger for the sink to know when to start
+       * plotting. Useful to isolate events and avoid noise.
+       *
+       * The trigger modes are Free, Auto, Normal, and Tag (see
+       * gr::qtgui::trigger_mode). The first three are like a normal
+       * oscope trigger function. Free means free running with no
+       * trigger, auto will trigger if the trigger event is seen, but
+       * will still plot otherwise, and normal will hold until the
+       * trigger event is observed. The Tag trigger mode allows us to
+       * trigger off a specific stream tag. The tag trigger is based
+       * only on the name of the tag, so when a tag of the given name
+       * is seen, the trigger is activated.
+       *
+       * In auto and normal mode, we look for the slope of the of the
+       * signal. Given a gr::qtgui::trigger_slope as either Positive
+       * or Negative, if the value between two samples moves in the
+       * given direction (x[1] > x[0] for Positive or x[1] < x[0] for
+       * Negative), then the trigger is activated.
+       *
+       * With the complex time sink, each input has two lines drawn
+       * for the real and imaginary parts of the signal. When
+       * selecting the \p channel value, channel 0 is the real signal
+       * and channel 1 is the imaginary signal. For more than 1 input
+       * stream, channel 2i is the real part of the ith input and
+       * channel (2i+1) is the imaginary part of the ith input
+       * channel.
+       *
+       * The \p delay value is specified in time based off the sample
+       * rate. If the sample rate of the block is set to 1, the delay
+       * is then also the sample number offset. This is the offset
+       * from the left-hand y-axis of the plot. It delays the signal
+       * to show the trigger event at the given delay along with some
+       * portion of the signal before the event. The delay must be
+       * within 0 - t_max where t_max is the maximum amount of time
+       * displayed on the time plot.
+       *
+       * \param mode The trigger_mode: free, auto, normal, or tag.
+       * \param slope The trigger_slope: positive or negative. Only
+       *              used for auto and normal modes.
+       * \param level The magnitude of the trigger even for auto or normal 
modes.
+       * \param delay The delay (in units of time) for where the trigger 
happens.
+       * \param channel Which input channel to use for the trigger events.
+       * \param tag_key The name (as a string) of the tag to trigger off
+       *                 of if using the tag mode.
+       */
       virtual void set_trigger_mode(trigger_mode mode, trigger_slope slope,
                                     float level, float delay, int channel,
                                     const std::string &tag_key="") = 0;
diff --git a/gr-qtgui/include/gnuradio/qtgui/time_sink_f.h 
b/gr-qtgui/include/gnuradio/qtgui/time_sink_f.h
index add53ef..1a09492 100644
--- a/gr-qtgui/include/gnuradio/qtgui/time_sink_f.h
+++ b/gr-qtgui/include/gnuradio/qtgui/time_sink_f.h
@@ -34,7 +34,7 @@
 
 namespace gr {
   namespace qtgui {
-    
+
     /*!
      * \brief A graphical sink to display multiple signals in time.
      * \ingroup instrumentation_blk
@@ -86,6 +86,45 @@ namespace gr {
       virtual void set_nsamps(const int newsize) = 0;
       virtual void set_samp_rate(const double samp_rate) = 0;
       virtual void set_line_alpha(int which, double alpha) = 0;
+
+      /*!
+       * Set up a trigger for the sink to know when to start
+       * plotting. Useful to isolate events and avoid noise.
+       *
+       * The trigger modes are Free, Auto, Normal, and Tag (see
+       * gr::qtgui::trigger_mode). The first three are like a normal
+       * oscope trigger function. Free means free running with no
+       * trigger, auto will trigger if the trigger event is seen, but
+       * will still plot otherwise, and normal will hold until the
+       * trigger event is observed. The Tag trigger mode allows us to
+       * trigger off a specific stream tag. The tag trigger is based
+       * only on the name of the tag, so when a tag of the given name
+       * is seen, the trigger is activated.
+       *
+       * In auto and normal mode, we look for the slope of the of the
+       * signal. Given a gr::qtgui::trigger_slope as either Positive
+       * or Negative, if the value between two samples moves in the
+       * given direction (x[1] > x[0] for Positive or x[1] < x[0] for
+       * Negative), then the trigger is activated.
+       *
+       * The \p delay value is specified in time based off the sample
+       * rate. If the sample rate of the block is set to 1, the delay
+       * is then also the sample number offset. This is the offset
+       * from the left-hand y-axis of the plot. It delays the signal
+       * to show the trigger event at the given delay along with some
+       * portion of the signal before the event. The delay must be
+       * within 0 - t_max where t_max is the maximum amount of time
+       * displayed on the time plot.
+       *
+       * \param mode The trigger_mode: free, auto, normal, or tag.
+       * \param slope The trigger_slope: positive or negative. Only
+       *              used for auto and normal modes.
+       * \param level The magnitude of the trigger even for auto or normal 
modes.
+       * \param delay The delay (in units of time) for where the trigger 
happens.
+       * \param channel Which input channel to use for the trigger events.
+       * \param tag_key The name (as a string) of the tag to trigger off
+       *                 of if using the tag mode.
+       */
       virtual void set_trigger_mode(trigger_mode mode, trigger_slope slope,
                                     float level, float delay, int channel,
                                     const std::string &tag_key="") = 0;
diff --git a/gr-qtgui/lib/const_sink_c_impl.cc 
b/gr-qtgui/lib/const_sink_c_impl.cc
index fb0cdad..a703336 100644
--- a/gr-qtgui/lib/const_sink_c_impl.cc
+++ b/gr-qtgui/lib/const_sink_c_impl.cc
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2012 Free Software Foundation, Inc.
+ * Copyright 2012,2014 Free Software Foundation, Inc.
  *
  * This file is part of GNU Radio
  *
@@ -49,9 +49,9 @@ namespace gr {
                                         int nconnections,
                                         QWidget *parent)
       : sync_block("const_sink_c",
-                     io_signature::make(nconnections, nconnections, 
sizeof(gr_complex)),
-                     io_signature::make(0, 0, 0)),
-       d_size(size), d_name(name),
+                  io_signature::make(nconnections, nconnections, 
sizeof(gr_complex)),
+                  io_signature::make(0, 0, 0)),
+       d_size(size), d_buffer_size(2*size), d_name(name),
        d_nconnections(nconnections), d_parent(parent)
     {
       // Required now for Qt; argc must be greater than 0 and argv
@@ -67,12 +67,12 @@ namespace gr {
       d_index = 0;
 
       for(int i = 0; i < d_nconnections; i++) {
-       d_residbufs_real.push_back((double*)volk_malloc(d_size*sizeof(double),
+       
d_residbufs_real.push_back((double*)volk_malloc(d_buffer_size*sizeof(double),
                                                         volk_get_alignment()));
-       d_residbufs_imag.push_back((double*)volk_malloc(d_size*sizeof(double),
+       
d_residbufs_imag.push_back((double*)volk_malloc(d_buffer_size*sizeof(double),
                                                         volk_get_alignment()));
-       memset(d_residbufs_real[i], 0, d_size*sizeof(double));
-       memset(d_residbufs_imag[i], 0, d_size*sizeof(double));
+       memset(d_residbufs_real[i], 0, d_buffer_size*sizeof(double));
+       memset(d_residbufs_imag[i], 0, d_buffer_size*sizeof(double));
       }
 
       // Set alignment properties for VOLK
@@ -81,7 +81,12 @@ namespace gr {
       set_alignment(std::max(1,alignment_multiple));
 
       initialize();
-    }
+
+      set_trigger_mode(TRIG_MODE_FREE, TRIG_SLOPE_POS, 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
+   }
 
     const_sink_c_impl::~const_sink_c_impl()
     {
@@ -221,6 +226,32 @@ namespace gr {
     }
 
     void
+    const_sink_c_impl::set_trigger_mode(trigger_mode mode,
+                                       trigger_slope slope,
+                                       float level,
+                                       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;
+      d_trigger_channel = channel;
+      d_trigger_tag_key = pmt::intern(tag_key);
+      d_triggered = false;
+      d_trigger_count = 0;
+
+      d_main_gui->setTriggerMode(d_trigger_mode);
+      d_main_gui->setTriggerSlope(d_trigger_slope);
+      d_main_gui->setTriggerLevel(d_trigger_level);
+      d_main_gui->setTriggerChannel(d_trigger_channel);
+      d_main_gui->setTriggerTagKey(tag_key);
+
+      _reset();
+    }
+
+    void
     const_sink_c_impl::set_size(int width, int height)
     {
       d_main_gui->resize(QSize(width, height));
@@ -274,35 +305,29 @@ namespace gr {
       gr::thread::scoped_lock lock(d_mutex);
 
       if(newsize != d_size) {
+       // Set new size and reset buffer index
+       // (throws away any currently held data, but who cares?)
+       d_size = newsize;
+        d_buffer_size = 2*d_size;
+       d_index = 0;
+
        // Resize residbuf and replace data
        for(int i = 0; i < d_nconnections; i++) {
          volk_free(d_residbufs_real[i]);
          volk_free(d_residbufs_imag[i]);
-         d_residbufs_real[i] = (double*)volk_malloc(newsize*sizeof(double),
+         d_residbufs_real[i] = 
(double*)volk_malloc(d_buffer_size*sizeof(double),
                                                      volk_get_alignment());
-         d_residbufs_imag[i] = (double*)volk_malloc(newsize*sizeof(double),
+         d_residbufs_imag[i] = 
(double*)volk_malloc(d_buffer_size*sizeof(double),
                                                      volk_get_alignment());
 
-         memset(d_residbufs_real[i], 0, newsize*sizeof(double));
-         memset(d_residbufs_imag[i], 0, newsize*sizeof(double));
+         memset(d_residbufs_real[i], 0, d_buffer_size*sizeof(double));
+         memset(d_residbufs_imag[i], 0, d_buffer_size*sizeof(double));
        }
 
-       // Set new size and reset buffer index
-       // (throws away any currently held data, but who cares?)
-       d_size = newsize;
-       d_index = 0;
-
        d_main_gui->setNPoints(d_size);
       }
     }
 
-    void
-    const_sink_c_impl::npoints_resize()
-    {
-      int newsize = d_main_gui->getNPoints();
-      set_nsamps(newsize);
-    }
-
     int
     const_sink_c_impl::nsamps() const
     {
@@ -324,7 +349,104 @@ namespace gr {
     void
     const_sink_c_impl::reset()
     {
+      gr::thread::scoped_lock lock(d_mutex);
+      _reset();
+    }
+
+    void
+    const_sink_c_impl::_reset()
+    {
+      // Reset the start and end indices.
+      d_start = 0;
+      d_end = d_size;
       d_index = 0;
+
+      // Reset the trigger.
+      if(d_trigger_mode == TRIG_MODE_FREE) {
+        d_triggered = true;
+      }
+      else {
+        d_triggered = false;
+      }
+    }
+
+    void
+    const_sink_c_impl::_npoints_resize()
+    {
+      int newsize = d_main_gui->getNPoints();
+      set_nsamps(newsize);
+    }
+
+    void
+    const_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;
+
+      std::string tagkey = d_main_gui->getTriggerTagKey();
+      d_trigger_tag_key = pmt::intern(tagkey);
+    }
+
+    void
+    const_sink_c_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 - 1;
+        d_end = d_start + d_size;
+        d_trigger_count = 0;
+      }
+    }
+
+    void
+    const_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];
+      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_end = d_start + d_size;
+          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;
+      }
+    }
+
+    bool
+    const_sink_c_impl::_test_trigger_slope(const gr_complex *in) const
+    {
+      float x0, x1;
+      x0 = abs(in[0]);
+      x1 = abs(in[1]);
+
+      if(d_trigger_slope == TRIG_SLOPE_POS)
+        return ((x0 <= d_trigger_level) && (x1 > d_trigger_level));
+      else
+        return ((x0 >= d_trigger_level) && (x1 < d_trigger_level));
     }
 
     int
@@ -332,54 +454,64 @@ namespace gr {
                            gr_vector_const_void_star &input_items,
                            gr_vector_void_star &output_items)
     {
-      int n=0, j=0, idx=0;
-      const gr_complex *in = (const gr_complex*)input_items[idx];
-
-      npoints_resize();
-
-      for(int i=0; i < noutput_items; i+=d_size) {
-       unsigned int datasize = noutput_items - i;
-       unsigned int resid = d_size-d_index;
-       idx = 0;
-
-       // 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 gr_complex*)input_items[idx++];
-           volk_32fc_deinterleave_64f_x2_u(&d_residbufs_real[n][d_index],
-                                           &d_residbufs_imag[n][d_index],
-                                           &in[j], resid);
-         }
-
-         // Update the plot if its 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 ConstUpdateEvent(d_residbufs_real,
-                                                          d_residbufs_imag,
-                                                          d_size));
-         }
-
-         d_index = 0;
-         j += resid;
-       }
+      int n=0;
+      const gr_complex *in;
+
+      _npoints_resize();
+      _gui_update_trigger();
+
+      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
+
+      // 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);
+        }
+      }
 
-       // Otherwise, copy what we received into the residbufs for next time
-       else {
-         for(n = 0; n < d_nconnections; n++) {
-           in = (const gr_complex*)input_items[idx++];
-           volk_32fc_deinterleave_64f_x2_u(&d_residbufs_real[n][d_index],
-                                           &d_residbufs_imag[n][d_index],
-                                           &in[j], datasize);
-         }
-         d_index += datasize;
-         j += datasize;
-       }
+      // Copy data into the buffers.
+      for(n = 0; n < d_nconnections; n++) {
+        in = (const gr_complex*)input_items[n];
+        volk_32fc_deinterleave_64f_x2(&d_residbufs_real[n][d_index],
+                                      &d_residbufs_imag[n][d_index],
+                                      &in[0], nitems);
+      }
+      d_index += nitems;
+
+
+      // 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_residbufs_real[n], &d_residbufs_real[n][d_start], 
d_size*sizeof(double));
+          memmove(d_residbufs_imag[n], &d_residbufs_imag[n][d_start], 
d_size*sizeof(double));
+        }
+
+        // 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 ConstUpdateEvent(d_residbufs_real,
+                                                        d_residbufs_imag,
+                                                        d_size));
+        }
+
+        // We've plotting, so reset the state
+        _reset();
+      }
+
+      // If we've filled up the buffers but haven't triggered, reset.
+      if(d_index == d_end) {
+        _reset();
       }
 
-      return j;
+      return nitems;
     }
 
   } /* namespace qtgui */
diff --git a/gr-qtgui/lib/const_sink_c_impl.h b/gr-qtgui/lib/const_sink_c_impl.h
index 3b1de22..0f1540d 100644
--- a/gr-qtgui/lib/const_sink_c_impl.h
+++ b/gr-qtgui/lib/const_sink_c_impl.h
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2012 Free Software Foundation, Inc.
+ * Copyright 2012,2014 Free Software Foundation, Inc.
  *
  * This file is part of GNU Radio
  *
@@ -30,7 +30,7 @@
 
 namespace gr {
   namespace qtgui {
-    
+
     class QTGUI_API const_sink_c_impl : public const_sink_c
     {
     private:
@@ -38,11 +38,11 @@ namespace gr {
 
       gr::thread::mutex d_mutex;
 
-      int d_size;
+      int d_size, d_buffer_size;
       std::string d_name;
       int d_nconnections;
 
-      int d_index;
+      int d_index, d_start, d_end;
       std::vector<double*> d_residbufs_real;
       std::vector<double*> d_residbufs_imag;
 
@@ -54,7 +54,21 @@ 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;
+      float d_trigger_level;
+      int d_trigger_channel;
+      pmt::pmt_t d_trigger_tag_key;
+      bool d_triggered;
+      int d_trigger_count;
+
+      void _reset();
+      void _npoints_resize();
+      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:
       const_sink_c_impl(int size,
@@ -86,6 +100,9 @@ namespace gr {
       void set_line_marker(int which, int marker);
       void set_nsamps(const int size);
       void set_line_alpha(int which, double alpha);
+      void set_trigger_mode(trigger_mode mode, trigger_slope slope,
+                            float level, int channel,
+                            const std::string &tag_key="");
 
       std::string title();
       std::string line_label(int which);
diff --git a/gr-qtgui/lib/constellationdisplayform.cc 
b/gr-qtgui/lib/constellationdisplayform.cc
index d0424b0..1325bec 100644
--- a/gr-qtgui/lib/constellationdisplayform.cc
+++ b/gr-qtgui/lib/constellationdisplayform.cc
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2012 Free Software Foundation, Inc.
+ * Copyright 2012,2014 Free Software Foundation, Inc.
  *
  * This file is part of GNU Radio
  *
@@ -36,11 +36,48 @@ ConstellationDisplayForm::ConstellationDisplayForm(int 
nplots, QWidget* parent)
   d_layout->addWidget(d_display_plot, 0, 0);
   setLayout(d_layout);
 
-  NPointsMenu *nptsmenu = new NPointsMenu(this);
-  d_menu->addAction(nptsmenu);
-  connect(nptsmenu, SIGNAL(whichTrigger(int)),
+  d_nptsmenu = new NPointsMenu(this);
+  d_menu->addAction(d_nptsmenu);
+  connect(d_nptsmenu, SIGNAL(whichTrigger(int)),
          this, SLOT(setNPoints(const int)));
 
+  // Set up the trigger menu
+  d_triggermenu = new QMenu("Trigger", this);
+  d_tr_mode_menu = new TriggerModeMenu(this);
+  d_tr_slope_menu = new TriggerSlopeMenu(this);
+  d_tr_level_act = new PopupMenu("Level", this);
+  d_tr_channel_menu = new TriggerChannelMenu(nplots, this);
+  d_tr_tag_key_act = new PopupMenu("Tag Key", this);
+  d_triggermenu->addMenu(d_tr_mode_menu);
+  d_triggermenu->addMenu(d_tr_slope_menu);
+  d_triggermenu->addAction(d_tr_level_act);
+  d_triggermenu->addMenu(d_tr_channel_menu);
+  d_triggermenu->addAction(d_tr_tag_key_act);
+  d_menu->addMenu(d_triggermenu);
+
+  setTriggerMode(gr::qtgui::TRIG_MODE_FREE);
+  connect(d_tr_mode_menu, SIGNAL(whichTrigger(gr::qtgui::trigger_mode)),
+         this, SLOT(setTriggerMode(gr::qtgui::trigger_mode)));
+  // updates trigger state by calling set level or set tag key.
+  connect(d_tr_mode_menu, SIGNAL(whichTrigger(gr::qtgui::trigger_mode)),
+         this, SLOT(updateTrigger(gr::qtgui::trigger_mode)));
+
+  setTriggerSlope(gr::qtgui::TRIG_SLOPE_POS);
+  connect(d_tr_slope_menu, SIGNAL(whichTrigger(gr::qtgui::trigger_slope)),
+         this, SLOT(setTriggerSlope(gr::qtgui::trigger_slope)));
+
+  setTriggerLevel(0);
+  connect(d_tr_level_act, SIGNAL(whichTrigger(QString)),
+         this, SLOT(setTriggerLevel(QString)));
+
+  setTriggerChannel(0);
+  connect(d_tr_channel_menu, SIGNAL(whichTrigger(int)),
+         this, SLOT(setTriggerChannel(int)));
+
+  setTriggerTagKey(std::string(""));
+  connect(d_tr_tag_key_act, SIGNAL(whichTrigger(QString)),
+         this, SLOT(setTriggerTagKey(QString)));
+
   Reset();
 
   connect(d_display_plot, SIGNAL(plotPointSelected(const QPointF)),
@@ -120,3 +157,96 @@ void
 ConstellationDisplayForm::setSampleRate(const QString &samprate)
 {
 }
+
+/********************************************************************
+ * TRIGGER METHODS
+ *******************************************************************/
+
+void
+ConstellationDisplayForm::setTriggerMode(gr::qtgui::trigger_mode mode)
+{
+  d_trig_mode = mode;
+  d_tr_mode_menu->getAction(mode)->setChecked(true);
+}
+
+void
+ConstellationDisplayForm::updateTrigger(gr::qtgui::trigger_mode mode)
+{
+  // If auto or normal mode, popup trigger level box to set
+  if((d_trig_mode == gr::qtgui::TRIG_MODE_AUTO) || (d_trig_mode == 
gr::qtgui::TRIG_MODE_NORM))
+    d_tr_level_act->activate(QAction::Trigger);
+
+  // if tag mode, popup tag key box to set
+  if(d_trig_mode == gr::qtgui::TRIG_MODE_TAG)
+    d_tr_tag_key_act->activate(QAction::Trigger);
+}
+
+gr::qtgui::trigger_mode
+ConstellationDisplayForm::getTriggerMode() const
+{
+  return d_trig_mode;
+}
+
+void
+ConstellationDisplayForm::setTriggerSlope(gr::qtgui::trigger_slope slope)
+{
+  d_trig_slope = slope;
+  d_tr_slope_menu->getAction(slope)->setChecked(true);
+}
+
+gr::qtgui::trigger_slope
+ConstellationDisplayForm::getTriggerSlope() const
+{
+  return d_trig_slope;
+}
+
+void
+ConstellationDisplayForm::setTriggerLevel(QString s)
+{
+  d_trig_level = s.toFloat();
+}
+
+void
+ConstellationDisplayForm::setTriggerLevel(float level)
+{
+  d_trig_level = level;
+  d_tr_level_act->setText(QString().setNum(d_trig_level));
+}
+
+float
+ConstellationDisplayForm::getTriggerLevel() const
+{
+  return d_trig_level;
+}
+
+void
+ConstellationDisplayForm::setTriggerChannel(int channel)
+{
+  d_trig_channel = channel;
+  d_tr_channel_menu->getAction(d_trig_channel)->setChecked(true);
+}
+
+int
+ConstellationDisplayForm::getTriggerChannel() const
+{
+  return d_trig_channel;
+}
+
+void
+ConstellationDisplayForm::setTriggerTagKey(QString s)
+{
+  d_trig_tag_key = s.toStdString();
+}
+
+void
+ConstellationDisplayForm::setTriggerTagKey(const std::string &key)
+{
+  d_trig_tag_key = key;
+  d_tr_tag_key_act->setText(QString().fromStdString(d_trig_tag_key));
+}
+
+std::string
+ConstellationDisplayForm::getTriggerTagKey() const
+{
+  return d_trig_tag_key;
+}
diff --git a/gr-qtgui/lib/time_sink_c_impl.cc b/gr-qtgui/lib/time_sink_c_impl.cc
index e86ffca..499529c 100644
--- a/gr-qtgui/lib/time_sink_c_impl.cc
+++ b/gr-qtgui/lib/time_sink_c_impl.cc
@@ -67,7 +67,7 @@ namespace gr {
 
       for(int n = 0; n < d_nconnections; n++) {
        d_buffers.push_back((double*)volk_malloc(d_buffer_size*sizeof(double),
-                                              volk_get_alignment()));
+                                                volk_get_alignment()));
        memset(d_buffers[n], 0, d_buffer_size*sizeof(double));
       }
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]