From eaa257925ddef888402e1b601dda45646ad6a373 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Sat, 5 Aug 2017 20:51:52 +0200 Subject: Check input zmq message size --- src/InputZeroMQReader.cpp | 73 ++++++++++++++++++++++++++++------------------- 1 file changed, 44 insertions(+), 29 deletions(-) diff --git a/src/InputZeroMQReader.cpp b/src/InputZeroMQReader.cpp index 1418db7..783f0f5 100644 --- a/src/InputZeroMQReader.cpp +++ b/src/InputZeroMQReader.cpp @@ -3,7 +3,7 @@ Her Majesty the Queen in Right of Canada (Communications Research Center Canada) - Copyright (C) 2013, 2014, 2015 + Copyright (C) 2017 Matthias P. Braendli, matthias.braendli@mpb.li http://opendigitalradio.org @@ -42,6 +42,8 @@ #include "PcDebug.h" #include "Utils.h" +using namespace std; + #define NUM_FRAMES_PER_ZMQ_MESSAGE 4 /* A concatenation of four ETI frames, * whose maximal size is 6144. @@ -63,7 +65,10 @@ struct zmq_dab_message_t uint8_t buf[NUM_FRAMES_PER_ZMQ_MESSAGE*6144]; }; -int InputZeroMQReader::Open(const std::string& uri, size_t max_queued_frames) +#define ZMQ_DAB_MESSAGE_T_HEADERSIZE \ + (sizeof(uint32_t) + NUM_FRAMES_PER_ZMQ_MESSAGE*sizeof(uint16_t)) + +int InputZeroMQReader::Open(const string& uri, size_t max_queued_frames) { // The URL might start with zmq+tcp:// if (uri.substr(0, 4) == "zmq+") { @@ -89,7 +94,7 @@ int InputZeroMQReader::GetNextFrame(void* buffer) return 0; } - std::shared_ptr > incoming; + shared_ptr > incoming; /* Do some prebuffering because reads will happen in bursts * (4 ETI frames in TM1) and we should make sure that @@ -167,41 +172,51 @@ void InputZeroMQWorker::RecvProcess(struct InputZeroMQThreadData* workerdata) } else if (queue_size < workerdata->max_queued_frames) { if (buffer_full) { - etiLog.level(info) << "ZeroMQ buffer recovered: " << queue_size << " elements"; + etiLog.level(info) << "ZeroMQ buffer recovered: " << + queue_size << " elements"; buffer_full = false; } - zmq_dab_message_t* dab_msg = (zmq_dab_message_t*)incoming.data(); - - if (dab_msg->version != 1) { - etiLog.level(error) << "ZeroMQ wrong packet version " << dab_msg->version; + if (incoming.size() < ZMQ_DAB_MESSAGE_T_HEADERSIZE) { + throw runtime_error("ZeroMQ packet too small for header"); } + else { + const zmq_dab_message_t* dab_msg = (zmq_dab_message_t*)incoming.data(); - int offset = sizeof(dab_msg->version) + - NUM_FRAMES_PER_ZMQ_MESSAGE * sizeof(*dab_msg->buflen); - - for (int i = 0; i < NUM_FRAMES_PER_ZMQ_MESSAGE; i++) - { - if (dab_msg->buflen[i] <= 0 || - dab_msg->buflen[i] > 6144) - { - etiLog.level(error) << "ZeroMQ buffer " << i << " has invalid length " << - dab_msg->buflen[i]; + if (dab_msg->version != 1) { + etiLog.level(error) << + "ZeroMQ wrong packet version " << + dab_msg->version; } - else { - std::shared_ptr > buf = - std::make_shared >(6144, 0x55); - const int framesize = dab_msg->buflen[i]; + int offset = sizeof(dab_msg->version) + + NUM_FRAMES_PER_ZMQ_MESSAGE * sizeof(*dab_msg->buflen); + + for (int i = 0; i < NUM_FRAMES_PER_ZMQ_MESSAGE; i++) { + if (dab_msg->buflen[i] > 6144) { + stringstream ss; + ss << "ZeroMQ buffer " << i << + " has invalid buflen " << dab_msg->buflen[i]; + throw runtime_error(ss.str()); + } + else { + auto buf = make_shared >(6144, 0x55); + + const int framesize = dab_msg->buflen[i]; + + if ((ssize_t)incoming.size() < offset + framesize) { + throw runtime_error("ZeroMQ packet too small"); + } - memcpy(&buf->front(), - ((uint8_t*)incoming.data()) + offset, - framesize); + memcpy(&buf->front(), + ((uint8_t*)incoming.data()) + offset, + framesize); - offset += framesize; + offset += framesize; - queue_size = workerdata->in_messages->push(buf); - etiLog.log(trace, "ZMQ,push %zu", queue_size); + queue_size = workerdata->in_messages->push(buf); + etiLog.log(trace, "ZMQ,push %zu", queue_size); + } } } } @@ -212,7 +227,7 @@ void InputZeroMQWorker::RecvProcess(struct InputZeroMQThreadData* workerdata) etiLog.level(warn) << "ZeroMQ buffer overfull !"; buffer_full = true; - throw std::runtime_error("ZMQ input full"); + throw runtime_error("ZMQ input full"); } queue_size = workerdata->in_messages->size(); -- cgit v1.2.3 From 56047e1f068b2ea4386cabd73bc0f29f55068250 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Sun, 6 Aug 2017 11:39:03 +0200 Subject: Remove raw flowgraph pointer from DabModulator --- src/DabModulator.cpp | 14 +++----------- src/DabModulator.h | 6 +----- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/src/DabModulator.cpp b/src/DabModulator.cpp index 4e0bc33..bebbedd 100644 --- a/src/DabModulator.cpp +++ b/src/DabModulator.cpp @@ -74,7 +74,7 @@ DabModulator::DabModulator( myNormalise(normalise), myGainmodeVariance(gainmodeVariance), myEtiSource(etiSource), - myFlowgraph(NULL), + myFlowgraph(), myFilterTapsFilename(filterTapsFilename), myPolyCoefFilename(polyCoefFilename), myTiiConfig(tiiConfig) @@ -90,14 +90,6 @@ DabModulator::DabModulator( } -DabModulator::~DabModulator() -{ - PDEBUG("DabModulator::~DabModulator() @ %p\n", this); - - delete myFlowgraph; -} - - void DabModulator::setMode(unsigned mode) { switch (mode) { @@ -145,7 +137,7 @@ int DabModulator::process(Buffer* dataOut) PDEBUG("DabModulator::process(dataOut: %p)\n", dataOut); - if (myFlowgraph == NULL) { + if (not myFlowgraph) { unsigned mode = myEtiSource.getMode(); if (myDabMode != 0) { mode = myDabMode; @@ -154,7 +146,7 @@ int DabModulator::process(Buffer* dataOut) } setMode(mode); - myFlowgraph = new Flowgraph(); + myFlowgraph = make_shared(); //////////////////////////////////////////////////////////////// // CIF data initialisation //////////////////////////////////////////////////////////////// diff --git a/src/DabModulator.h b/src/DabModulator.h index 0c691dd..e8048ac 100644 --- a/src/DabModulator.h +++ b/src/DabModulator.h @@ -57,9 +57,6 @@ public: float gainmodeVariance, const std::string& filterTapsFilename, const std::string& polyCoefFilename); - DabModulator(const DabModulator& other) = delete; - DabModulator& operator=(const DabModulator& other) = delete; - virtual ~DabModulator(); int process(Buffer* dataOut); const char* name() { return "DabModulator"; } @@ -78,8 +75,7 @@ protected: float myNormalise; float myGainmodeVariance; EtiSource& myEtiSource; - Flowgraph* myFlowgraph; - OutputMemory* myOutput; + std::shared_ptr myFlowgraph; std::string myFilterTapsFilename; std::string myPolyCoefFilename; tii_config_t& myTiiConfig; -- cgit v1.2.3 From 84c8d100c682fece37b448f38228260f84c070f2 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Wed, 16 Aug 2017 19:48:02 +0200 Subject: configure.ac: Properly check for FFTW --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 4d94592..172d43c 100644 --- a/configure.ac +++ b/configure.ac @@ -79,7 +79,7 @@ AC_ARG_ENABLE([output_uhd], [AS_HELP_STRING([--disable-output-uhd], [Disable UHD output])], [], [enable_output_uhd=yes]) -PKG_CHECK_MODULES([FFTW], [fftw3f], enable_fftw=yes, enable_fftw=no) +PKG_CHECK_MODULES([FFTW], [fftw3f], [], [AC_MSG_ERROR([FFTW is required])]) echo "Checking zeromq" -- cgit v1.2.3 From 15651ab0020ba594bff02491b3d2b6472f5e4fda Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Sat, 12 Aug 2017 14:37:45 +0200 Subject: show_spectrum: dump image and try to get upsampled constellation to work --- dpd/show_spectrum.py | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/dpd/show_spectrum.py b/dpd/show_spectrum.py index 95dbef9..f23dba2 100755 --- a/dpd/show_spectrum.py +++ b/dpd/show_spectrum.py @@ -169,14 +169,26 @@ def plot_constellation_once(options): num_syms = int(len(frame) / n) print("frame {} has {} symbols".format(len(frame), num_syms)) spectrums = np.array([np.fft.fftshift(np.fft.fft(frame[n*i:n*(i+1)], n)) for i in range(num_syms)]) - #imsave("spectrums.png", np.abs(spectrums)) + + def normalise(x): + """Normalise a real-valued array x to the range [0,1]""" + y = x + np.min(x) + return x / np.max(x) + + imsave("spectrums.png", np.concatenate([ + normalise(np.abs(spectrums)), + normalise(np.angle(spectrums))])) # Only take bins that are supposed to contain energy - #TODO this is only valid for 2048000 sample rate! - spectrums = np.concatenate([spectrums[...,256:1024], spectrums[...,1025:1793]], axis=1) + # i.e. the middle 1536 bins, excluding the bin at n/2 + assert(n % 2 == 0) + n_half = int(n/2) + spectrums = np.concatenate( + [spectrums[...,n_half-768:n_half], + spectrums[...,n_half + 1:n_half + 769]], axis=1) sym_indices = (np.tile(np.arange(num_syms-1).reshape(num_syms-1,1), (1,NbCarriers)) + - np.tile(np.linspace(-0.25, 0.25, NbCarriers), (num_syms-1, 1) ) ) + np.tile(np.linspace(-0.4, 0.4, NbCarriers), (num_syms-1, 1) ) ) sym_indices = sym_indices.reshape(-1) diff_angles = np.mod(np.diff(np.angle(spectrums, deg=1), axis=0), 360) #sym_points = spectrums[:-1].reshape(-1) -- cgit v1.2.3 From a82f72eb04d4b5766f12d94febdf2f989ca7210a Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Thu, 17 Aug 2017 15:25:47 +0200 Subject: Add number of threads setting for MemlessPoly --- dpd/dpd.ini | 4 ++++ src/ConfigParser.cpp | 3 +++ src/ConfigParser.h | 2 +- src/DabMod.cpp | 6 ++++-- src/DabModulator.cpp | 7 +++++-- src/DabModulator.h | 5 ++++- src/MemlessPoly.cpp | 29 ++++++++++++++++++----------- src/MemlessPoly.h | 3 ++- 8 files changed, 41 insertions(+), 18 deletions(-) diff --git a/dpd/dpd.ini b/dpd/dpd.ini index 08564d9..21d7d45 100644 --- a/dpd/dpd.ini +++ b/dpd/dpd.ini @@ -24,6 +24,10 @@ enabled=1 enabled=1 polycoeffile=dpdpoly.coef +# How many threads to use for the predistorter. +# If not set, detect automatically. +#num_threads=2 + [output] # to prepare a file for the dpd/iq_file_server.py script, # use output=file diff --git a/src/ConfigParser.cpp b/src/ConfigParser.cpp index 459811f..f27eb08 100644 --- a/src/ConfigParser.cpp +++ b/src/ConfigParser.cpp @@ -172,6 +172,9 @@ static void parse_configfile( if (pt.get("poly.enabled", 0) == 1) { mod_settings.polyCoefFilename = pt.get("poly.polycoeffile", "default"); + + mod_settings.polyNumThreads = + pt.get("poly.num_threads", 0); } // Output options diff --git a/src/ConfigParser.h b/src/ConfigParser.h index 22a4fc5..89f0fb7 100644 --- a/src/ConfigParser.h +++ b/src/ConfigParser.h @@ -75,7 +75,7 @@ struct mod_settings_t { std::string filterTapsFilename = ""; std::string polyCoefFilename = ""; - + unsigned polyNumThreads = 0; #if defined(HAVE_OUTPUT_UHD) OutputUHDConfig outputuhd_conf; diff --git a/src/DabMod.cpp b/src/DabMod.cpp index 7c342a2..1f10fb8 100644 --- a/src/DabMod.cpp +++ b/src/DabMod.cpp @@ -328,7 +328,8 @@ int launch_modulator(int argc, char* argv[]) mod_settings.normalise, mod_settings.gainmodeVariance, mod_settings.filterTapsFilename, - mod_settings.polyCoefFilename); + mod_settings.polyCoefFilename, + mod_settings.polyNumThreads); if (format_converter) { flowgraph.connect(modulator, format_converter); @@ -433,7 +434,8 @@ int launch_modulator(int argc, char* argv[]) mod_settings.normalise, mod_settings.gainmodeVariance, mod_settings.filterTapsFilename, - mod_settings.polyCoefFilename); + mod_settings.polyCoefFilename, + mod_settings.polyNumThreads); if (format_converter) { flowgraph.connect(modulator, format_converter); diff --git a/src/DabModulator.cpp b/src/DabModulator.cpp index 5282a2d..ccc2085 100644 --- a/src/DabModulator.cpp +++ b/src/DabModulator.cpp @@ -63,7 +63,8 @@ DabModulator::DabModulator( float& digGain, float normalise, float gainmodeVariance, const std::string& filterTapsFilename, - const std::string& polyCoefFilename + const std::string& polyCoefFilename, + unsigned int polyNumThreads ) : ModInput(), myOutputRate(outputRate), @@ -77,6 +78,7 @@ DabModulator::DabModulator( myFlowgraph(NULL), myFilterTapsFilename(filterTapsFilename), myPolyCoefFilename(polyCoefFilename), + myPolyNumThreads(polyNumThreads), myTiiConfig(tiiConfig) { PDEBUG("DabModulator::DabModulator(%u, %u, %u, %zu) @ %p\n", @@ -222,7 +224,8 @@ int DabModulator::process(Buffer* dataOut) shared_ptr cifPoly; if (not myPolyCoefFilename.empty()) { - cifPoly = make_shared(myPolyCoefFilename); + cifPoly = make_shared( + myPolyCoefFilename, myPolyNumThreads); rcs.enrol(cifPoly.get()); } diff --git a/src/DabModulator.h b/src/DabModulator.h index 0c691dd..56a6f91 100644 --- a/src/DabModulator.h +++ b/src/DabModulator.h @@ -56,7 +56,9 @@ public: float& digGain, float normalise, float gainmodeVariance, const std::string& filterTapsFilename, - const std::string& polyCoefFilename); + const std::string& polyCoefFilename, + unsigned int polyNumThreads); + DabModulator(const DabModulator& other) = delete; DabModulator& operator=(const DabModulator& other) = delete; virtual ~DabModulator(); @@ -82,6 +84,7 @@ protected: OutputMemory* myOutput; std::string myFilterTapsFilename; std::string myPolyCoefFilename; + unsigned int myPolyNumThreads; tii_config_t& myTiiConfig; size_t myNbSymbols; diff --git a/src/MemlessPoly.cpp b/src/MemlessPoly.cpp index 71ceac3..b0d950c 100644 --- a/src/MemlessPoly.cpp +++ b/src/MemlessPoly.cpp @@ -53,9 +53,10 @@ static const std::array default_coefficients({{ }}); -MemlessPoly::MemlessPoly(const std::string& coefs_file) : +MemlessPoly::MemlessPoly(const std::string& coefs_file, unsigned int num_threads) : PipelinedModCodec(), RemoteControllable("memlesspoly"), + m_num_threads(num_threads), m_coefs(), m_coefs_file(coefs_file), m_coefs_mutex() @@ -63,6 +64,16 @@ MemlessPoly::MemlessPoly(const std::string& coefs_file) : PDEBUG("MemlessPoly::MemlessPoly(%s) @ %p\n", coefs_file.c_str(), this); + if (m_num_threads == 0) { + const unsigned int hw_concurrency = std::thread::hardware_concurrency(); + etiLog.level(info) << "Polynomial Predistorter will use " << + hw_concurrency << " threads (auto detected)"; + } + else { + etiLog.level(info) << "Polynomial Predistorter will use " << + m_num_threads << " threads (set in config file)"; + } + RC_ADD_PARAMETER(ncoefs, "(Read-only) number of coefficients."); RC_ADD_PARAMETER(coeffile, "Filename containing coefficients. When written to, the new file gets automatically loaded."); @@ -156,12 +167,15 @@ int MemlessPoly::internal_process(Buffer* const dataIn, Buffer* dataOut) std::lock_guard lock(m_coefs_mutex); const unsigned int hw_concurrency = std::thread::hardware_concurrency(); - if (hw_concurrency) { - const size_t step = sizeOut / hw_concurrency; + const unsigned int num_threads = + (m_num_threads > 0) ? m_num_threads : hw_concurrency; + + if (num_threads) { + const size_t step = sizeOut / num_threads; vector > flags; size_t start = 0; - for (size_t i = 0; i < hw_concurrency - 1; i++) { + for (size_t i = 0; i < num_threads - 1; i++) { flags.push_back(async(launch::async, apply_coeff, m_coefs, in, start, start + step, out)); @@ -177,13 +191,6 @@ int MemlessPoly::internal_process(Buffer* const dataIn, Buffer* dataOut) } } else { - static bool error_printed = false; - if (not error_printed) { - etiLog.level(warn) << - "Your platform doesn't seem to have hardware concurrency. " - "MemlessPoly will run single-threaded"; - } - // For some reason we don't have hw concurrency. apply_coeff(m_coefs, in, 0, sizeOut, out); } } diff --git a/src/MemlessPoly.h b/src/MemlessPoly.h index 9fe19d7..b7fd81e 100644 --- a/src/MemlessPoly.h +++ b/src/MemlessPoly.h @@ -52,7 +52,7 @@ typedef std::complex complexf; class MemlessPoly : public PipelinedModCodec, public RemoteControllable { public: - MemlessPoly(const std::string& coefs_file); + MemlessPoly(const std::string& coefs_file, unsigned int num_threads); virtual const char* name() { return "MemlessPoly"; } @@ -67,6 +67,7 @@ private: int internal_process(Buffer* const dataIn, Buffer* dataOut); void load_coefficients(const std::string &coefFile); + unsigned int m_num_threads; std::vector m_coefs; std::string m_coefs_file; mutable std::mutex m_coefs_mutex; -- cgit v1.2.3 From 6a9af4b8ff4f73e01ccb3bd07c0a971ef503c73d Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Thu, 17 Aug 2017 15:35:36 +0200 Subject: Move default poly to dpd/poly.coef --- dpd/dpd.ini | 2 +- dpd/poly.coef | 11 +++++++++++ dpdpoly.coef | 11 ----------- src/ConfigParser.cpp | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) create mode 100644 dpd/poly.coef delete mode 100644 dpdpoly.coef diff --git a/dpd/dpd.ini b/dpd/dpd.ini index 21d7d45..eb221e3 100644 --- a/dpd/dpd.ini +++ b/dpd/dpd.ini @@ -22,7 +22,7 @@ enabled=1 [poly] enabled=1 -polycoeffile=dpdpoly.coef +polycoeffile=dpd/poly.coef # How many threads to use for the predistorter. # If not set, detect automatically. diff --git a/dpd/poly.coef b/dpd/poly.coef new file mode 100644 index 0000000..b29fa26 --- /dev/null +++ b/dpd/poly.coef @@ -0,0 +1,11 @@ +5 +0 +0 +0.8 +0 +0 +0 +0 +0 +0 +0 diff --git a/dpdpoly.coef b/dpdpoly.coef deleted file mode 100644 index b29fa26..0000000 --- a/dpdpoly.coef +++ /dev/null @@ -1,11 +0,0 @@ -5 -0 -0 -0.8 -0 -0 -0 -0 -0 -0 -0 diff --git a/src/ConfigParser.cpp b/src/ConfigParser.cpp index f27eb08..9ac1280 100644 --- a/src/ConfigParser.cpp +++ b/src/ConfigParser.cpp @@ -171,7 +171,7 @@ static void parse_configfile( // Poly coefficients: if (pt.get("poly.enabled", 0) == 1) { mod_settings.polyCoefFilename = - pt.get("poly.polycoeffile", "default"); + pt.get("poly.polycoeffile", "dpd/poly.coef"); mod_settings.polyNumThreads = pt.get("poly.num_threads", 0); -- cgit v1.2.3 From 1cfebd56f205f95498079a20bca1a0667be07296 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Thu, 17 Aug 2017 16:15:54 +0200 Subject: Simplify DabModulator ctor signature --- src/DabMod.cpp | 26 ++---------------- src/DabModulator.cpp | 77 ++++++++++++++++++++++++---------------------------- src/DabModulator.h | 24 ++++------------ src/GainControl.cpp | 2 +- src/GainControl.h | 4 +-- src/TII.cpp | 2 +- src/TII.h | 4 +-- 7 files changed, 49 insertions(+), 90 deletions(-) diff --git a/src/DabMod.cpp b/src/DabMod.cpp index 7c342a2..15b3be2 100644 --- a/src/DabMod.cpp +++ b/src/DabMod.cpp @@ -317,18 +317,7 @@ int launch_modulator(int argc, char* argv[]) } Flowgraph flowgraph; - auto modulator = make_shared( - ediReader, - mod_settings.tiiConfig, - mod_settings.outputRate, - mod_settings.clockRate, - mod_settings.dabMode, - mod_settings.gainMode, - mod_settings.digitalgain, - mod_settings.normalise, - mod_settings.gainmodeVariance, - mod_settings.filterTapsFilename, - mod_settings.polyCoefFilename); + auto modulator = make_shared(ediReader, mod_settings); if (format_converter) { flowgraph.connect(modulator, format_converter); @@ -422,18 +411,7 @@ int launch_modulator(int argc, char* argv[]) m.etiReader = &etiReader; auto input = make_shared(&m.data); - auto modulator = make_shared( - etiReader, - mod_settings.tiiConfig, - mod_settings.outputRate, - mod_settings.clockRate, - mod_settings.dabMode, - mod_settings.gainMode, - mod_settings.digitalgain, - mod_settings.normalise, - mod_settings.gainmodeVariance, - mod_settings.filterTapsFilename, - mod_settings.polyCoefFilename); + auto modulator = make_shared(etiReader, mod_settings); if (format_converter) { flowgraph.connect(modulator, format_converter); diff --git a/src/DabModulator.cpp b/src/DabModulator.cpp index bebbedd..34d8e66 100644 --- a/src/DabModulator.cpp +++ b/src/DabModulator.cpp @@ -55,37 +55,21 @@ #include "RemoteControl.h" #include "Log.h" -DabModulator::DabModulator( - EtiSource& etiSource, - tii_config_t& tiiConfig, - unsigned outputRate, unsigned clockRate, - unsigned dabMode, GainMode gainMode, - float& digGain, float normalise, - float gainmodeVariance, - const std::string& filterTapsFilename, - const std::string& polyCoefFilename - ) : +DabModulator::DabModulator(EtiSource& etiSource, + const mod_settings_t& settings) : ModInput(), - myOutputRate(outputRate), - myClockRate(clockRate), - myDabMode(dabMode), - myGainMode(gainMode), - myDigGain(digGain), - myNormalise(normalise), - myGainmodeVariance(gainmodeVariance), + m_settings(settings), myEtiSource(etiSource), - myFlowgraph(), - myFilterTapsFilename(filterTapsFilename), - myPolyCoefFilename(polyCoefFilename), - myTiiConfig(tiiConfig) + myFlowgraph() { PDEBUG("DabModulator::DabModulator(%u, %u, %u, %zu) @ %p\n", outputRate, clockRate, dabMode, (size_t)gainMode, this); - if (myDabMode == 0) { + if (m_settings.dabMode == 0) { setMode(2); - } else { - setMode(myDabMode); + } + else { + setMode(m_settings.dabMode); } } @@ -139,8 +123,8 @@ int DabModulator::process(Buffer* dataOut) if (not myFlowgraph) { unsigned mode = myEtiSource.getMode(); - if (myDabMode != 0) { - mode = myDabMode; + if (m_settings.dabMode != 0) { + mode = m_settings.dabMode; } else if (mode == 0) { mode = 4; } @@ -166,10 +150,10 @@ int DabModulator::process(Buffer* dataOut) // TODO this needs a review bool useCicEq = false; unsigned cic_ratio = 1; - if (myClockRate) { - cic_ratio = myClockRate / myOutputRate; + if (m_settings.clockRate) { + cic_ratio = m_settings.clockRate / m_settings.outputRate; cic_ratio /= 4; // FPGA DUC - if (myClockRate == 400000000) { // USRP2 + if (m_settings.clockRate == 400000000) { // USRP2 if (cic_ratio & 1) { // odd useCicEq = true; } // even, no filter @@ -181,12 +165,16 @@ int DabModulator::process(Buffer* dataOut) auto cifCicEq = make_shared( myNbCarriers, - (float)mySpacing * (float)myOutputRate / 2048000.0f, cic_ratio); + (float)mySpacing * (float)m_settings.outputRate / 2048000.0f, + cic_ratio); shared_ptr tii; shared_ptr tiiRef; try { - tii = make_shared(myDabMode, myTiiConfig, myEtiSource.getFp()); + tii = make_shared( + m_settings.dabMode, + m_settings.tiiConfig, + myEtiSource.getFp()); rcs.enrol(tii.get()); tiiRef = make_shared(mode); } @@ -198,8 +186,11 @@ int DabModulator::process(Buffer* dataOut) (1 + myNbSymbols), myNbCarriers, mySpacing); auto cifGain = make_shared( - mySpacing, myGainMode, myDigGain, myNormalise, - myGainmodeVariance); + mySpacing, + m_settings.gainMode, + m_settings.digitalgain, + m_settings.normalise, + m_settings.gainmodeVariance); rcs.enrol(cifGain.get()); @@ -207,15 +198,15 @@ int DabModulator::process(Buffer* dataOut) myNbSymbols, mySpacing, myNullSize, mySymSize); shared_ptr cifFilter; - if (not myFilterTapsFilename.empty()) { - cifFilter = make_shared(myFilterTapsFilename); + if (not m_settings.filterTapsFilename.empty()) { + cifFilter = make_shared(m_settings.filterTapsFilename); rcs.enrol(cifFilter.get()); } shared_ptr cifPoly; - if (not myPolyCoefFilename.empty()) { - cifPoly = make_shared(myPolyCoefFilename); - etiLog.level(debug) << myPolyCoefFilename << "\n"; + if (not m_settings.polyCoefFilename.empty()) { + cifPoly = make_shared(m_settings.polyCoefFilename); + etiLog.level(debug) << m_settings.polyCoefFilename << "\n"; etiLog.level(debug) << cifPoly->m_coefs[0] << " " << cifPoly->m_coefs[1] << " "<< cifPoly->m_coefs[2] << " "<< cifPoly->m_coefs[3] << " "<< cifPoly->m_coefs[4] << " "<< @@ -227,9 +218,13 @@ int DabModulator::process(Buffer* dataOut) auto myOutput = make_shared(dataOut); shared_ptr cifRes; - if (myOutputRate != 2048000) { - cifRes = make_shared(2048000, myOutputRate, mySpacing); - } else { + if (m_settings.outputRate != 2048000) { + cifRes = make_shared( + 2048000, + m_settings.outputRate, + mySpacing); + } + else { fprintf(stderr, "No resampler\n"); } diff --git a/src/DabModulator.h b/src/DabModulator.h index e8048ac..6878853 100644 --- a/src/DabModulator.h +++ b/src/DabModulator.h @@ -36,6 +36,7 @@ #include #include "ModPlugin.h" +#include "ConfigParser.h" #include "EtiReader.h" #include "Flowgraph.h" #include "GainControl.h" @@ -48,15 +49,8 @@ class DabModulator : public ModInput { public: - DabModulator( - EtiSource& etiSource, - tii_config_t& tiiConfig, - unsigned outputRate, unsigned clockRate, - unsigned dabMode, GainMode gainMode, - float& digGain, float normalise, - float gainmodeVariance, - const std::string& filterTapsFilename, - const std::string& polyCoefFilename); + DabModulator(EtiSource& etiSource, + const mod_settings_t& settings); int process(Buffer* dataOut); const char* name() { return "DabModulator"; } @@ -67,18 +61,10 @@ public: protected: void setMode(unsigned mode); - unsigned myOutputRate; - unsigned myClockRate; - unsigned myDabMode; - GainMode myGainMode; - float& myDigGain; - float myNormalise; - float myGainmodeVariance; + const mod_settings_t& m_settings; + EtiSource& myEtiSource; std::shared_ptr myFlowgraph; - std::string myFilterTapsFilename; - std::string myPolyCoefFilename; - tii_config_t& myTiiConfig; size_t myNbSymbols; size_t myNbCarriers; diff --git a/src/GainControl.cpp b/src/GainControl.cpp index f363d20..2a91b12 100644 --- a/src/GainControl.cpp +++ b/src/GainControl.cpp @@ -47,7 +47,7 @@ static float var_variance; GainControl::GainControl(size_t framesize, GainMode mode, - float& digGain, + float digGain, float normalise, float varVariance) : PipelinedModCodec(), diff --git a/src/GainControl.h b/src/GainControl.h index e8f1be9..44c9fa9 100644 --- a/src/GainControl.h +++ b/src/GainControl.h @@ -52,7 +52,7 @@ class GainControl : public PipelinedModCodec, public RemoteControllable public: GainControl(size_t framesize, GainMode mode, - float& digGain, + float digGain, float normalise, float varVariance); @@ -76,7 +76,7 @@ class GainControl : public PipelinedModCodec, public RemoteControllable Buffer* const dataIn, Buffer* dataOut) override; size_t m_frameSize; - float& m_digGain; + float m_digGain; float m_normalise; // The following variables are accessed from the RC thread diff --git a/src/TII.cpp b/src/TII.cpp index 6bc3f0d..8a8bd86 100644 --- a/src/TII.cpp +++ b/src/TII.cpp @@ -106,7 +106,7 @@ 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, tii_config_t& tii_config, unsigned phase) : +TII::TII(unsigned int dabmode, const tii_config_t& tii_config, unsigned phase) : ModCodec(), RemoteControllable("tii"), m_dabmode(dabmode), diff --git a/src/TII.h b/src/TII.h index 2bd2040..fe67978 100644 --- a/src/TII.h +++ b/src/TII.h @@ -83,7 +83,7 @@ class TIIError : public std::runtime_error { class TII : public ModCodec, public RemoteControllable { public: - TII(unsigned int dabmode, tii_config_t& tii_config, unsigned phase); + TII(unsigned int dabmode, const tii_config_t& tii_config, unsigned phase); virtual ~TII(); TII(const TII&) = delete; TII& operator=(const TII&) = delete; @@ -110,7 +110,7 @@ class TII : public ModCodec, public RemoteControllable unsigned int m_dabmode; // Remote-controllable settings - tii_config_t& m_conf; + tii_config_t m_conf; // Internal flag when to insert TII bool m_insert; -- cgit v1.2.3