mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2025-01-19 05:33:02 +00:00
addressing feedback by @jwmelto
- documentation file name mismatch - removed unnecc. headers - changed std::cout to GLOG - simlified read process for gr_complex data types - seperated fifo end of file check from fail/other types (also added default case for unforseen events) - changed vector to array for interleaved read fct other changes: - harmonized FIFO capitalization in docs - changed gr_complex constructor. Real/Imaginary parts were swapped in upd source class used for reference. Not intuitive there though (swap= false will call constructor w/ (imag, real). Swapping should introduce just a phase shift, so it didn't break functionality for me either way.
This commit is contained in:
parent
2072197f0f
commit
dbc8ea18bf
@ -1,7 +1,7 @@
|
|||||||
/*!
|
/*!
|
||||||
* \file file_source_base.cc
|
* \file fifo_signal_source.cc
|
||||||
*
|
*
|
||||||
* \brief Implementation of the class for retrieving samples through a Unix fifo
|
* \brief Implementation of the class for retrieving samples through a Unix FIFO
|
||||||
* \author Malte Lenhart, 2021. malte.lenhart(at)mailbox.org
|
* \author Malte Lenhart, 2021. malte.lenhart(at)mailbox.org
|
||||||
*
|
*
|
||||||
* -----------------------------------------------------------------------------
|
* -----------------------------------------------------------------------------
|
||||||
@ -18,12 +18,10 @@
|
|||||||
#include "fifo_signal_source.h"
|
#include "fifo_signal_source.h"
|
||||||
#include "configuration_interface.h"
|
#include "configuration_interface.h"
|
||||||
#include "fifo_reader.h"
|
#include "fifo_reader.h"
|
||||||
#include "gnss_sdr_flags.h"
|
|
||||||
#include "gnss_sdr_string_literals.h"
|
#include "gnss_sdr_string_literals.h"
|
||||||
#include <glog/logging.h>
|
#include <glog/logging.h>
|
||||||
#include <gnuradio/blocks/file_sink.h>
|
#include <gnuradio/blocks/file_sink.h>
|
||||||
#include <gnuradio/blocks/file_source.h>
|
#include <gnuradio/blocks/file_source.h>
|
||||||
#include <cmath> // ceil, floor
|
|
||||||
|
|
||||||
|
|
||||||
using namespace std::string_literals;
|
using namespace std::string_literals;
|
||||||
@ -69,7 +67,7 @@ void FifoSignalSource::disconnect(gr::top_block_sptr top_block)
|
|||||||
if (dump_)
|
if (dump_)
|
||||||
{
|
{
|
||||||
top_block->disconnect(fifo_reader_, 0, file_sink_, 0);
|
top_block->disconnect(fifo_reader_, 0, file_sink_, 0);
|
||||||
DLOG(INFO) << "disconnected source to file sink";
|
DLOG(INFO) << "disconnected source from file sink";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*!
|
/*!
|
||||||
* \file file_source_base.h
|
* \file fifo_signal_source.h
|
||||||
*
|
*
|
||||||
* \brief Header file of the class for retrieving samples through a Unix fifo
|
* \brief Header file of the class for retrieving samples through a Unix FIFO
|
||||||
* \author Malte Lenhart, 2021. malte.lenhart(at)mailbox.org
|
* \author Malte Lenhart, 2021. malte.lenhart(at)mailbox.org
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
@ -29,23 +29,23 @@
|
|||||||
/** \addtogroup Signal_Source_adapters
|
/** \addtogroup Signal_Source_adapters
|
||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
|
// forward declaration to avoid include in header
|
||||||
class ConfigurationInterface;
|
class ConfigurationInterface;
|
||||||
|
|
||||||
//! \brief Class that reads a sample stream from a Unix fifo
|
//! \brief Class that reads a sample stream from a Unix FIFO.
|
||||||
//!
|
//!
|
||||||
//! This class supports the following properties:
|
//! This class supports the following properties:
|
||||||
//!
|
//!
|
||||||
//! .filename - the path to the input file
|
//! .filename - the path to the input file
|
||||||
//! - may be overridden by the -signal_source or -s command-line arguments
|
//! - may be overridden by the -signal_source or -s command-line arguments
|
||||||
//!
|
//!
|
||||||
//! .sample_type - data type read out from the fifo. default ishort ;
|
//! .sample_type - data type read out from the FIFO. default ishort ;
|
||||||
//! - note: not output format. that is always gr_complex
|
//! - note: not output format. that is always gr_complex
|
||||||
//!
|
//!
|
||||||
//! .dump - whether to archive input data
|
//! .dump - whether to archive input data
|
||||||
//!
|
//!
|
||||||
//! .dump_filename - if dumping, path to file for output
|
//! .dump_filename - if dumping, path to file for output
|
||||||
|
//!
|
||||||
|
|
||||||
class FifoSignalSource : public SignalSourceBase
|
class FifoSignalSource : public SignalSourceBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -17,10 +17,6 @@
|
|||||||
|
|
||||||
#include "fifo_reader.h"
|
#include "fifo_reader.h"
|
||||||
#include <glog/logging.h>
|
#include <glog/logging.h>
|
||||||
#include <cstdlib>
|
|
||||||
#include <fstream>
|
|
||||||
#include <iostream>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
// initial construction; pass to private constructor
|
// initial construction; pass to private constructor
|
||||||
FifoReader::sptr FifoReader::make(const std::string &file_name, const std::string &sample_type)
|
FifoReader::sptr FifoReader::make(const std::string &file_name, const std::string &sample_type)
|
||||||
@ -36,8 +32,7 @@ FifoReader::FifoReader(const std::string &file_name, const std::string &sample_t
|
|||||||
file_name_(file_name),
|
file_name_(file_name),
|
||||||
sample_type_(sample_type)
|
sample_type_(sample_type)
|
||||||
{
|
{
|
||||||
std::cout << "Starting FifoReader\n";
|
DLOG(INFO) << "Starting FifoReader";
|
||||||
// instream: https://en.cppreference.com/w/cpp/io/basic_ifstream
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FifoReader::start()
|
bool FifoReader::start()
|
||||||
@ -45,7 +40,7 @@ bool FifoReader::start()
|
|||||||
fifo_.open(file_name_, std::ios::binary);
|
fifo_.open(file_name_, std::ios::binary);
|
||||||
if (!fifo_.is_open())
|
if (!fifo_.is_open())
|
||||||
{
|
{
|
||||||
DLOG(ERROR) << "Error opening fifo\n";
|
LOG(ERROR) << "Error opening FIFO";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -59,7 +54,7 @@ int FifoReader::work(int noutput_items,
|
|||||||
{
|
{
|
||||||
if (output_items.size() > 1)
|
if (output_items.size() > 1)
|
||||||
{
|
{
|
||||||
DLOG(ERROR) << "FifoReader connected to too many outputs\n";
|
LOG(ERROR) << "FifoReader connected to too many outputs";
|
||||||
}
|
}
|
||||||
|
|
||||||
// read samples out
|
// read samples out
|
||||||
@ -71,13 +66,13 @@ int FifoReader::work(int noutput_items,
|
|||||||
}
|
}
|
||||||
else if (sample_type_ == "gr_complex")
|
else if (sample_type_ == "gr_complex")
|
||||||
{
|
{
|
||||||
DLOG(WARNING) << sample_type_ << " is not yet tested. Please consider removing this warning if tested successfully\n";
|
LOG(WARNING) << sample_type_ << " is not yet tested. Please consider removing this warning if tested successfully";
|
||||||
items_retrieved = read_gr_complex(noutput_items, output_items);
|
items_retrieved = read_gr_complex(noutput_items, output_items);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// please see gr_complex_ip_packet_source for inspiration on how to implement other sample types
|
// please see gr_complex_ip_packet_source for inspiration on how to implement other sample types
|
||||||
DLOG(ERROR) << sample_type_ << " is unfortunately not yet implemented as sample type\n";
|
LOG(ERROR) << sample_type_ << " is unfortunately not yet implemented as sample type";
|
||||||
}
|
}
|
||||||
|
|
||||||
// we return varying number of data -> call produce & return flag
|
// we return varying number of data -> call produce & return flag
|
||||||
@ -86,26 +81,29 @@ int FifoReader::work(int noutput_items,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// read gr_complex items from fifo
|
// read gr_complex items from fifo
|
||||||
|
// this fct has duplicate code with the templated read_interleaved fct in header
|
||||||
size_t FifoReader::read_gr_complex(int noutput_items, gr_vector_void_star &output_items)
|
size_t FifoReader::read_gr_complex(int noutput_items, gr_vector_void_star &output_items)
|
||||||
{
|
{
|
||||||
size_t items_retrieved = 0;
|
size_t items_retrieved = 0;
|
||||||
for (int n = 0; n < noutput_items; n++)
|
for (int n = 0; n < noutput_items; n++)
|
||||||
{
|
{
|
||||||
std::vector<char> buffer(4);
|
gr_complex sample;
|
||||||
fifo_.read((char *)&buffer[0], buffer.size());
|
fifo_.read(reinterpret_cast<char *>(&sample), sizeof(sample));
|
||||||
if (fifo_.good())
|
if (fifo_.good())
|
||||||
{
|
{
|
||||||
gr_complex sample;
|
|
||||||
memcpy(&sample, &buffer[0], sizeof(sample));
|
|
||||||
static_cast<gr_complex *>(output_items.at(0))[n] = sample;
|
static_cast<gr_complex *>(output_items.at(0))[n] = sample;
|
||||||
items_retrieved++;
|
items_retrieved++;
|
||||||
}
|
}
|
||||||
else if (fifo_.eof() || fifo_.fail())
|
else if (fifo_.eof())
|
||||||
{
|
{
|
||||||
// not enough samples.. what if we did not have a complete sample? need to reassemble in between loops
|
|
||||||
fifo_.clear();
|
fifo_.clear();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG(ERROR) << "unhandled FIFO event";
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return items_retrieved;
|
return items_retrieved;
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ public:
|
|||||||
|
|
||||||
~FifoReader() = default;
|
~FifoReader() = default;
|
||||||
|
|
||||||
//! initialize istream resource for fifo
|
//! initialize istream resource for FIFO
|
||||||
bool start();
|
bool start();
|
||||||
|
|
||||||
// gnu radio work cycle function
|
// gnu radio work cycle function
|
||||||
@ -52,7 +52,7 @@ private:
|
|||||||
|
|
||||||
|
|
||||||
size_t read_gr_complex(int noutput_items, gr_vector_void_star &output_items);
|
size_t read_gr_complex(int noutput_items, gr_vector_void_star &output_items);
|
||||||
//! function to read data out of fifo which is stored as interleaved I/Q stream.
|
//! function to read data out of FIFO which is stored as interleaved I/Q stream.
|
||||||
//! template argument determines sample_type
|
//! template argument determines sample_type
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
size_t read_interleaved(int noutput_items, gr_vector_void_star &output_items)
|
size_t read_interleaved(int noutput_items, gr_vector_void_star &output_items)
|
||||||
@ -61,24 +61,28 @@ private:
|
|||||||
for (int n = 0; n < noutput_items; n++)
|
for (int n = 0; n < noutput_items; n++)
|
||||||
{
|
{
|
||||||
// TODO: try if performance increases if we copy larger chunks to vector.
|
// TODO: try if performance increases if we copy larger chunks to vector.
|
||||||
// read from fifo: https://en.cppreference.com/w/cpp/io/basic_ifstream
|
// how to read from stream: https://en.cppreference.com/w/cpp/io/basic_ifstream
|
||||||
std::vector<char> buffer(4); // dynamically change buffer size depending on read speed? where to throttle?
|
std::array<char, 4> buffer; // gr_complex is 32bit = 4*char
|
||||||
fifo_.read((char *)&buffer[0], buffer.size());
|
fifo_.read(reinterpret_cast<char *>(&buffer[0]), buffer.size());
|
||||||
if (fifo_.good())
|
if (fifo_.good())
|
||||||
{
|
{
|
||||||
Type real;
|
Type real;
|
||||||
Type imag;
|
Type imag;
|
||||||
memcpy(&real, &buffer[0], sizeof(real));
|
memcpy(&real, &buffer[0], sizeof(real));
|
||||||
memcpy(&imag, &buffer[2], sizeof(imag));
|
memcpy(&imag, &buffer[2], sizeof(imag));
|
||||||
static_cast<gr_complex *>(output_items.at(0))[n] = gr_complex(imag, real);
|
static_cast<gr_complex *>(output_items.at(0))[n] = gr_complex(real, imag);
|
||||||
items_retrieved++;
|
items_retrieved++;
|
||||||
}
|
}
|
||||||
else if (fifo_.eof() || fifo_.fail())
|
else if (fifo_.eof())
|
||||||
{
|
{
|
||||||
// not enough samples.. what if we did not have a complete sample? need to reassemble in between loops
|
|
||||||
fifo_.clear();
|
fifo_.clear();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG(ERROR) << "unhandled FIFO event";
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return items_retrieved;
|
return items_retrieved;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user