commit-gnuradio
[Top][All Lists]
Advanced

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

[Commit-gnuradio] r11042 - in gnuradio/branches/developers/eb/vrt/vrt: a


From: eb
Subject: [Commit-gnuradio] r11042 - in gnuradio/branches/developers/eb/vrt/vrt: apps lib
Date: Fri, 15 May 2009 03:39:20 -0600 (MDT)

Author: eb
Date: 2009-05-15 03:39:20 -0600 (Fri, 15 May 2009)
New Revision: 11042

Modified:
   gnuradio/branches/developers/eb/vrt/vrt/apps/simple_rx_samples.cc
   gnuradio/branches/developers/eb/vrt/vrt/lib/expanded_header.cc
Log:
simple_rx_samples now writes samples to disk, either as shorts of complex float.


Modified: gnuradio/branches/developers/eb/vrt/vrt/apps/simple_rx_samples.cc
===================================================================
--- gnuradio/branches/developers/eb/vrt/vrt/apps/simple_rx_samples.cc   
2009-05-15 08:30:52 UTC (rev 11041)
+++ gnuradio/branches/developers/eb/vrt/vrt/apps/simple_rx_samples.cc   
2009-05-15 09:39:20 UTC (rev 11042)
@@ -35,6 +35,7 @@
 #include <string.h>
 #include <vrt/rx_udp.h>
 #include <gruel/realtime.h>
+#include <complex>
 
 #define        MIN_IP_LOCAL_PORT       32768
 #define        MAX_IP_LOCAL_PORT       61000
@@ -65,7 +66,249 @@
 }
 
 // ------------------------------------------------------------------------
+// Copy and convert from net format to host format
+// ------------------------------------------------------------------------
 
