1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2024-12-14 04:00:34 +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:
Carles Fernandez 2021-02-17 22:07:22 +01:00
parent 704b99e633
commit 03e53477c7
No known key found for this signature in database
GPG Key ID: 4C583C52B0C3877D
2 changed files with 143 additions and 112 deletions

View File

@ -28,9 +28,82 @@
using namespace std::string_literals; 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) void FileSourceBase::connect(gr::top_block_sptr top_block)
{ {
init();
pre_connect_hook(top_block); pre_connect_hook(top_block);
auto input = gr::basic_block_sptr(); auto input = gr::basic_block_sptr();
@ -150,109 +223,43 @@ std::string FileSourceBase::filename() const
return filename_; return filename_;
} }
std::string FileSourceBase::item_type() const std::string FileSourceBase::item_type() const
{ {
return item_type_; return item_type_;
} }
size_t FileSourceBase::item_size() size_t FileSourceBase::item_size()
{ {
return item_size_; return item_size_;
} }
size_t FileSourceBase::item_size() const size_t FileSourceBase::item_size() const
{ {
return item_size_; return item_size_;
} }
bool FileSourceBase::repeat() const bool FileSourceBase::repeat() const
{ {
return repeat_; return repeat_;
} }
int64_t FileSourceBase::sampling_frequency() const int64_t FileSourceBase::sampling_frequency() const
{ {
return sampling_frequency_; return sampling_frequency_;
} }
uint64_t FileSourceBase::samples() const uint64_t FileSourceBase::samples() const
{ {
return samples_; 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() std::tuple<size_t, bool> FileSourceBase::itemTypeToSize()
{ {
auto is_complex_t = false; 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); return std::make_tuple(item_size, is_complex_t);
} }
// Default case is one decoded packet per one read sample // Default case is one decoded packet per one read sample
double FileSourceBase::packetsPerSample() const { return 1.0; } double FileSourceBase::packetsPerSample() const { return 1.0; }
size_t FileSourceBase::samplesToSkip() const size_t FileSourceBase::samplesToSkip() const
{ {
auto samples_to_skip = size_t(0); auto samples_to_skip = size_t(0);
@ -327,11 +336,11 @@ size_t FileSourceBase::samplesToSkip() const
return samples_to_skip; return samples_to_skip;
} }
size_t FileSourceBase::computeSamplesInFile() const size_t FileSourceBase::computeSamplesInFile() const
{ {
auto n_samples = size_t(samples()); 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 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) if (n_samples == 0)
{ {
@ -369,21 +378,26 @@ size_t FileSourceBase::computeSamplesInFile() const
return n_samples; return n_samples;
} }
gnss_shared_ptr<gr::block> FileSourceBase::source() const { return file_source(); }
size_t FileSourceBase::source_item_size() const 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 // 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); DLOG(INFO) << "source_item_size is " << source()->output_signature()->sizeof_stream_item(0);
return source()->output_signature()->sizeof_stream_item(0); return source()->output_signature()->sizeof_stream_item(0);
} }
bool FileSourceBase::is_complex() const { return is_complex_; } bool FileSourceBase::is_complex() const { return is_complex_; }
// Simple accessors // 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::file_source() const { return file_source_; }
gnss_shared_ptr<gr::block> FileSourceBase::valve() const { return valve_; } 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::throttle() const { return throttle_; }
gnss_shared_ptr<gr::block> FileSourceBase::sink() const { return sink_; } gnss_shared_ptr<gr::block> FileSourceBase::sink() const { return sink_; }
gr::blocks::file_source::sptr FileSourceBase::create_file_source() gr::blocks::file_source::sptr FileSourceBase::create_file_source()
{ {
auto item_tuple = itemTypeToSize(); auto item_tuple = itemTypeToSize();
@ -430,10 +444,10 @@ gr::blocks::file_source::sptr FileSourceBase::create_file_source()
// enable subclass hooks // enable subclass hooks
create_file_source_hook(); create_file_source_hook();
return file_source_; return file_source_;
} }
gr::blocks::throttle::sptr FileSourceBase::create_throttle() gr::blocks::throttle::sptr FileSourceBase::create_throttle()
{ {
if (enable_throttle_control_) if (enable_throttle_control_)
@ -448,6 +462,7 @@ gr::blocks::throttle::sptr FileSourceBase::create_throttle()
return throttle_; return throttle_;
} }
gnss_shared_ptr<gr::block> FileSourceBase::create_valve() gnss_shared_ptr<gr::block> FileSourceBase::create_valve()
{ {
if (samples() > 0) if (samples() > 0)
@ -463,6 +478,7 @@ gnss_shared_ptr<gr::block> FileSourceBase::create_valve()
return valve_; return valve_;
} }
gr::blocks::file_sink::sptr FileSourceBase::create_sink() gr::blocks::file_sink::sptr FileSourceBase::create_sink()
{ {
if (dump_) if (dump_)
@ -476,12 +492,14 @@ gr::blocks::file_sink::sptr FileSourceBase::create_sink()
return sink_; return sink_;
} }
// Subclass hooks to augment created objects, as required // Subclass hooks to augment created objects, as required
void FileSourceBase::create_file_source_hook() {} void FileSourceBase::create_file_source_hook() {}
void FileSourceBase::create_throttle_hook() {} void FileSourceBase::create_throttle_hook() {}
void FileSourceBase::create_valve_hook() {} void FileSourceBase::create_valve_hook() {}
void FileSourceBase::create_sink_hook() {} void FileSourceBase::create_sink_hook() {}
// Subclass hooks for connection/disconnectino // Subclass hooks for connection/disconnectino
void FileSourceBase::pre_connect_hook(gr::top_block_sptr top_block [[maybe_unused]]) {} 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]]) {} void FileSourceBase::post_connect_hook(gr::top_block_sptr top_block [[maybe_unused]]) {}

