[Top][All Lists]
[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"
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Commit-gnuradio] r11042 - in gnuradio/branches/developers/eb/vrt/vrt: apps lib,
eb <=