summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rondeau <trondeau@vt.edu>2012-11-21 17:25:24 -0500
committerTom Rondeau <trondeau@vt.edu>2012-11-21 18:12:11 -0500
commiteb4163c7bdd63783e570fb28ba87144a4c86d22f (patch)
tree01ca91bb43b77100847aa9b4e528343aad75642d
parent9a2393aac834c43216d2a83b524ac19e9596f4e9 (diff)
core: Adding a file sink block that stores metadata with file.
Current working version only has a single header at the top of the file. Must update to add metadata fields when changes occur. Also adding extra_header structure to store extram, users-specified info.
-rw-r--r--gnuradio-core/src/lib/io/CMakeLists.txt1
-rw-r--r--gnuradio-core/src/lib/io/gr_file_meta_sink.cc125
-rw-r--r--gnuradio-core/src/lib/io/gr_file_meta_sink.h86
-rw-r--r--gnuradio-core/src/lib/io/gr_file_meta_sink.i71
-rw-r--r--gnuradio-core/src/lib/io/io.i2
5 files changed, 285 insertions, 0 deletions
diff --git a/gnuradio-core/src/lib/io/CMakeLists.txt b/gnuradio-core/src/lib/io/CMakeLists.txt
index 3dea13396c..ddd43a4a32 100644
--- a/gnuradio-core/src/lib/io/CMakeLists.txt
+++ b/gnuradio-core/src/lib/io/CMakeLists.txt
@@ -81,6 +81,7 @@ endif(ENABLE_PYTHON)
########################################################################
set(gr_core_io_triple_threats
gr_file_sink
+ gr_file_meta_sink
gr_file_sink_base
gr_file_source
gr_file_descriptor_sink
diff --git a/gnuradio-core/src/lib/io/gr_file_meta_sink.cc b/gnuradio-core/src/lib/io/gr_file_meta_sink.cc
new file mode 100644
index 0000000000..aa34bf9b70
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_file_meta_sink.cc
@@ -0,0 +1,125 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_file_meta_sink.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+
+gr_file_meta_sink_sptr
+gr_make_file_meta_sink(size_t itemsize, const char *filename,
+ double samp_rate, gr_file_types type, bool complex,
+ const std::string &extra_dict)
+{
+ return gnuradio::get_initial_sptr
+ (new gr_file_meta_sink(itemsize, filename,
+ samp_rate, type, complex,
+ extra_dict));
+}
+
+gr_file_meta_sink::gr_file_meta_sink(size_t itemsize, const char *filename,
+ double samp_rate, gr_file_types type, bool complex,
+ const std::string &extra_dict)
+ : gr_sync_block("file_meta_sink",
+ gr_make_io_signature(1, 1, itemsize),
+ gr_make_io_signature(0, 0, 0)),
+ gr_file_sink_base(filename, true),
+ d_itemsize(itemsize)
+{
+ if(!open(filename))
+ throw std::runtime_error("file_meta_sink: can't open file\n");
+
+ pmt_t timestamp = pmt_make_tuple(pmt_from_uint64(0),
+ pmt_from_double(0));
+
+ d_header = pmt_make_dict();
+ d_header = pmt_dict_add(d_header, mp("sr"), mp(samp_rate));
+ d_header = pmt_dict_add(d_header, mp("time"), timestamp);
+ d_header = pmt_dict_add(d_header, mp("type"), pmt_from_long(type));
+ d_header = pmt_dict_add(d_header, mp("cplx"), complex ? PMT_T : PMT_F);
+ d_header = pmt_dict_add(d_header, mp("strt"), pmt_from_uint64(109));
+ d_header = pmt_dict_add(d_header, mp("size"), pmt_from_uint64(0));
+ // handle extra dictionary
+
+ write_header(d_header);
+}
+
+void
+gr_file_meta_sink::write_header(pmt_t header)
+{
+ do_update();
+
+ std::string header_str = pmt_serialize_str(header);
+
+ size_t nwritten = 0;
+ while(nwritten < header_str.size()) {
+ std::string sub = header_str.substr(nwritten);
+ int count = fwrite(sub.c_str(), sizeof(char), sub.size(), d_fp);
+ nwritten += count;
+ if((count == 0) && (ferror(d_fp))) {
+ fclose(d_fp);
+ throw std::runtime_error("file_meta_sink: error writing header to file\n");
+ }
+ }
+}
+
+gr_file_meta_sink::~gr_file_meta_sink()
+{
+ fseek(d_fp, 0, SEEK_SET);
+
+ // Replace the dictionary item with the data size now that we're
+ // done.
+ uint64_t s = nitems_read(0) * d_itemsize;
+ d_header = pmt_dict_delete(d_header, mp("size"));
+ d_header = pmt_dict_add(d_header, mp("size"), pmt_from_uint64(s));
+ write_header(d_header);
+}
+
+int
+gr_file_meta_sink::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ char *inbuf = (char*)input_items[0];
+ int nwritten = 0;
+
+ do_update(); // update d_fp is reqd
+
+ if(!d_fp)
+ return noutput_items; // drop output on the floor
+
+ while(nwritten < noutput_items) {
+ int count = fwrite(inbuf, d_itemsize, noutput_items - nwritten, d_fp);
+ if(count == 0) // FIXME add error handling
+ break;
+ nwritten += count;
+ inbuf += count * d_itemsize;
+ }
+
+ if(d_unbuffered)
+ fflush(d_fp);
+
+ return nwritten;
+}
diff --git a/gnuradio-core/src/lib/io/gr_file_meta_sink.h b/gnuradio-core/src/lib/io/gr_file_meta_sink.h
new file mode 100644
index 0000000000..741408de18
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_file_meta_sink.h
@@ -0,0 +1,86 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_FILE_META_SINK_H
+#define INCLUDED_GR_FILE_META_SINK_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <gr_file_sink_base.h>
+#include <gruel/pmt.h>
+
+using namespace pmt;
+
+enum gr_file_types {
+ GR_FILE_BYTE=0,
+ GR_FILE_CHAR=0,
+ GR_FILE_SHORT=1,
+ GR_FILE_INT,
+ GR_FILE_LONG,
+ GR_FILE_LONG_LONG,
+ GR_FILE_FLOAT,
+ GR_FILE_DOUBLE,
+};
+
+class gr_file_meta_sink;
+typedef boost::shared_ptr<gr_file_meta_sink> gr_file_meta_sink_sptr;
+
+GR_CORE_API gr_file_meta_sink_sptr
+gr_make_file_meta_sink(size_t itemsize, const char *filename,
+ double samp_rate, gr_file_types type, bool complex,
+ const std::string &extra_dict="");
+
+/*!
+ * \brief Write stream to file.
+ * \ingroup sink_blk
+ */
+
+class GR_CORE_API gr_file_meta_sink : public gr_sync_block, public gr_file_sink_base
+{
+
+ friend GR_CORE_API gr_file_meta_sink_sptr
+ gr_make_file_meta_sink(size_t itemsize, const char *filename,
+ double samp_rate, gr_file_types type, bool complex,
+ const std::string &extra_dict);
+
+ private:
+ size_t d_itemsize;
+ pmt_t d_header;
+ pmt_t d_extra_dict;
+
+ protected:
+ gr_file_meta_sink(size_t itemsize, const char *filename,
+ double samp_rate, gr_file_types type, bool complex,
+ const std::string &extra_dict);
+
+
+ void write_header(pmt_t header);
+
+ public:
+ ~gr_file_meta_sink();
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_FILE_META_SINK_H */
diff --git a/gnuradio-core/src/lib/io/gr_file_meta_sink.i b/gnuradio-core/src/lib/io/gr_file_meta_sink.i
new file mode 100644
index 0000000000..27fb4debbf
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_file_meta_sink.i
@@ -0,0 +1,71 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,file_meta_sink)
+
+enum gr_file_types {
+ GR_FILE_BYTE=0,
+ GR_FILE_CHAR=0,
+ GR_FILE_SHORT,
+ GR_FILE_INT,
+ GR_FILE_LONG,
+ GR_FILE_LONG_LONG,
+ GR_FILE_FLOAT,
+ GR_FILE_DOUBLE,
+};
+
+gr_file_meta_sink_sptr
+gr_make_file_meta_sink(size_t itemsize, const char *filename,
+ double samp_rate, gr_file_types type, bool complex,
+ const std::string & extra_dict="");
+
+class gr_file_meta_sink : public gr_sync_block, public gr_file_sink_base
+{
+ protected:
+ gr_file_meta_sink(size_t itemsize, const char *filename,
+ double samp_rate, gr_file_types type, bool complex,
+ const std::string & extra_dict);
+
+ public:
+ ~gr_file_meta_sink();
+
+ enum file_types {
+ FILE_BYTE=0,
+ FILE_CHAR=0,
+ FILE_SHORT,
+ FILE_INT,
+ FILE_LONG,
+ FILE_LONG_LONG,
+ FILE_FLOAT,
+ FILE_DOUBLE,
+ };
+
+ /*!
+ * \brief open filename and begin output to it.
+ */
+ bool open(const char *filename);
+
+ /*!
+ * \brief close current output file.
+ */
+ void close();
+};
diff --git a/gnuradio-core/src/lib/io/io.i b/gnuradio-core/src/lib/io/io.i
index 5cd352905d..07f2e9195e 100644
--- a/gnuradio-core/src/lib/io/io.i
+++ b/gnuradio-core/src/lib/io/io.i
@@ -27,6 +27,7 @@
#endif
#include <gr_file_sink.h>
+#include <gr_file_meta_sink.h>
#include <gr_file_source.h>
#include <gr_file_descriptor_sink.h>
#include <gr_file_descriptor_source.h>
@@ -49,6 +50,7 @@
%include "gr_file_sink_base.i"
%include "gr_file_sink.i"
+%include "gr_file_meta_sink.i"
%include "gr_file_source.i"
%include "gr_file_descriptor_sink.i"
%include "gr_file_descriptor_source.i"