From cce9f3d981560696af36fdcf3a8ea03230d354dc Mon Sep 17 00:00:00 2001 From: Kostis Triantayllakis Date: Mon, 7 Aug 2017 17:05:35 +0300 Subject: [PATCH] Introduce IQ sink block --- CMakeLists.txt | 2 +- grc/CMakeLists.txt | 3 +- grc/satnogs_iq_sink.xml | 52 ++++++++++++++ include/satnogs/CMakeLists.txt | 3 +- include/satnogs/iq_sink.h | 72 +++++++++++++++++++ lib/CMakeLists.txt | 3 +- lib/iq_sink_impl.cc | 124 +++++++++++++++++++++++++++++++++ lib/iq_sink_impl.h | 65 +++++++++++++++++ swig/satnogs_swig.i | 3 + 9 files changed, 323 insertions(+), 4 deletions(-) create mode 100644 grc/satnogs_iq_sink.xml create mode 100644 include/satnogs/iq_sink.h create mode 100644 lib/iq_sink_impl.cc create mode 100644 lib/iq_sink_impl.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 7644674..ac70c9c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -152,7 +152,7 @@ endif() # components required to the list of GR_REQUIRED_COMPONENTS (in all # caps such as FILTER or FFT) and change the version to the minimum # API compatible version required. -set(GR_REQUIRED_COMPONENTS RUNTIME FFT FILTER DIGITAL) +set(GR_REQUIRED_COMPONENTS RUNTIME FFT FILTER DIGITAL BLOCKS) find_package(Gnuradio "3.7.7" REQUIRED) list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_SOURCE_DIR}/cmake/Modules) include(GrVersion) diff --git a/grc/CMakeLists.txt b/grc/CMakeLists.txt index e5fb976..73ae86e 100644 --- a/grc/CMakeLists.txt +++ b/grc/CMakeLists.txt @@ -51,5 +51,6 @@ install(FILES ${enabled_blocks} satnogs_ogg_source.xml satnogs_noaa_apt_sink.xml - satnogs_frame_file_sink.xml DESTINATION share/gnuradio/grc/blocks + satnogs_frame_file_sink.xml + satnogs_iq_sink.xml DESTINATION share/gnuradio/grc/blocks ) diff --git a/grc/satnogs_iq_sink.xml b/grc/satnogs_iq_sink.xml new file mode 100644 index 0000000..853d1a4 --- /dev/null +++ b/grc/satnogs_iq_sink.xml @@ -0,0 +1,52 @@ + + + IQ Sink + satnogs_iq_sink + [SatNOGS] + import satnogs + satnogs.iq_sink($scale, $filename, $append, $status) + open($file) + + + File + filename + + file_save + + + + Status + status + 0 + int + part + + + + Scale + scale + 32767 + float + + + + Append file + append + False + bool + + + + + + in + complex + + + diff --git a/include/satnogs/CMakeLists.txt b/include/satnogs/CMakeLists.txt index b1b2329..dad2300 100644 --- a/include/satnogs/CMakeLists.txt +++ b/include/satnogs/CMakeLists.txt @@ -65,5 +65,6 @@ install(FILES ${HEADER_FILES} ogg_source.h noaa_apt_sink.h - frame_file_sink.h DESTINATION include/satnogs + frame_file_sink.h + iq_sink.h DESTINATION include/satnogs ) \ No newline at end of file diff --git a/include/satnogs/iq_sink.h b/include/satnogs/iq_sink.h new file mode 100644 index 0000000..52773f3 --- /dev/null +++ b/include/satnogs/iq_sink.h @@ -0,0 +1,72 @@ +/* -*- c++ -*- */ +/* + * gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module + * + * Copyright (C) 2017, Libre Space Foundation + * + * This program 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 of the License, or + * (at your option) any later version. + * + * This program 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 this program. If not, see . + */ + +#ifndef INCLUDED_SATNOGS_IQ_SINK_H +#define INCLUDED_SATNOGS_IQ_SINK_H + +#include +#include +#include + +namespace gr +{ + namespace satnogs + { + + /*! + * \brief This block converts a complex float input stream to short and stores + * it to a file. If the value of status argument is zero the block behaves + * as a null sink block. + * + * \ingroup satnogs + * + */ + class SATNOGS_API iq_sink : virtual public gr::sync_block, + virtual public gr::blocks::file_sink_base + { + public: + typedef boost::shared_ptr sptr; + + /** + * This block converts a complex float input stream to short and stores + * it to a file. If the value of status argument is zero the block behaves + * as a null sink block. + * + * @param scale the value multiplied against each point in the input stream + * @param filename name of the file to open and write output to. + * @param append if true, data is appended to the file instead of + * overwriting the initial content. + * @param status the status of the block. + * - 0: Block acts as a null sink + * - 1: Active + * + * @return a shared_ptr to a new instance of satnogs::iq_sink. + */ + static sptr make(const float scale, + const char *filename, bool append=false, + const int status = 0); + }; + +} + // namespace satnogs +}// namespace gr + +#endif /* INCLUDED_SATNOGS_IQ_SINK_H */ + diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 678f031..7f7730c 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -63,7 +63,8 @@ list(APPEND satnogs_sources waterfall_sink_impl.cc ogg_source_impl.cc noaa_apt_sink_impl.cc - frame_file_sink_impl.cc) + frame_file_sink_impl.cc + iq_sink_impl.cc) if(${INCLUDE_DEBUG_BLOCKS}) list(APPEND satnogs_sources ${satnogs_debug_sources}) diff --git a/lib/iq_sink_impl.cc b/lib/iq_sink_impl.cc new file mode 100644 index 0000000..d5ac027 --- /dev/null +++ b/lib/iq_sink_impl.cc @@ -0,0 +1,124 @@ +/* -*- c++ -*- */ +/* + * gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module + * + * Copyright (C) 2017, Libre Space Foundation + * + * This program 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 of the License, or + * (at your option) any later version. + * + * This program 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 this program. If not, see . + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include "iq_sink_impl.h" +#include +#include + +namespace gr +{ + namespace satnogs + { + + iq_sink::sptr + iq_sink::make (const float scale, const char *filename, bool append, + const int status) + { + return gnuradio::get_initial_sptr ( + new iq_sink_impl (scale, filename, append, status)); + } + + /* + * The private constructor + */ + iq_sink_impl::iq_sink_impl (const float scale, const char *filename, + bool append, const int status) : + gr::sync_block ("iq_sink", + gr::io_signature::make (1, 1, sizeof(gr_complex)), + gr::io_signature::make (0, 0, 0)), + file_sink_base (filename, true, append), + d_scale (scale), + d_num_points (16384), + d_status ((iq_sink_status_t) status) + { + set_max_noutput_items (d_num_points); + unsigned int alignment = volk_get_alignment (); + d_out = (int16_t*) volk_malloc (sizeof(int16_t) * d_num_points * 2, + alignment); + } + + /* + * Our virtual destructor. + */ + iq_sink_impl::~iq_sink_impl () + { + volk_free (d_out); + } + + int + iq_sink_impl::work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + gr_complex *inbuf = (gr_complex*) input_items[0]; + int nwritten = 0; + switch (d_status) + { + case IQ_SINK_STATUS_NULL: + { + return noutput_items; + break; + } + + case IQ_SINK_STATUS_ACTIVE: + { + /* update d_fp is required */ + do_update (); + + if (!d_fp) + /* drop output on the floor */ + return noutput_items; + + volk_32f_s32f_convert_16i (d_out, (float*) inbuf, d_scale, + noutput_items * 2); + + while (nwritten < noutput_items) { + int count = fwrite (d_out, 2 * sizeof(int16_t), + noutput_items - nwritten, d_fp); + if (count == 0) { + if (ferror (d_fp)) { + std::cout << count << std::endl; + std::stringstream s; + s << "file_sink write failed with error " << fileno (d_fp) + << std::endl; + throw std::runtime_error (s.str ()); + } + /* if EOF */ + else { + break; + } + } + nwritten += count; + } + + return nwritten; + break; + } + } + } + + } /* namespace satnogs */ +} /* namespace gr */ + diff --git a/lib/iq_sink_impl.h b/lib/iq_sink_impl.h new file mode 100644 index 0000000..843105f --- /dev/null +++ b/lib/iq_sink_impl.h @@ -0,0 +1,65 @@ +/* -*- c++ -*- */ +/* + * gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module + * + * Copyright (C) 2017, Libre Space Foundation + * + * This program 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 of the License, or + * (at your option) any later version. + * + * This program 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 this program. If not, see . + */ + +#ifndef INCLUDED_SATNOGS_IQ_SINK_IMPL_H +#define INCLUDED_SATNOGS_IQ_SINK_IMPL_H + +#include +#include +#include + +namespace gr +{ + namespace satnogs + { + + class iq_sink_impl : public iq_sink + { + private: + /** + * The different values for iq sink status + */ + typedef enum + { + IQ_SINK_STATUS_NULL = 0, //!< IQ_SINK_STATUS_NULL IQ sink block behaves just like a null sink + IQ_SINK_STATUS_ACTIVE = 1, //!< IQ_SINK_STATUS_ACTIVE IQ sink block is active + } iq_sink_status_t; + + iq_sink_status_t d_status; + size_t d_num_points; + float d_scale; + int16_t *d_out; + const char *d_filename; + + public: + iq_sink_impl (const float scale, const char *filename, bool append, + const int status); + ~iq_sink_impl (); + + int + work (int noutput_items, gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } // namespace satnogs +} // namespace gr + +#endif /* INCLUDED_SATNOGS_IQ_SINK_IMPL_H */ + diff --git a/swig/satnogs_swig.i b/swig/satnogs_swig.i index a903fdd..40e5a7f 100644 --- a/swig/satnogs_swig.i +++ b/swig/satnogs_swig.i @@ -35,6 +35,7 @@ #include "satnogs/ogg_source.h" #include "satnogs/noaa_apt_sink.h" #include "satnogs/frame_file_sink.h" +#include "satnogs/iq_sink.h" %} @@ -109,3 +110,5 @@ GR_SWIG_BLOCK_MAGIC2(satnogs, ogg_source); GR_SWIG_BLOCK_MAGIC2(satnogs, noaa_apt_sink); %include "satnogs/frame_file_sink.h" GR_SWIG_BLOCK_MAGIC2(satnogs, frame_file_sink); +%include "satnogs/iq_sink.h" +GR_SWIG_BLOCK_MAGIC2(satnogs, iq_sink);