From 29b8643def49d7d15cd6a632bfd2353745c4bb44 Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Fri, 12 Jan 2018 13:15:20 +0100 Subject: [PATCH 1/6] Added Spirent GSS6450 file signal source --- .../signal_source/adapters/CMakeLists.txt | 1 + .../spir_gss6450_file_signal_source.cc | 261 ++++++++++++++++++ .../spir_gss6450_file_signal_source.h | 130 +++++++++ .../gnuradio_blocks/CMakeLists.txt | 1 + .../unpack_spir_gss6450_samples.cc | 75 +++++ .../unpack_spir_gss6450_samples.h | 62 +++++ 6 files changed, 530 insertions(+) create mode 100644 src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc create mode 100644 src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.h create mode 100644 src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.cc create mode 100644 src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.h diff --git a/src/algorithms/signal_source/adapters/CMakeLists.txt b/src/algorithms/signal_source/adapters/CMakeLists.txt index bac9aee3d..3d786bb46 100644 --- a/src/algorithms/signal_source/adapters/CMakeLists.txt +++ b/src/algorithms/signal_source/adapters/CMakeLists.txt @@ -139,6 +139,7 @@ set(SIGNAL_SOURCE_ADAPTER_SOURCES file_signal_source.cc gen_signal_source.cc nsr_file_signal_source.cc spir_file_signal_source.cc + spir_gss6450_file_signal_source.cc rtl_tcp_signal_source.cc ${OPT_DRIVER_SOURCES} ) diff --git a/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc b/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc new file mode 100644 index 000000000..6e577810a --- /dev/null +++ b/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc @@ -0,0 +1,261 @@ +/*! + * \file spir_file_signal_source.cc + * \brief Implementation of a class that reads signals samples from a SPIR file + * and adapts it to a SignalSourceInterface. + * \author Fran Fabra, 2014 fabra(at)ice.csic.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is not part of GNSS-SDR. + * + * GNSS-SDR 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. + * + * GNSS-SDR 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 GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#include "spir_gss6450_file_signal_source.h" +#include +#include +#include +#include +#include +#include +#include +#include "configuration_interface.h" + + +using google::LogMessage; + +DEFINE_string(spir_gss6450_signal_source, "-", + "If defined, path to the file containing the Spirent GSS6450 signal samples (overrides the configuration file)"); + + +SpirGSS6450FileSignalSource::SpirGSS6450FileSignalSource(ConfigurationInterface* configuration, + std::string role, unsigned int in_streams, unsigned int out_streams, gr::msg_queue::sptr queue) : + role_(role), in_streams_(in_streams), out_streams_(out_streams), queue_(queue) +{ + std::string default_filename = "../data/my_capture.dat"; + std::string default_dump_filename = "../data/my_capture_dump.dat"; + item_type_ = "int"; + + samples_ = configuration->property(role + ".samples", 0); + sampling_frequency_ = configuration->property(role + ".sampling_frequency", 0); + filename_ = configuration->property(role + ".filename", default_filename); + + // override value with commandline flag, if present + if (FLAGS_spir_gss6450_signal_source.compare("-") != 0) filename_= FLAGS_spir_gss6450_signal_source; + + 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); + adc_bits_ = configuration->property(role + ".adc_bits", 4); + n_channels_ = configuration->property(role + ".RF_channels", 1); + sel_ch_ = configuration->property(role + ".sel_ch", 1); + item_size_ = sizeof(int); + long bytes_seek = 65536; + double sample_size_byte = static_cast(adc_bits_) / 4.0; + int samples_per_item = 16 / adc_bits_; + + if(sel_ch_ > n_channels_) { LOG(WARNING) << "Invalid RF channel selection"; } + try + { + file_source_ = gr::blocks::file_source::make(item_size_, filename_.c_str(), repeat_); + file_source_->seek(bytes_seek, SEEK_SET); + unpack_ii_ = gr::blocks::packed_to_unpacked_ii::make(2 * adc_bits_, gr::GR_MSB_FIRST); + unpack_spir_ = make_unpack_spir_gss6450_samples(n_channels_, sel_ch_, item_size_); + } + catch (const std::exception &e) + { + std::cerr + << "The receiver was configured to work with a file signal source " + << std::endl + << "but the specified file is unreachable by GNSS-SDR." + << std::endl + << "Please modify your configuration file" + << std::endl + << "and point SignalSource.filename to a valid raw data file. Then:" + << std::endl + << "$ gnss-sdr --config_file=/path/to/my_GNSS_SDR_configuration.conf" + << std::endl + << "Examples of configuration files available at:" + << std::endl + << GNSSSDR_INSTALL_DIR "/share/gnss-sdr/conf/" + << std::endl; + + 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 100 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() << std::endl; + 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]" << std::endl; + std::cout.precision (ss); + + if(size > 0) + { + samples_ = floor(static_cast(size - bytes_seek) / (sample_size_byte * static_cast(n_channels_))); + 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."; + double signal_duration_s; + 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]" << std::endl; + + valve_ = gnss_sdr_make_valve(sizeof(gr_complex), samples_, queue_); + DLOG(INFO) << "valve(" << valve_->unique_id() << ")"; + + if (dump_) + { + 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_; +} + + + + +SpirGSS6450FileSignalSource::~SpirGSS6450FileSignalSource() +{} + + + + +void SpirGSS6450FileSignalSource::connect(gr::top_block_sptr top_block) +{ + if (samples_ > 0) + { + if (enable_throttle_control_) + { + top_block->connect(file_source_, 0, unpack_ii_, 0); + top_block->connect(unpack_ii_, 0, unpack_spir_, 0); + top_block->connect(unpack_spir_, 0, throttle_, 0); + top_block->connect(throttle_, 0, valve_, 0); + } + else + { + top_block->connect(file_source_, 0, unpack_ii_, 0); + top_block->connect(unpack_ii_, 0, unpack_spir_, 0); + top_block->connect(unpack_spir_, 0, valve_, 0); + } + if(dump_) + { + top_block->connect(valve_, 0, sink_, 0); + DLOG(INFO) << "connected valve to file sink"; + } + } + else + { + LOG(WARNING) << "0 samples to read"; + } +} + + + + + + +void SpirGSS6450FileSignalSource::disconnect(gr::top_block_sptr top_block) +{ + if (samples_ > 0) + { + if (enable_throttle_control_) + { + top_block->disconnect(file_source_, 0, unpack_ii_, 0); + top_block->disconnect(unpack_ii_, 0, unpack_spir_, 0); + top_block->disconnect(unpack_spir_, 0, throttle_, 0); + top_block->disconnect(throttle_, 0, valve_, 0); + if (dump_) + { + top_block->disconnect(valve_, 0, sink_, 0); + } + } + else + { + top_block->disconnect(file_source_, 0, unpack_ii_, 0); + top_block->disconnect(unpack_ii_, 0, unpack_spir_, 0); + top_block->disconnect(unpack_spir_, 0, valve_, 0); + if (dump_) + { + top_block->disconnect(valve_, 0, sink_, 0); + } + } + } + else + { + LOG(WARNING) << "Nothing to disconnect"; + } +} + + +gr::basic_block_sptr SpirGSS6450FileSignalSource::get_left_block() +{ + LOG(WARNING) << "Left block of a signal source should not be retrieved"; + return gr::blocks::file_source::sptr(); +} + + +gr::basic_block_sptr SpirGSS6450FileSignalSource::get_right_block() +{ + if(samples_ > 0) { return valve_; } + else + { + if(enable_throttle_control_) { return throttle_; } + else { return unpack_spir_; } + } +} diff --git a/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.h b/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.h new file mode 100644 index 000000000..346ebdc79 --- /dev/null +++ b/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.h @@ -0,0 +1,130 @@ +/*! + * \file spir_file_signal_source.h + * \brief Implementation of a class that reads signals samples from a SPIR file + * and adapts it to a SignalSourceInterface. + * \author Fran Fabra, 2014 fabra(at)ice.csic.es + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is not part of GNSS-SDR. + * + * GNSS-SDR 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. + * + * GNSS-SDR 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 GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_SPIR_GSS6450_FILE_SIGNAL_SOURCE_H_ +#define GNSS_SDR_SPIR_GSS6450_FILE_SIGNAL_SOURCE_H_ + +#include +#include +#include +#include +#include +#include +#include +#include "gnss_block_interface.h" +#include "gnss_sdr_valve.h" +#include "unpack_spir_gss6450_samples.h" + + +class ConfigurationInterface; + +/*! + * \brief Class that reads signals samples from a file + * and adapts it to a SignalSourceInterface + */ +class SpirGSS6450FileSignalSource: public GNSSBlockInterface +{ +public: + SpirGSS6450FileSignalSource(ConfigurationInterface* configuration, std::string role, + unsigned int in_streams, unsigned int out_streams, gr::msg_queue::sptr queue); + + virtual ~SpirGSS6450FileSignalSource(); + inline std::string role() override + { + return role_; + } + + inline std::string implementation() override + { + return "Spir_GSS6450_File_Signal_Source"; + } + + 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 long sampling_frequency() const + { + return sampling_frequency_; + } + + inline long samples() const + { + return samples_; + } + +private: + unsigned long long samples_; + long sampling_frequency_; + std::string filename_; + bool repeat_; + bool dump_; + std::string dump_filename_; + std::string role_; + std::string item_type_; + unsigned int in_streams_; + unsigned int out_streams_; + unsigned int adc_bits_; + unsigned int n_channels_; + unsigned int sel_ch_; + gr::blocks::file_source::sptr file_source_; + gr::blocks::packed_to_unpacked_ii::sptr unpack_ii_; + unpack_spir_gss6450_samples_sptr unpack_spir_; + boost::shared_ptr valve_; + gr::blocks::file_sink::sptr sink_; + gr::blocks::throttle::sptr throttle_; + gr::msg_queue::sptr queue_; + size_t item_size_; + bool enable_throttle_control_; +}; + +#endif /*GNSS_SDR_SPIR_GSS6450_FILE_SIGNAL_SOURCE_H_*/ diff --git a/src/algorithms/signal_source/gnuradio_blocks/CMakeLists.txt b/src/algorithms/signal_source/gnuradio_blocks/CMakeLists.txt index 4159321f3..67b9f3162 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/CMakeLists.txt +++ b/src/algorithms/signal_source/gnuradio_blocks/CMakeLists.txt @@ -23,6 +23,7 @@ set(SIGNAL_SOURCE_GR_BLOCKS_SOURCES unpack_intspir_1bit_samples.cc rtl_tcp_signal_source_c.cc unpack_2bit_samples.cc + unpack_spir_gss6450_samples.cc ) include_directories( diff --git a/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.cc b/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.cc new file mode 100644 index 000000000..8d7d4e3fc --- /dev/null +++ b/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.cc @@ -0,0 +1,75 @@ +/*! + * \file unpack_intspir_1bit_samples.cc + * + * \brief Unpacks SPIR int samples to NSR 1 bit samples + * \author Fran Fabra fabra (at) ice.csic.es + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is not part of GNSS-SDR. + * + * GNSS-SDR 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. + * + * GNSS-SDR 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 GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + + +#include "unpack_spir_gss6450_samples.h" +#include + + + +unpack_spir_gss6450_samples_sptr make_unpack_spir_gss6450_samples(unsigned int n_chann, unsigned int sel_ch, size_t item_size) +{ + return unpack_spir_gss6450_samples_sptr(new unpack_spir_gss6450_samples(n_chann, sel_ch, item_size)); +} + + +unpack_spir_gss6450_samples::unpack_spir_gss6450_samples( + unsigned int n_chann, unsigned int sel_ch, size_t item_size) : gr::block("unpack_spir_gss6450_samples", + gr::io_signature::make(1, 1, sizeof(int)), + gr::io_signature::make(1, 1, sizeof(gr_complex))) +{ + d_channels = n_chann; + d_sel_ch = sel_ch; + item_size_ = item_size; + ch_processing = 1; +} + +void unpack_spir_gss6450_samples::forecast(int noutput_items, gr_vector_int &ninput_items_required) +{ + ninput_items_required[0] = d_channels * noutput_items; +} + + +unpack_spir_gss6450_samples::~unpack_spir_gss6450_samples() +{} + + +int unpack_spir_gss6450_samples::general_work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const int *in = reinterpret_cast(input_items[0]); + gr_complex *out = reinterpret_cast(output_items[0]); + + + + + return noutput_items; +} diff --git a/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.h b/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.h new file mode 100644 index 000000000..6e83c88e2 --- /dev/null +++ b/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.h @@ -0,0 +1,62 @@ +/*! + * \file unpack_intspir_1bit_samples.h + * + * \brief Unpacks SPIR int samples to NSR 1 bit samples + * \author Fran Fabra fabra (at) ice.csic.es + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is not part of GNSS-SDR. + * + * GNSS-SDR 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. + * + * GNSS-SDR 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 GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_UNPACK_SPIR_GSS6450_SAMPLES_H +#define GNSS_SDR_UNPACK_SPIR_GSS6450_SAMPLES_H + +#include + +class unpack_spir_gss6450_samples; + +typedef boost::shared_ptr unpack_spir_gss6450_samples_sptr; + +unpack_spir_gss6450_samples_sptr make_unpack_spir_gss6450_samples(unsigned int n_chann, unsigned int sel_ch, size_t item_size); + + +class unpack_spir_gss6450_samples: public gr::block +{ +public: + int general_work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + void forecast(int noutput_items, gr_vector_int &ninput_items_required); + ~unpack_spir_gss6450_samples(); + +private: + unsigned int d_channels; + unsigned int d_sel_ch; + unsigned int ch_processing; + size_t item_size_; + friend unpack_spir_gss6450_samples_sptr make_unpack_spir_gss6450_samples_sptr(unsigned int n_chann, unsigned int sel_ch, size_t item_size); + unpack_spir_gss6450_samples(unsigned int n_chann, unsigned int sel_ch, size_t item_size); + +}; + +#endif From 282c3d865998ae49e076aea79505175c80d13555 Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Tue, 16 Jan 2018 17:20:55 +0100 Subject: [PATCH 2/6] Implement Spirent GSS6450 file signal source --- .../spir_gss6450_file_signal_source.cc | 7 +- .../unpack_spir_gss6450_samples.cc | 111 +++++++++++++++--- .../unpack_spir_gss6450_samples.h | 18 ++- src/core/receiver/gnss_block_factory.cc | 16 +++ 4 files changed, 128 insertions(+), 24 deletions(-) diff --git a/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc b/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc index 6e577810a..ede0abb72 100644 --- a/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc +++ b/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc @@ -78,8 +78,8 @@ SpirGSS6450FileSignalSource::SpirGSS6450FileSignalSource(ConfigurationInterface* { file_source_ = gr::blocks::file_source::make(item_size_, filename_.c_str(), repeat_); file_source_->seek(bytes_seek, SEEK_SET); - unpack_ii_ = gr::blocks::packed_to_unpacked_ii::make(2 * adc_bits_, gr::GR_MSB_FIRST); - unpack_spir_ = make_unpack_spir_gss6450_samples(n_channels_, sel_ch_, item_size_); + unpack_ii_ = gr::blocks::packed_to_unpacked_ii::make(adc_bits_, gr::GR_MSB_FIRST); + unpack_spir_ = make_unpack_spir_gss6450_samples(n_channels_, sel_ch_, samples_per_item, item_size_); } catch (const std::exception &e) { @@ -139,8 +139,7 @@ SpirGSS6450FileSignalSource::SpirGSS6450FileSignalSource(ConfigurationInterface* } CHECK(samples_ > 0) << "File does not contain enough samples to process."; - double signal_duration_s; - signal_duration_s = static_cast(samples_) * ( 1 /static_cast(sampling_frequency_)); + 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]" << std::endl; diff --git a/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.cc b/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.cc index 8d7d4e3fc..d8ae66e39 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.cc +++ b/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.cc @@ -34,14 +34,14 @@ -unpack_spir_gss6450_samples_sptr make_unpack_spir_gss6450_samples(unsigned int n_chann, unsigned int sel_ch, size_t item_size) +unpack_spir_gss6450_samples_sptr make_unpack_spir_gss6450_samples(unsigned int n_chann, unsigned int sel_ch, int samp_item, size_t item_size) { - return unpack_spir_gss6450_samples_sptr(new unpack_spir_gss6450_samples(n_chann, sel_ch, item_size)); + return unpack_spir_gss6450_samples_sptr(new unpack_spir_gss6450_samples(n_chann, sel_ch, samp_item, item_size)); } unpack_spir_gss6450_samples::unpack_spir_gss6450_samples( - unsigned int n_chann, unsigned int sel_ch, size_t item_size) : gr::block("unpack_spir_gss6450_samples", + unsigned int n_chann, unsigned int sel_ch, int samp_item, size_t item_size) : gr::block("unpack_spir_gss6450_samples", gr::io_signature::make(1, 1, sizeof(int)), gr::io_signature::make(1, 1, sizeof(gr_complex))) { @@ -49,27 +49,108 @@ unpack_spir_gss6450_samples::unpack_spir_gss6450_samples( d_sel_ch = sel_ch; item_size_ = item_size; ch_processing = 1; -} - -void unpack_spir_gss6450_samples::forecast(int noutput_items, gr_vector_int &ninput_items_required) -{ - ninput_items_required[0] = d_channels * noutput_items; + d_samp_item = samp_item; + samp_frame = 0; + adc_bits = 16 / d_samp_item; + i_ = true; + new_sample = false; + i_data = 0; + q_data = 0; } unpack_spir_gss6450_samples::~unpack_spir_gss6450_samples() {} +void unpack_spir_gss6450_samples::process_sample(gr_complex* out) +{ + gr_complex result = gr_complex(0.5, 0.5); + compute_two_complement(i_data); + compute_two_complement(q_data); + result += gr_complex(static_cast(i_data), static_cast(q_data)); + *out = result; +} int unpack_spir_gss6450_samples::general_work(int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { - const int *in = reinterpret_cast(input_items[0]); - gr_complex *out = reinterpret_cast(output_items[0]); - - - - - return noutput_items; + const int* in = reinterpret_cast(input_items[0]); + gr_complex* out = reinterpret_cast(output_items[0]); + int samples_produced = 0; + for(int i = 0; i < noutput_items; i++) + { + if(ch_processing == d_sel_ch) + { + if(i_) + { + i_data = in[i]; + swap_data(i_data); + i_ = false; + } + else + { + q_data = in[i]; + swap_data(q_data); + i_ = true; + process_sample(out); + out++; + samples_produced++; + new_sample = true; + } + } + else + { + if(i_) { i_ = false;} + else + { + i_ = true; + new_sample = true; + } + } + if(new_sample) + { + new_sample = false; + samp_frame++; + if(samp_frame == d_samp_item) + { + samp_frame = 0; + ch_processing++; + if(ch_processing > d_channels) { ch_processing = 1; } + } + } + } + consume_each(noutput_items); + return samples_produced; +} + +void unpack_spir_gss6450_samples::swap_data(int& data) +{ + int result = 0; + int aux = data; + int mask = 1; + for (int i = 0; i < adc_bits; i++) + { + result = result << 1; + result += (aux & mask); + aux = aux >> 1; + } + data = result; +} + +void unpack_spir_gss6450_samples::compute_two_complement(int& data) +{ + int result = 0; + int mask = 1; + for(int i = 0; i < (adc_bits - 1); i++) + { + result = result << 1; + result += (data >> i) & mask; + } + if((data >> (adc_bits - 1)) == 1) + { + if(adc_bits == 2) { result -= 2; } + else { result -= 8; } + } + data = result; } diff --git a/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.h b/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.h index 6e83c88e2..1077fcc73 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.h +++ b/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.h @@ -37,7 +37,7 @@ class unpack_spir_gss6450_samples; typedef boost::shared_ptr unpack_spir_gss6450_samples_sptr; -unpack_spir_gss6450_samples_sptr make_unpack_spir_gss6450_samples(unsigned int n_chann, unsigned int sel_ch, size_t item_size); +unpack_spir_gss6450_samples_sptr make_unpack_spir_gss6450_samples(unsigned int n_chann, unsigned int sel_ch, int samp_item, size_t item_size); class unpack_spir_gss6450_samples: public gr::block @@ -46,17 +46,25 @@ public: int general_work (int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); - void forecast(int noutput_items, gr_vector_int &ninput_items_required); + friend unpack_spir_gss6450_samples_sptr make_unpack_spir_gss6450_samples_sptr(unsigned int n_chann, unsigned int sel_ch, int samp_item, size_t item_size); + unpack_spir_gss6450_samples(unsigned int n_chann, unsigned int sel_ch, int samp_item, size_t item_size); ~unpack_spir_gss6450_samples(); private: unsigned int d_channels; unsigned int d_sel_ch; unsigned int ch_processing; + int d_samp_item; + int samp_frame; + int adc_bits; size_t item_size_; - friend unpack_spir_gss6450_samples_sptr make_unpack_spir_gss6450_samples_sptr(unsigned int n_chann, unsigned int sel_ch, size_t item_size); - unpack_spir_gss6450_samples(unsigned int n_chann, unsigned int sel_ch, size_t item_size); - + void process_sample(gr_complex* out); + void swap_data(int& data); + void compute_two_complement(int& data); + bool i_; + bool new_sample; + int i_data; + int q_data; }; #endif diff --git a/src/core/receiver/gnss_block_factory.cc b/src/core/receiver/gnss_block_factory.cc index bdf34dc22..322577e62 100644 --- a/src/core/receiver/gnss_block_factory.cc +++ b/src/core/receiver/gnss_block_factory.cc @@ -48,6 +48,7 @@ #include "nsr_file_signal_source.h" #include "two_bit_cpx_file_signal_source.h" #include "spir_file_signal_source.h" +#include "spir_gss6450_file_signal_source.h" #include "rtl_tcp_signal_source.h" #include "two_bit_packed_file_signal_source.h" #include "channel.h" @@ -864,6 +865,21 @@ std::unique_ptr GNSSBlockFactory::GetBlock( out_streams, queue)); block = std::move(block_); + } + catch (const std::exception &e) + { + std::cout << "GNSS-SDR program ended." << std::endl; + exit(1); + } + } + else if (implementation.compare("Spir_GSS6450_File_Signal_Source") == 0) + { + try + { + std::unique_ptr block_(new SpirGSS6450FileSignalSource(configuration.get(), role, in_streams, + out_streams, queue)); + block = std::move(block_); + } catch (const std::exception &e) { From 4873ea2b88720f4091b1f8a92bda3f7c9e5ede7f Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Thu, 18 Jan 2018 16:57:15 +0100 Subject: [PATCH 3/6] Fix GSS6450 signal source --- .../spir_gss6450_file_signal_source.cc | 141 ++++++++++-------- .../spir_gss6450_file_signal_source.h | 19 ++- .../unpack_spir_gss6450_samples.cc | 133 +++++++---------- .../unpack_spir_gss6450_samples.h | 33 ++-- 4 files changed, 153 insertions(+), 173 deletions(-) diff --git a/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc b/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc index ede0abb72..590c60c33 100644 --- a/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc +++ b/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc @@ -1,12 +1,12 @@ /*! - * \file spir_file_signal_source.cc + * \file spir_gss6450_file_signal_source.cc * \brief Implementation of a class that reads signals samples from a SPIR file * and adapts it to a SignalSourceInterface. - * \author Fran Fabra, 2014 fabra(at)ice.csic.es + * \author Antonio Ramos, 2017 antonio.ramos(at)cttc.es * * ------------------------------------------------------------------------- * - * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) * * GNSS-SDR is a software defined Global Navigation * Satellite Systems receiver @@ -35,16 +35,11 @@ #include #include #include -#include #include #include "configuration_interface.h" - using google::LogMessage; -DEFINE_string(spir_gss6450_signal_source, "-", - "If defined, path to the file containing the Spirent GSS6450 signal samples (overrides the configuration file)"); - SpirGSS6450FileSignalSource::SpirGSS6450FileSignalSource(ConfigurationInterface* configuration, std::string role, unsigned int in_streams, unsigned int out_streams, gr::msg_queue::sptr queue) : @@ -55,31 +50,35 @@ SpirGSS6450FileSignalSource::SpirGSS6450FileSignalSource(ConfigurationInterface* item_type_ = "int"; samples_ = configuration->property(role + ".samples", 0); - sampling_frequency_ = configuration->property(role + ".sampling_frequency", 0); + sampling_frequency_ = configuration->property(role + ".sampling_frequency", 0.0); filename_ = configuration->property(role + ".filename", default_filename); - - // override value with commandline flag, if present - if (FLAGS_spir_gss6450_signal_source.compare("-") != 0) filename_= FLAGS_spir_gss6450_signal_source; - 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); adc_bits_ = configuration->property(role + ".adc_bits", 4); - n_channels_ = configuration->property(role + ".RF_channels", 1); + n_channels_ = configuration->property(role + ".total_channels", 1); sel_ch_ = configuration->property(role + ".sel_ch", 1); item_size_ = sizeof(int); - long bytes_seek = 65536; + long bytes_seek = configuration->property(role + ".bytes_to_skip", 65536); double sample_size_byte = static_cast(adc_bits_) / 4.0; - int samples_per_item = 16 / adc_bits_; if(sel_ch_ > n_channels_) { LOG(WARNING) << "Invalid RF channel selection"; } + if(n_channels_ > 1) + { + for(unsigned int i = 0; i < (n_channels_ - 1); i++) + { + null_sinks_.push_back(gr::blocks::null_sink::make(item_size_)); + } + std::cout << "NUMBER OF NULL SINKS = " << null_sinks_.size() << std::endl; + } try { - file_source_ = gr::blocks::file_source::make(item_size_, filename_.c_str(), repeat_); - file_source_->seek(bytes_seek, SEEK_SET); - unpack_ii_ = gr::blocks::packed_to_unpacked_ii::make(adc_bits_, gr::GR_MSB_FIRST); - unpack_spir_ = make_unpack_spir_gss6450_samples(n_channels_, sel_ch_, samples_per_item, item_size_); + file_source_ = gr::blocks::file_source::make(item_size_, filename_.c_str(), repeat_); + file_source_->seek(bytes_seek / item_size_, SEEK_SET); + unpack_spir_ = make_unpack_spir_gss6450_samples(adc_bits_); + deint_ = gr::blocks::deinterleave::make(item_size_); + endian_ = gr::blocks::endian_swap::make(item_size_); } catch (const std::exception &e) { @@ -103,14 +102,13 @@ SpirGSS6450FileSignalSource::SpirGSS6450FileSignalSource(ConfigurationInterface* << 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 100 milliseconds, and enable always the + * 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); @@ -119,7 +117,7 @@ SpirGSS6450FileSignalSource::SpirGSS6450FileSignalSource(ConfigurationInterface* if (file.is_open()) { size = file.tellg(); - LOG(INFO) << "Total samples in the file= " << floor(static_cast(size) / static_cast(item_size())); + LOG(INFO) << "Total samples in the file= " << floor(static_cast(size) / static_cast(item_size_)); } else { @@ -133,13 +131,13 @@ SpirGSS6450FileSignalSource::SpirGSS6450FileSignalSource(ConfigurationInterface* if(size > 0) { - samples_ = floor(static_cast(size - bytes_seek) / (sample_size_byte * static_cast(n_channels_))); - samples_ = samples_- ceil(0.002 * static_cast(sampling_frequency_)); //process all the samples available in the file excluding the last 2 ms + samples_ = static_cast(floor(static_cast(size - bytes_seek) / (sample_size_byte * static_cast(n_channels_)))); + samples_ = samples_- static_cast(ceil(0.002 * 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."; - double signal_duration_s = static_cast(samples_) * ( 1 /static_cast(sampling_frequency_)); + double signal_duration_s = static_cast(samples_) / 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]" << std::endl; @@ -149,9 +147,9 @@ SpirGSS6450FileSignalSource::SpirGSS6450FileSignalSource(ConfigurationInterface* if (dump_) { sink_ = gr::blocks::file_sink::make(sizeof(gr_complex), dump_filename_.c_str()); + //sink_test = gr::blocks::file_sink::make(sizeof(int), "/home/aramos/Escritorio/test_int.dat"); DLOG(INFO) << "file_sink(" << sink_->unique_id() << ")"; } - if (enable_throttle_control_) { throttle_ = gr::blocks::throttle::make(sizeof(gr_complex), sampling_frequency_); @@ -167,36 +165,46 @@ SpirGSS6450FileSignalSource::SpirGSS6450FileSignalSource(ConfigurationInterface* } - - SpirGSS6450FileSignalSource::~SpirGSS6450FileSignalSource() {} - - void SpirGSS6450FileSignalSource::connect(gr::top_block_sptr top_block) { if (samples_ > 0) { + top_block->connect(file_source_, 0, deint_, 0); + /* + top_block->connect(deint_, sel_ch_ - 1, endian_ ,0); + top_block->connect(endian_, 0, unpack_spir_, 0); + */ + top_block->connect(deint_, sel_ch_ - 1, unpack_spir_, 0); + if(n_channels_ > 1) + { + unsigned int aux = 0; + for(unsigned int i = 0; i < n_channels_; i++) + { + if(i != (sel_ch_ - 1)) + { + top_block->connect(deint_, i, null_sinks_.at(aux), 0); + aux++; + } + } + } if (enable_throttle_control_) { - top_block->connect(file_source_, 0, unpack_ii_, 0); - top_block->connect(unpack_ii_, 0, unpack_spir_, 0); top_block->connect(unpack_spir_, 0, throttle_, 0); top_block->connect(throttle_, 0, valve_, 0); } else { - top_block->connect(file_source_, 0, unpack_ii_, 0); - top_block->connect(unpack_ii_, 0, unpack_spir_, 0); top_block->connect(unpack_spir_, 0, valve_, 0); } if(dump_) - { - top_block->connect(valve_, 0, sink_, 0); - DLOG(INFO) << "connected valve to file sink"; - } + { + top_block->connect(valve_, 0, sink_, 0); + //top_block->connect(deint_, sel_ch_ - 1, sink_test, 0); + } } else { @@ -205,40 +213,43 @@ void SpirGSS6450FileSignalSource::connect(gr::top_block_sptr top_block) } - - - - void SpirGSS6450FileSignalSource::disconnect(gr::top_block_sptr top_block) { if (samples_ > 0) + { + top_block->disconnect(file_source_, 0, deint_, 0); + top_block->disconnect(deint_, sel_ch_ - 1, unpack_spir_, 0); + if(n_channels_ > 1) { - if (enable_throttle_control_) + unsigned int aux = 0; + for(unsigned int i = 0; i < n_channels_; i++) + { + if(i != (sel_ch_ - 1)) { - top_block->disconnect(file_source_, 0, unpack_ii_, 0); - top_block->disconnect(unpack_ii_, 0, unpack_spir_, 0); - top_block->disconnect(unpack_spir_, 0, throttle_, 0); - top_block->disconnect(throttle_, 0, valve_, 0); - if (dump_) - { - top_block->disconnect(valve_, 0, sink_, 0); - } - } - else - { - top_block->disconnect(file_source_, 0, unpack_ii_, 0); - top_block->disconnect(unpack_ii_, 0, unpack_spir_, 0); - top_block->disconnect(unpack_spir_, 0, valve_, 0); - if (dump_) - { - top_block->disconnect(valve_, 0, sink_, 0); - } + top_block->disconnect(deint_, i, null_sinks_.at(aux), 0); + aux++; } + } } + if (enable_throttle_control_) + { + top_block->disconnect(unpack_spir_, 0, throttle_, 0); + top_block->disconnect(throttle_, 0, valve_, 0); + } + else + { + top_block->disconnect(unpack_spir_, 0, valve_, 0); + } + if(dump_) + { + top_block->disconnect(valve_, 0, sink_, 0); + //top_block->disconnect(deint_, sel_ch_ - 1, sink_test, 0); + } + } else - { - LOG(WARNING) << "Nothing to disconnect"; - } + { + LOG(WARNING) << "Nothing to disconnect"; + } } diff --git a/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.h b/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.h index 346ebdc79..e8387dbd7 100644 --- a/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.h +++ b/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.h @@ -1,12 +1,12 @@ /*! - * \file spir_file_signal_source.h + * \file spir_gss6450_file_signal_source.h * \brief Implementation of a class that reads signals samples from a SPIR file * and adapts it to a SignalSourceInterface. - * \author Fran Fabra, 2014 fabra(at)ice.csic.es + * \author Antonio Ramos, 2017 antonio.ramos(at)cttc.es * * ------------------------------------------------------------------------- * - * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) * * GNSS-SDR is a software defined Global Navigation * Satellite Systems receiver @@ -33,10 +33,14 @@ #define GNSS_SDR_SPIR_GSS6450_FILE_SIGNAL_SOURCE_H_ #include +#include #include #include #include #include +#include +#include +#include #include #include #include "gnss_block_interface.h" @@ -104,10 +108,11 @@ public: private: unsigned long long samples_; - long sampling_frequency_; + double sampling_frequency_; std::string filename_; bool repeat_; bool dump_; + bool enable_throttle_control_; std::string dump_filename_; std::string role_; std::string item_type_; @@ -117,14 +122,16 @@ private: unsigned int n_channels_; unsigned int sel_ch_; gr::blocks::file_source::sptr file_source_; - gr::blocks::packed_to_unpacked_ii::sptr unpack_ii_; + gr::blocks::deinterleave::sptr deint_; + gr::blocks::endian_swap::sptr endian_; + std::vector null_sinks_; unpack_spir_gss6450_samples_sptr unpack_spir_; boost::shared_ptr valve_; gr::blocks::file_sink::sptr sink_; + gr::blocks::file_sink::sptr sink_test; gr::blocks::throttle::sptr throttle_; gr::msg_queue::sptr queue_; size_t item_size_; - bool enable_throttle_control_; }; #endif /*GNSS_SDR_SPIR_GSS6450_FILE_SIGNAL_SOURCE_H_*/ diff --git a/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.cc b/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.cc index d8ae66e39..5992c7025 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.cc +++ b/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.cc @@ -34,123 +34,90 @@ -unpack_spir_gss6450_samples_sptr make_unpack_spir_gss6450_samples(unsigned int n_chann, unsigned int sel_ch, int samp_item, size_t item_size) +unpack_spir_gss6450_samples_sptr make_unpack_spir_gss6450_samples(unsigned int adc_nbit) { - return unpack_spir_gss6450_samples_sptr(new unpack_spir_gss6450_samples(n_chann, sel_ch, samp_item, item_size)); + return unpack_spir_gss6450_samples_sptr(new unpack_spir_gss6450_samples(adc_nbit)); } -unpack_spir_gss6450_samples::unpack_spir_gss6450_samples( - unsigned int n_chann, unsigned int sel_ch, int samp_item, size_t item_size) : gr::block("unpack_spir_gss6450_samples", +unpack_spir_gss6450_samples::unpack_spir_gss6450_samples(unsigned int adc_nbit) : gr::sync_interpolator("unpack_spir_gss6450_samples", gr::io_signature::make(1, 1, sizeof(int)), - gr::io_signature::make(1, 1, sizeof(gr_complex))) + gr::io_signature::make(1, 1, sizeof(gr_complex)), 16 / adc_nbit) { - d_channels = n_chann; - d_sel_ch = sel_ch; - item_size_ = item_size; - ch_processing = 1; - d_samp_item = samp_item; - samp_frame = 0; - adc_bits = 16 / d_samp_item; - i_ = true; - new_sample = false; + adc_bits = adc_nbit; i_data = 0; q_data = 0; + samples_per_int = 16 / adc_bits; + if(adc_bits == 2) + { + mask_data = 0x00000003; + map_ = {0, 1, -2, -1}; + } + else + { + mask_data = 0x0000000F; + map_ = {0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1}; + } } unpack_spir_gss6450_samples::~unpack_spir_gss6450_samples() {} -void unpack_spir_gss6450_samples::process_sample(gr_complex* out) +void unpack_spir_gss6450_samples::process_sample(gr_complex& out) { - gr_complex result = gr_complex(0.5, 0.5); + out = gr_complex(0.5, 0.5); compute_two_complement(i_data); compute_two_complement(q_data); - result += gr_complex(static_cast(i_data), static_cast(q_data)); - *out = result; + out += gr_complex(static_cast(i_data), static_cast(q_data)); } -int unpack_spir_gss6450_samples::general_work(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) + +int unpack_spir_gss6450_samples::work(int noutput_items, + gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { const int* in = reinterpret_cast(input_items[0]); gr_complex* out = reinterpret_cast(output_items[0]); - int samples_produced = 0; + unsigned int n_sample = 0; + unsigned int in_counter = 0; for(int i = 0; i < noutput_items; i++) { - if(ch_processing == d_sel_ch) + int sample_aux = in[in_counter]; + //reverse_bits(sample_aux); + int aux_i = sample_aux; + int aux_q = sample_aux; + int i_shift = adc_bits * 2 * (samples_per_int - n_sample - 1) + adc_bits; + int q_shift = adc_bits * 2 * (samples_per_int - n_sample - 1); + i_data = (aux_i >> i_shift) & mask_data; + q_data = (aux_q >> q_shift) & mask_data; + process_sample(out[samples_per_int * in_counter + samples_per_int - n_sample - 1]); + n_sample++; + if(n_sample == samples_per_int) { - if(i_) - { - i_data = in[i]; - swap_data(i_data); - i_ = false; - } - else - { - q_data = in[i]; - swap_data(q_data); - i_ = true; - process_sample(out); - out++; - samples_produced++; - new_sample = true; - } - } - else - { - if(i_) { i_ = false;} - else - { - i_ = true; - new_sample = true; - } - } - if(new_sample) - { - new_sample = false; - samp_frame++; - if(samp_frame == d_samp_item) - { - samp_frame = 0; - ch_processing++; - if(ch_processing > d_channels) { ch_processing = 1; } - } + n_sample = 0; + in_counter++; } } - consume_each(noutput_items); - return samples_produced; + return noutput_items; } -void unpack_spir_gss6450_samples::swap_data(int& data) +void unpack_spir_gss6450_samples::reverse_bits(int& data) { - int result = 0; - int aux = data; - int mask = 1; - for (int i = 0; i < adc_bits; i++) + unsigned int v = data; // input bits to be reversed + unsigned int r = v; // r will be reversed bits of v; first get LSB of v + int s = sizeof(v) * CHAR_BIT - 1; // extra shift needed at end + + for (v >>= 1; v; v >>= 1) { - result = result << 1; - result += (aux & mask); - aux = aux >> 1; + r <<= 1; + r |= v & 1; + s--; } - data = result; + r <<= s; // shift when v's highest bits are zero + data = r; } void unpack_spir_gss6450_samples::compute_two_complement(int& data) { - int result = 0; - int mask = 1; - for(int i = 0; i < (adc_bits - 1); i++) - { - result = result << 1; - result += (data >> i) & mask; - } - if((data >> (adc_bits - 1)) == 1) - { - if(adc_bits == 2) { result -= 2; } - else { result -= 8; } - } - data = result; + data = map_[data]; } diff --git a/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.h b/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.h index 1077fcc73..df890fc74 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.h +++ b/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.h @@ -31,40 +31,35 @@ #ifndef GNSS_SDR_UNPACK_SPIR_GSS6450_SAMPLES_H #define GNSS_SDR_UNPACK_SPIR_GSS6450_SAMPLES_H -#include +#include +#include class unpack_spir_gss6450_samples; typedef boost::shared_ptr unpack_spir_gss6450_samples_sptr; -unpack_spir_gss6450_samples_sptr make_unpack_spir_gss6450_samples(unsigned int n_chann, unsigned int sel_ch, int samp_item, size_t item_size); +unpack_spir_gss6450_samples_sptr make_unpack_spir_gss6450_samples(unsigned int adc_nbit); -class unpack_spir_gss6450_samples: public gr::block +class unpack_spir_gss6450_samples: public gr::sync_interpolator { public: - int general_work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); - friend unpack_spir_gss6450_samples_sptr make_unpack_spir_gss6450_samples_sptr(unsigned int n_chann, unsigned int sel_ch, int samp_item, size_t item_size); - unpack_spir_gss6450_samples(unsigned int n_chann, unsigned int sel_ch, int samp_item, size_t item_size); + int work(int noutput_items, + gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); + friend unpack_spir_gss6450_samples_sptr make_unpack_spir_gss6450_samples_sptr(unsigned int adc_nbit); + unpack_spir_gss6450_samples(unsigned int adc_nbit); ~unpack_spir_gss6450_samples(); private: - unsigned int d_channels; - unsigned int d_sel_ch; - unsigned int ch_processing; - int d_samp_item; - int samp_frame; - int adc_bits; - size_t item_size_; - void process_sample(gr_complex* out); - void swap_data(int& data); + unsigned int adc_bits; + unsigned int samples_per_int; + void process_sample(gr_complex& out); void compute_two_complement(int& data); - bool i_; - bool new_sample; + void reverse_bits(int& data); int i_data; int q_data; + int mask_data; + std::vector map_; }; #endif From 7a2a02252a3385011c16a1455bf8e2b255ca9822 Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Fri, 19 Jan 2018 13:50:33 +0100 Subject: [PATCH 4/6] Minor changes --- .../spir_gss6450_file_signal_source.cc | 56 ++++++++++++++----- .../spir_gss6450_file_signal_source.h | 4 +- 2 files changed, 45 insertions(+), 15 deletions(-) diff --git a/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc b/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc index 590c60c33..81a7d33e6 100644 --- a/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc +++ b/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc @@ -54,6 +54,8 @@ SpirGSS6450FileSignalSource::SpirGSS6450FileSignalSource(ConfigurationInterface* filename_ = configuration->property(role + ".filename", default_filename); repeat_ = configuration->property(role + ".repeat", false); dump_ = configuration->property(role + ".dump", false); + dump_test_ = configuration->property(role + ".dump_test", false); + endian_swap_ = configuration->property(role + ".endian", false); dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename); enable_throttle_control_ = configuration->property(role + ".enable_throttle_control", false); adc_bits_ = configuration->property(role + ".adc_bits", 4); @@ -70,7 +72,7 @@ SpirGSS6450FileSignalSource::SpirGSS6450FileSignalSource(ConfigurationInterface* { null_sinks_.push_back(gr::blocks::null_sink::make(item_size_)); } - std::cout << "NUMBER OF NULL SINKS = " << null_sinks_.size() << std::endl; + DLOG(INFO)<< "NUMBER OF NULL SINKS = " << null_sinks_.size(); } try { @@ -78,7 +80,6 @@ SpirGSS6450FileSignalSource::SpirGSS6450FileSignalSource(ConfigurationInterface* file_source_->seek(bytes_seek / item_size_, SEEK_SET); unpack_spir_ = make_unpack_spir_gss6450_samples(adc_bits_); deint_ = gr::blocks::deinterleave::make(item_size_); - endian_ = gr::blocks::endian_swap::make(item_size_); } catch (const std::exception &e) { @@ -147,13 +148,20 @@ SpirGSS6450FileSignalSource::SpirGSS6450FileSignalSource(ConfigurationInterface* if (dump_) { sink_ = gr::blocks::file_sink::make(sizeof(gr_complex), dump_filename_.c_str()); - //sink_test = gr::blocks::file_sink::make(sizeof(int), "/home/aramos/Escritorio/test_int.dat"); DLOG(INFO) << "file_sink(" << sink_->unique_id() << ")"; } + if (dump_test_) + { + sink_test = gr::blocks::file_sink::make(sizeof(int), (dump_filename_ + "int").c_str()); + } if (enable_throttle_control_) { throttle_ = gr::blocks::throttle::make(sizeof(gr_complex), sampling_frequency_); } + if (endian_swap_) + { + endian_ = gr::blocks::endian_swap::make(item_size_); + } DLOG(INFO) << "File source filename " << filename_; DLOG(INFO) << "Samples " << samples_; DLOG(INFO) << "Sampling frequency " << sampling_frequency_; @@ -174,11 +182,15 @@ void SpirGSS6450FileSignalSource::connect(gr::top_block_sptr top_block) if (samples_ > 0) { top_block->connect(file_source_, 0, deint_, 0); - /* - top_block->connect(deint_, sel_ch_ - 1, endian_ ,0); - top_block->connect(endian_, 0, unpack_spir_, 0); - */ - top_block->connect(deint_, sel_ch_ - 1, unpack_spir_, 0); + if(endian_swap_) + { + top_block->connect(deint_, sel_ch_ - 1, endian_ ,0); + top_block->connect(endian_, 0, unpack_spir_, 0); + } + else + { + top_block->connect(deint_, sel_ch_ - 1, unpack_spir_, 0); + } if(n_channels_ > 1) { unsigned int aux = 0; @@ -203,7 +215,11 @@ void SpirGSS6450FileSignalSource::connect(gr::top_block_sptr top_block) if(dump_) { top_block->connect(valve_, 0, sink_, 0); - //top_block->connect(deint_, sel_ch_ - 1, sink_test, 0); + } + if(dump_test_) + { + if(endian_swap_) top_block->connect(endian_, 0, sink_test, 0); + else top_block->connect(deint_, sel_ch_ - 1, sink_test, 0); } } else @@ -218,7 +234,15 @@ void SpirGSS6450FileSignalSource::disconnect(gr::top_block_sptr top_block) if (samples_ > 0) { top_block->disconnect(file_source_, 0, deint_, 0); - top_block->disconnect(deint_, sel_ch_ - 1, unpack_spir_, 0); + if(endian_swap_) + { + top_block->disconnect(deint_, sel_ch_ - 1, endian_ ,0); + top_block->disconnect(endian_, 0, unpack_spir_, 0); + } + else + { + top_block->disconnect(deint_, sel_ch_ - 1, unpack_spir_, 0); + } if(n_channels_ > 1) { unsigned int aux = 0; @@ -241,10 +265,14 @@ void SpirGSS6450FileSignalSource::disconnect(gr::top_block_sptr top_block) top_block->disconnect(unpack_spir_, 0, valve_, 0); } if(dump_) - { - top_block->disconnect(valve_, 0, sink_, 0); - //top_block->disconnect(deint_, sel_ch_ - 1, sink_test, 0); - } + { + top_block->disconnect(valve_, 0, sink_, 0); + } + if(dump_test_) + { + if(endian_swap_) top_block->disconnect(endian_, 0, sink_test, 0); + else top_block->disconnect(deint_, sel_ch_ - 1, sink_test, 0); + } } else { diff --git a/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.h b/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.h index e8387dbd7..411d04069 100644 --- a/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.h +++ b/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.h @@ -111,8 +111,10 @@ private: double sampling_frequency_; std::string filename_; bool repeat_; - bool dump_; + bool dump_; //Enables dumping the gr_complex sample output + bool dump_test_; //Enables dumping the raw 32-bits deinterleaved (and endian swapped if enabled) words bool enable_throttle_control_; + bool endian_swap_; std::string dump_filename_; std::string role_; std::string item_type_; From dd77cd10dfc23e4f92a300f7a15e7e0b229118c5 Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Mon, 22 Jan 2018 12:21:28 +0100 Subject: [PATCH 5/6] Remove debug lines --- .../adapters/spir_gss6450_file_signal_source.cc | 15 --------------- .../adapters/spir_gss6450_file_signal_source.h | 2 -- .../unpack_spir_gss6450_samples.cc | 17 ----------------- .../unpack_spir_gss6450_samples.h | 1 - 4 files changed, 35 deletions(-) diff --git a/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc b/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc index 81a7d33e6..f19d9d3d6 100644 --- a/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc +++ b/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.cc @@ -54,7 +54,6 @@ SpirGSS6450FileSignalSource::SpirGSS6450FileSignalSource(ConfigurationInterface* filename_ = configuration->property(role + ".filename", default_filename); repeat_ = configuration->property(role + ".repeat", false); dump_ = configuration->property(role + ".dump", false); - dump_test_ = configuration->property(role + ".dump_test", false); endian_swap_ = configuration->property(role + ".endian", false); dump_filename_ = configuration->property(role + ".dump_filename", default_dump_filename); enable_throttle_control_ = configuration->property(role + ".enable_throttle_control", false); @@ -150,10 +149,6 @@ SpirGSS6450FileSignalSource::SpirGSS6450FileSignalSource(ConfigurationInterface* sink_ = gr::blocks::file_sink::make(sizeof(gr_complex), dump_filename_.c_str()); DLOG(INFO) << "file_sink(" << sink_->unique_id() << ")"; } - if (dump_test_) - { - sink_test = gr::blocks::file_sink::make(sizeof(int), (dump_filename_ + "int").c_str()); - } if (enable_throttle_control_) { throttle_ = gr::blocks::throttle::make(sizeof(gr_complex), sampling_frequency_); @@ -216,11 +211,6 @@ void SpirGSS6450FileSignalSource::connect(gr::top_block_sptr top_block) { top_block->connect(valve_, 0, sink_, 0); } - if(dump_test_) - { - if(endian_swap_) top_block->connect(endian_, 0, sink_test, 0); - else top_block->connect(deint_, sel_ch_ - 1, sink_test, 0); - } } else { @@ -268,11 +258,6 @@ void SpirGSS6450FileSignalSource::disconnect(gr::top_block_sptr top_block) { top_block->disconnect(valve_, 0, sink_, 0); } - if(dump_test_) - { - if(endian_swap_) top_block->disconnect(endian_, 0, sink_test, 0); - else top_block->disconnect(deint_, sel_ch_ - 1, sink_test, 0); - } } else { diff --git a/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.h b/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.h index 411d04069..caa26c8fb 100644 --- a/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.h +++ b/src/algorithms/signal_source/adapters/spir_gss6450_file_signal_source.h @@ -112,7 +112,6 @@ private: std::string filename_; bool repeat_; bool dump_; //Enables dumping the gr_complex sample output - bool dump_test_; //Enables dumping the raw 32-bits deinterleaved (and endian swapped if enabled) words bool enable_throttle_control_; bool endian_swap_; std::string dump_filename_; @@ -130,7 +129,6 @@ private: unpack_spir_gss6450_samples_sptr unpack_spir_; boost::shared_ptr valve_; gr::blocks::file_sink::sptr sink_; - gr::blocks::file_sink::sptr sink_test; gr::blocks::throttle::sptr throttle_; gr::msg_queue::sptr queue_; size_t item_size_; diff --git a/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.cc b/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.cc index 5992c7025..7bbb2cb75 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.cc +++ b/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.cc @@ -83,7 +83,6 @@ int unpack_spir_gss6450_samples::work(int noutput_items, for(int i = 0; i < noutput_items; i++) { int sample_aux = in[in_counter]; - //reverse_bits(sample_aux); int aux_i = sample_aux; int aux_q = sample_aux; int i_shift = adc_bits * 2 * (samples_per_int - n_sample - 1) + adc_bits; @@ -101,22 +100,6 @@ int unpack_spir_gss6450_samples::work(int noutput_items, return noutput_items; } -void unpack_spir_gss6450_samples::reverse_bits(int& data) -{ - unsigned int v = data; // input bits to be reversed - unsigned int r = v; // r will be reversed bits of v; first get LSB of v - int s = sizeof(v) * CHAR_BIT - 1; // extra shift needed at end - - for (v >>= 1; v; v >>= 1) - { - r <<= 1; - r |= v & 1; - s--; - } - r <<= s; // shift when v's highest bits are zero - data = r; -} - void unpack_spir_gss6450_samples::compute_two_complement(int& data) { data = map_[data]; diff --git a/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.h b/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.h index df890fc74..a592c2aee 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.h +++ b/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.h @@ -55,7 +55,6 @@ private: unsigned int samples_per_int; void process_sample(gr_complex& out); void compute_two_complement(int& data); - void reverse_bits(int& data); int i_data; int q_data; int mask_data; From 0dab500fb0483bcb1e082a5b122976e96b98d8f6 Mon Sep 17 00:00:00 2001 From: Antonio Ramos Date: Mon, 22 Jan 2018 12:38:38 +0100 Subject: [PATCH 6/6] Update author --- .../gnuradio_blocks/unpack_spir_gss6450_samples.cc | 8 ++++---- .../gnuradio_blocks/unpack_spir_gss6450_samples.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.cc b/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.cc index 7bbb2cb75..6a7bf869a 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.cc +++ b/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.cc @@ -1,11 +1,11 @@ /*! - * \file unpack_intspir_1bit_samples.cc + * \file unpack_spir_gss6450_samples.cc * - * \brief Unpacks SPIR int samples to NSR 1 bit samples - * \author Fran Fabra fabra (at) ice.csic.es + * \brief Unpacks SPIR int samples + * \author Antonio Ramos, antonio(at)cttc.es * ------------------------------------------------------------------------- * - * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) * * GNSS-SDR is a software defined Global Navigation * Satellite Systems receiver diff --git a/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.h b/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.h index a592c2aee..25db1a9d6 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.h +++ b/src/algorithms/signal_source/gnuradio_blocks/unpack_spir_gss6450_samples.h @@ -1,11 +1,11 @@ /*! - * \file unpack_intspir_1bit_samples.h + * \file unpack_spir_gss6450_samples.h * - * \brief Unpacks SPIR int samples to NSR 1 bit samples - * \author Fran Fabra fabra (at) ice.csic.es + * \brief Unpacks SPIR int samples + * \author Antonio Ramos, antonio.ramos(at)cttc.es * ------------------------------------------------------------------------- * - * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) * * GNSS-SDR is a software defined Global Navigation * Satellite Systems receiver