View File

@ -23,6 +23,7 @@
#include <gnuradio/blocks/file_source.h> #include <gnuradio/blocks/file_source.h>
#include <gnuradio/blocks/throttle.h> #include <gnuradio/blocks/throttle.h>
#include <pmt/pmt.h> #include <pmt/pmt.h>
#include <tuple>
// for dump // for dump
#include <gnuradio/blocks/file_sink.h> #include <gnuradio/blocks/file_sink.h>
@ -32,88 +33,100 @@
class ConfigurationInterface; class ConfigurationInterface;
// This class supports the following properties:
// //! \brief Base class to file-oriented SignalSourceBase GNSS blocks.
// .filename - the path to the input file //!
// - may be overridden by the -signal_source or -s command-line arguments //! This class supports the following properties:
// .samples - number of samples to process (default 0) //!
// - if not specified or 0, read the entire file; otherwise stop after that many samples //! .filename - the path to the input file
// .sampling_frequency - the frequency of the sampled data (samples/second) //! - may be overridden by the -signal_source or -s command-line arguments
// .item_type - data type of the samples (default "short") //!
// .header_size - the size of a prefixed header to skip in "samples" (default 0) //! .samples - number of samples to process (default 0)
// .seconds_to_skip - number of seconds of lead-in data to skip over (default 0) //! - if not specified or 0, read the entire file; otherwise stop after that many samples
// .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) //! .sampling_frequency - the frequency of the sampled data (samples/second)
// //!
// (probably abstracted to the base class) //! .item_type - data type of the samples (default "short")
// .dump - whether to archive input data //!
// .dump_filename - if dumping, path to file for output //! .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 class FileSourceBase : public SignalSourceBase
{ {
public: public:
//! virtual overrides // Virtual overrides
void connect(gr::top_block_sptr top_block) override; void connect(gr::top_block_sptr top_block) override;
void disconnect(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_left_block() override;
gr::basic_block_sptr get_right_block() override; gr::basic_block_sptr get_right_block() override;
//! The file to read
//! the file to read
std::string filename() const; std::string filename() const;
//! the item type //! The item type
std::string item_type() const; std::string item_type() const;
//! the configured size of each item //! The configured size of each item
size_t item_size() override; size_t item_size() override;
virtual size_t item_size() const; // what the interface **should** have declared virtual size_t item_size() const; // what the interface **should** have declared
//! Whether to repeat reading after end-of-file //! Whether to repeat reading after end-of-file
bool repeat() const; bool repeat() const;
//! the sampling frequency of the source file //! The sampling frequency of the source file
int64_t sampling_frequency() const; int64_t sampling_frequency() const;
//! the number of samples in the file //! The number of samples in the file
uint64_t samples() const; uint64_t samples() const;
protected: protected:
//! Constructor //! \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 //! Subclasses may want to assert default item types that are appropriate to the specific file
// sub-classes to impose their will //! 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, FileSourceBase(ConfigurationInterface const* configuration, std::string const& role, std::string impl,
Concurrent_Queue<pmt::pmt_t>* queue, Concurrent_Queue<pmt::pmt_t>* queue,
std::string default_item_type = "short"); std::string default_item_type = "short");
//! perform post-construction initialization //! Perform post-construction initialization
void init(); 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 // sense. The return of this method is a tuple of item_size and is_complex
virtual std::tuple<size_t, bool> itemTypeToSize(); 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; virtual double packetsPerSample() const;
//! compute the number of samples to skip //! Compute the number of samples to skip
virtual size_t samplesToSkip() const; 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; 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 //! decode source files into a usable format
virtual gnss_shared_ptr<gr::block> source() const; 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 // "source" (decoded) item. This method allows subclasses to handle these differences
virtual size_t source_item_size() const; virtual size_t source_item_size() const;
bool is_complex() 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> file_source() const;
gnss_shared_ptr<gr::block> valve() const; gnss_shared_ptr<gr::block> valve() const;
gnss_shared_ptr<gr::block> throttle() const; gnss_shared_ptr<gr::block> throttle() const;