diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/DabMod.cpp | 12 | ||||
-rw-r--r-- | src/DabModulator.cpp | 13 | ||||
-rw-r--r-- | src/DabModulator.h | 8 | ||||
-rw-r--r-- | src/TII.cpp | 94 | ||||
-rw-r--r-- | src/TII.h | 47 |
5 files changed, 140 insertions, 34 deletions
diff --git a/src/DabMod.cpp b/src/DabMod.cpp index 618e0fe..01125b2 100644 --- a/src/DabMod.cpp +++ b/src/DabMod.cpp @@ -132,8 +132,7 @@ int launch_modulator(int argc, char* argv[]) float normalise = 1.0f; GainMode gainMode = GAIN_VAR; - int tiiPattern = 0; - int tiiComb = 0; + tii_config_t tiiConfig; /* UHD requires the input I and Q samples to be in the interval * [-1.0,1.0], otherwise they get truncated, which creates very @@ -582,8 +581,9 @@ int launch_modulator(int argc, char* argv[]) #endif /* Read TII parameters from config file */ - tiiComb = pt.get("tii.comb", 0); - tiiPattern = pt.get("tii.pattern", 0); + tiiConfig.enable = pt.get("tii.enable", 0); + tiiConfig.comb = pt.get("tii.comb", 0); + tiiConfig.pattern = pt.get("tii.pattern", 0); } if (rcs.get_no_controllers() == 0) { @@ -755,8 +755,8 @@ int launch_modulator(int argc, char* argv[]) shared_ptr<InputMemory> input(new InputMemory(&m.data)); shared_ptr<DabModulator> modulator( new DabModulator(tist_offset_s, tist_delay_stages, &rcs, - outputRate, clockRate, dabMode, gainMode, digitalgain, - normalise, filterTapsFilename, tiiComb, tiiPattern)); + tiiConfig, outputRate, clockRate, dabMode, gainMode, + digitalgain, normalise, filterTapsFilename)); flowgraph.connect(input, modulator); if (format_converter) { diff --git a/src/DabModulator.cpp b/src/DabModulator.cpp index dbc6827..9d4647e 100644 --- a/src/DabModulator.cpp +++ b/src/DabModulator.cpp @@ -58,11 +58,11 @@ using namespace boost; DabModulator::DabModulator( double tist_offset_s, unsigned tist_delay_stages, RemoteControllers* rcs, + const tii_config_t& tiiConfig, unsigned outputRate, unsigned clockRate, unsigned dabMode, GainMode gainMode, float digGain, float normalise, - std::string filterTapsFilename, - int tiiComb, int tiiPattern + std::string filterTapsFilename ) : ModCodec(ModFormat(1), ModFormat(0)), myOutputRate(outputRate), @@ -74,8 +74,7 @@ DabModulator::DabModulator( myEtiReader(EtiReader(tist_offset_s, tist_delay_stages, rcs)), myFlowgraph(NULL), myFilterTapsFilename(filterTapsFilename), - myTiiComb(tiiComb), - myTiiPattern(tiiPattern), + myTiiConfig(tiiConfig), myRCs(rcs) { PDEBUG("DabModulator::DabModulator(%u, %u, %u, %u) @ %p\n", @@ -198,10 +197,8 @@ int DabModulator::process(Buffer* const dataIn, Buffer* dataOut) (float)mySpacing * (float)myOutputRate / 2048000.0f, cic_ratio)); - shared_ptr<TII> tii; - if (myTiiComb != 0) { - tii = make_shared<TII>(myDabMode, myTiiPattern, myTiiComb); - } + shared_ptr<TII> tii = make_shared<TII>(myDabMode, myTiiConfig); + tii->enrol_at(*myRCs); shared_ptr<OfdmGenerator> cifOfdm( new OfdmGenerator((1 + myNbSymbols), myNbCarriers, mySpacing)); diff --git a/src/DabModulator.h b/src/DabModulator.h index 48cdd42..cee066a 100644 --- a/src/DabModulator.h +++ b/src/DabModulator.h @@ -43,6 +43,7 @@ #include "OutputMemory.h" #include "RemoteControl.h" #include "Log.h" +#include "TII.h" class DabModulator : public ModCodec @@ -51,11 +52,11 @@ public: DabModulator( double tist_offset_s, unsigned tist_delay_stages, RemoteControllers* rcs, + const tii_config_t& tiiConfig, unsigned outputRate = 2048000, unsigned clockRate = 0, unsigned dabMode = 0, GainMode gainMode = GAIN_VAR, float digGain = 1.0, float normalise = 1.0, - std::string filterTapsFilename = "", - int tiiComb = 0, int tiiPattern = 0); + std::string filterTapsFilename = ""); DabModulator(const DabModulator& copy); virtual ~DabModulator(); @@ -78,8 +79,7 @@ protected: Flowgraph* myFlowgraph; OutputMemory* myOutput; std::string myFilterTapsFilename; - int myTiiComb; - int myTiiPattern; + tii_config_t myTiiConfig; RemoteControllers* myRCs; size_t myNbSymbols; diff --git a/src/TII.cpp b/src/TII.cpp index 5c85302..6d969a5 100644 --- a/src/TII.cpp +++ b/src/TII.cpp @@ -106,19 +106,20 @@ const int pattern_tm1_2_4[][8] = { // {{{ {1,1,1,0,1,0,0,0}, {1,1,1,1,0,0,0,0} }; // }}} - -TII::TII(unsigned int dabmode, unsigned int comb, unsigned int pattern) : +TII::TII(unsigned int dabmode, const tii_config_t& tii_config) : ModCodec(ModFormat(0), ModFormat(0)), + RemoteControllable("tii"), m_dabmode(dabmode), - m_comb(comb), - m_pattern(pattern), + m_enable(tii_config.enable), + m_comb(tii_config.comb), + m_pattern(tii_config.pattern), m_insert(true) { PDEBUG("TII::TII(%u) @ %p\n", dabmode, this); - std::stringstream ss; - ss << "TII(comb:" << m_comb << ", pattern:" << m_pattern << ")"; - m_name = ss.str(); + RC_ADD_PARAMETER(enable, "enable TII [0-1]"); + RC_ADD_PARAMETER(comb, "TII comb number [0-23]"); + RC_ADD_PARAMETER(pattern, "TII pattern number [0-69]"); switch (m_dabmode) { case 1: @@ -152,7 +153,7 @@ TII::TII(unsigned int dabmode, unsigned int comb, unsigned int pattern) : throw std::runtime_error(ss_exception.str()); } - if (not(0 < m_comb and m_comb <= 23) ) { + if (not(0 <= m_comb and m_comb <= 23) ) { throw std::runtime_error( "TII::TII comb not valid!"); } @@ -170,6 +171,17 @@ TII::~TII() PDEBUG("TII::~TII() @ %p\n", this); } +const char* TII::name() +{ + // Calculate name on demand because comb and pattern are + // modifiable through RC + std::stringstream ss; + ss << "TII(comb:" << m_comb << ", pattern:" << m_pattern << ")"; + m_name = ss.str(); + + return m_name.c_str(); +} + int TII::process(Buffer* const dataIn, Buffer* dataOut) { @@ -181,7 +193,8 @@ int TII::process(Buffer* const dataIn, Buffer* dataOut) "TII::process input size not valid!"); } - if (m_insert) { + if (m_enable and m_insert) { + boost::mutex::scoped_lock lock(m_dataIn_mutex); dataOut->setData(&m_dataIn[0], m_carriers * sizeof(complexf)); } else { @@ -211,6 +224,13 @@ void TII::enable_carrier(int k) { void TII::prepare_pattern() { int comb = m_comb; // Convert from unsigned to signed + boost::mutex::scoped_lock lock(m_dataIn_mutex); + + // Clear previous pattern + for (size_t i = 0; i < m_dataIn.size(); i++) { + m_dataIn[i] = 0.0; + } + // This could be written more efficiently, but since it is // not performance-critial, it makes sense to write it // in the same way as the specification in @@ -273,10 +293,66 @@ void TII::prepare_pattern() { throw std::runtime_error( "TII::TII DAB mode not valid!"); } +} + +void TII::set_parameter(const std::string& parameter, const std::string& value) +{ + using namespace std; + stringstream ss(value); + ss.exceptions ( stringstream::failbit | stringstream::badbit ); + if (parameter == "enable") { + ss >> m_enable; + } + else if (parameter == "pattern") { + int new_pattern; + ss >> new_pattern; + if ( (m_dabmode == 1 or m_dabmode == 2) and + not(0 <= new_pattern and new_pattern <= 69) ) { + throw std::runtime_error( + "TII pattern not valid!"); + } + m_pattern = new_pattern; + prepare_pattern(); + } + else if (parameter == "comb") { + int new_comb; + ss >> new_comb; + if (not(0 <= new_comb and new_comb <= 23) ) { + throw std::runtime_error( + "TII comb not valid!"); + } + m_comb = new_comb; + prepare_pattern(); + } + else { + stringstream ss; + ss << "Parameter '" << parameter << "' is not exported by controllable " << get_rc_name(); + throw ParameterError(ss.str()); + } +} +const std::string TII::get_parameter(const std::string& parameter) const +{ + using namespace std; + stringstream ss; + if (parameter == "enable") { + ss << (m_enable ? 1 : 0); + } + else if (parameter == "pattern") { + ss << m_pattern; + } + else if (parameter == "comb") { + ss << m_comb; + } + else { + ss << "Parameter '" << parameter << "' is not exported by controllable " << get_rc_name(); + throw ParameterError(ss.str()); + } + return ss.str(); } + #ifdef TII_TEST int main(int argc, char** argv) { @@ -6,6 +6,8 @@ Matthias P. Braendli, matthias.braendli@mpb.li http://opendigitalradio.org + + TII generation according to ETSI EN 300 401 Clause 14.8 */ /* This file is part of ODR-DabMod. @@ -32,36 +34,67 @@ #endif #include "ModCodec.h" +#include "RemoteControl.h" +#include <boost/thread.hpp> #include <sys/types.h> #include <complex> #include <vector> #include <string> -class TII : public ModCodec +struct tii_config_t +{ + tii_config_t() : enable(false), comb(0), pattern(0) {} + + bool enable; + int comb; + int pattern; +}; + +class TII : public ModCodec, public RemoteControllable { public: - TII(unsigned int dabmode, unsigned int comb, unsigned int pattern); + TII(unsigned int dabmode, const tii_config_t& tii_config); virtual ~TII(); int process(Buffer* const dataIn, Buffer* dataOut); - const char* name() { return m_name.c_str(); }; + const char* name(); + + /******* REMOTE CONTROL ********/ + virtual void set_parameter(const std::string& parameter, + const std::string& value); + + virtual const std::string get_parameter( + const std::string& parameter) const; + protected: + // Fill m_dataIn with the correct carriers for the pattern/comb + // combination + void prepare_pattern(void); + + // prerequisites: calling thread must hold m_dataIn mutex + void enable_carrier(int k); + + // Configuration settings unsigned int m_dabmode; + + // Remote-controllable settings + bool m_enable; unsigned int m_comb; unsigned int m_pattern; + // Internal flag when to insert TII bool m_insert; size_t m_carriers; std::string m_name; - std::vector<std::complex<float> > m_dataIn; - void prepare_pattern(void); - - void enable_carrier(int k); + // m_dataIn is read by modulator thread, and written + // to by RC thread. + mutable boost::mutex m_dataIn_mutex; + std::vector<std::complex<float> > m_dataIn; private: TII(const TII&); |