commit-gnuradio
[Top][All Lists]
Advanced

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

[Commit-gnuradio] [gnuradio] 07/21: qtgui: freq plotters support PDU mes


From: git
Subject: [Commit-gnuradio] [gnuradio] 07/21: qtgui: freq plotters support PDU message plotting.
Date: Fri, 30 Oct 2015 21:11:26 +0000 (UTC)

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

jcorgan pushed a commit to branch master
in repository gnuradio.

commit e21dda109887b4ad16a5f4c06bb805bbf0330dd8
Author: Tom Rondeau <address@hidden>
Date:   Wed Oct 21 15:59:32 2015 -0400

    qtgui: freq plotters support PDU message plotting.
---
 gr-qtgui/grc/qtgui_freq_sink_x.xml            |   7 ++
 gr-qtgui/include/gnuradio/qtgui/freq_sink_c.h |  11 ++-
 gr-qtgui/include/gnuradio/qtgui/freq_sink_f.h |  18 +++-
 gr-qtgui/lib/freq_sink_c_impl.cc              | 113 ++++++++++++++++++++++++--
 gr-qtgui/lib/freq_sink_c_impl.h               |   6 +-
 gr-qtgui/lib/freq_sink_f_impl.cc              | 112 +++++++++++++++++++++++--
 gr-qtgui/lib/freq_sink_f_impl.h               |   6 +-
 7 files changed, 255 insertions(+), 18 deletions(-)

diff --git a/gr-qtgui/grc/qtgui_freq_sink_x.xml 
b/gr-qtgui/grc/qtgui_freq_sink_x.xml
index 67e852c..0cf31f5 100644
--- a/gr-qtgui/grc/qtgui_freq_sink_x.xml
+++ b/gr-qtgui/grc/qtgui_freq_sink_x.xml
@@ -706,6 +706,13 @@ $(gui_hint()($win))</make>
     <name>in</name>
     <type>$type</type>
     <nports>$nconnections</nports>
+    <optional>1</optional>
+  </sink>
+
+  <sink>
+    <name>pdus</name>
+    <type>message</type>
+    <optional>1</optional>
   </sink>
 
   <sink>
diff --git a/gr-qtgui/include/gnuradio/qtgui/freq_sink_c.h 
b/gr-qtgui/include/gnuradio/qtgui/freq_sink_c.h
index 8869afc..c3c7de0 100644
--- a/gr-qtgui/include/gnuradio/qtgui/freq_sink_c.h
+++ b/gr-qtgui/include/gnuradio/qtgui/freq_sink_c.h
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2012,2014 Free Software Foundation, Inc.
+ * Copyright 2012,2014-2015 Free Software Foundation, Inc.
  *
  * This file is part of GNU Radio
  *
