mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2026-10-17 21:12:35 +00:00
Add EVK1029 file_offset config to seek into a raw capture
Evk1029SignalSource.file_offset (seconds, default 0 = disabled) lets a long capture be jumped straight to a time of interest instead of always reprocessed from the start. Converted to a byte count using the source's own sampling frequency, then rounded up to the next 64-bit word boundary in Evk1029Source before seeking, matching the capture's native packing (16 OBA samples per little-endian 64-bit word).
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
|
||||
#include "evk1029_signal_source.h"
|
||||
#include "configuration_interface.h"
|
||||
#include <cmath>
|
||||
#include <utility>
|
||||
|
||||
#if USE_GLOG_AND_GFLAGS
|
||||
@@ -46,6 +47,19 @@ Evk1029SignalSource::Evk1029SignalSource(
|
||||
const int64_t default_fs = configuration->property("GNSS-SDR.internal_fs_sps"s, int64_t(0));
|
||||
const int64_t fs = configuration->property(role + ".sampling_frequency"s, default_fs);
|
||||
|
||||
// Lets a long capture be jumped straight to a "time of interest" (e.g.
|
||||
// to check effective signal strength at a specific point) instead of
|
||||
// always reprocessed from the start. Expressed in seconds, not bytes --
|
||||
// fs (the raw capture's own sample rate) is already known right here,
|
||||
// so converting is trivial and saves the caller from hand-computing a
|
||||
// byte count themselves. Two OBA samples are packed per byte, hence the
|
||||
// /2; Evk1029Source rounds the resulting byte count up to the next
|
||||
// 64-bit word boundary itself (see its header) before seeking.
|
||||
const double file_offset_s = configuration->property(role + ".file_offset"s, 0.0);
|
||||
const auto file_offset_bytes = (file_offset_s > 0.0 && fs > 0)
|
||||
? static_cast<uint64_t>(std::llround(file_offset_s * static_cast<double>(fs) / 2.0))
|
||||
: uint64_t(0);
|
||||
|
||||
if (rf_channels_ == 0)
|
||||
{
|
||||
rf_channels_ = 1;
|
||||
@@ -60,9 +74,10 @@ Evk1029SignalSource::Evk1029SignalSource(
|
||||
enable_throttle_control_ = false;
|
||||
}
|
||||
|
||||
DLOG(INFO) << "EVK1029 Signal Source: filename=" << filename << ", fs=" << fs << ", item_size=" << item_size_ << ", RF_channels=" << rf_channels_;
|
||||
DLOG(INFO) << "EVK1029 Signal Source: filename=" << filename << ", fs=" << fs << ", item_size=" << item_size_
|
||||
<< ", RF_channels=" << rf_channels_ << ", file_offset_s=" << file_offset_s;
|
||||
|
||||
evk1029_source_ = evk1029_make_source(filename, static_cast<int>(rf_channels_), queue, static_cast<double>(fs));
|
||||
evk1029_source_ = evk1029_make_source(filename, static_cast<int>(rf_channels_), queue, static_cast<double>(fs), file_offset_bytes);
|
||||
|
||||
if (enable_throttle_control_)
|
||||
{
|
||||
|
||||
@@ -62,13 +62,13 @@ int output_multiple_from_sampling_frequency(double sampling_frequency)
|
||||
} // namespace
|
||||
|
||||
|
||||
Evk1029Source_sptr evk1029_make_source(const std::string& filename, int n_streams, Concurrent_Queue<pmt::pmt_t>* queue, double sampling_frequency)
|
||||
Evk1029Source_sptr evk1029_make_source(const std::string& filename, int n_streams, Concurrent_Queue<pmt::pmt_t>* queue, double sampling_frequency, uint64_t file_offset_bytes)
|
||||
{
|
||||
return Evk1029Source_sptr(new Evk1029Source(filename, n_streams, queue, sampling_frequency));
|
||||
return Evk1029Source_sptr(new Evk1029Source(filename, n_streams, queue, sampling_frequency, file_offset_bytes));
|
||||
}
|
||||
|
||||
|
||||
Evk1029Source::Evk1029Source(const std::string& filename, int n_streams, Concurrent_Queue<pmt::pmt_t>* queue, double sampling_frequency)
|
||||
Evk1029Source::Evk1029Source(const std::string& filename, int n_streams, Concurrent_Queue<pmt::pmt_t>* queue, double sampling_frequency, uint64_t file_offset_bytes)
|
||||
: gr::sync_block("evk1029_source",
|
||||
gr::io_signature::make(0, 0, 0),
|
||||
gr::io_signature::make(n_streams, n_streams, sizeof(int8_t))),
|
||||
@@ -97,6 +97,28 @@ Evk1029Source::Evk1029Source(const std::string& filename, int n_streams, Concurr
|
||||
std::cerr << "EVK1029_Source: failed to open file: " << filename << '\n';
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (file_offset_bytes > 0)
|
||||
{
|
||||
// Round up to the next 64-bit (8-byte) word boundary -- see this
|
||||
// parameter's doc comment in the header for why.
|
||||
constexpr uint64_t kWordBytes = 8;
|
||||
const uint64_t aligned_offset = ((file_offset_bytes + kWordBytes - 1) / kWordBytes) * kWordBytes;
|
||||
|
||||
binary_input_file_.seekg(0, std::ios::end);
|
||||
const auto file_size = static_cast<uint64_t>(binary_input_file_.tellg());
|
||||
if (aligned_offset >= file_size)
|
||||
{
|
||||
std::cerr << "EVK1029_Source: file_offset (" << aligned_offset
|
||||
<< " bytes, aligned) is at or beyond the end of '" << filename
|
||||
<< "' (" << file_size << " bytes) -- nothing to read.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
binary_input_file_.seekg(static_cast<std::streamoff>(aligned_offset), std::ios::beg);
|
||||
std::cout << "EVK1029_Source: skipping to file offset " << aligned_offset
|
||||
<< " bytes (requested " << file_offset_bytes << ", rounded up to a 64-bit word boundary).\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -52,7 +52,19 @@ class Evk1029Source;
|
||||
|
||||
using Evk1029Source_sptr = gnss_shared_ptr<Evk1029Source>;
|
||||
|
||||
Evk1029Source_sptr evk1029_make_source(const std::string& filename, int n_streams, Concurrent_Queue<pmt::pmt_t>* queue, double sampling_frequency);
|
||||
// file_offset_bytes: byte position in the raw capture to seek to before the
|
||||
// first read, letting a long capture be jumped straight to a "time of
|
||||
// interest" instead of always reprocessed from the start (see
|
||||
// Evk1029SignalSource.file_offset in the adapter, which converts a
|
||||
// requested offset in seconds -- since the sampling frequency is already
|
||||
// known there -- into this byte count). Rounded up to the next multiple of
|
||||
// 8 bytes (64 bits) here, matching the capture's native packing (16 OBA
|
||||
// samples per little-endian 64-bit word): this block itself only ever reads
|
||||
// byte-by-byte and would decode correctly from any byte offset, but seeking
|
||||
// to a non-word-aligned byte splits a 64-bit DMA word the real hardware
|
||||
// always transferred as one unit, which needlessly complicates comparing a
|
||||
// jumped-to run against a from-the-start one at the file/word level.
|
||||
Evk1029Source_sptr evk1029_make_source(const std::string& filename, int n_streams, Concurrent_Queue<pmt::pmt_t>* queue, double sampling_frequency, uint64_t file_offset_bytes = 0);
|
||||
|
||||
/*!
|
||||
* \brief Reads a continuous, header-less EVK1029 raw capture file and
|
||||
@@ -65,8 +77,8 @@ public:
|
||||
~Evk1029Source() override;
|
||||
|
||||
private:
|
||||
friend Evk1029Source_sptr evk1029_make_source(const std::string& filename, int n_streams, Concurrent_Queue<pmt::pmt_t>* queue, double sampling_frequency);
|
||||
Evk1029Source(const std::string& filename, int n_streams, Concurrent_Queue<pmt::pmt_t>* queue, double sampling_frequency);
|
||||
friend Evk1029Source_sptr evk1029_make_source(const std::string& filename, int n_streams, Concurrent_Queue<pmt::pmt_t>* queue, double sampling_frequency, uint64_t file_offset_bytes);
|
||||
Evk1029Source(const std::string& filename, int n_streams, Concurrent_Queue<pmt::pmt_t>* queue, double sampling_frequency, uint64_t file_offset_bytes = 0);
|
||||
|
||||
int work(int noutput_items,
|
||||
gr_vector_const_void_star& input_items,
|
||||
|
||||
Reference in New Issue
Block a user