diff --git a/src/algorithms/signal_source/adapters/CMakeLists.txt b/src/algorithms/signal_source/adapters/CMakeLists.txt index 7a4c6e065..32a9c6bc9 100644 --- a/src/algorithms/signal_source/adapters/CMakeLists.txt +++ b/src/algorithms/signal_source/adapters/CMakeLists.txt @@ -99,6 +99,7 @@ set(SIGNAL_SOURCE_ADAPTER_SOURCES labsat_signal_source.cc two_bit_cpx_file_signal_source.cc two_bit_packed_file_signal_source.cc + four_bit_cpx_file_signal_source.cc file_timestamp_signal_source.cc ${OPT_DRIVER_SOURCES} ) @@ -117,6 +118,7 @@ set(SIGNAL_SOURCE_ADAPTER_HEADERS labsat_signal_source.h two_bit_cpx_file_signal_source.h two_bit_packed_file_signal_source.h + four_bit_cpx_file_signal_source.h file_timestamp_signal_source.h ${OPT_DRIVER_HEADERS} ) diff --git a/src/algorithms/signal_source/adapters/four_bit_cpx_file_signal_source.cc b/src/algorithms/signal_source/adapters/four_bit_cpx_file_signal_source.cc new file mode 100644 index 000000000..0fc521fe9 --- /dev/null +++ b/src/algorithms/signal_source/adapters/four_bit_cpx_file_signal_source.cc @@ -0,0 +1,102 @@ +/*! + * \file four_bit_cpx_file_signal_source.cc + * \brief Implementation of a class that reads signals samples from a 2 bit complex sampler front-end file + * and adapts it to a SignalSourceInterface. + * \author Javier Arribas, 2015 jarribas(at)cttc.es + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2021 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#include "four_bit_cpx_file_signal_source.h" +#include "configuration_interface.h" +#include "gnss_sdr_string_literals.h" +#include + +using namespace std::string_literals; + + +FourBitCpxFileSignalSource::FourBitCpxFileSignalSource( + const ConfigurationInterface* configuration, + const std::string& role, + unsigned int in_streams, unsigned int out_streams, + Concurrent_Queue* queue) + : FileSourceBase(configuration, role, "Four_Bit_Cpx_File_Signal_Source"s, queue, "byte"s) +{ + sample_type_ = configuration->property(role + ".sample_type", "iq"s); + // the complex-ness of the input is inferred from the output type + if (sample_type_ == "iq") + { + reverse_interleaving_ = false; + } + else if (sample_type_ == "qi") + { + reverse_interleaving_ = true; + } + else + { + LOG(WARNING) << sample_type_ << " unrecognized sample type. Assuming: "; + } + + + if (in_streams > 0) + { + LOG(ERROR) << "A signal source does not have an input stream"; + } + if (out_streams > 1) + { + LOG(ERROR) << "This implementation only supports one output stream"; + } +} + + +std::tuple FourBitCpxFileSignalSource::itemTypeToSize() +{ + auto is_complex = false; + auto item_size = size_t(sizeof(char)); // default + + if (item_type() == "byte") + { + item_size = sizeof(char); + } + else + { + LOG(WARNING) << item_type() << " unrecognized item type. Using byte."; + } + + return std::make_tuple(item_size, is_complex); +} + +// 1 byte -> 1 complex samples +double FourBitCpxFileSignalSource::packetsPerSample() const { return 1.0; } +gnss_shared_ptr FourBitCpxFileSignalSource::source() const { return inter_shorts_to_cpx_; } + + +void FourBitCpxFileSignalSource::create_file_source_hook() +{ + unpack_byte_ = make_unpack_byte_4bit_samples(); + DLOG(INFO) << "unpack_byte_2bit_cpx_samples(" << unpack_byte_->unique_id() << ")"; + inter_shorts_to_cpx_ = gr::blocks::interleaved_short_to_complex::make(false, reverse_interleaving_); // I/Q swap enabled + DLOG(INFO) << "interleaved_short_to_complex(" << inter_shorts_to_cpx_->unique_id() << ")"; +} + +void FourBitCpxFileSignalSource::pre_connect_hook(gr::top_block_sptr top_block) +{ + 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"; +} + +void FourBitCpxFileSignalSource::pre_disconnect_hook(gr::top_block_sptr top_block) +{ + 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/four_bit_cpx_file_signal_source.h b/src/algorithms/signal_source/adapters/four_bit_cpx_file_signal_source.h new file mode 100644 index 000000000..ac9b5c3fb --- /dev/null +++ b/src/algorithms/signal_source/adapters/four_bit_cpx_file_signal_source.h @@ -0,0 +1,71 @@ +/*! + * \file FOUR_BIT_cpx_file_signal_source.h + * \brief Interface of a class that reads signals samples from a 2 bit complex sampler front-end file + * and adapts it to a SignalSourceInterface. + * \author Javier Arribas, 2015 jarribas(at)cttc.es + * + * This class represents a file signal source. + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2021 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_FOUR_BIT_CPX_FILE_SIGNAL_SOURCE_H +#define GNSS_SDR_FOUR_BIT_CPX_FILE_SIGNAL_SOURCE_H + +#include "file_source_base.h" +#include "unpack_byte_4bit_samples.h" +#include +#include +#include +#include + +/** \addtogroup Signal_Source + * \{ */ +/** \addtogroup Signal_Source_adapters + * \{ */ + + +class ConfigurationInterface; + +/*! + * \brief Class that reads signals samples from a file + * and adapts it to a SignalSourceInterface + */ +class FourBitCpxFileSignalSource : public FileSourceBase +{ +public: + FourBitCpxFileSignalSource(const ConfigurationInterface* configuration, + const std::string& role, + unsigned int in_streams, + unsigned int out_streams, + Concurrent_Queue* queue); + + ~FourBitCpxFileSignalSource() = default; + +protected: + std::tuple itemTypeToSize() 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: + unpack_byte_4bit_samples_sptr unpack_byte_; + gr::blocks::interleaved_short_to_complex::sptr inter_shorts_to_cpx_; + std::string sample_type_; + bool reverse_interleaving_; +}; + + +/** \} */ +/** \} */ +#endif // GNSS_SDR_FOUR_BIT_CPX_FILE_SIGNAL_SOURCE_H diff --git a/src/algorithms/signal_source/gnuradio_blocks/unpack_byte_4bit_samples.cc b/src/algorithms/signal_source/gnuradio_blocks/unpack_byte_4bit_samples.cc index ca82f23b5..ccc04374f 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/unpack_byte_4bit_samples.cc +++ b/src/algorithms/signal_source/gnuradio_blocks/unpack_byte_4bit_samples.cc @@ -26,8 +26,8 @@ unpack_byte_4bit_samples_sptr make_unpack_byte_4bit_samples() unpack_byte_4bit_samples::unpack_byte_4bit_samples() : sync_interpolator("unpack_byte_4bit_samples", - gr::io_signature::make(1, 1, sizeof(signed char)), - gr::io_signature::make(1, 1, sizeof(signed char)), + gr::io_signature::make(1, 1, sizeof(int8_t)), + gr::io_signature::make(1, 1, sizeof(int16_t)), 2) { } @@ -37,8 +37,8 @@ int unpack_byte_4bit_samples::work(int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { - const auto *in = reinterpret_cast(input_items[0]); - auto *out = reinterpret_cast(output_items[0]); + const auto *in = reinterpret_cast(input_items[0]); + auto *out = reinterpret_cast(output_items[0]); int n = 0; unsigned char tmp_char2; for (int i = 0; i < noutput_items / 2; i++) @@ -46,21 +46,21 @@ int unpack_byte_4bit_samples::work(int noutput_items, tmp_char2 = in[i] & 0x0F; if (tmp_char2 >= 8) { - out[n++] = 2 * (tmp_char2 - 16) + 1; + out[n++] = static_cast(2 * (tmp_char2 - 16) + 1); } else { - out[n++] = 2 * tmp_char2 + 1; + out[n++] = static_cast(2 * tmp_char2 + 1); } tmp_char2 = in[i] >> 4; tmp_char2 = tmp_char2 & 0x0F; if (tmp_char2 >= 8) { - out[n++] = 2 * (tmp_char2 - 16) + 1; + out[n++] = static_cast(2 * (tmp_char2 - 16) + 1); } else { - out[n++] = 2 * tmp_char2 + 1; + out[n++] = static_cast(2 * tmp_char2 + 1); } } return noutput_items; diff --git a/src/algorithms/signal_source/gnuradio_blocks/unpack_byte_4bit_samples.h b/src/algorithms/signal_source/gnuradio_blocks/unpack_byte_4bit_samples.h index 1d3d91da6..2b75c763c 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/unpack_byte_4bit_samples.h +++ b/src/algorithms/signal_source/gnuradio_blocks/unpack_byte_4bit_samples.h @@ -20,8 +20,8 @@ #ifndef GNSS_SDR_UNPACK_BYTE_4BIT_SAMPLES_H #define GNSS_SDR_UNPACK_BYTE_4BIT_SAMPLES_H +#include "gnss_block_interface.h" #include -#include /** \addtogroup Signal_Source * \{ */ @@ -31,7 +31,7 @@ class unpack_byte_4bit_samples; -using unpack_byte_4bit_samples_sptr = std::shared_ptr; +using unpack_byte_4bit_samples_sptr = gnss_shared_ptr; unpack_byte_4bit_samples_sptr make_unpack_byte_4bit_samples(); diff --git a/src/core/receiver/gnss_block_factory.cc b/src/core/receiver/gnss_block_factory.cc index 6a92df891..adba9c0df 100644 --- a/src/core/receiver/gnss_block_factory.cc +++ b/src/core/receiver/gnss_block_factory.cc @@ -41,6 +41,7 @@ #include "file_signal_source.h" #include "file_timestamp_signal_source.h" #include "fir_filter.h" +#include "four_bit_cpx_file_signal_source.h" #include "freq_xlating_fir_filter.h" #include "galileo_e1_dll_pll_veml_tracking.h" #include "galileo_e1_pcps_8ms_ambiguous_acquisition.h" @@ -694,6 +695,12 @@ std::unique_ptr GNSSBlockFactory::GetBlock( out_streams, queue); block = std::move(block_); } + else if (implementation == "Four_Bit_Cpx_File_Signal_Source") + { + std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, + out_streams, queue); + block = std::move(block_); + } else if (implementation == "Two_Bit_Packed_File_Signal_Source") { std::unique_ptr block_ = std::make_unique(configuration, role, in_streams,