1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2025-11-20 09:05:25 +00:00

Merge branch 'initial-labsat-4-support' into next

This commit is contained in:
Carles Fernandez
2025-10-01 16:39:28 +02:00
3 changed files with 552 additions and 448 deletions

View File

@@ -46,8 +46,9 @@ LabsatSignalSource::LabsatSignalSource(const ConfigurationInterface* configurati
item_type_ = configuration->property(role + ".item_type", default_item_type);
dump_filename_ = configuration->property(role + ".dump_filename", default_dump_file);
const int64_t sampling_frequency_deprecated = configuration->property(role + ".sampling_frequency", static_cast<int64_t>(16368000));
const int64_t throttle_frequency_sps = configuration->property(role + ".throttle_frequency_sps", static_cast<int64_t>(sampling_frequency_deprecated));
const int64_t sampling_frequency = configuration->property(role + ".sampling_frequency", static_cast<int64_t>(16368000));
const int64_t throttle_frequency_sps = configuration->property(role + ".throttle_frequency_sps", static_cast<int64_t>(sampling_frequency));
const double seconds_to_skip = configuration->property(role + ".seconds_to_skip", 0.);
std::string channels_to_read = configuration->property(role + ".selected_channel", default_item_type);
std::stringstream ss(channels_to_read);
@@ -77,7 +78,7 @@ LabsatSignalSource::LabsatSignalSource(const ConfigurationInterface* configurati
if (item_type_ == "gr_complex")
{
item_size_ = sizeof(gr_complex);
labsat23_source_ = labsat23_make_source_sptr(filename_.c_str(), channels_selector_vec_, queue, digital_io_enabled);
labsat23_source_ = labsat23_make_source_sptr(filename_.c_str(), channels_selector_vec_, queue, digital_io_enabled, sampling_frequency, seconds_to_skip);
DLOG(INFO) << "Item size " << item_size_;
DLOG(INFO) << "labsat23_source_(" << labsat23_source_->unique_id() << ")";
}

View File

@@ -20,33 +20,108 @@
#include "labsat23_source.h"
#include "INIReader.h"
#include "command_event.h"
#include "gnss_sdr_filesystem.h"
#include "gnss_sdr_make_unique.h"
#include <gnuradio/io_signature.h>
#include <algorithm>
#include <array>
#include <bitset>
#include <exception>
#include <iomanip>
#include <iostream>
#include <memory>
#include <sstream>
#include <utility>
#if HAS_BOOST_ENDIAN
#include <boost/endian/conversion.hpp>
#endif
#if USE_GLOG_AND_GFLAGS
#include <glog/logging.h>
#else
#include <absl/log/log.h>
#endif
labsat23_source_sptr labsat23_make_source_sptr(const char *signal_file_basename, const std::vector<int> &channel_selector, Concurrent_Queue<pmt::pmt_t> *queue, bool digital_io_enabled)
namespace
{
return labsat23_source_sptr(new labsat23_source(signal_file_basename, channel_selector, queue, digital_io_enabled));
void write_iq_from_bitset(const std::bitset<64> &bs, int bit_offset, int qua, gr_complex &out)
{
float sampleI = 0.0;
float sampleQ = 0.0;
switch (qua)
{
case 1:
sampleI = bs[bit_offset] ? -1.0 : 1.0;
sampleQ = bs[bit_offset + 1] ? -1.0 : 1.0;
break;
case 2:
{
// Mapping for: 00, 01, 10, 11
static const double mapping[4] = {0.5, 1.0, -1.0, -0.5};
const auto i_bits = (bs[bit_offset] << 1) | bs[bit_offset + 1];
const auto q_bits = (bs[bit_offset + 2] << 1) | bs[bit_offset + 3];
sampleI = mapping[i_bits];
sampleQ = mapping[q_bits];
}
break;
case 3:
{
// Mapping for: 000, 001, 010, 011, 100, 101, 110, 111
static const double mapping[8] = {0.25, 0.5, 0.75, 1.0, -1.0, -0.75, -0.5, -0.25};
const auto i_bits = (bs[bit_offset] << 2) | (bs[bit_offset + 1] << 1) | bs[bit_offset + 2];
const auto q_bits = (bs[bit_offset + 3] << 2) | (bs[bit_offset + 4] << 1) | bs[bit_offset + 5];
sampleI = mapping[i_bits];
sampleQ = mapping[q_bits];
}
break;
default:
break;
}
out = gr_complex(sampleI, sampleQ);
}
void invert_bitset(std::bitset<64> &bs)
{
for (size_t i = 0; i < 32; ++i)
{
const auto t = bs[i];
bs[i] = bs[64 - i - 1];
bs[64 - i - 1] = t;
}
}
void read_file_register_to_local_endian(std::ifstream &binary_input_file, uint64_t &read_register)
{
#if HAS_BOOST_ENDIAN
binary_input_file.read(reinterpret_cast<char *>(&read_register), sizeof(read_register));
boost::endian::little_to_native_inplace(read_register);
#else
std::array<char, 8> memory_block{};
binary_input_file.read(memory_block.data(), 8);
for (int k = 7; k >= 0; --k)
{
read_register <<= 8;
read_register |= uint64_t(memory_block[k]); // This is buggy if the MSB of the char is set.
}
#endif
}
} // namespace
labsat23_source_sptr labsat23_make_source_sptr(
const char *signal_file_basename,
const std::vector<int> &channel_selector,
Concurrent_Queue<pmt::pmt_t> *queue,
bool digital_io_enabled,
int64_t sampling_frequency,
double seconds_to_skip)
{
return labsat23_source_sptr(new labsat23_source(signal_file_basename, channel_selector, queue, digital_io_enabled, sampling_frequency, seconds_to_skip));
}
labsat23_source::labsat23_source(const char *signal_file_basename,
labsat23_source::labsat23_source(
const char *signal_file_basename,
const std::vector<int> &channel_selector,
Concurrent_Queue<pmt::pmt_t> *queue,
bool digital_io_enabled) : gr::block("labsat23_source",
bool digital_io_enabled,
int64_t sampling_frequency,
double seconds_to_skip) : gr::block("labsat23_source",
gr::io_signature::make(0, 0, 0),
gr::io_signature::make(1, 3, sizeof(gr_complex))),
d_queue(queue),
@@ -64,13 +139,25 @@ labsat23_source::labsat23_source(const char *signal_file_basename,
this->set_output_multiple(8);
signal_file = generate_filename();
if (d_is_ls3w || d_is_ls4)
{
if (d_is_ls3w)
{
d_labsat_version = 3;
std::cout << "LabSat file version 3 Wideband detected.\n";
}
else if (d_is_ls4)
{
this->set_output_multiple(16);
d_labsat_version = 4;
std::cout << "LabSat file version 4 detected.\n";
}
fs::path file_path(signal_file);
file_path.replace_extension(".ini");
// Read ini file
std::string ini_file = signal_file.substr(0, signal_file.length() - 4) + std::string("ini");
if (read_ls3w_ini(ini_file) != 0)
if (read_ls3w_ini(file_path.string()) != 0)
{
exit(1);
}
@@ -80,7 +167,65 @@ labsat23_source::labsat23_source(const char *signal_file_basename,
if (binary_input_file.is_open())
{
std::cout << "LabSat file source is reading samples from " << signal_file << '\n';
std::cout << "LabSat file source is reading samples from " << signal_file;
if (d_is_ls4)
{
const auto size = fs::file_size(d_signal_file_basename);
const auto samples = (size * CHAR_BIT) / d_ls3w_SFT;
const auto samples_to_skip = static_cast<size_t>(seconds_to_skip * sampling_frequency);
const auto samples_to_read = static_cast<int64_t>(samples - samples_to_skip);
std::cout << ", which contains " << samples << " samples (" << size << " bytes)\n";
if (samples_to_read < 0)
{
std::cout << "File duration is smaller then the seconds to skip!\n";
exit(1);
}
const auto signal_duration_s = static_cast<double>(samples_to_read) / sampling_frequency;
std::cout << "GNSS signal recorded time to be processed: " << signal_duration_s << " [s]\n";
if (samples_to_skip > 0)
{
LOG(INFO) << "Skipping " << samples_to_skip << " samples of the input file";
// We assume all buffers have same size and take advantage of integer rounding
const auto bytes_to_skip = (samples_to_skip * d_ls3w_SFT) / CHAR_BIT;
const auto bytes_to_skip_per_channel = bytes_to_skip / d_ls3w_CHN;
const auto nb_of_channel_buffer_to_skip = bytes_to_skip_per_channel / d_ls4_BUFF_SIZE;
const auto bytes_to_seek_per_channel = nb_of_channel_buffer_to_skip * d_ls4_BUFF_SIZE;
const auto bytes_to_seek = bytes_to_seek_per_channel * d_ls3w_CHN;
const auto bytes_to_read_per_channel = bytes_to_skip_per_channel - bytes_to_seek_per_channel;
// Advance in the file by a multiple of buffers, then read one buffer of each channel
if (!binary_input_file.seekg(bytes_to_seek, std::ios::beg) || !read_ls4_data())
{
LOG(ERROR) << "Error skipping bytes!";
exit(1);
}
// Advances the indices to start at the correct index in the buffer we just read
if (d_ls4_BUFF_SIZE_A > 0)
{
d_data_index_a += (bytes_to_read_per_channel / sizeof(uint64_t));
}
if (d_ls4_BUFF_SIZE_B > 0)
{
d_data_index_b += (bytes_to_read_per_channel / sizeof(uint64_t));
}
if (d_ls4_BUFF_SIZE_C > 0)
{
d_data_index_c += (bytes_to_read_per_channel / sizeof(uint64_t));
}
}
}
else
{
std::cout << '\n';
}
}
else
{
@@ -112,7 +257,10 @@ labsat23_source::~labsat23_source()
std::string labsat23_source::generate_filename()
{
if (d_signal_file_basename.substr(d_signal_file_basename.length() - 4, 4) == ".ls2" or d_signal_file_basename.substr(d_signal_file_basename.length() - 4, 4) == ".LS2")
fs::path file_path(d_signal_file_basename);
const auto extension = file_path.extension();
if (extension == ".ls2" or extension == ".LS2")
{
if (d_current_file_number == 0)
{
@@ -120,11 +268,16 @@ std::string labsat23_source::generate_filename()
}
return {"donotexist"}; // just to stop processing
}
if (d_signal_file_basename.substr(d_signal_file_basename.length() - 5, 5) == ".ls3w" or d_signal_file_basename.substr(d_signal_file_basename.length() - 5, 5) == ".LS3W")
if (extension == ".ls3w" or extension == ".LS3W")
{
d_is_ls3w = true;
return d_signal_file_basename;
}
if (extension == ".ls4" or extension == ".LS4")
{
d_is_ls4 = true;
return d_signal_file_basename;
}
std::ostringstream ss;
ss << std::setw(4) << std::setfill('0') << d_current_file_number;
@@ -132,12 +285,6 @@ std::string labsat23_source::generate_filename()
}
int labsat23_source::getBit(uint8_t byte, int position)
{
return (byte >> position) & 0x01;
}
int labsat23_source::parse_header()
{
if (binary_input_file.eof() == false)
@@ -537,64 +684,60 @@ int labsat23_source::read_ls3w_ini(const std::string &filename)
}
}
// Channel A
if (ini_reader->HasSection("channel A"))
const auto channel_handler = [this, &ini_reader, &empty_string](const std::string &channel_char, int32_t &cf, int32_t &bw, int32_t &buffer_size, std::vector<uint64_t> &buffer) {
const auto channel_name = "channel " + channel_char;
if (ini_reader->HasSection(channel_name))
{
std::string ls3w_CFA_aux = ini_reader->Get("channel A", "CFA", empty_string);
if (!ls3w_CFA_aux.empty())
const auto cf_str = ini_reader->Get(channel_name, "CF" + channel_char, empty_string);
if (!cf_str.empty())
{
std::stringstream cfa_ss(ls3w_CFA_aux);
cfa_ss >> d_ls3w_CFA;
std::cout << "LabSat center frequency for RF channel A: " << d_ls3w_CFA << " Hz\n";
std::stringstream cf_ss(cf_str);
cf_ss >> cf;
std::cout << "LabSat center frequency for RF " << channel_name << ": " << cf << " Hz\n";
}
std::string ls3w_BWA_aux = ini_reader->Get("channel A", "BWA", empty_string);
if (!ls3w_BWA_aux.empty())
const auto bw_str = ini_reader->Get(channel_name, "BW" + channel_char, empty_string);
if (!bw_str.empty())
{
std::stringstream bwa_ss(ls3w_BWA_aux);
bwa_ss >> d_ls3w_BWA;
std::cout << "LabSat RF filter bandwidth for RF channel A: " << d_ls3w_BWA << " Hz\n";
}
std::stringstream bw_ss(bw_str);
bw_ss >> bw;
std::cout << "LabSat RF filter bandwidth for RF " << channel_name << ": " << bw << " Hz\n";
}
// Channel B
if (ini_reader->HasSection("channel B"))
if (d_is_ls4)
{
std::string ls3w_CFB_aux = ini_reader->Get("channel B", "CFB", empty_string);
if (!ls3w_CFB_aux.empty())
const auto buffer_size_str = ini_reader->Get(channel_name, "BUF_SIZE_" + channel_char, empty_string);
if (!buffer_size_str.empty())
{
std::stringstream cfb_ss(ls3w_CFB_aux);
cfb_ss >> d_ls3w_CFB;
std::cout << "LabSat center frequency for RF channel B: " << d_ls3w_CFB << " Hz\n";
std::stringstream buff_size_ss(buffer_size_str);
buff_size_ss >> buffer_size;
if (buffer_size > 0)
{
d_ls4_BUFF_SIZE = buffer_size;
if (buffer_size % sizeof(uint64_t) != 0)
{
std::cerr << "\nConfiguration error: RF " << channel_name << " is BUFF SIZE is not a multiple of " << sizeof(uint64_t) << ".\n";
std::cerr << "Exiting the program.\n";
return false;
}
std::string ls3w_BWB_aux = ini_reader->Get("channel B", "BWB", empty_string);
if (!ls3w_BWB_aux.empty())
{
std::stringstream bwb_ss(ls3w_BWB_aux);
bwb_ss >> d_ls3w_BWB;
std::cout << "LabSat RF filter bandwidth for RF channel B: " << d_ls3w_BWB << " Hz\n";
buffer.resize(buffer_size / sizeof(uint64_t));
}
std::cout << "LabSat RF BUFFER SIZE for RF " << channel_name << ": " << buffer_size << " bytes\n";
}
}
}
return true;
};
// Channel C
if (ini_reader->HasSection("channel C"))
if (!channel_handler("A", d_ls3w_CFA, d_ls3w_BWA, d_ls4_BUFF_SIZE_A, d_ls4_data_a) ||
!channel_handler("B", d_ls3w_CFB, d_ls3w_BWB, d_ls4_BUFF_SIZE_B, d_ls4_data_b) ||
!channel_handler("C", d_ls3w_CFC, d_ls3w_BWC, d_ls4_BUFF_SIZE_C, d_ls4_data_c))
{
std::string ls3w_CFC_aux = ini_reader->Get("channel C", "CFC", empty_string);
if (!ls3w_CFC_aux.empty())
{
std::stringstream cfc_ss(ls3w_CFC_aux);
cfc_ss >> d_ls3w_CFC;
std::cout << "LabSat center frequency for RF channel C: " << d_ls3w_CFC << " Hz\n";
}
std::string ls3w_BWC_aux = ini_reader->Get("channel C", "BWC", empty_string);
if (!ls3w_BWC_aux.empty())
{
std::stringstream bwc_ss(ls3w_BWC_aux);
bwc_ss >> d_ls3w_BWC;
std::cout << "LabSat RF filter bandwidth for RF channel C: " << d_ls3w_BWC << " Hz\n";
}
return -1;
}
std::cout << "LabSat selected channel" << ((d_channel_selector_config.size() > 1) ? "s" : "") << ": ";
@@ -743,202 +886,24 @@ void labsat23_source::decode_ls3w_register(uint64_t input, std::vector<gr_comple
// Earlier samples are written in the MSBs of the register. Bit-reverse the register
// for easier indexing. Note this bit-reverses individual samples as well for quant > 1 bit
for (std::size_t i = 0; i < 32; ++i)
{
bool t = bs[i];
bs[i] = bs[64 - i - 1];
bs[64 - i - 1] = t;
}
invert_bitset(bs);
int output_chan = 0;
for (auto channel_offset : d_ls3w_selected_channel_offset)
for (const auto channel_offset : d_ls3w_selected_channel_offset)
{
gr_complex *aux = out[output_chan];
for (int i = 0; i < d_ls3w_samples_per_register; i++)
{
float sampleI = 0.0;
float sampleQ = 0.0;
const int bit_offset = d_ls3w_spare_bits + i * d_ls3w_SFT + channel_offset;
switch (d_ls3w_QUA)
{
case 1:
sampleI = bs[bit_offset] ? -1.0 : 1.0;
sampleQ = bs[bit_offset + 1] ? -1.0 : 1.0;
break;
case 2:
if (bs[bit_offset])
{
if (bs[bit_offset + 1]) // 11
{
sampleI = -0.5;
}
else // 10
{
sampleI = -1.0;
}
}
else
{
if (bs[bit_offset + 1]) // 01
{
sampleI = 1.0;
}
else // 00
{
sampleI = 0.5;
}
}
if (bs[bit_offset + 2])
{
if (bs[bit_offset + 3]) // 11
{
sampleQ = -0.5;
}
else // 10
{
sampleQ = -1.0;
}
}
else
{
if (bs[bit_offset + 3]) // 01
{
sampleQ = 1.0;
}
else // 00
{
sampleQ = 0.5;
}
}
break;
case 3:
if (bs[bit_offset])
{
if (bs[bit_offset + 1])
{
if (bs[bit_offset + 2]) // 111
{
sampleI = -0.25;
}
else // 110
{
sampleI = -0.5;
}
}
else
{
if (bs[bit_offset + 2]) // 101
{
sampleI = -0.75;
}
else // 100
{
sampleI = -1.0;
}
}
}
else
{
if (bs[bit_offset + 1])
{
if (bs[bit_offset + 2]) // 011
{
sampleI = 1;
}
else // 010
{
sampleI = 0.75;
}
}
else
{
if (bs[bit_offset + 2]) // 001
{
sampleI = 0.5;
}
else // 000
{
sampleI = 0.25;
}
}
}
if (bs[bit_offset + 3])
{
if (bs[bit_offset + 4])
{
if (bs[bit_offset + 5]) // 111
{
sampleQ = -0.25;
}
else // 110
{
sampleQ = -0.5;
}
}
else
{
if (bs[bit_offset + 5]) // 101
{
sampleQ = -0.75;
}
else // 100
{
sampleQ = -1.0;
}
}
}
else
{
if (bs[bit_offset + 4])
{
if (bs[bit_offset + 5]) // 011
{
sampleQ = 1;
}
else // 010
{
sampleQ = 0.75;
}
}
else
{
if (bs[bit_offset + 5]) // 001
{
sampleQ = 0.5;
}
else // 000
{
sampleQ = 0.25;
}
}
}
break;
default:
break;
}
gr_complex *aux = out[output_chan];
aux[output_pointer + i] = gr_complex(sampleI, sampleQ);
write_iq_from_bitset(bs, bit_offset, d_ls3w_QUA, aux[output_pointer + i]);
}
output_chan++;
}
}
int labsat23_source::general_work(int noutput_items,
__attribute__((unused)) gr_vector_int &ninput_items,
__attribute__((unused)) gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items)
int labsat23_source::parse_ls23_data(int noutput_items, std::vector<gr_complex *> out)
{
std::vector<gr_complex *> out;
for (auto &output_item : output_items)
{
out.push_back(reinterpret_cast<gr_complex *>(output_item));
}
if (!d_is_ls3w)
{
if (d_header_parsed == false)
{
return parse_header();
@@ -1065,9 +1030,12 @@ int labsat23_source::general_work(int noutput_items,
default:
return -1;
}
}
else // Labsat 3 Wideband
{
return -1;
}
int labsat23_source::parse_ls3w_data(int noutput_items, std::vector<gr_complex *> out)
{
if (binary_input_file.eof() == false)
{
// Integer division, any fractional part of the answer is discarded
@@ -1081,18 +1049,7 @@ int labsat23_source::general_work(int noutput_items,
{
uint64_t read_register = 0ULL;
// Labsat3W writes its 64-bit shift register to files in little endian. Read and convert to host endianness.
#if HAS_BOOST_ENDIAN
binary_input_file.read(reinterpret_cast<char *>(&read_register), sizeof(read_register));
boost::endian::little_to_native_inplace(read_register);
#else
std::array<char, 8> memory_block{};
binary_input_file.read(memory_block.data(), 8);
for (int k = 7; k >= 0; --k)
{
read_register <<= 8;
read_register |= uint64_t(memory_block[k]); // This is buggy if the MSB of the char is set.
}
#endif
read_file_register_to_local_endian(binary_input_file, read_register);
if (binary_input_file.gcount() == 8)
{
@@ -1114,6 +1071,126 @@ int labsat23_source::general_work(int noutput_items,
d_queue->push(pmt::make_any(command_event_make(200, 0)));
return -1;
}
}
int labsat23_source::parse_ls4_data(int noutput_items, std::vector<gr_complex *> out)
{
if (binary_input_file.eof() == false)
{
int output_index = 0;
const auto shift = d_ls3w_QUA * 2;
const auto item_count = 64 / shift;
int registers_to_read = noutput_items / item_count;
for (int j = 0; j < registers_to_read; j++)
{
if ((d_data_index_a + d_data_index_b + d_data_index_c) >= d_read_index)
{
if (!read_ls4_data())
{
std::cout << "End of file reached, LabSat source stop.\n";
d_queue->push(pmt::make_any(command_event_make(200, 0)));
return -1;
}
}
for (size_t channel_index = 0; channel_index < d_channel_selector_config.size(); ++channel_index)
{
gr_complex *aux = out[channel_index];
const auto data_parser = [shift, item_count, output_index](uint64_t data_index, int32_t qua, std::vector<uint64_t> &data, gr_complex *out_samples) {
std::bitset<64> bs(data[data_index % data.size()]);
invert_bitset(bs);
for (int i = 0; i < item_count; ++i)
{
write_iq_from_bitset(bs, i * shift, qua, out_samples[output_index + i]);
}
};
switch (d_channel_selector_config[channel_index])
{
case 1:
data_parser(d_data_index_a, d_ls3w_QUA, d_ls4_data_a, aux);
break;
case 2:
data_parser(d_data_index_b, d_ls3w_QUA, d_ls4_data_b, aux);
break;
case 3:
data_parser(d_data_index_c, d_ls3w_QUA, d_ls4_data_c, aux);
break;
}
}
output_index += item_count;
if (d_ls4_BUFF_SIZE_A > 0)
{
++d_data_index_a;
}
if (d_ls4_BUFF_SIZE_B > 0)
{
++d_data_index_b;
}
if (d_ls4_BUFF_SIZE_C > 0)
{
++d_data_index_c;
}
}
return output_index;
}
else
{
std::cout << "End of file reached, LabSat source stop.\n";
d_queue->push(pmt::make_any(command_event_make(200, 0)));
return -1;
}
}
bool labsat23_source::read_ls4_data()
{
const auto read_file = [this](int size, std::vector<uint64_t> &data) {
if (size > 0)
{
binary_input_file.read(reinterpret_cast<char *>(data.data()), size);
d_read_index += data.size();
if (binary_input_file.gcount() != size)
{
return false;
}
}
return true;
};
return read_file(d_ls4_BUFF_SIZE_A, d_ls4_data_a) &&
read_file(d_ls4_BUFF_SIZE_B, d_ls4_data_b) &&
read_file(d_ls4_BUFF_SIZE_C, d_ls4_data_c);
}
int labsat23_source::general_work(int noutput_items,
__attribute__((unused)) gr_vector_int &ninput_items,
__attribute__((unused)) gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items)
{
std::vector<gr_complex *> out;
for (auto &output_item : output_items)
{
out.push_back(reinterpret_cast<gr_complex *>(output_item));
}
if (!d_is_ls3w && !d_is_ls4)
{
return parse_ls23_data(noutput_items, out);
}
else if (d_is_ls3w) // Labsat 3 Wideband
{
return parse_ls3w_data(noutput_items, out);
}
else // Labsat 4
{
return parse_ls4_data(noutput_items, out);
}
std::cout << "Warning!!\n";

View File

@@ -43,7 +43,9 @@ labsat23_source_sptr labsat23_make_source_sptr(
const char *signal_file_basename,
const std::vector<int> &channel_selector,
Concurrent_Queue<pmt::pmt_t> *queue,
bool digital_io_enabled);
bool digital_io_enabled,
int64_t sampling_frequency,
double seconds_to_skip);
/*!
* \brief This class implements conversion between Labsat 2, 3 and 3 Wideband
@@ -64,22 +66,29 @@ private:
const char *signal_file_basename,
const std::vector<int> &channel_selector,
Concurrent_Queue<pmt::pmt_t> *queue,
bool digital_io_enabled);
bool digital_io_enabled,
int64_t sampling_frequency,
double seconds_to_skip);
labsat23_source(const char *signal_file_basename,
const std::vector<int> &channel_selector,
Concurrent_Queue<pmt::pmt_t> *queue,
bool digital_io_enabled);
bool digital_io_enabled,
int64_t sampling_frequency,
double seconds_to_skip);
std::string generate_filename();
int parse_header();
int getBit(uint8_t byte, int position);
int read_ls3w_ini(const std::string &filename);
int number_of_samples_per_ls3w_register() const;
void decode_samples_one_channel(int16_t input_short, gr_complex *out, int type);
void decode_ls3w_register(uint64_t input, std::vector<gr_complex *> &out, std::size_t output_pointer) const;
int parse_ls23_data(int noutput_items, std::vector<gr_complex *> out);
int parse_ls3w_data(int noutput_items, std::vector<gr_complex *> out);
int parse_ls4_data(int noutput_items, std::vector<gr_complex *> out);
bool read_ls4_data();
std::ifstream binary_input_file;
std::string d_signal_file_basename;
@@ -108,7 +117,24 @@ private:
int d_ls3w_spare_bits{};
int d_ls3w_samples_per_register{};
bool d_is_ls3w = false;
bool d_is_ls4 = false;
bool d_ls3w_digital_io_enabled = false;
// Data members for Labsat 4
uint64_t d_read_index{0};
uint64_t d_data_index_a{0};
uint64_t d_data_index_b{0};
uint64_t d_data_index_c{0};
int32_t d_ls4_BUFF_SIZE_A{};
int32_t d_ls4_BUFF_SIZE_B{};
int32_t d_ls4_BUFF_SIZE_C{};
int32_t d_ls4_BUFF_SIZE{};
std::vector<uint64_t> d_ls4_data_a;
std::vector<uint64_t> d_ls4_data_b;
std::vector<uint64_t> d_ls4_data_c;
};