@@ -76,12 +76,17 @@ namespace gr {
       /*!
        * \brief Build a complex PSD sink.
        *
-       * \param fftsize size of the FFT to compute and display
+       * \param fftsize size of the FFT to compute and display. If using
+       *        the PDU message port to plot samples, the length of
+       *        each PDU must be a multiple of the FFT size.
        * \param wintype type of window to apply (see gnuradio/filter/firdes.h)
        * \param fc center frequency of signal (use for x-axis labels)
        * \param bw bandwidth of signal (used to set x-axis labels)
        * \param name title for the plot
-       * \param nconnections number of signals connected to sink
+       * \param nconnections number of signals to be connected to the
+       *        sink. The PDU message port is always available for a
+       *        connection, and this value must be set to 0 if only
+       *        the PDU message port is being used.
        * \param parent a QWidget parent object, if any
        */
       static sptr make(int fftsize, int wintype,
diff --git a/gr-qtgui/include/gnuradio/qtgui/freq_sink_f.h 
b/gr-qtgui/include/gnuradio/qtgui/freq_sink_f.h
index 552e1e4..ff08f81 100644
--- a/gr-qtgui/include/gnuradio/qtgui/freq_sink_f.h
+++ b/gr-qtgui/include/gnuradio/qtgui/freq_sink_f.h
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2012,2014 Free Software Foundation, Inc.
+ * Copyright 2012,2014-2015 Free Software Foundation, Inc.
  *
  * This file is part of GNU Radio
  *
@@ -50,6 +50,13 @@ namespace gr {
      *
      * Message Ports:
      *
+     * - pdus (input):
+     *        Receives and plots a PDU. Each PDU must have a length
+     *        that is an integer multiple of the FFT size. The PDU
+     *        must be formatted as a PDU with float/double
+     *        samples. The block will throw a runtime error if either
+     *        of these conditions is not met.
+     *
      * - freq (input):
      *        Receives a PMT pair: (intern("freq"), double(frequency).
      *        This is used to retune the center frequency of the
@@ -76,12 +83,17 @@ namespace gr {
       /*!
        * \brief Build a floating point PSD sink.
        *
-       * \param fftsize size of the FFT to compute and display
+       * \param fftsize size of the FFT to compute and display. If using
+       *        the PDU message port to plot samples, the length of
+       *        each PDU must be a multiple of the FFT size.
        * \param wintype type of window to apply (see gnuradio/filter/firdes.h)
        * \param fc center frequency of signal (use for x-axis labels)
        * \param bw bandwidth of signal (used to set x-axis labels)
        * \param name title for the plot
-       * \param nconnections number of signals connected to sink
+       * \param nconnections number of signals to be connected to the
+       *        sink. The PDU message port is always available for a
+       *        connection, and this value must be set to 0 if only
+       *        the PDU message port is being used.
        * \param parent a QWidget parent object, if any
        */
       static sptr make(int fftsize, int wintype,
diff --git a/gr-qtgui/lib/freq_sink_c_impl.cc b/gr-qtgui/lib/freq_sink_c_impl.cc
index ee2fc52..bef88c4 100644
--- a/gr-qtgui/lib/freq_sink_c_impl.cc
+++ b/gr-qtgui/lib/freq_sink_c_impl.cc
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2012,2014 Free Software Foundation, Inc.
+ * Copyright 2012,2014-2015 Free Software Foundation, Inc.
  *
  * This file is part of GNU Radio
  *
@@ -54,7 +54,7 @@ namespace gr {
                                       int nconnections,
                                       QWidget *parent)
       : sync_block("freq_sink_c",
-                   io_signature::make(nconnections, nconnections, 
sizeof(gr_complex)),
+                   io_signature::make(0, nconnections, sizeof(gr_complex)),
                    io_signature::make(0, 0, 0)),
        d_fftsize(fftsize), d_fftavg(1.0),
        d_wintype((filter::firdes::win_type)(wintype)),
@@ -76,6 +76,11 @@ namespace gr {
       set_msg_handler(pmt::mp("freq"),
                       boost::bind(&freq_sink_c_impl::handle_set_freq, this, 
_1));
 
+      // setup PDU handling input port
+      message_port_register_in(pmt::mp("pdus"));
+      set_msg_handler(pmt::mp("pdus"),
+                      boost::bind(&freq_sink_c_impl::handle_pdus, this, _1));
+
       d_main_gui = NULL;
 
       // Perform fftshift operation;
@@ -93,6 +98,7 @@ namespace gr {
 
 
       d_index = 0;
+      // save the last "connection" for the PDU memory
       for(int i = 0; i < d_nconnections; i++) {
        
d_residbufs.push_back((gr_complex*)volk_malloc(d_fftsize*sizeof(gr_complex),
                                                        volk_get_alignment()));
@@ -103,6 +109,14 @@ namespace gr {
        memset(d_magbufs[i], 0, d_fftsize*sizeof(double));
       }
 
+      
d_residbufs.push_back((gr_complex*)volk_malloc(d_fftsize*sizeof(gr_complex),
+                                                     volk_get_alignment()));
+      d_pdu_magbuf = (double*)volk_malloc(d_fftsize*sizeof(double),
+                                          volk_get_alignment());
+      d_magbufs.push_back(d_pdu_magbuf);
+      memset(d_residbufs[d_nconnections], 0, d_fftsize*sizeof(gr_complex));
+      memset(d_pdu_magbuf, 0, d_fftsize*sizeof(double));
+
       buildwindow();
 
       initialize();
@@ -115,7 +129,8 @@ namespace gr {
       if(!d_main_gui->isClosed())
         d_main_gui->close();
 
-      for(int i = 0; i < d_nconnections; i++) {
+      // +1 to handle PDU buffers; will also take care of d_pdu_magbuf
+      for(int i = 0; i < d_nconnections+1; i++) {
        volk_free(d_residbufs[i]);
        volk_free(d_magbufs[i]);
       }
@@ -153,7 +168,8 @@ namespace gr {
         d_qApplication->setStyleSheet(sstext);
       }
 
-      d_main_gui = new FreqDisplayForm(d_nconnections, d_parent);
+      int numplots = (d_nconnections > 0) ? d_nconnections : 1;
+      d_main_gui = new FreqDisplayForm(numplots, d_parent);
       set_fft_window(d_wintype);
       set_fft_size(d_fftsize);
       set_frequency_range(d_center_freq, d_bandwidth);
@@ -507,7 +523,8 @@ namespace gr {
 
       if(newfftsize != d_fftsize) {
        // Resize residbuf and replace data
-       for(int i = 0; i < d_nconnections; i++) {
+        // +1 to handle PDU buffers
+       for(int i = 0; i < d_nconnections+1; i++) {
          volk_free(d_residbufs[i]);
          volk_free(d_magbufs[i]);
 
@@ -520,6 +537,9 @@ namespace gr {
          memset(d_magbufs[i], 0, newfftsize*sizeof(double));
        }
 
+        // Update the pointer to the newly allocated memory
+        d_pdu_magbuf = d_magbufs[d_nconnections];
+
        // Set new fft size and reset buffer index
        // (throws away any currently held data, but who cares?)
        d_fftsize = newfftsize;
@@ -692,5 +712,88 @@ namespace gr {
       return noutput_items;
     }
 
+
+    void
+    freq_sink_c_impl::handle_pdus(pmt::pmt_t msg)
+    {
+      size_t len;
+      pmt::pmt_t dict, samples;
+
+      // Test to make sure this is either a PDU or a uniform vector of
+      // samples. Get the samples PMT and the dictionary if it's a PDU.
+      // If not, we throw an error and exit.
+      if(pmt::is_pair(msg)) {
+        dict = pmt::car(msg);
+        samples = pmt::cdr(msg);
+      }
+      else if(pmt::is_uniform_vector(msg)) {
+        samples = msg;
+      }
+      else {
+        throw std::runtime_error("time_sink_c: message must be either "
+                                 "a PDU or a uniform vector of samples.");
+      }
+
+      len = pmt::length(samples);
+
+      const gr_complex *in;
+      if(pmt::is_c32vector(samples)) {
+        in = (const gr_complex*)pmt::c32vector_elements(samples, len);
+      }
+      else {
+        throw std::runtime_error("freq_sink_c: unknown data type "
+                                 "of samples; must be complex.");
+      }
+
+      // Plot if we're past the last update time
+      if(gr::high_res_timer_now() - d_last_time > d_update_time) {
+        d_last_time = gr::high_res_timer_now();
+
+        // Update the FFT size from the application
+        fftresize();
+        windowreset();
+        check_clicked();
+
+        int winoverlap = 4;
+        int fftoverlap = d_fftsize / winoverlap;
+        float num = static_cast<float>(winoverlap * len) / 
static_cast<float>(d_fftsize);
+        int nffts = static_cast<int>(ceilf(num));
+
+        // Clear this as we will be accumulating in the for loop over nffts
+        memset(d_pdu_magbuf, 0, sizeof(double)*d_fftsize);
+
+        size_t min = 0;
+        size_t max = std::min(d_fftsize, static_cast<int>(len));
+        for(int n = 0; n < nffts; n++) {
+          // Clear in case (max-min) < d_fftsize
+          memset(d_residbufs[d_nconnections], 0x00, 
sizeof(gr_complex)*d_fftsize);
+
+          // Copy in as much of the input samples as we can
+          memcpy(d_residbufs[d_nconnections], &in[min], 
sizeof(gr_complex)*(max-min));
+
+          // Apply the window and FFT; copy data into the PDU
+          // magnitude buffer.
+          fft(d_fbuf, d_residbufs[d_nconnections], d_fftsize);
+          for(int x = 0; x < d_fftsize; x++) {
+            d_pdu_magbuf[x] += (double)d_fbuf[x];
+          }
+
+          // Increment our indices; set max up to the number of
+          // samples in the input PDU.
+          min += fftoverlap;
+          max = std::min(max + fftoverlap, len);
+        }
+
+        // Perform the averaging
+        for(int x = 0; x < d_fftsize; x++) {
+          d_pdu_magbuf[x] /= static_cast<double>(nffts);
+        }
+
+        //update gui per-pdu
+        d_qApplication->postEvent(d_main_gui,
+                                  new FreqUpdateEvent(d_magbufs, d_fftsize));
+      }
+    }
+
   } /* namespace qtgui */
 } /* namespace gr */
diff --git a/gr-qtgui/lib/freq_sink_c_impl.h b/gr-qtgui/lib/freq_sink_c_impl.h
index 908ce0b..8da193b 100644
--- a/gr-qtgui/lib/freq_sink_c_impl.h
+++ b/gr-qtgui/lib/freq_sink_c_impl.h
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2012 Free Software Foundation, Inc.
+ * Copyright 2012,2015 Free Software Foundation, Inc.
  *
  * This file is part of GNU Radio
  *
@@ -53,6 +53,7 @@ namespace gr {
       int d_index;
       std::vector<gr_complex*> d_residbufs;
       std::vector<double*> d_magbufs;
+      double* d_pdu_magbuf;
       float *d_fbuf;
       float *d_tmpbuf;
 
@@ -74,6 +75,9 @@ namespace gr {
       // The message is a PMT pair (intern('freq'), double(frequency)).
       void handle_set_freq(pmt::pmt_t msg);
 
+      // Handles message input port for displaying PDU samples.
+      void handle_pdus(pmt::pmt_t msg);
+
       // Members used for triggering scope
       trigger_mode d_trigger_mode;
       float d_trigger_level;
diff --git a/gr-qtgui/lib/freq_sink_f_impl.cc b/gr-qtgui/lib/freq_sink_f_impl.cc
index 05a2ff7..fee8e6b 100644
--- a/gr-qtgui/lib/freq_sink_f_impl.cc
+++ b/gr-qtgui/lib/freq_sink_f_impl.cc
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2012,2014 Free Software Foundation, Inc.
+ * Copyright 2012,2014-2015 Free Software Foundation, Inc.
  *
  * This file is part of GNU Radio
  *
@@ -54,7 +54,7 @@ namespace gr {
                                       int nconnections,
                                       QWidget *parent)
       : sync_block("freq_sink_f",
-                   io_signature::make(nconnections, nconnections, 
sizeof(float)),
+                   io_signature::make(0, nconnections, sizeof(float)),
                    io_signature::make(0, 0, 0)),
        d_fftsize(fftsize), d_fftavg(1.0),
        d_wintype((filter::firdes::win_type)(wintype)),
@@ -76,6 +76,11 @@ namespace gr {
       set_msg_handler(pmt::mp("freq"),
                       boost::bind(&freq_sink_f_impl::handle_set_freq, this, 
_1));
 
+      // setup PDU handling input port
+      message_port_register_in(pmt::mp("pdus"));
+      set_msg_handler(pmt::mp("pdus"),
+                      boost::bind(&freq_sink_f_impl::handle_pdus, this, _1));
+
       d_main_gui = NULL;
 
       // Perform fftshift operation;
@@ -92,6 +97,7 @@ namespace gr {
                                      volk_get_alignment());
 
       d_index = 0;
+      // save the last "connection" for the PDU memory
       for(int i = 0; i < d_nconnections; i++) {
        d_residbufs.push_back((float*)volk_malloc(d_fftsize*sizeof(float),
                                                   volk_get_alignment()));
@@ -102,6 +108,14 @@ namespace gr {
        memset(d_magbufs[i], 0, d_fftsize*sizeof(double));
       }
 
+      d_residbufs.push_back((float*)volk_malloc(d_fftsize*sizeof(float),
+                                                volk_get_alignment()));
+      d_pdu_magbuf = (double*)volk_malloc(d_fftsize*sizeof(double),
+                                          volk_get_alignment());
+      d_magbufs.push_back(d_pdu_magbuf);
+      memset(d_residbufs[d_nconnections], 0, d_fftsize*sizeof(float));
+      memset(d_pdu_magbuf, 0, d_fftsize*sizeof(double));
+
       buildwindow();
 
       initialize();
@@ -114,7 +128,8 @@ namespace gr {
       if(!d_main_gui->isClosed())
         d_main_gui->close();
 
-      for(int i = 0; i < d_nconnections; i++) {
+      // +1 to handle PDU buffers; will also take care of d_pdu_magbuf
+      for(int i = 0; i < d_nconnections+1; i++) {
        volk_free(d_residbufs[i]);
        volk_free(d_magbufs[i]);
       }
@@ -152,7 +167,8 @@ namespace gr {
         d_qApplication->setStyleSheet(sstext);
       }
 
-      d_main_gui = new FreqDisplayForm(d_nconnections, d_parent);
+      int numplots = (d_nconnections > 0) ? d_nconnections : 1;
+      d_main_gui = new FreqDisplayForm(numplots, d_parent);
       set_fft_window(d_wintype);
       set_fft_size(d_fftsize);
       set_frequency_range(d_center_freq, d_bandwidth);
@@ -512,7 +528,8 @@ namespace gr {
 
       if(newfftsize != d_fftsize) {
        // Resize residbuf and replace data
-       for(int i = 0; i < d_nconnections; i++) {
+        // +1 to handle PDU buffers
+       for(int i = 0; i < d_nconnections+1; i++) {
          volk_free(d_residbufs[i]);
          volk_free(d_magbufs[i]);
 
@@ -525,6 +542,9 @@ namespace gr {
          memset(d_magbufs[i], 0, newfftsize*sizeof(double));
        }
 
+        // Update the pointer to the newly allocated memory
+        d_pdu_magbuf = d_magbufs[d_nconnections];
+
        // Set new fft size and reset buffer index
        // (throws away any currently held data, but who cares?)
        d_fftsize = newfftsize;
@@ -697,5 +717,87 @@ namespace gr {
       return noutput_items;
     }
 
+    void
+    freq_sink_f_impl::handle_pdus(pmt::pmt_t msg)
+    {
+      size_t len;
+      pmt::pmt_t dict, samples;
+
+      // Test to make sure this is either a PDU or a uniform vector of
+      // samples. Get the samples PMT and the dictionary if it's a PDU.
+      // If not, we throw an error and exit.
+      if(pmt::is_pair(msg)) {
+        dict = pmt::car(msg);
+        samples = pmt::cdr(msg);
+      }
+      else if(pmt::is_uniform_vector(msg)) {
+        samples = msg;
+      }
+      else {
+        throw std::runtime_error("time_sink_c: message must be either "
+                                 "a PDU or a uniform vector of samples.");
+      }
+
+      len = pmt::length(samples);
+
+      const float *in;
+      if(pmt::is_f32vector(samples)) {
+        in = (const float*)pmt::f32vector_elements(samples, len);
+      }
+      else {
+        throw std::runtime_error("freq_sink_f: unknown data type "
+                                 "of samples; must be float.");
+      }
+
+      // Plot if we're past the last update time
+      if(gr::high_res_timer_now() - d_last_time > d_update_time) {
+        d_last_time = gr::high_res_timer_now();
+
+        // Update the FFT size from the application
+        fftresize();
+        windowreset();
+        check_clicked();
+
+        int winoverlap = 4;
+        int fftoverlap = d_fftsize / winoverlap;
+        float num = static_cast<float>(winoverlap * len) / 
static_cast<float>(d_fftsize);
+        int nffts = static_cast<int>(ceilf(num));
+
+        // Clear this as we will be accumulating in the for loop over nffts
+        memset(d_pdu_magbuf, 0, sizeof(double)*d_fftsize);
+
+        size_t min = 0;
+        size_t max = std::min(d_fftsize, static_cast<int>(len));
+        for(int n = 0; n < nffts; n++) {
+          // Clear in case (max-min) < d_fftsize
+          memset(d_residbufs[d_nconnections], 0x00, sizeof(float)*d_fftsize);
+
+          // Copy in as much of the input samples as we can
+          memcpy(d_residbufs[d_nconnections], &in[min], 
sizeof(float)*(max-min));
+
+          // Apply the window and FFT; copy data into the PDU
+          // magnitude buffer.
+          fft(d_fbuf, d_residbufs[d_nconnections], d_fftsize);
+          for(int x = 0; x < d_fftsize; x++) {
+            d_pdu_magbuf[x] += (double)d_fbuf[x];
+          }
+
+          // Increment our indices; set max up to the number of
+          // samples in the input PDU.
+          min += fftoverlap;
+          max = std::min(max + fftoverlap, len);
+        }
+
+        // Perform the averaging
+        for(int x = 0; x < d_fftsize; x++) {
+          d_pdu_magbuf[x] /= static_cast<double>(nffts);
+        }
+
+        //update gui per-pdu
+        d_qApplication->postEvent(d_main_gui,
+                                  new FreqUpdateEvent(d_magbufs, d_fftsize));
+      }
+    }
+
   } /* namespace qtgui */
 } /* namespace gr */
diff --git a/gr-qtgui/lib/freq_sink_f_impl.h b/gr-qtgui/lib/freq_sink_f_impl.h
index e1ae0e9..39e5c92 100644
--- a/gr-qtgui/lib/freq_sink_f_impl.h
+++ b/gr-qtgui/lib/freq_sink_f_impl.h
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2012,2014 Free Software Foundation, Inc.
+ * Copyright 2012,2014-2015 Free Software Foundation, Inc.
  *
  * This file is part of GNU Radio
  *
@@ -53,6 +53,7 @@ namespace gr {
       int d_index;
       std::vector<float*> d_residbufs;
       std::vector<double*> d_magbufs;
+      double* d_pdu_magbuf;
       float *d_fbuf;
       float *d_tmpbuf;
 
@@ -74,6 +75,9 @@ namespace gr {
       // The message is a PMT pair (intern('freq'), double(frequency)).
       void handle_set_freq(pmt::pmt_t msg);
 
+      // Handles message input port for displaying PDU samples.
+      void handle_pdus(pmt::pmt_t msg);
+
       // Members used for triggering scope
       trigger_mode d_trigger_mode;
       float d_trigger_level;



reply via email to

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