mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2024-12-14 20:20:35 +00:00
Apply some mostly cosmetic changes
This is not so cosmetic: Moved init() chores from connect() to the constructor for consistency with other implementations. Not relevant here since files are not processed in real-time, but is it common practice in other blocks to set everything needed (and get all the resources) in the constructor, before connect() Moved the constructor code to the top of the file, also for consistency with other files. This is an opinionated practice, I know, since one could expect the same order than in the header file. Improved comment formatting for Doxygen Added and removed some blank lines to match the style of other files (two blank lines within method implementations, no two consecutive blank lines inside the method. Again opinionated, but for the sake of consistency. Included the <tuple> library (include what you use)
This commit is contained in:
parent
704b99e633
commit
03e53477c7
@ -28,9 +28,82 @@
|
||||
|
||||
using namespace std::string_literals;
|
||||
|
||||
FileSourceBase::FileSourceBase(ConfigurationInterface const* configuration, std::string const& role, std::string impl,
|
||||
Concurrent_Queue<pmt::pmt_t>* queue,
|
||||
std::string default_item_type)
|
||||
: SignalSourceBase(configuration, role, std::move(impl)), filename_(configuration->property(role + ".filename"s, "../data/example_capture.dat"s)),
|
||||
|
||||
file_source_(), // NOLINT
|
||||
|
||||
item_type_(configuration->property(role + ".item_type"s, default_item_type)), // NOLINT
|
||||
item_size_(0),
|
||||
is_complex_(false),
|
||||
|
||||
// apparently, MacOS (LLVM) finds 0UL ambiguous with bool, int64_t, uint64_t, int32_t, int16_t, uint16_t,... float, double
|
||||
header_size_(configuration->property(role + ".header_size"s, uint64_t(0))),
|
||||
seconds_to_skip_(configuration->property(role + ".seconds_to_skip"s, 0.0)),
|
||||
repeat_(configuration->property(role + ".repeat"s, false)),
|
||||
|
||||
samples_(configuration->property(role + ".samples"s, uint64_t(0))),
|
||||
sampling_frequency_(configuration->property(role + ".sampling_frequency"s, int64_t(0))),
|
||||
valve_(), // NOLINT
|
||||
queue_(queue),
|
||||
|
||||
enable_throttle_control_(configuration->property(role + ".enable_throttle_control"s, false)),
|
||||
throttle_(), // NOLINT
|
||||
|
||||
dump_(configuration->property(role + ".dump"s, false)),
|
||||
dump_filename_(configuration->property(role + ".dump_filename"s, "../data/my_capture.dat"s)),
|
||||
sink_() // NOLINT
|
||||
{
|
||||
// override value with commandline flag, if present
|
||||
if (FLAGS_signal_source != "-")
|
||||
{
|
||||
filename_ = FLAGS_signal_source;
|
||||
}
|
||||
if (FLAGS_s != "-")
|
||||
{
|
||||
filename_ = FLAGS_s;
|
||||
}
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
void FileSourceBase::init()
|
||||
{
|
||||
create_file_source();
|
||||
|
||||
// At this point, we know that the file exists
|
||||
samples_ = computeSamplesInFile();
|
||||
auto signal_duration_s = 1.0 * samples_ / sampling_frequency_;
|
||||
|
||||
if (is_complex())
|
||||
{
|
||||
signal_duration_s /= 2.0;
|
||||
}
|
||||
|
||||
DLOG(INFO) << "Total number samples to be processed= " << samples_ << " GNSS signal duration= " << signal_duration_s << " [s]";
|
||||
std::cout << "GNSS signal recorded time to be processed: " << signal_duration_s << " [s]\n";
|
||||
|
||||
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_;
|
||||
|
||||
create_throttle();
|
||||
create_valve();
|
||||
create_sink();
|
||||
}
|
||||
|
||||
|
||||
void FileSourceBase::connect(gr::top_block_sptr top_block)
|
||||
{
|
||||
init();
|
||||
pre_connect_hook(top_block);
|
||||
|
||||
auto input = gr::basic_block_sptr();
|
||||
@ -150,109 +223,43 @@ std::string FileSourceBase::filename() const
|
||||
return filename_;
|
||||
}
|
||||
|
||||
|
||||
std::string FileSourceBase::item_type() const
|
||||
{
|
||||
return item_type_;
|
||||
}
|
||||
|
||||
|
||||
size_t FileSourceBase::item_size()
|
||||
{
|
||||
return item_size_;
|
||||
}
|
||||
|
||||
|
||||
size_t FileSourceBase::item_size() const
|
||||
{
|
||||
return item_size_;
|
||||
}
|
||||
|
||||
|
||||
bool FileSourceBase::repeat() const
|
||||
{
|
||||
return repeat_;
|
||||
}
|
||||
|
||||
|
||||
int64_t FileSourceBase::sampling_frequency() const
|
||||
{
|
||||
return sampling_frequency_;
|
||||
}
|
||||
|
||||
|
||||
uint64_t FileSourceBase::samples() const
|
||||
{
|
||||
return samples_;
|
||||
}
|
||||
|
||||
|
||||
FileSourceBase::FileSourceBase(ConfigurationInterface const* configuration, std::string const& role, std::string impl,
|
||||
Concurrent_Queue<pmt::pmt_t>* queue,
|
||||
std::string default_item_type)
|
||||
: SignalSourceBase(configuration, role, std::move(impl)), filename_(configuration->property(role + ".filename"s, "../data/example_capture.dat"s)),
|
||||
|
||||
file_source_(), // NOLINT
|
||||
|
||||
item_type_(configuration->property(role + ".item_type"s, default_item_type)), // NOLINT
|
||||
item_size_(0),
|
||||
is_complex_(false),
|
||||
|
||||
// apparently, MacOS (LLVM) finds 0UL ambiguous with bool, int64_t, uint64_t, int32_t, int16_t, uint16_t,... float, double
|
||||
header_size_(configuration->property(role + ".header_size"s, uint64_t(0))),
|
||||
seconds_to_skip_(configuration->property(role + ".seconds_to_skip", 0.0)),
|
||||
repeat_(configuration->property(role + ".repeat"s, false)),
|
||||
|
||||
|
||||
samples_(configuration->property(role + ".samples"s, uint64_t(0))),
|
||||
sampling_frequency_(configuration->property(role + ".sampling_frequency"s, int64_t(0))),
|
||||
valve_(), // NOLINT
|
||||
queue_(queue),
|
||||
|
||||
enable_throttle_control_(configuration->property(role + ".enable_throttle_control"s, false)),
|
||||
throttle_(), // NOLINT
|
||||
|
||||
dump_(configuration->property(role + ".dump"s, false)),
|
||||
dump_filename_(configuration->property(role + ".dump_filename"s, "../data/my_capture.dat"s)),
|
||||
sink_() // NOLINT
|
||||
{
|
||||
// override value with commandline flag, if present
|
||||
if (FLAGS_signal_source != "-")
|
||||
{
|
||||
filename_ = FLAGS_signal_source;
|
||||
}
|
||||
if (FLAGS_s != "-")
|
||||
{
|
||||
filename_ = FLAGS_s;
|
||||
}
|
||||
}
|
||||
|
||||
void FileSourceBase::init()
|
||||
{
|
||||
create_file_source();
|
||||
|
||||
// At this point, we know that the file exists
|
||||
samples_ = computeSamplesInFile();
|
||||
auto signal_duration_s = 1.0 * samples_ / sampling_frequency_;
|
||||
|
||||
if (is_complex())
|
||||
{
|
||||
signal_duration_s /= 2.0;
|
||||
}
|
||||
|
||||
DLOG(INFO) << "Total number samples to be processed= " << samples_ << " GNSS signal duration= " << signal_duration_s << " [s]";
|
||||
std::cout << "GNSS signal recorded time to be processed: " << signal_duration_s << " [s]\n";
|
||||
|
||||
|
||||
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_;
|
||||
|
||||
create_throttle();
|
||||
create_valve();
|
||||
create_sink();
|
||||
}
|
||||
|
||||
|
||||
std::tuple<size_t, bool> FileSourceBase::itemTypeToSize()
|
||||
{
|
||||
auto is_complex_t = false;
|
||||
@ -294,9 +301,11 @@ std::tuple<size_t, bool> FileSourceBase::itemTypeToSize()
|
||||
return std::make_tuple(item_size, is_complex_t);
|
||||
}
|
||||
|
||||
|
||||
// Default case is one decoded packet per one read sample
|
||||
double FileSourceBase::packetsPerSample() const { return 1.0; }
|
||||
|
||||
|
||||
size_t FileSourceBase::samplesToSkip() const
|
||||
{
|
||||
auto samples_to_skip = size_t(0);
|
||||
@ -327,11 +336,11 @@ size_t FileSourceBase::samplesToSkip() const
|
||||
return samples_to_skip;
|
||||
}
|
||||
|
||||
|
||||
size_t FileSourceBase::computeSamplesInFile() const
|
||||
{
|
||||
auto n_samples = size_t(samples());
|
||||
|
||||
|
||||
// if configured with 0 samples (read the whole file), figure out how many samples are in the file, and go from there
|
||||
if (n_samples == 0)
|
||||
{
|
||||
@ -369,21 +378,26 @@ size_t FileSourceBase::computeSamplesInFile() const
|
||||
return n_samples;
|
||||
}
|
||||
|
||||
gnss_shared_ptr<gr::block> FileSourceBase::source() const { return file_source(); }
|
||||
|
||||
size_t FileSourceBase::source_item_size() const
|
||||
{
|
||||
// delegate the size of the source to the source() object, so sub-classes have less work to do
|
||||
DLOG(INFO) << "source_item_size is " << source()->output_signature()->sizeof_stream_item(0);
|
||||
return source()->output_signature()->sizeof_stream_item(0);
|
||||
}
|
||||
|
||||
|
||||
bool FileSourceBase::is_complex() const { return is_complex_; }
|
||||
|
||||
|
||||
// Simple accessors
|
||||
gnss_shared_ptr<gr::block> FileSourceBase::source() const { return file_source(); }
|
||||
gnss_shared_ptr<gr::block> FileSourceBase::file_source() const { return file_source_; }
|
||||
gnss_shared_ptr<gr::block> FileSourceBase::valve() const { return valve_; }
|
||||
gnss_shared_ptr<gr::block> FileSourceBase::throttle() const { return throttle_; }
|
||||
gnss_shared_ptr<gr::block> FileSourceBase::sink() const { return sink_; }
|
||||
|
||||
|
||||
gr::blocks::file_source::sptr FileSourceBase::create_file_source()
|
||||
{
|
||||
auto item_tuple = itemTypeToSize();
|
||||
@ -430,10 +444,10 @@ gr::blocks::file_source::sptr FileSourceBase::create_file_source()
|
||||
// enable subclass hooks
|
||||
create_file_source_hook();
|
||||
|
||||
|
||||
return file_source_;
|
||||
}
|
||||
|
||||
|
||||
gr::blocks::throttle::sptr FileSourceBase::create_throttle()
|
||||
{
|
||||
if (enable_throttle_control_)
|
||||
@ -448,6 +462,7 @@ gr::blocks::throttle::sptr FileSourceBase::create_throttle()
|
||||
return throttle_;
|
||||
}
|
||||
|
||||
|
||||
gnss_shared_ptr<gr::block> FileSourceBase::create_valve()
|
||||
{
|
||||
if (samples() > 0)
|
||||
@ -463,6 +478,7 @@ gnss_shared_ptr<gr::block> FileSourceBase::create_valve()
|
||||
return valve_;
|
||||
}
|
||||
|
||||
|
||||
gr::blocks::file_sink::sptr FileSourceBase::create_sink()
|
||||
{
|
||||
if (dump_)
|
||||
@ -476,12 +492,14 @@ gr::blocks::file_sink::sptr FileSourceBase::create_sink()
|
||||
return sink_;
|
||||
}
|
||||
|
||||
|
||||
// Subclass hooks to augment created objects, as required
|
||||
void FileSourceBase::create_file_source_hook() {}
|
||||
void FileSourceBase::create_throttle_hook() {}
|
||||
void FileSourceBase::create_valve_hook() {}
|
||||
void FileSourceBase::create_sink_hook() {}
|
||||
|
||||
|
||||
// Subclass hooks for connection/disconnectino
|
||||
void FileSourceBase::pre_connect_hook(gr::top_block_sptr top_block [[maybe_unused]]) {}
|
||||
void FileSourceBase::post_connect_hook(gr::top_block_sptr top_block [[maybe_unused]]) {}
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <gnuradio/blocks/file_source.h>
|
||||
#include <gnuradio/blocks/throttle.h>
|
||||
#include <pmt/pmt.h>
|
||||
#include <tuple>
|
||||
|
||||
// for dump
|
||||
#include <gnuradio/blocks/file_sink.h>
|
||||
@ -32,88 +33,100 @@
|
||||
|
||||
class ConfigurationInterface;
|
||||
|
||||
// This class supports the following properties:
|
||||
//
|
||||
// .filename - the path to the input file
|
||||
// - may be overridden by the -signal_source or -s command-line arguments
|
||||
// .samples - number of samples to process (default 0)
|
||||
// - if not specified or 0, read the entire file; otherwise stop after that many samples
|
||||
// .sampling_frequency - the frequency of the sampled data (samples/second)
|
||||
// .item_type - data type of the samples (default "short")
|
||||
// .header_size - the size of a prefixed header to skip in "samples" (default 0)
|
||||
// .seconds_to_skip - number of seconds of lead-in data to skip over (default 0)
|
||||
// .enable_throttle_control - whether to stop reading if the upstream buffer is full (default false)
|
||||
// .repeat - whether to rewind and continue at end of file (default false)
|
||||
//
|
||||
// (probably abstracted to the base class)
|
||||
// .dump - whether to archive input data
|
||||
// .dump_filename - if dumping, path to file for output
|
||||
|
||||
//! \brief Base class to file-oriented SignalSourceBase GNSS blocks.
|
||||
//!
|
||||
//! This class supports the following properties:
|
||||
//!
|
||||
//! .filename - the path to the input file
|
||||
//! - may be overridden by the -signal_source or -s command-line arguments
|
||||
//!
|
||||
//! .samples - number of samples to process (default 0)
|
||||
//! - if not specified or 0, read the entire file; otherwise stop after that many samples
|
||||
//!
|
||||
//! .sampling_frequency - the frequency of the sampled data (samples/second)
|
||||
//!
|
||||
//! .item_type - data type of the samples (default "short")
|
||||
//!
|
||||
//! .header_size - the size of a prefixed header to skip in "samples" (default 0)
|
||||
//!
|
||||
//! .seconds_to_skip - number of seconds of lead-in data to skip over (default 0)
|
||||
//!
|
||||
//! .enable_throttle_control - whether to stop reading if the upstream buffer is full (default false)
|
||||
//!
|
||||
//! .repeat - whether to rewind and continue at end of file (default false)
|
||||
//!
|
||||
//! (probably abstracted to the base class)
|
||||
//!
|
||||
//! .dump - whether to archive input data
|
||||
//!
|
||||
//! .dump_filename - if dumping, path to file for output
|
||||
|
||||
|
||||
class FileSourceBase : public SignalSourceBase
|
||||
{
|
||||
public:
|
||||
//! virtual overrides
|
||||
// Virtual overrides
|
||||
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;
|
||||
|
||||
|
||||
//! the file to read
|
||||
//! The file to read
|
||||
std::string filename() const;
|
||||
|
||||
//! the item type
|
||||
//! The item type
|
||||
std::string item_type() const;
|
||||
|
||||
//! the configured size of each item
|
||||
//! The configured size of each item
|
||||
size_t item_size() override;
|
||||
virtual size_t item_size() const; // what the interface **should** have declared
|
||||
|
||||
//! Whether to repeat reading after end-of-file
|
||||
bool repeat() const;
|
||||
|
||||
//! the sampling frequency of the source file
|
||||
//! The sampling frequency of the source file
|
||||
int64_t sampling_frequency() const;
|
||||
|
||||
//! the number of samples in the file
|
||||
//! The number of samples in the file
|
||||
uint64_t samples() const;
|
||||
|
||||
protected:
|
||||
//! Constructor
|
||||
// Subclasses may want to assert default item types that are appropriate to the specific file
|
||||
// type supported. Rather than require the item type to be specified in the config file, allow
|
||||
// sub-classes to impose their will
|
||||
//! \brief Constructor
|
||||
//!
|
||||
//! Subclasses may want to assert default item types that are appropriate to the specific file
|
||||
//! type supported. Rather than require the item type to be specified in the config file, allow
|
||||
//! sub-classes to impose their will
|
||||
FileSourceBase(ConfigurationInterface const* configuration, std::string const& role, std::string impl,
|
||||
Concurrent_Queue<pmt::pmt_t>* queue,
|
||||
std::string default_item_type = "short");
|
||||
|
||||
//! perform post-construction initialization
|
||||
//! Perform post-construction initialization
|
||||
void init();
|
||||
|
||||
//! compute the item size, from the item_type(). Subclasses may constrain types that don't make
|
||||
//! Compute the item size, from the item_type(). Subclasses may constrain types that don't make
|
||||
// sense. The return of this method is a tuple of item_size and is_complex
|
||||
virtual std::tuple<size_t, bool> itemTypeToSize();
|
||||
|
||||
//! the number of (possibly unpacked) samples in a (raw) file sample (default=1)
|
||||
//! The number of (possibly unpacked) samples in a (raw) file sample (default=1)
|
||||
virtual double packetsPerSample() const;
|
||||
|
||||
//! compute the number of samples to skip
|
||||
//! Compute the number of samples to skip
|
||||
virtual size_t samplesToSkip() const;
|
||||
|
||||
//! compute the number of samples in the file
|
||||
//! Compute the number of samples in the file
|
||||
size_t computeSamplesInFile() const;
|
||||
|
||||
//! abstracted front-end source. Sub-classes may override if they create specialized chains to
|
||||
//! Abstracted front-end source. Sub-classes may override if they create specialized chains to
|
||||
//! decode source files into a usable format
|
||||
virtual gnss_shared_ptr<gr::block> source() const;
|
||||
|
||||
//! for complex source chains, the size of the file item may not be the same as the size of the
|
||||
//! For complex source chains, the size of the file item may not be the same as the size of the
|
||||
// "source" (decoded) item. This method allows subclasses to handle these differences
|
||||
virtual size_t source_item_size() const;
|
||||
bool is_complex() const;
|
||||
|
||||
//! generic access to created objects
|
||||
// Generic access to created objects
|
||||
gnss_shared_ptr<gr::block> file_source() const;
|
||||
gnss_shared_ptr<gr::block> valve() const;
|
||||
gnss_shared_ptr<gr::block> throttle() const;
|
||||
|
Loading…
Reference in New Issue
Block a user