+void 
+copy_net_16sc_to_host_16sc(size_t nitems,
+                         const uint32_t *items,
+                         std::complex<int16_t> *host_items)
+{
+#ifdef WORDS_BIGENDIAN
+
+  assert(sizeof(items[0]) == sizeof(host_items[0]));
+  memcpy(host_items, items, nitems * sizeof(items[0]));
+
+#else
+
+  // FIXME SIMD welcome here
+
+  for (size_t i = 0; i < nitems; i++){
+    uint32_t t = ntohl(items[i]);
+    //printf("%9d\n", items[i]);
+    host_items[i] = std::complex<int16_t>((t >> 16), t & 0xffff);
+  }
+
+#endif
+}
+
+
+/*
+ * endian swap if required and map [-32768, 32767] -> [1.0, +1.0)
+ */
+void 
+copy_net_16sc_to_host_32fc(size_t nitems,
+                          const uint32_t *items,
+                          std::complex<float> *host_items)
+{
+  for (size_t i = 0; i < nitems; i++){
+    uint32_t t = ntohl(items[i]);
+    int16_t re = (t >> 16) & 0xffff;
+    int16_t im = (t & 0xffff);
+    host_items[i] = std::complex<float>(re * 1.0/32768, im * 1.0/32768);
+  }
+}
+
+// ------------------------------------------------------------------------
+
+class rx_nop_handler : public vrt::rx_packet_handler
+{
+private:
+  uint64_t     d_max_samples;
+  uint64_t     d_max_quantum;
+  uint64_t     d_nsamples;
+  uint64_t     d_npackets;
+  int          d_last_pkt_cnt;
+  uint64_t     d_nwrong_pkt_cnt;
+
+protected:
+  bool         d_err;
+
+public:
+
+  // Shared pointer to an instance of this class
+  typedef boost::shared_ptr<rx_nop_handler> sptr;
+
+  /*!
+   * Constructor
+   *
+   * \param max_samples  Maximum number of samples to copy. Use zero for no 
maximum.
+   * \param max_quantum  Maximum number of samples required to accept in one 
call.
+   *                     Use 0 to indicate no maximum.
+   */
+  rx_nop_handler(uint64_t max_samples, uint64_t max_quantum=0)
+    : d_max_samples(max_samples), d_max_quantum(max_quantum),
+      d_nsamples(0), d_npackets(0), 
+      d_last_pkt_cnt(0xf), d_nwrong_pkt_cnt(0),
+      d_err(false){}
+
+    
+    ~rx_nop_handler();
+  
+  bool operator()(const uint32_t *payload,
+                 size_t n32_bit_words,
+                 const vrt::expanded_header *hdr);
+
+  /*!
+   * \brief Returns number of packets this copier was called with
+   */
+  uint64_t npackets() const { return d_npackets; }
+
+  /*!
+   * \brief Returns actual number of samples copied
+   */
+  uint64_t nsamples() const { return d_nsamples; }
+
+  /*!
+   * \brief Returns maximum number of samples that will be copied
+   */
+  uint64_t max_samples() const { return d_max_samples; }
+
+  /*!
+   * Returns true if an error has occurred. Derived classes must set d_err to 
true
+   * when an error occurs in the () operator
+   */
+  bool has_errored_p() const { return d_err; }
+
+  /*!
+   * \brief Returns true if this instance has reached the maximum number of 
samples
+   */
+  bool has_finished_p() const 
+  { return d_max_samples == 0 ? false : d_nsamples >= 
d_max_samples-d_max_quantum; }
+      
+  uint64_t nwrong_pkt_cnt() const { return d_nwrong_pkt_cnt; }
+
+
+};
+
+
+rx_nop_handler::~rx_nop_handler()
+{
+}
+
+bool
+rx_nop_handler::operator()(const uint32_t *payload,
+                          size_t n32_bit_words,
+                          const vrt::expanded_header *hdr)
+{
+  d_nsamples += n32_bit_words;
+  d_npackets++;
+
+  if (hdr->pkt_cnt() != ((d_last_pkt_cnt + 1) & 0xf)){
+    d_nwrong_pkt_cnt++;
+    fprintf(stderr, "bad cnt ");
+  }
+  d_last_pkt_cnt = hdr->pkt_cnt();
+
+  return !has_finished_p();
+}
+
+// ------------------------------------------------------------------------
+
+class file_writer_16sc : public rx_nop_handler
+{
+  FILE        *d_fp;
+  std::string  d_filename;
+  
+public:
+
+  file_writer_16sc(const std::string &filename, uint64_t max_samples)
+    : rx_nop_handler(max_samples), d_filename(filename)
+  {
+    d_fp = fopen(filename.c_str(), "wb");
+    if (d_fp == 0){
+      perror(filename.c_str());
+      throw std::invalid_argument(filename);
+    }
+  }
+
+  ~file_writer_16sc();
+
+  bool 
+  operator()(const uint32_t *items, size_t nitems, const vrt::expanded_header 
*hdr)
+  {
+    bool ok = rx_nop_handler::operator()(items, nitems, hdr);
+
+    size_t host_nitems = nitems;
+    std::complex<int16_t> host_items[host_nitems];
+
+    copy_net_16sc_to_host_16sc(nitems, items, host_items);
+
+    size_t n = 0;
+    while (n < host_nitems){
+      size_t r = fwrite(&host_items[n], sizeof(host_items[0]), host_nitems - 
n, d_fp);
+      n += r;
+      if (r == 0){     // out of space?
+        d_err = true;
+       perror(d_filename.c_str());
+       ok = false;
+       break;
+      }
+    }
+
+    return ok;
+  }
+};
+
+file_writer_16sc::~file_writer_16sc()
+{
+  fclose(d_fp);
+}
+
+// ------------------------------------------------------------------------
+
+class file_writer_32fc : public rx_nop_handler
+{
+  FILE        *d_fp;
+  std::string  d_filename;
+  
+public:
+
+  file_writer_32fc(const std::string &filename, uint64_t max_samples)
+    : rx_nop_handler(max_samples), d_filename(filename)
+  {
+    d_fp = fopen(filename.c_str(), "wb");
+    if (d_fp == 0){
+      perror(filename.c_str());
+      throw std::invalid_argument(filename);
+    }
+  }
+
+  ~file_writer_32fc();
+
+  bool 
+  operator()(const uint32_t *items, size_t nitems, const vrt::expanded_header 
*hdr)
+  {
+    bool ok = rx_nop_handler::operator()(items, nitems, hdr);
+
+    size_t host_nitems = nitems;
+    std::complex<float> host_items[host_nitems];
+
+    copy_net_16sc_to_host_32fc(nitems, items, host_items);
+
+    size_t n = 0;
+    while (n < host_nitems){
+      size_t r = fwrite(&host_items[n], sizeof(host_items[0]), host_nitems - 
n, d_fp);
+      n += r;
+      if (r == 0){     // out of space?
+        d_err = true;
+       perror(d_filename.c_str());
+       ok = false;
+       break;
+      }
+    }
+
+    return ok;
+  }
+};
+
+file_writer_32fc::~file_writer_32fc()
+{
+  fclose(d_fp);
+}
+
+// ------------------------------------------------------------------------
+
 static bool
 open_sockets(const char *quad_radio_ip, int quad_radio_ctrl_port,
             int *ctrl_fd_ptr, struct in_addr *ctrl_port_inaddr,
@@ -200,101 +443,6 @@
 
 // ------------------------------------------------------------------------
 
-class rx_nop_handler : public vrt::rx_packet_handler
-{
-private:
-  uint64_t     d_max_samples;
-  uint64_t     d_max_quantum;
-  uint64_t     d_nsamples;
-  uint64_t     d_npackets;
-  int          d_last_pkt_cnt;
-  uint64_t     d_nwrong_pkt_cnt;
-
-protected:
-  bool         d_err;
-
-public:
-
-  // Shared pointer to an instance of this class
-  typedef boost::shared_ptr<rx_nop_handler> sptr;
-
-  /*!
-   * Constructor
-   *
-   * \param max_samples  Maximum number of samples to copy. Use zero for no 
maximum.
-   * \param max_quantum  Maximum number of samples required to accept in one 
call.
-   *                     Use 0 to indicate no maximum.
-   */
-  rx_nop_handler(uint64_t max_samples, uint64_t max_quantum=0)
-    : d_max_samples(max_samples), d_max_quantum(max_quantum),
-      d_nsamples(0), d_npackets(0), 
-      d_last_pkt_cnt(0xf), d_nwrong_pkt_cnt(0),
-      d_err(false){}
-
-    
-    ~rx_nop_handler();
-  
-  bool operator()(const uint32_t *payload,
-                 size_t n32_bit_words,
-                 const vrt::expanded_header *hdr);
-
-  /*!
-   * \brief Returns number of packets this copier was called with
-   */
-  uint64_t npackets() const { return d_npackets; }
-
-  /*!
-   * \brief Returns actual number of samples copied
-   */
-  uint64_t nsamples() const { return d_nsamples; }
-
-  /*!
-   * \brief Returns maximum number of samples that will be copied
-   */
-  uint64_t max_samples() const { return d_max_samples; }
-
-  /*!
-   * Returns true if an error has occurred. Derived classes must set d_err to 
true
-   * when an error occurs in the () operator
-   */
-  bool has_errored_p() const { return d_err; }
-
-  /*!
-   * \brief Returns true if this instance has reached the maximum number of 
samples
-   */
-  bool has_finished_p() const 
-  { return d_max_samples == 0 ? false : d_nsamples >= 
d_max_samples-d_max_quantum; }
-      
-  uint64_t nwrong_pkt_cnt() const { return d_nwrong_pkt_cnt; }
-
-
-};
-
-
-rx_nop_handler::~rx_nop_handler()
-{
-}
-
-bool
-rx_nop_handler::operator()(const uint32_t *payload,
-                            size_t n32_bit_words,
-                            const vrt::expanded_header *hdr)
-{
-  d_nsamples += n32_bit_words;
-  d_npackets++;
-
-
-  if (hdr->pkt_cnt() != ((d_last_pkt_cnt + 1) & 0xf)){
-    d_nwrong_pkt_cnt++;
-    fprintf(stderr, "bad cnt ");
-  }
-  d_last_pkt_cnt = hdr->pkt_cnt();
-
-  return !has_finished_p();
-}
-
-// ------------------------------------------------------------------------
-
 static void
 usage(const char *progname)
 {
@@ -315,7 +463,7 @@
 //fprintf(stderr, "  -g GAIN              specify receive daughterboard gain 
[default=0]\n");
   fprintf(stderr, "  -N NSAMPLES          specify number of samples to receive 
[default=infinite]\n");
   fprintf(stderr, "  -o OUTPUT_FILENAME   specify file to receive samples 
[default=none]\n");
-//fprintf(stderr, "  -s                   write complex<short> 
[default=complex<float>]\n");
+  fprintf(stderr, "  -s                   write complex<short> 
[default=complex<float>]\n");
 //fprintf(stderr, "  -v                   verbose output\n");
 }
 
@@ -329,6 +477,7 @@
   int samples_per_pkt = 0;         // use default
   uint64_t nsamples = 0;
   char *output_filename = 0;
+  bool output_shorts = false;
   int siggen_param = 0;
 
   int           ctrl_fd;           // socket for control
@@ -339,7 +488,7 @@
 
   int ch;
 
-  while ((ch = getopt(argc, argv, "hN:o:")) != EOF){
+  while ((ch = getopt(argc, argv, "hN:o:s")) != EOF){
     switch (ch){
     case 'N':
       nsamples = (uint64_t) strtod(optarg, 0);
@@ -349,6 +498,10 @@
       output_filename = optarg;
       break;
 
+    case 's':
+      output_shorts = true;
+      break;
+
     case 'h':
     default:
       usage(argv[0]);
@@ -371,9 +524,18 @@
   vrt::rx_udp::sptr vrt_receiver = vrt::rx_udp::make(data_fd, rx_bufsize);
   
 
-  rx_nop_handler::sptr handler =
-    rx_nop_handler::sptr(new rx_nop_handler(nsamples));
+  rx_nop_handler::sptr handler;
 
+  if (output_filename){
+    if (output_shorts)
+      handler = rx_nop_handler::sptr(new file_writer_16sc(output_filename, 
nsamples));
+    else
+      handler = rx_nop_handler::sptr(new file_writer_32fc(output_filename, 
nsamples));
+  }
+  else
+    handler = rx_nop_handler::sptr(new rx_nop_handler(nsamples));
+
+
   if (!send_rx_command(ctrl_fd, true, ctrl_port_inaddr, data_port, 
samples_per_pkt, siggen_param)){
     fprintf(stderr, "failed to send_rx_command\n");
     return 1;

Modified: gnuradio/branches/developers/eb/vrt/vrt/lib/expanded_header.cc
===================================================================
--- gnuradio/branches/developers/eb/vrt/vrt/lib/expanded_header.cc      
2009-05-15 08:30:52 UTC (rev 11041)
+++ gnuradio/branches/developers/eb/vrt/vrt/lib/expanded_header.cc      
2009-05-15 09:39:20 UTC (rev 11042)
@@ -24,6 +24,7 @@
 #endif
 #include <vrt/expanded_header.h>
 #include <arpa/inet.h>                 // needs autoconf'ing
+//#include <stdio.h>
 
 namespace vrt {
 
@@ -83,6 +84,8 @@
     *payload = 0;
     *n32_bit_words_payload = 0;
 
+    // printf("parse: n32_bit_words_packet = %zd\n", n32_bit_words_packet);
+
     if (len < 1){              // must have at least the header word
       h->header = 0;
       return false;
@@ -102,6 +105,9 @@
     *payload = p + cw_header_len(cw);
     *n32_bit_words_payload = len - (cw_header_len(cw) + cw_trailer_len(cw));
 
+    // printf("parse: hdr = 0x%08x, cw = 0x%02x, cw_header_len(cw) = %d, 
cw_trailer_len(cw) = %d\n",
+    //   h->header, cw, cw_header_len(cw), cw_trailer_len(cw));
+
     switch (cw & 0x1f){
 #include "expanded_header_switch_body.h"
     }





reply via email to

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