diff --git a/src/algorithms/signal_source/adapters/two_bit_cpx_file_signal_source.cc b/src/algorithms/signal_source/adapters/two_bit_cpx_file_signal_source.cc index b968793d7..6df4af185 100644 --- a/src/algorithms/signal_source/adapters/two_bit_cpx_file_signal_source.cc +++ b/src/algorithms/signal_source/adapters/two_bit_cpx_file_signal_source.cc @@ -9,22 +9,14 @@ * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. * This file is part of GNSS-SDR. * - * Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors) + * Copyright (C) 2010-2021 (see AUTHORS file for a list of contributors) * SPDX-License-Identifier: GPL-3.0-or-later * * ----------------------------------------------------------------------------- */ #include "two_bit_cpx_file_signal_source.h" -#include "configuration_interface.h" -#include "gnss_sdr_flags.h" -#include "gnss_sdr_valve.h" #include -#include -#include -#include -#include -#include using namespace std::string_literals; @@ -32,274 +24,61 @@ using namespace std::string_literals; TwoBitCpxFileSignalSource::TwoBitCpxFileSignalSource( const ConfigurationInterface* configuration, const std::string& role, - unsigned int in_streams, - unsigned int out_streams, + unsigned int in_streams, unsigned int out_streams, Concurrent_Queue* queue) - : SignalSourceBase(configuration, role, "Two_Bit_Cpx_File_Signal_Source"s), in_streams_(in_streams), out_streams_(out_streams) + : FileSourceBase(configuration, role, "Two_Bit_Cpx_File_Signal_Source"s, queue, "byte"s) { - const std::string default_filename("../data/my_capture.dat"); - const std::string default_item_type("byte"); - const std::string default_dump_filename("../data/my_capture_dump.dat"); - - samples_ = configuration->property(role + ".samples", static_cast(0)); - sampling_frequency_ = configuration->property(role + ".sampling_frequency", static_cast(0)); - filename_ = configuration->property(role + ".filename", default_filename); - - // override value with commandline flag, if present - if (FLAGS_signal_source != "-") - { - filename_ = FLAGS_signal_source; - } - if (FLAGS_s != "-") - { - filename_ = FLAGS_s; - } - - item_type_ = configuration->property(role + ".item_type", default_item_type); - repeat_ = configuration->property(role + ".repeat", false); - dump_ = configuration->property(role + ".dump", false); - dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename); - enable_throttle_control_ = configuration->property(role + ".enable_throttle_control", false); - - if (item_type_ == "byte") - { - item_size_ = sizeof(char); - } - else - { - LOG(WARNING) << item_type_ << " unrecognized item type. Using byte."; - item_size_ = sizeof(char); - } - try - { - file_source_ = gr::blocks::file_source::make(item_size_, filename_.c_str(), repeat_); - unpack_byte_ = make_unpack_byte_2bit_cpx_samples(); - inter_shorts_to_cpx_ = gr::blocks::interleaved_short_to_complex::make(false, true); // I/Q swap enabled - } - catch (const std::exception& e) - { - std::cerr - << "The receiver was configured to work with a file signal source\n" - << "but the specified file is unreachable by GNSS-SDR.\n" - << "Please modify your configuration file\n" - << "and point SignalSource.filename to a valid raw data file. Then:\n" - << "$ gnss-sdr --config_file=/path/to/my_GNSS_SDR_configuration.conf\n" - << "Examples of configuration files available at:\n" - << GNSSSDR_INSTALL_DIR "/share/gnss-sdr/conf/\n"; - - LOG(WARNING) << "file_signal_source: Unable to open the samples file " - << filename_.c_str() << ", exiting the program."; - throw(e); - } - - DLOG(INFO) << "file_source(" << file_source_->unique_id() << ")"; - - if (samples_ == 0) // read all file - { - /*! - * BUG workaround: The GNU Radio file source does not stop the receiver after reaching the End of File. - * A possible solution is to compute the file length in samples using file size, excluding the last 2 milliseconds, and enable always the - * valve block - */ - std::ifstream file(filename_.c_str(), std::ios::in | std::ios::binary | std::ios::ate); - std::ifstream::pos_type size; - - if (file.is_open()) - { - size = file.tellg(); - LOG(INFO) << "Total samples in the file= " << floor(static_cast(size) / static_cast(item_size())); - } - else - { - std::cout << "file_signal_source: Unable to open the samples file " << filename_.c_str() << '\n'; - LOG(ERROR) << "file_signal_source: Unable to open the samples file " << filename_.c_str(); - } - std::streamsize ss = std::cout.precision(); - std::cout << std::setprecision(16); - std::cout << "Processing file " << filename_ << ", which contains " << size << " [bytes]\n"; - std::cout.precision(ss); - - if (size > 0) - { - int sample_packet_factor = 2; // 1 byte -> 2 samples - samples_ = floor(static_cast(size) / static_cast(item_size())) * sample_packet_factor; - samples_ = samples_ - ceil(0.002 * static_cast(sampling_frequency_)); // process all the samples available in the file excluding the last 2 ms - } - } - - CHECK(samples_ > 0) << "File does not contain enough samples to process."; - const double signal_duration_s = static_cast(samples_) * (1 / static_cast(sampling_frequency_)); - LOG(INFO) << "Total number samples to be processed= " << samples_ << " GNSS signal duration= " << signal_duration_s << " [s]"; - std::cout << "GNSS signal recorded time to be processed: " << signal_duration_s << " [s]\n"; - - valve_ = gnss_sdr_make_valve(sizeof(gr_complex), samples_, queue); - DLOG(INFO) << "valve(" << valve_->unique_id() << ")"; - - if (dump_) - { - // sink_ = gr_make_file_sink(item_size_, dump_filename_.c_str()); - sink_ = gr::blocks::file_sink::make(sizeof(gr_complex), dump_filename_.c_str()); - DLOG(INFO) << "file_sink(" << sink_->unique_id() << ")"; - } - - if (enable_throttle_control_) - { - throttle_ = gr::blocks::throttle::make(sizeof(gr_complex), sampling_frequency_); - } - DLOG(INFO) << "File source filename " << filename_; - DLOG(INFO) << "Samples " << samples_; - DLOG(INFO) << "Sampling frequency " << sampling_frequency_; - DLOG(INFO) << "Item type " << item_type_; - DLOG(INFO) << "Item size " << item_size_; - DLOG(INFO) << "Repeat " << repeat_; - DLOG(INFO) << "Dump " << dump_; - DLOG(INFO) << "Dump filename " << dump_filename_; - if (in_streams_ > 0) + if (in_streams > 0) { LOG(ERROR) << "A signal source does not have an input stream"; } - if (out_streams_ > 1) + if (out_streams > 1) { LOG(ERROR) << "This implementation only supports one output stream"; } } -void TwoBitCpxFileSignalSource::connect(gr::top_block_sptr top_block) +std::tuple TwoBitCpxFileSignalSource::itemTypeToSize() const { - if (samples_ > 0) + auto is_complex = false; + auto item_size = size_t(sizeof(char)); // default + + if (item_type() == "byte") { - if (enable_throttle_control_ == true) - { - top_block->connect(file_source_, 0, unpack_byte_, 0); - top_block->connect(unpack_byte_, 0, inter_shorts_to_cpx_, 0); - top_block->connect(inter_shorts_to_cpx_, 0, throttle_, 0); - DLOG(INFO) << "connected file source to throttle"; - top_block->connect(throttle_, 0, valve_, 0); - DLOG(INFO) << "connected throttle to valve"; - if (dump_) - { - top_block->connect(valve_, 0, sink_, 0); - DLOG(INFO) << "connected valve to file sink"; - } - } - else - { - top_block->connect(file_source_, 0, unpack_byte_, 0); - top_block->connect(unpack_byte_, 0, inter_shorts_to_cpx_, 0); - top_block->connect(inter_shorts_to_cpx_, 0, valve_, 0); - DLOG(INFO) << "connected file source to valve"; - if (dump_) - { - top_block->connect(valve_, 0, sink_, 0); - DLOG(INFO) << "connected valve to file sink"; - } - } + item_size = sizeof(char); } else { - if (enable_throttle_control_ == true) - { - top_block->connect(file_source_, 0, unpack_byte_, 0); - top_block->connect(unpack_byte_, 0, inter_shorts_to_cpx_, 0); - top_block->connect(inter_shorts_to_cpx_, 0, throttle_, 0); - DLOG(INFO) << "connected file source to throttle"; - if (dump_) - { - top_block->connect(throttle_, 0, sink_, 0); - DLOG(INFO) << "connected file source to sink"; - } - } - else - { - if (dump_) - { - top_block->connect(file_source_, 0, unpack_byte_, 0); - top_block->connect(unpack_byte_, 0, inter_shorts_to_cpx_, 0); - top_block->connect(inter_shorts_to_cpx_, 0, sink_, 0); - DLOG(INFO) << "connected file source to sink"; - } - } + LOG(WARNING) << item_type() << " unrecognized item type. Using byte."; } + + return std::make_tuple(item_size, is_complex); } +// 1 byte -> 2 samples +double TwoBitCpxFileSignalSource::packetsPerSample() const { return 2.0; } +gnss_shared_ptr TwoBitCpxFileSignalSource::source() const { return inter_shorts_to_cpx_; } -void TwoBitCpxFileSignalSource::disconnect(gr::top_block_sptr top_block) + +void TwoBitCpxFileSignalSource::create_file_source_hook() { - if (samples_ > 0) - { - if (enable_throttle_control_ == true) - { - top_block->disconnect(file_source_, 0, unpack_byte_, 0); - DLOG(INFO) << "disconnected file source to unpack_byte_"; - top_block->connect(unpack_byte_, 0, throttle_, 0); - DLOG(INFO) << "disconnected unpack_byte_ to throttle_"; - top_block->disconnect(throttle_, 0, valve_, 0); - DLOG(INFO) << "disconnected throttle to valve"; - if (dump_) - { - top_block->disconnect(valve_, 0, sink_, 0); - DLOG(INFO) << "disconnected valve to file sink"; - } - } - else - { - top_block->disconnect(file_source_, 0, unpack_byte_, 0); - DLOG(INFO) << "disconnected file source to unpack_byte_"; - top_block->disconnect(unpack_byte_, 0, valve_, 0); - DLOG(INFO) << "disconnected unpack_byte_ to valve"; - if (dump_) - { - top_block->disconnect(valve_, 0, sink_, 0); - DLOG(INFO) << "disconnected valve to file sink"; - } - } - } - else - { - if (enable_throttle_control_ == true) - { - top_block->disconnect(file_source_, 0, unpack_byte_, 0); - DLOG(INFO) << "disconnected file source to unpack_byte_"; - top_block->disconnect(unpack_byte_, 0, throttle_, 0); - DLOG(INFO) << "disconnected unpack_byte_ to throttle"; - if (dump_) - { - top_block->disconnect(unpack_byte_, 0, sink_, 0); - DLOG(INFO) << "disconnected funpack_byte_ to sink"; - } - } - else - { - if (dump_) - { - top_block->disconnect(file_source_, 0, unpack_byte_, 0); - DLOG(INFO) << "disconnected file source to unpack_byte_"; - top_block->disconnect(unpack_byte_, 0, sink_, 0); - DLOG(INFO) << "disconnected unpack_byte_ to sink"; - } - } - } + unpack_byte_ = make_unpack_byte_2bit_cpx_samples(); + DLOG(INFO) << "unpack_byte_2bit_cpx_samples(" << unpack_byte_->unique_id() << ")"; + inter_shorts_to_cpx_ = gr::blocks::interleaved_short_to_complex::make(false, true); // I/Q swap enabled + DLOG(INFO) << "interleaved_short_to_complex(" << inter_shorts_to_cpx_->unique_id() << ")"; } - -gr::basic_block_sptr TwoBitCpxFileSignalSource::get_left_block() +void TwoBitCpxFileSignalSource::pre_connect_hook(gr::top_block_sptr top_block) { - LOG(WARNING) << "Left block of a signal source should not be retrieved"; - // return gr_block_sptr(); - return gr::blocks::file_source::sptr(); + top_block->connect(file_source(), 0, unpack_byte_, 0); + top_block->connect(unpack_byte_, 0, inter_shorts_to_cpx_, 0); + DLOG(INFO) << "connected file_source to unpacker"; } - -gr::basic_block_sptr TwoBitCpxFileSignalSource::get_right_block() +void TwoBitCpxFileSignalSource::pre_disconnect_hook(gr::top_block_sptr top_block) { - if (samples_ > 0) - { - return valve_; - } - if (enable_throttle_control_ == true) - { - return throttle_; - } - return unpack_byte_; + top_block->disconnect(file_source(), 0, unpack_byte_, 0); + top_block->disconnect(unpack_byte_, 0, inter_shorts_to_cpx_, 0); + DLOG(INFO) << "disconnected file_source from unpacker"; } diff --git a/src/algorithms/signal_source/adapters/two_bit_cpx_file_signal_source.h b/src/algorithms/signal_source/adapters/two_bit_cpx_file_signal_source.h index eabdc22cf..df72176b8 100644 --- a/src/algorithms/signal_source/adapters/two_bit_cpx_file_signal_source.h +++ b/src/algorithms/signal_source/adapters/two_bit_cpx_file_signal_source.h @@ -11,7 +11,7 @@ * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. * This file is part of GNSS-SDR. * - * Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors) + * Copyright (C) 2010-2021 (see AUTHORS file for a list of contributors) * SPDX-License-Identifier: GPL-3.0-or-later * * ----------------------------------------------------------------------------- @@ -20,18 +20,9 @@ #ifndef GNSS_SDR_TWO_BIT_CPX_FILE_SIGNAL_SOURCE_H #define GNSS_SDR_TWO_BIT_CPX_FILE_SIGNAL_SOURCE_H -#include "signal_source_base.h" - -#include "concurrent_queue.h" +#include "file_source_base.h" #include "unpack_byte_2bit_cpx_samples.h" -#include -#include #include -#include -#include -#include -#include -#include /** \addtogroup Signal_Source * \{ */ @@ -45,7 +36,7 @@ class ConfigurationInterface; * \brief Class that reads signals samples from a file * and adapts it to a SignalSourceInterface */ -class TwoBitCpxFileSignalSource : public SignalSourceBase +class TwoBitCpxFileSignalSource : public FileSourceBase { public: TwoBitCpxFileSignalSource(const ConfigurationInterface* configuration, @@ -56,60 +47,17 @@ public: ~TwoBitCpxFileSignalSource() = default; - inline size_t item_size() override - { - return item_size_; - } - - void connect(gr::top_block_sptr top_block) override; - void disconnect(gr::top_block_sptr top_block) override; - gr::basic_block_sptr get_left_block() override; - gr::basic_block_sptr get_right_block() override; - - inline std::string filename() const - { - return filename_; - } - - inline std::string item_type() const - { - return item_type_; - } - - inline bool repeat() const - { - return repeat_; - } - - inline int64_t sampling_frequency() const - { - return sampling_frequency_; - } - - inline uint64_t samples() const - { - return samples_; - } +protected: + std::tuple itemTypeToSize() const override; + double packetsPerSample() const override; + gnss_shared_ptr source() const override; + void create_file_source_hook() override; + void pre_connect_hook(gr::top_block_sptr top_block) override; + void pre_disconnect_hook(gr::top_block_sptr top_block) override; private: - gr::blocks::file_source::sptr file_source_; - gr::blocks::interleaved_short_to_complex::sptr inter_shorts_to_cpx_; unpack_byte_2bit_cpx_samples_sptr unpack_byte_; - gnss_shared_ptr valve_; - gr::blocks::file_sink::sptr sink_; - gr::blocks::throttle::sptr throttle_; - std::string filename_; - std::string item_type_; - std::string dump_filename_; - size_t item_size_; - uint64_t samples_; - int64_t sampling_frequency_; - unsigned int in_streams_; - unsigned int out_streams_; - bool repeat_; - bool dump_; - // Throttle control - bool enable_throttle_control_; + gr::blocks::interleaved_short_to_complex::sptr inter_shorts_to_cpx_; };