diff options
author | Tom Rondeau <trondeau@vt.edu> | 2012-11-21 17:25:24 -0500 |
---|---|---|
committer | Tom Rondeau <trondeau@vt.edu> | 2012-11-21 18:12:11 -0500 |
commit | eb4163c7bdd63783e570fb28ba87144a4c86d22f (patch) | |
tree | 01ca91bb43b77100847aa9b4e528343aad75642d | |
parent | 9a2393aac834c43216d2a83b524ac19e9596f4e9 (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.txt | 1 | ||||
-rw-r--r-- | gnuradio-core/src/lib/io/gr_file_meta_sink.cc | 125 | ||||
-rw-r--r-- | gnuradio-core/src/lib/io/gr_file_meta_sink.h | 86 | ||||
-rw-r--r-- | gnuradio-core/src/lib/io/gr_file_meta_sink.i | 71 | ||||
-rw-r--r-- | gnuradio-core/src/lib/io/io.i | 2 |
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" |