From 1834e7886112944cbb8b92751c13f50799142079 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Sun, 10 Dec 2017 04:49:18 +0100 Subject: Rename misleading variable name --- src/OutputUHD.cpp | 10 +++++----- src/OutputUHD.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/OutputUHD.cpp b/src/OutputUHD.cpp index e1fe9dd..e2616a6 100644 --- a/src/OutputUHD.cpp +++ b/src/OutputUHD.cpp @@ -267,7 +267,7 @@ OutputUHD::OutputUHD( myConf.muteNoTimestamps ? "enabled" : "disabled"); // preparing output thread worker data - sourceContainsTimestamp = false; + sync_and_ts_valid = false; SetDelayBuffer(myConf.dabMode); @@ -407,7 +407,7 @@ int OutputUHD::process(Buffer* dataIn) throw std::runtime_error("Non-constant input length!"); } - sourceContainsTimestamp = myConf.enableSync and + sync_and_ts_valid = myConf.enableSync and myEtiSource->sourceContainsTimestamp(); if (gpsfix_needs_check()) { @@ -733,7 +733,7 @@ void OutputUHD::handle_frame(const struct UHDWorkerFrameData *frame) double usrp_time = myUsrp->get_time_now().get_real_secs(); bool timestamp_discontinuity = false; - if (sourceContainsTimestamp) { + if (sync_and_ts_valid) { // Tx time from MNSC and TIST uint32_t tx_second = frame->ts.timestamp_sec; uint32_t tx_pps = frame->ts.timestamp_pps; @@ -812,7 +812,7 @@ void OutputUHD::handle_frame(const struct UHDWorkerFrameData *frame) throw std::runtime_error("Timestamp error. Aborted."); } } - else { // !sourceContainsTimestamp + else { // !sync_and_ts_valid if (myConf.muting or myConf.muteNoTimestamps) { /* There was some error decoding the timestamp */ if (myConf.muting) { @@ -849,7 +849,7 @@ void OutputUHD::tx_frame(const struct UHDWorkerFrameData *frame, bool ts_update) //ensure the the last packet has EOB set if the timestamps has been //refreshed and need to be reconsidered. md_tx.end_of_burst = ( - sourceContainsTimestamp and + sync_and_ts_valid and (frame->ts.timestamp_refresh or ts_update) and samps_to_send <= usrp_max_num_samps ); diff --git a/src/OutputUHD.h b/src/OutputUHD.h index dfa471d..0630480 100644 --- a/src/OutputUHD.h +++ b/src/OutputUHD.h @@ -209,7 +209,7 @@ class OutputUHD: public ModOutput, public RemoteControllable { // Used to print statistics once a second std::chrono::steady_clock::time_point last_print_time; - bool sourceContainsTimestamp = false; + bool sync_and_ts_valid = false; ThreadsafeQueue frames; -- cgit v1.2.3 From 1087a7f4ad8bb1bc9bf4472bf2734b0e4929e7d1 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Mon, 11 Dec 2017 15:07:18 +0100 Subject: Remove references to malloc.h and use posix_memalign --- configure.ac | 3 +-- src/Buffer.cpp | 12 ++++-------- src/DabMod.cpp | 7 ------- src/Flowgraph.cpp | 6 ------ src/FormatConverter.cpp | 1 - src/FrequencyInterleaver.cpp | 8 ++++++-- src/Resampler.cpp | 7 +++++-- 7 files changed, 16 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/configure.ac b/configure.ac index 23369c9..d260f9e 100644 --- a/configure.ac +++ b/configure.ac @@ -154,8 +154,7 @@ AS_IF([test "x$enable_debug" != "xno"], )]) # Checks for header files. -AC_CHECK_HEADERS([fcntl.h limits.h malloc.h memory.h netinet/in.h stdint.h stdlib.h string.h sys/time.h sys/timeb.h unistd.h]) -AC_CHECK_DECLS([_mm_malloc], [], [], [#include ]) +AC_CHECK_HEADERS([fcntl.h limits.h memory.h netinet/in.h stdint.h stdlib.h string.h sys/time.h sys/timeb.h unistd.h]) AC_HEADER_STDC # Checks for typedefs, structures, and compiler characteristics. diff --git a/src/Buffer.cpp b/src/Buffer.cpp index 8631c42..6b14561 100644 --- a/src/Buffer.cpp +++ b/src/Buffer.cpp @@ -30,13 +30,6 @@ #include #include -#include -#if HAVE_DECL__MM_MALLOC -# include -#else -# define memalign(a, b) malloc(b) -#endif - Buffer::Buffer(size_t len, const void *data) @@ -92,7 +85,10 @@ void Buffer::setLength(size_t len) void *tmp = data; /* Align to 32-byte boundary for AVX. */ - data = memalign(32, len); + const int ret = posix_memalign(&data, 32, len); + if (ret != 0) { + throw std::runtime_error("memory allocation failed: " + std::to_string(ret)); + } if (tmp != NULL) { memcpy(data, tmp, this->len); diff --git a/src/DabMod.cpp b/src/DabMod.cpp index af3adde..1625a82 100644 --- a/src/DabMod.cpp +++ b/src/DabMod.cpp @@ -64,13 +64,6 @@ # include #endif -#if HAVE_DECL__MM_MALLOC -# include -#else -# define memalign(a, b) malloc(b) -#endif - - /* UHD requires the input I and Q samples to be in the interval * [-1.0,1.0], otherwise they get truncated, which creates very * wide-spectrum spikes. Depending on the Transmission Mode, the diff --git a/src/Flowgraph.cpp b/src/Flowgraph.cpp index 6ee7b81..4870534 100644 --- a/src/Flowgraph.cpp +++ b/src/Flowgraph.cpp @@ -29,12 +29,6 @@ #include #include #include - -#if HAVE_DECL__MM_MALLOC -# include -#else -# define memalign(a, b) malloc(b) -#endif #include #include #include diff --git a/src/FormatConverter.cpp b/src/FormatConverter.cpp index 6826972..60c0545 100644 --- a/src/FormatConverter.cpp +++ b/src/FormatConverter.cpp @@ -29,7 +29,6 @@ #include "FormatConverter.h" #include "PcDebug.h" -#include #include #include #include diff --git a/src/FrequencyInterleaver.cpp b/src/FrequencyInterleaver.cpp index 29d54bb..bd5042c 100644 --- a/src/FrequencyInterleaver.cpp +++ b/src/FrequencyInterleaver.cpp @@ -24,7 +24,7 @@ #include #include -#include +#include #include typedef std::complex complexf; @@ -68,7 +68,11 @@ FrequencyInterleaver::FrequencyInterleaver(size_t mode) : break; } - d_indexes = (size_t*)memalign(16, d_carriers * sizeof(size_t)); + const int ret = posix_memalign((void**)(&d_indexes), 16, d_carriers * sizeof(size_t)); + if (ret != 0) { + throw std::runtime_error("memory allocation failed: " + std::to_string(ret)); + } + size_t* index = d_indexes; size_t perm = 0; PDEBUG("i: %4u, R: %4u\n", 0, 0); diff --git a/src/Resampler.cpp b/src/Resampler.cpp index 8069a61..2be753e 100644 --- a/src/Resampler.cpp +++ b/src/Resampler.cpp @@ -27,7 +27,7 @@ #include "Resampler.h" #include "PcDebug.h" -#include +#include #include #include #include @@ -81,7 +81,10 @@ Resampler::Resampler(size_t inputRate, size_t outputRate, size_t resolution) : myFactor = 1.0f / myFftSizeOut * outputRate / inputRate; } - myWindow = (float*)memalign(16, myFftSizeIn * sizeof(float)); + const int ret = posix_memalign((void**)(&myWindow), 16, myFftSizeIn * sizeof(float)); + if (ret != 0) { + throw std::runtime_error("memory allocation failed: " + std::to_string(ret)); + } for (size_t i = 0; i < myFftSizeIn; ++i) { myWindow[i] = (float)(0.5 * (1.0 - cos(2.0 * M_PI * i / (myFftSizeIn - 1)))); PDEBUG("Window[%zu] = %f\n", i, myWindow[i]); -- cgit v1.2.3 From fa003e1facb2ec5d45a28f27a0e293701c673ec6 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Mon, 11 Dec 2017 15:23:21 +0100 Subject: Replace legacy bzero() by memset() --- src/NullSymbol.cpp | 2 +- src/OfdmGenerator.cpp | 2 +- src/TII.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/NullSymbol.cpp b/src/NullSymbol.cpp index 015e564..4684dfe 100644 --- a/src/NullSymbol.cpp +++ b/src/NullSymbol.cpp @@ -53,7 +53,7 @@ int NullSymbol::process(Buffer* dataOut) PDEBUG("NullSymbol::process(dataOut: %p)\n", dataOut); dataOut->setLength(myNbCarriers * 2 * sizeof(float)); - bzero(dataOut->getData(), dataOut->getLength()); + memset(dataOut->getData(), 0, dataOut->getLength()); return dataOut->getLength(); } diff --git a/src/OfdmGenerator.cpp b/src/OfdmGenerator.cpp index bac3db0..a6609a3 100644 --- a/src/OfdmGenerator.cpp +++ b/src/OfdmGenerator.cpp @@ -190,7 +190,7 @@ int OfdmGenerator::process(Buffer* const dataIn, Buffer* dataOut) myFftIn[0][0] = 0; myFftIn[0][1] = 0; - bzero(&myFftIn[myZeroDst], myZeroSize * sizeof(FFT_TYPE)); + memset(&myFftIn[myZeroDst], 0, myZeroSize * sizeof(FFT_TYPE)); memcpy(&myFftIn[myPosDst], &in[myPosSrc], myPosSize * sizeof(FFT_TYPE)); memcpy(&myFftIn[myNegDst], &in[myNegSrc], diff --git a/src/TII.cpp b/src/TII.cpp index 4710ed4..a30d7f6 100644 --- a/src/TII.cpp +++ b/src/TII.cpp @@ -190,7 +190,7 @@ int TII::process(Buffer* dataIn, Buffer* dataOut) } dataOut->setLength(m_carriers * sizeof(complexf)); - bzero(dataOut->getData(), dataOut->getLength()); + memset(dataOut->getData(), 0, dataOut->getLength()); if (m_conf.enable and m_insert) { boost::mutex::scoped_lock lock(m_enabled_carriers_mutex); -- cgit v1.2.3 From b2c5c74b7954279e8cc15790e168a1d4283b4e63 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Mon, 11 Dec 2017 15:25:05 +0100 Subject: Simplify porting.{h,c} --- configure.ac | 2 +- src/porting.c | 13 ------------- src/porting.h | 20 +------------------- 3 files changed, 2 insertions(+), 33 deletions(-) (limited to 'src') diff --git a/configure.ac b/configure.ac index 47e1c81..3a55d7b 100644 --- a/configure.ac +++ b/configure.ac @@ -192,7 +192,7 @@ AS_IF([test "x$enable_native" = "xyes"], ]) AC_TYPE_SIGNAL -AC_CHECK_FUNCS([bzero floor ftime gettimeofday memset sqrt strchr strerror strtol]) +AC_CHECK_FUNCS([floor memset sqrt strchr strerror strtol]) AC_CONFIG_FILES([Makefile]) AC_OUTPUT diff --git a/src/porting.c b/src/porting.c index 79523e5..f7421b0 100644 --- a/src/porting.c +++ b/src/porting.c @@ -21,19 +21,6 @@ #include "porting.h" - -#ifndef HAVE_GETTIMEOFDAY -#include -int gettimeofday(struct timeval* t, void* timezone) -{ - struct timeb timebuffer; - ftime(&timebuffer); - t->tv_sec=timebuffer.time; - t->tv_usec=1000*timebuffer.millitm; - return 0; -} -#endif - #ifdef _WIN32 unsigned int _CRT_fmode = _O_BINARY; #endif diff --git a/src/porting.h b/src/porting.h index 2ac9b90..1799ba7 100644 --- a/src/porting.h +++ b/src/porting.h @@ -19,25 +19,12 @@ along with ODR-DabMod. If not, see . */ -#ifndef PORTING_H -#define PORTING_H +#pragma once #ifdef HAVE_CONFIG_H # include #endif -#ifndef HAVE_BZERO -# define bzero(s, n) memset(s, 0, n) -#endif - -#ifndef HAVE_GETTIMEOFDAY -#include -#ifdef __cplusplus -extern "C" -#endif -int gettimeofday(struct timeval* t, void* timezone); -#endif - #ifdef _WIN32 #include // For setting default opening mode with fopen as binary, for all files @@ -45,8 +32,3 @@ int gettimeofday(struct timeval* t, void* timezone); extern unsigned int _CRT_fmode; #endif -#ifndef HAVE_KILL -# define kill(a, b) raise(b) -#endif - -#endif // PORTING_H -- cgit v1.2.3 From fdbea05b16e3c716b5226a1f0d45cc98561500e4 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Mon, 11 Dec 2017 15:56:55 +0100 Subject: Fix all the warnings shown since previous commit --- src/Buffer.cpp | 43 ++++++++++++++++++++++--------------------- src/Buffer.h | 10 +++++----- src/ConvEncoder.cpp | 1 + src/DabMod.cpp | 5 +++-- src/FIRFilter.cpp | 3 --- src/FicSource.cpp | 1 + src/Flowgraph.cpp | 1 + src/FrameMultiplexer.cpp | 1 + src/FrequencyInterleaver.cpp | 1 + src/GainControl.cpp | 12 ++++++------ src/GainControl.h | 2 +- src/MemlessPoly.cpp | 5 +---- src/OfdmGenerator.cpp | 12 ++++++------ src/OutputUHD.cpp | 10 +++++----- src/OutputUHD.h | 2 +- src/PrbsGenerator.cpp | 7 ++++--- src/PuncturingEncoder.cpp | 1 + src/RemoteControl.cpp | 18 +++++++++--------- src/Resampler.cpp | 3 ++- src/Socket.h | 1 + src/SubchannelSource.cpp | 1 + src/TII.cpp | 6 +++--- src/TimeInterleaver.cpp | 1 + src/TimestampDecoder.cpp | 6 +++--- 24 files changed, 80 insertions(+), 73 deletions(-) (limited to 'src') diff --git a/src/Buffer.cpp b/src/Buffer.cpp index 6b14561..9df834a 100644 --- a/src/Buffer.cpp +++ b/src/Buffer.cpp @@ -28,17 +28,17 @@ #include "Buffer.h" #include "PcDebug.h" +#include #include #include - Buffer::Buffer(size_t len, const void *data) { PDEBUG("Buffer::Buffer(%zu, %p)\n", len, data); - this->len = 0; - this->size = 0; - this->data = NULL; + m_len = 0; + m_size = 0; + m_data = NULL; setData(data, len); } @@ -46,23 +46,23 @@ Buffer::Buffer(const std::vector &vec) { PDEBUG("Buffer::Buffer(vector [%zu])\n", vec.size()); - this->len = 0; - this->size = 0; - this->data = NULL; + m_len = 0; + m_size = 0; + m_data = NULL; setData(vec.data(), vec.size()); } Buffer::~Buffer() { - PDEBUG("Buffer::~Buffer() len=%zu, data=%p\n", len, data); - free(data); + PDEBUG("Buffer::~Buffer() len=%zu, data=%p\n", m_len, m_data); + free(m_data); } Buffer &Buffer::operator=(const Buffer ©) { - setData(copy.data, copy.len); + setData(copy.m_data, copy.m_len); return *this; } @@ -74,29 +74,30 @@ Buffer &Buffer::operator=(const std::vector ©) Buffer &Buffer::operator+=(const Buffer ©) { - appendData(copy.data, copy.len); + appendData(copy.m_data, copy.m_len); return *this; } void Buffer::setLength(size_t len) { - if (len > size) { - void *tmp = data; + if (len > m_size) { + void *tmp = m_data; /* Align to 32-byte boundary for AVX. */ - const int ret = posix_memalign(&data, 32, len); + const int ret = posix_memalign(&m_data, 32, len); if (ret != 0) { - throw std::runtime_error("memory allocation failed: " + std::to_string(ret)); + throw std::runtime_error("memory allocation failed: " + + std::to_string(ret)); } if (tmp != NULL) { - memcpy(data, tmp, this->len); + memcpy(m_data, tmp, m_len); free(tmp); } - size = len; + m_size = len; } - this->len = len; + m_len = len; } @@ -109,10 +110,10 @@ void Buffer::setData(const void *data, size_t len) void Buffer::appendData(const void *data, size_t len) { - size_t offset = this->len; - setLength(this->len + len); + size_t offset = m_len; + setLength(m_len + len); if (data != NULL) { - memcpy((char*)this->data + offset, data, len); + memcpy((char*)m_data + offset, data, len); } } diff --git a/src/Buffer.h b/src/Buffer.h index 8c5c768..60a7d50 100644 --- a/src/Buffer.h +++ b/src/Buffer.h @@ -43,15 +43,15 @@ class Buffer { protected: /* Current length of the data in the Buffer */ - size_t len; + size_t m_len; /* Allocated size of the Buffer */ - size_t size; + size_t m_size; /* Pointer to the data. Memory allocation is entirely * handled by setLength. */ - void *data; + void *m_data; public: using sptr = std::shared_ptr; @@ -77,7 +77,7 @@ class Buffer { void appendData(const void *data, size_t len); Buffer &operator+=(const Buffer ©); - size_t getLength() const { return len; } - void *getData() const { return data; } + size_t getLength() const { return m_len; } + void *getData() const { return m_data; } }; diff --git a/src/ConvEncoder.cpp b/src/ConvEncoder.cpp index 06b2e85..074898f 100644 --- a/src/ConvEncoder.cpp +++ b/src/ConvEncoder.cpp @@ -25,6 +25,7 @@ #include #include #include +#include const static uint8_t PARITY[] = { diff --git a/src/DabMod.cpp b/src/DabMod.cpp index 1625a82..0ac7d4f 100644 --- a/src/DabMod.cpp +++ b/src/DabMod.cpp @@ -445,7 +445,7 @@ int launch_modulator(int argc, char* argv[]) } } #if defined(HAVE_ZEROMQ) - else if (auto in = dynamic_pointer_cast(inputReader)) { + else if (dynamic_pointer_cast(inputReader)) { run_again = true; // Create a new input reader auto inputZeroMQReader = make_shared(); @@ -453,7 +453,8 @@ int launch_modulator(int argc, char* argv[]) inputReader = inputZeroMQReader; } #endif - else if (auto in = dynamic_pointer_cast(inputReader)) { + else if (dynamic_pointer_cast(inputReader)) { + // Create a new input reader auto inputTcpReader = make_shared(); inputTcpReader->Open(mod_settings.inputName); inputReader = inputTcpReader; diff --git a/src/FIRFilter.cpp b/src/FIRFilter.cpp index 4296822..1450b1e 100644 --- a/src/FIRFilter.cpp +++ b/src/FIRFilter.cpp @@ -306,9 +306,6 @@ int FIRFilter::internal_process(Buffer* const dataIn, Buffer* dataOut) void FIRFilter::set_parameter(const string& parameter, const string& value) { - stringstream ss(value); - ss.exceptions ( stringstream::failbit | stringstream::badbit ); - if (parameter == "ntaps") { throw ParameterError("Parameter 'ntaps' is read-only"); } diff --git a/src/FicSource.cpp b/src/FicSource.cpp index 92932ec..04197db 100644 --- a/src/FicSource.cpp +++ b/src/FicSource.cpp @@ -28,6 +28,7 @@ #include "PcDebug.h" #include +#include #include #include #include diff --git a/src/Flowgraph.cpp b/src/Flowgraph.cpp index 4870534..465ef41 100644 --- a/src/Flowgraph.cpp +++ b/src/Flowgraph.cpp @@ -26,6 +26,7 @@ #include "Flowgraph.h" #include "PcDebug.h" +#include #include #include #include diff --git a/src/FrameMultiplexer.cpp b/src/FrameMultiplexer.cpp index 1cfaadd..4cee0b2 100644 --- a/src/FrameMultiplexer.cpp +++ b/src/FrameMultiplexer.cpp @@ -28,6 +28,7 @@ #include "PcDebug.h" #include +#include #include #include #include diff --git a/src/FrequencyInterleaver.cpp b/src/FrequencyInterleaver.cpp index bd5042c..e76d525 100644 --- a/src/FrequencyInterleaver.cpp +++ b/src/FrequencyInterleaver.cpp @@ -24,6 +24,7 @@ #include #include +#include #include #include diff --git a/src/GainControl.cpp b/src/GainControl.cpp index 2a91b12..f44aa68 100644 --- a/src/GainControl.cpp +++ b/src/GainControl.cpp @@ -46,7 +46,7 @@ using namespace std; static float var_variance; GainControl::GainControl(size_t framesize, - GainMode mode, + GainMode gainMode, float digGain, float normalise, float varVariance) : @@ -60,10 +60,10 @@ GainControl::GainControl(size_t framesize, m_digGain(digGain), m_normalise(normalise), m_var_variance_rc(varVariance), - m_gainmode(mode), + m_gainmode(gainMode), m_mutex() { - PDEBUG("GainControl::GainControl(%zu, %zu) @ %p\n", framesize, (size_t)mode, this); + PDEBUG("GainControl::GainControl(%zu, %zu) @ %p\n", framesize, (size_t)m_gainMode, this); /* register the parameters that can be remote controlled */ RC_ADD_PARAMETER(digital, "Digital Gain"); @@ -532,10 +532,10 @@ void GainControl::set_parameter(const string& parameter, const string& value) } } else { - stringstream ss; - ss << "Parameter '" << parameter + stringstream ss_err; + ss_err << "Parameter '" << parameter << "' is not exported by controllable " << get_rc_name(); - throw ParameterError(ss.str()); + throw ParameterError(ss_err.str()); } } diff --git a/src/GainControl.h b/src/GainControl.h index 44c9fa9..e9eaa8c 100644 --- a/src/GainControl.h +++ b/src/GainControl.h @@ -51,7 +51,7 @@ class GainControl : public PipelinedModCodec, public RemoteControllable { public: GainControl(size_t framesize, - GainMode mode, + GainMode gainMode, float digGain, float normalise, float varVariance); diff --git a/src/MemlessPoly.cpp b/src/MemlessPoly.cpp index f223d34..ae097c9 100644 --- a/src/MemlessPoly.cpp +++ b/src/MemlessPoly.cpp @@ -38,7 +38,7 @@ #include #include - +#include #include #include #include @@ -370,9 +370,6 @@ int MemlessPoly::internal_process(Buffer* const dataIn, Buffer* dataOut) void MemlessPoly::set_parameter(const string& parameter, const string& value) { - stringstream ss(value); - ss.exceptions ( stringstream::failbit | stringstream::badbit ); - if (parameter == "ncoefs") { throw ParameterError("Parameter 'ncoefs' is read-only"); } diff --git a/src/OfdmGenerator.cpp b/src/OfdmGenerator.cpp index a6609a3..915d568 100644 --- a/src/OfdmGenerator.cpp +++ b/src/OfdmGenerator.cpp @@ -230,9 +230,9 @@ int OfdmGenerator::process(Buffer* const dataIn, Buffer* dataOut) */ double sum_iq = 0; double sum_delta = 0; - for (size_t i = 0; i < mySpacing; i++) { - sum_iq += (double)std::norm(before_cfr[i]); - sum_delta += (double)std::norm(symbol[i] - before_cfr[i]); + for (size_t j = 0; j < mySpacing; j++) { + sum_iq += (double)std::norm(before_cfr[j]); + sum_delta += (double)std::norm(symbol[j] - before_cfr[j]); } // Clamp to 90dB, otherwise the MER average is going to be inf @@ -362,10 +362,10 @@ void OfdmGenerator::set_parameter(const std::string& parameter, throw ParameterError("Parameter 'clip_stats' is read-only"); } else { - stringstream ss; - ss << "Parameter '" << parameter + stringstream ss_err; + ss_err << "Parameter '" << parameter << "' is not exported by controllable " << get_rc_name(); - throw ParameterError(ss.str()); + throw ParameterError(ss_err.str()); } } diff --git a/src/OutputUHD.cpp b/src/OutputUHD.cpp index e2616a6..b533075 100644 --- a/src/OutputUHD.cpp +++ b/src/OutputUHD.cpp @@ -472,7 +472,7 @@ int OutputUHD::process(Buffer* dataIn) myUsrp, myConf.dpdFeedbackServerPort, myConf.sampleRate); } - size_t num_frames = frames.push_wait_if_full(frame, + size_t num_frames = m_frames.push_wait_if_full(frame, FRAMES_MAX_SIZE); etiLog.log(trace, "UHD,push %zu", num_frames); } @@ -686,7 +686,7 @@ void OutputUHD::workerthread() struct UHDWorkerFrameData frame; etiLog.log(trace, "UHD,wait"); - frames.wait_and_pop(frame, pop_prebuffering); + m_frames.wait_and_pop(frame, pop_prebuffering); etiLog.log(trace, "UHD,pop"); handle_frame(&frame); @@ -989,10 +989,10 @@ void OutputUHD::set_parameter(const string& parameter, const string& value) throw ParameterError("Parameter " + parameter + " is read-only."); } else { - stringstream ss; - ss << "Parameter '" << parameter + stringstream ss_err; + ss_err << "Parameter '" << parameter << "' is not exported by controllable " << get_rc_name(); - throw ParameterError(ss.str()); + throw ParameterError(ss_err.str()); } } diff --git a/src/OutputUHD.h b/src/OutputUHD.h index 0630480..9213183 100644 --- a/src/OutputUHD.h +++ b/src/OutputUHD.h @@ -211,7 +211,7 @@ class OutputUHD: public ModOutput, public RemoteControllable { bool sync_and_ts_valid = false; - ThreadsafeQueue frames; + ThreadsafeQueue m_frames; // Returns true if we want to verify loss of refclk bool refclk_loss_needs_check(void) const; diff --git a/src/PrbsGenerator.cpp b/src/PrbsGenerator.cpp index 69d6af4..b159bd3 100644 --- a/src/PrbsGenerator.cpp +++ b/src/PrbsGenerator.cpp @@ -22,9 +22,10 @@ #include "PrbsGenerator.h" #include "PcDebug.h" +#include +#include #include #include -#include PrbsGenerator::PrbsGenerator(size_t framesize, uint32_t polynomial, @@ -178,8 +179,8 @@ int PrbsGenerator::process( throw std::runtime_error("PrbsGenerator::process " "input size is not equal to output size!\n"); } - for (size_t i = 0; i < dataOut[0]->getLength(); ++i) { - out[i] ^= in[i]; + for (size_t j = 0; j < dataOut[0]->getLength(); ++j) { + out[j] ^= in[j]; } } diff --git a/src/PuncturingEncoder.cpp b/src/PuncturingEncoder.cpp index 9bd9004..de4319b 100644 --- a/src/PuncturingEncoder.cpp +++ b/src/PuncturingEncoder.cpp @@ -27,6 +27,7 @@ #include "PuncturingEncoder.h" #include "PcDebug.h" +#include #include #include #include diff --git a/src/RemoteControl.cpp b/src/RemoteControl.cpp index ceae942..a050278 100644 --- a/src/RemoteControl.cpp +++ b/src/RemoteControl.cpp @@ -422,11 +422,11 @@ void RemoteControllerZmq::process() std::string msg_s = ss.str(); - zmq::message_t msg(ss.str().size()); - memcpy ((void*) msg.data(), msg_s.data(), msg_s.size()); + zmq::message_t zmsg(ss.str().size()); + memcpy ((void*) zmsg.data(), msg_s.data(), msg_s.size()); int flag = (--cohort_size > 0) ? ZMQ_SNDMORE : 0; - repSocket.send(msg, flag); + repSocket.send(zmsg, flag); } } else if (msg.size() == 2 && command == "show") { @@ -437,11 +437,11 @@ void RemoteControllerZmq::process() for (auto ¶m_val : r) { std::stringstream ss; ss << param_val[0] << ": " << param_val[1] << endl; - zmq::message_t msg(ss.str().size()); - memcpy(msg.data(), ss.str().data(), ss.str().size()); + zmq::message_t zmsg(ss.str().size()); + memcpy(zmsg.data(), ss.str().data(), ss.str().size()); int flag = (--r_size > 0) ? ZMQ_SNDMORE : 0; - repSocket.send(msg, flag); + repSocket.send(zmsg, flag); } } catch (ParameterError &e) { @@ -454,9 +454,9 @@ void RemoteControllerZmq::process() try { std::string value = rcs.get_param(module, parameter); - zmq::message_t msg(value.size()); - memcpy ((void*) msg.data(), value.data(), value.size()); - repSocket.send(msg, 0); + zmq::message_t zmsg(value.size()); + memcpy ((void*) zmsg.data(), value.data(), value.size()); + repSocket.send(zmsg, 0); } catch (ParameterError &err) { send_fail_reply(repSocket, err.what()); diff --git a/src/Resampler.cpp b/src/Resampler.cpp index 2be753e..42951c5 100644 --- a/src/Resampler.cpp +++ b/src/Resampler.cpp @@ -27,10 +27,11 @@ #include "Resampler.h" #include "PcDebug.h" +#include +#include #include #include #include -#include #include #define FFT_REAL(x) x[0] diff --git a/src/Socket.h b/src/Socket.h index f6a023d..39554ca 100644 --- a/src/Socket.h +++ b/src/Socket.h @@ -37,6 +37,7 @@ DESCRIPTION: #include #include #include +#include #include #include #include diff --git a/src/SubchannelSource.cpp b/src/SubchannelSource.cpp index 2a8dc37..b4d6750 100644 --- a/src/SubchannelSource.cpp +++ b/src/SubchannelSource.cpp @@ -28,6 +28,7 @@ #include "PcDebug.h" #include "Log.h" +#include #include #include #include diff --git a/src/TII.cpp b/src/TII.cpp index a30d7f6..af64c9f 100644 --- a/src/TII.cpp +++ b/src/TII.cpp @@ -350,10 +350,10 @@ void TII::set_parameter(const std::string& parameter, const std::string& value) ss >> m_conf.old_variant; } else { - stringstream ss; - ss << "Parameter '" << parameter << + stringstream ss_err; + ss_err << "Parameter '" << parameter << "' is not exported by controllable " << get_rc_name(); - throw ParameterError(ss.str()); + throw ParameterError(ss_err.str()); } } diff --git a/src/TimeInterleaver.cpp b/src/TimeInterleaver.cpp index 3bf6339..7e19af8 100644 --- a/src/TimeInterleaver.cpp +++ b/src/TimeInterleaver.cpp @@ -23,6 +23,7 @@ #include "PcDebug.h" #include +#include #include diff --git a/src/TimestampDecoder.cpp b/src/TimestampDecoder.cpp index ddd3fb7..26deb60 100644 --- a/src/TimestampDecoder.cpp +++ b/src/TimestampDecoder.cpp @@ -228,10 +228,10 @@ void TimestampDecoder::set_parameter( throw ParameterError("timestamp is read-only"); } else { - stringstream ss; - ss << "Parameter '" << parameter + stringstream ss_err; + ss_err << "Parameter '" << parameter << "' is not exported by controllable " << get_rc_name(); - throw ParameterError(ss.str()); + throw ParameterError(ss_err.str()); } } -- cgit v1.2.3 From f041360ac17bc032c7e5a4553372893e42ba68c6 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Fri, 15 Dec 2017 10:07:03 +0100 Subject: Check for prctl portability --- configure.ac | 11 +++++++++++ src/Utils.cpp | 6 +++++- src/Utils.h | 1 + 3 files changed, 17 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/configure.ac b/configure.ac index 9bb0ebc..261d444 100644 --- a/configure.ac +++ b/configure.ac @@ -173,6 +173,17 @@ AC_COMPILE_IFELSE( [AC_MSG_RESULT([yes])], [AC_MSG_RESULT([no]) AC_DEFINE([M_PIl], [M_PI], [Replacing define])]) AC_LANG_POP([C++]) +# Linux has prctl to set thread names +AC_MSG_CHECKING(for prctl and PR_SET_NAME) +AC_COMPILE_IFELSE([ AC_LANG_PROGRAM([[ + #include + void set_thread_name() { + prctl(PR_SET_NAME,"test",0,0,0); + } + ]])], + [ AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_PRCTL, 1, [Define this symbol if you have prctl and PR_SET_NAME]) ], + [ AC_MSG_RESULT(no) ]) # Check for march AS_IF([test "x$enable_native" = "xyes"], diff --git a/src/Utils.cpp b/src/Utils.cpp index cd116c7..f423dc1 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -27,7 +27,9 @@ #include "Utils.h" #include "GainControl.h" -#include +#if defined(HAVE_PRCTL) +# include +#endif #include static void printHeader() @@ -160,7 +162,9 @@ int set_realtime_prio(int prio) void set_thread_name(const char *name) { +#if defined(HAVE_PRCTL) prctl(PR_SET_NAME,name,0,0,0); +#endif } double parseChannel(const std::string& chan) diff --git a/src/Utils.h b/src/Utils.h index 8da3a1b..6a36baf 100644 --- a/src/Utils.h +++ b/src/Utils.h @@ -62,6 +62,7 @@ inline long timespecdiff_us(struct timespec& oldTime, struct timespec& time) // Set SCHED_RR with priority prio (0=lowest) int set_realtime_prio(int prio); +// Set the name of the thread void set_thread_name(const char *name); // Convert a channel like 10A to a frequency -- cgit v1.2.3 From 0e15b3df559a17c352c5135a786caac2d7c2111f Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Mon, 18 Dec 2017 08:45:53 +0100 Subject: Remove unused variable myCurrentFrame --- src/EtiReader.cpp | 1 - src/EtiReader.h | 1 - 2 files changed, 2 deletions(-) (limited to 'src') diff --git a/src/EtiReader.cpp b/src/EtiReader.cpp index 0b27126..5f2be50 100644 --- a/src/EtiReader.cpp +++ b/src/EtiReader.cpp @@ -58,7 +58,6 @@ EtiReader::EtiReader( unsigned tist_delay_stages) : state(EtiReaderStateSync), myTimestampDecoder(tist_offset_s, tist_delay_stages), - myCurrentFrame(0), eti_fc_valid(false) { rcs.enrol(&myTimestampDecoder); diff --git a/src/EtiReader.h b/src/EtiReader.h index 892afb4..f3a9764 100644 --- a/src/EtiReader.h +++ b/src/EtiReader.h @@ -107,7 +107,6 @@ private: eti_TIST eti_tist; TimestampDecoder myTimestampDecoder; - size_t myCurrentFrame; bool eti_fc_valid; std::vector > mySources; -- cgit v1.2.3 From 5ef2067ee1750cf32f12c05ee397106602f49390 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Mon, 18 Dec 2017 08:50:31 +0100 Subject: Remove unused variable d_polarity_mask --- src/PrbsGenerator.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'src') diff --git a/src/PrbsGenerator.h b/src/PrbsGenerator.h index b86bc70..9390179 100644 --- a/src/PrbsGenerator.h +++ b/src/PrbsGenerator.h @@ -53,8 +53,6 @@ private: unsigned char d_weight[256]; // PRBS polynomial generator uint32_t d_polynomial; - // PRBS generator polarity mask - unsigned char d_polarity_mask; // PRBS accumulator uint32_t d_accum; uint32_t d_accum_init; -- cgit v1.2.3 From 0cceefe1774263690dce352cf41c3fff3bf85135 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Thu, 21 Dec 2017 04:24:24 +0100 Subject: Simplify GuardIntervalInserter slightly --- src/GuardIntervalInserter.cpp | 26 +++++--------------------- src/GuardIntervalInserter.h | 18 ++++++++---------- 2 files changed, 13 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/GuardIntervalInserter.cpp b/src/GuardIntervalInserter.cpp index 80ba900..a2542f7 100644 --- a/src/GuardIntervalInserter.cpp +++ b/src/GuardIntervalInserter.cpp @@ -21,16 +21,12 @@ #include "GuardIntervalInserter.h" #include "PcDebug.h" - - -#include #include #include #include typedef std::complex complexf; - GuardIntervalInserter::GuardIntervalInserter(size_t nbSymbols, size_t spacing, size_t nullSize, @@ -43,19 +39,6 @@ GuardIntervalInserter::GuardIntervalInserter(size_t nbSymbols, { PDEBUG("GuardIntervalInserter::GuardIntervalInserter(%zu, %zu, %zu, %zu)" " @ %p\n", nbSymbols, spacing, nullSize, symSize, this); - - if (d_nullSize) { - myHasNull = true; - } else { - myHasNull = false; - } -} - - -GuardIntervalInserter::~GuardIntervalInserter() -{ - PDEBUG("GuardIntervalInserter::~GuardIntervalInserter() @ %p\n", this); - } @@ -71,7 +54,7 @@ int GuardIntervalInserter::process(Buffer* const dataIn, Buffer* dataOut) complexf* out = reinterpret_cast(dataOut->getData()); size_t sizeIn = dataIn->getLength() / sizeof(complexf); - if (sizeIn != (d_nbSymbols + (myHasNull ? 1 : 0)) * d_spacing) { + if (sizeIn != (d_nbSymbols + (d_nullSize ? 1 : 0)) * d_spacing) { PDEBUG("Nb symbols: %zu\n", d_nbSymbols); PDEBUG("Spacing: %zu\n", d_spacing); PDEBUG("Null size: %zu\n", d_nullSize); @@ -81,8 +64,8 @@ int GuardIntervalInserter::process(Buffer* const dataIn, Buffer* dataOut) "GuardIntervalInserter::process input size not valid!"); } - // Null symbol - if (myHasNull) { + // Handle Null symbol separately because it is longer + if (d_nullSize) { // end - (nullSize - spacing) = 2 * spacing - nullSize memcpy(out, &in[2 * d_spacing - d_nullSize], (d_nullSize - d_spacing) * sizeof(complexf)); @@ -90,9 +73,10 @@ int GuardIntervalInserter::process(Buffer* const dataIn, Buffer* dataOut) in += d_spacing; out += d_nullSize; } + // Data symbols for (size_t i = 0; i < d_nbSymbols; ++i) { - // end - (nullSize - spacing) = 2 * spacing - nullSize + // end - (symSize - spacing) = 2 * spacing - symSize memcpy(out, &in[2 * d_spacing - d_symSize], (d_symSize - d_spacing) * sizeof(complexf)); memcpy(&out[d_symSize - d_spacing], in, d_spacing * sizeof(complexf)); diff --git a/src/GuardIntervalInserter.h b/src/GuardIntervalInserter.h index 70a8fcd..e6b3b64 100644 --- a/src/GuardIntervalInserter.h +++ b/src/GuardIntervalInserter.h @@ -25,20 +25,19 @@ # include #endif - #include "ModPlugin.h" +#include -#include - - +/* The GuardIntervalInserter prepends the cyclic prefix to all + * symbols in the transmission frame. */ class GuardIntervalInserter : public ModCodec { public: - GuardIntervalInserter(size_t nbSymbols, size_t spacing, size_t nullSize, size_t symSize); - virtual ~GuardIntervalInserter(); - GuardIntervalInserter(const GuardIntervalInserter&); - GuardIntervalInserter& operator=(const GuardIntervalInserter&); - + GuardIntervalInserter( + size_t nbSymbols, + size_t spacing, + size_t nullSize, + size_t symSize); int process(Buffer* const dataIn, Buffer* dataOut); const char* name() { return "GuardIntervalInserter"; } @@ -48,6 +47,5 @@ protected: size_t d_spacing; size_t d_nullSize; size_t d_symSize; - bool myHasNull; }; -- cgit v1.2.3 From 7da0cf21faf31888f8412a61ae4a12abe01a827f Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Thu, 21 Dec 2017 07:59:30 +0100 Subject: Make Buffer movable --- src/Buffer.cpp | 51 +++++++++++++++++++++++++++++++++++++++++---------- src/Buffer.h | 42 ++++++++++++++++++++++-------------------- 2 files changed, 63 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/Buffer.cpp b/src/Buffer.cpp index 9df834a..3f6f296 100644 --- a/src/Buffer.cpp +++ b/src/Buffer.cpp @@ -3,7 +3,7 @@ Her Majesty the Queen in Right of Canada (Communications Research Center Canada) - Copyright (C) 2016 + Copyright (C) 2017 Matthias P. Braendli, matthias.braendli@mpb.li http://opendigitalradio.org @@ -37,18 +37,34 @@ Buffer::Buffer(size_t len, const void *data) PDEBUG("Buffer::Buffer(%zu, %p)\n", len, data); m_len = 0; - m_size = 0; - m_data = NULL; + m_capacity = 0; + m_data = nullptr; setData(data, len); } +Buffer::Buffer(const Buffer& other) +{ + setData(other.m_data, other.m_len); +} + +Buffer::Buffer(Buffer&& other) +{ + m_len = other.m_len; + m_capacity = other.m_capacity; + m_data = other.m_data; + + other.m_len = 0; + other.m_capacity = 0; + other.m_data = nullptr; +} + Buffer::Buffer(const std::vector &vec) { PDEBUG("Buffer::Buffer(vector [%zu])\n", vec.size()); m_len = 0; - m_size = 0; - m_data = NULL; + m_capacity = 0; + m_data = nullptr; setData(vec.data(), vec.size()); } @@ -56,7 +72,9 @@ Buffer::Buffer(const std::vector &vec) Buffer::~Buffer() { PDEBUG("Buffer::~Buffer() len=%zu, data=%p\n", m_len, m_data); - free(m_data); + if (m_data) { + free(m_data); + } } @@ -66,6 +84,19 @@ Buffer &Buffer::operator=(const Buffer ©) return *this; } +Buffer& Buffer::operator=(Buffer&& other) +{ + m_len = other.m_len; + m_capacity = other.m_capacity; + m_data = other.m_data; + + other.m_len = 0; + other.m_capacity = 0; + other.m_data = nullptr; + + return *this; +} + Buffer &Buffer::operator=(const std::vector ©) { setData(copy.data(), copy.size()); @@ -81,7 +112,7 @@ Buffer &Buffer::operator+=(const Buffer ©) void Buffer::setLength(size_t len) { - if (len > m_size) { + if (len > m_capacity) { void *tmp = m_data; /* Align to 32-byte boundary for AVX. */ @@ -91,11 +122,11 @@ void Buffer::setLength(size_t len) std::to_string(ret)); } - if (tmp != NULL) { + if (tmp != nullptr) { memcpy(m_data, tmp, m_len); free(tmp); } - m_size = len; + m_capacity = len; } m_len = len; } @@ -112,7 +143,7 @@ void Buffer::appendData(const void *data, size_t len) { size_t offset = m_len; setLength(m_len + len); - if (data != NULL) { + if (data != nullptr) { memcpy((char*)m_data + offset, data, len); } } diff --git a/src/Buffer.h b/src/Buffer.h index 60a7d50..88bd442 100644 --- a/src/Buffer.h +++ b/src/Buffer.h @@ -3,7 +3,7 @@ Her Majesty the Queen in Right of Canada (Communications Research Center Canada) - Copyright (C) 2016 + Copyright (C) 2017 Matthias P. Braendli, matthias.braendli@mpb.li http://opendigitalradio.org @@ -41,24 +41,13 @@ * The allocation/freeing of the data is handled internally. */ class Buffer { - protected: - /* Current length of the data in the Buffer */ - size_t m_len; - - /* Allocated size of the Buffer */ - size_t m_size; - - /* Pointer to the data. Memory allocation is entirely - * handled by setLength. - */ - void *m_data; - public: using sptr = std::shared_ptr; - Buffer(const Buffer& copy) = default; - Buffer(const std::vector &vec); - Buffer(size_t len = 0, const void *data = NULL); + Buffer(size_t len = 0, const void *data = nullptr); + Buffer(const Buffer& copy); + Buffer(Buffer&& other); + Buffer(const std::vector& vec); ~Buffer(); /* Resize the buffer, reallocate memory if needed */ @@ -68,16 +57,29 @@ class Buffer { * Reallocates memory if needed. */ void setData(const void *data, size_t len); - Buffer &operator=(const Buffer ©); - Buffer &operator=(const std::vector ©); + Buffer& operator=(const Buffer& copy); + Buffer& operator=(Buffer&& other); + Buffer& operator=(const std::vector& copy); /* Concatenate the current data with the new data given. * Reallocates memory if needed. */ void appendData(const void *data, size_t len); - Buffer &operator+=(const Buffer ©); + Buffer& operator+=(const Buffer& copy); size_t getLength() const { return m_len; } - void *getData() const { return m_data; } + void* getData() const { return m_data; } + + private: + /* Current length of the data in the Buffer */ + size_t m_len; + + /* Allocated size of the Buffer */ + size_t m_capacity; + + /* Pointer to the data. Memory allocation is entirely + * handled by setLength. */ + void *m_data; + }; -- cgit v1.2.3 From 5e45beb6a385a6830aa1e3efa1093d7d0eb88ab8 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Thu, 21 Dec 2017 08:00:10 +0100 Subject: Improve Buffer initialisation in EtiReader --- src/EtiReader.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/EtiReader.cpp b/src/EtiReader.cpp index 5f2be50..d84ed1f 100644 --- a/src/EtiReader.cpp +++ b/src/EtiReader.cpp @@ -207,8 +207,8 @@ int EtiReader::loadEtiData(const Buffer& dataIn) if (input_size < 128) { return dataIn.getLength() - input_size; } - PDEBUG("Writting 128 bytes of FIC channel data\n"); - Buffer fic = Buffer(128, in); + PDEBUG("Writing 128 bytes of FIC channel data\n"); + Buffer fic(128, in); myFicSource->loadFicData(fic); input_size -= 128; framesize -= 128; @@ -217,8 +217,8 @@ int EtiReader::loadEtiData(const Buffer& dataIn) if (input_size < 96) { return dataIn.getLength() - input_size; } - PDEBUG("Writting 96 bytes of FIC channel data\n"); - Buffer fic = Buffer(96, in); + PDEBUG("Writing 96 bytes of FIC channel data\n"); + Buffer fic(96, in); myFicSource->loadFicData(fic); input_size -= 96; framesize -= 96; @@ -230,7 +230,7 @@ int EtiReader::loadEtiData(const Buffer& dataIn) for (size_t i = 0; i < eti_stc.size(); ++i) { unsigned size = mySources[i]->framesize(); PDEBUG("Writting %i bytes of subchannel data\n", size); - Buffer subch = Buffer(size, in); + Buffer subch(size, in); mySources[i]->loadSubchannelData(subch); input_size -= size; framesize -= size; -- cgit v1.2.3 From 3255ff66dab0870c54c8f5c62b1c461b38abfe20 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Fri, 22 Dec 2017 09:07:13 +0100 Subject: Check for invalid file output format --- src/DabMod.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/DabMod.cpp b/src/DabMod.cpp index 0ac7d4f..dfefb53 100644 --- a/src/DabMod.cpp +++ b/src/DabMod.cpp @@ -199,6 +199,10 @@ static shared_ptr prepare_output( output = make_shared(s.outputName); } + else { + throw runtime_error("File output format " + s.fileOutputFormat + + " not known"); + } } #if defined(HAVE_OUTPUT_UHD) else if (s.useUHDOutput) { -- cgit v1.2.3 From 45b180cd1a0ccbd12b5fb1baf82a9430e4567d2b Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Fri, 22 Dec 2017 09:08:42 +0100 Subject: Fix some PDEBUG calls --- src/DabModulator.cpp | 3 +-- src/FIRFilter.cpp | 2 +- src/GainControl.cpp | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/DabModulator.cpp b/src/DabModulator.cpp index 0914469..be140d3 100644 --- a/src/DabModulator.cpp +++ b/src/DabModulator.cpp @@ -62,8 +62,7 @@ DabModulator::DabModulator(EtiSource& etiSource, myEtiSource(etiSource), myFlowgraph() { - PDEBUG("DabModulator::DabModulator(%u, %u, %u, %zu) @ %p\n", - outputRate, clockRate, dabMode, (size_t)gainMode, this); + PDEBUG("DabModulator::DabModulator() @ %p\n", this); if (m_settings.dabMode == 0) { setMode(2); diff --git a/src/FIRFilter.cpp b/src/FIRFilter.cpp index 1450b1e..bc2314a 100644 --- a/src/FIRFilter.cpp +++ b/src/FIRFilter.cpp @@ -119,7 +119,7 @@ void FIRFilter::load_filter_taps(const std::string &tapsFile) int n; for (n = 0; n < n_taps; n++) { taps_fstream >> filter_taps[n]; - PDEBUG("FIRFilter: tap: %f\n", filter_taps[n] ); + PDEBUG("FIRFilter: tap: %f\n", (double)filter_taps[n] ); if (taps_fstream.eof()) { fprintf(stderr, "FIRFilter: file %s should contains %d taps, but EOF reached "\ "after %d taps !\n", tapsFile.c_str(), n_taps, n); diff --git a/src/GainControl.cpp b/src/GainControl.cpp index f44aa68..0411482 100644 --- a/src/GainControl.cpp +++ b/src/GainControl.cpp @@ -63,7 +63,7 @@ GainControl::GainControl(size_t framesize, m_gainmode(gainMode), m_mutex() { - PDEBUG("GainControl::GainControl(%zu, %zu) @ %p\n", framesize, (size_t)m_gainMode, this); + PDEBUG("GainControl::GainControl(%zu, %zu) @ %p\n", framesize, (size_t)m_gainmode, this); /* register the parameters that can be remote controlled */ RC_ADD_PARAMETER(digital, "Digital Gain"); -- cgit v1.2.3 From ce490c8c25bdbb1fc40fc43d8631a807f6effa6a Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Fri, 22 Dec 2017 09:10:17 +0100 Subject: Add OFDM windowing support to GuardIntervalInserter --- src/DabModulator.cpp | 1 + src/GuardIntervalInserter.cpp | 232 ++++++++++++++++++++++++++++++++++++++---- src/GuardIntervalInserter.h | 60 +++++++---- 3 files changed, 257 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/DabModulator.cpp b/src/DabModulator.cpp index be140d3..cded280 100644 --- a/src/DabModulator.cpp +++ b/src/DabModulator.cpp @@ -202,6 +202,7 @@ int DabModulator::process(Buffer* dataOut) auto cifGuard = make_shared( myNbSymbols, mySpacing, myNullSize, mySymSize); + rcs.enrol(cifGuard.get()); shared_ptr cifFilter; if (not m_settings.filterTapsFilename.empty()) { diff --git a/src/GuardIntervalInserter.cpp b/src/GuardIntervalInserter.cpp index a2542f7..1381a3c 100644 --- a/src/GuardIntervalInserter.cpp +++ b/src/GuardIntervalInserter.cpp @@ -1,6 +1,11 @@ /* Copyright (C) 2005, 2206, 2007, 2008, 2009, 2010, 2011 Her Majesty the Queen in Right of Canada (Communications Research Center Canada) + + Copyright (C) 2017 + Matthias P. Braendli, matthias.braendli@mpb.li + + http://opendigitalradio.org */ /* This file is part of ODR-DabMod. @@ -24,37 +29,98 @@ #include #include #include +#include typedef std::complex complexf; -GuardIntervalInserter::GuardIntervalInserter(size_t nbSymbols, +GuardIntervalInserter::GuardIntervalInserter( + size_t nbSymbols, size_t spacing, size_t nullSize, - size_t symSize) : + size_t symSize, + size_t windowOverlap) : ModCodec(), + RemoteControllable("guardinterval"), d_nbSymbols(nbSymbols), d_spacing(spacing), d_nullSize(nullSize), - d_symSize(symSize) + d_symSize(symSize), + d_windowOverlap(0) { - PDEBUG("GuardIntervalInserter::GuardIntervalInserter(%zu, %zu, %zu, %zu)" - " @ %p\n", nbSymbols, spacing, nullSize, symSize, this); + if (d_nullSize == 0) { + throw std::logic_error("NULL symbol must be present"); + } + + RC_ADD_PARAMETER(windowlen, "Window length for OFDM windowng [0 to disable]"); + + /* We use a raised-cosine window for the OFDM windowing. + * Each symbol is extended on both sides by d_windowOverlap samples. + * + * + * Sym n |####################| + * Sym n+1 |####################| + * + * We now extend the symbols by d_windowOverlap (one dash) + * + * Sym n extended -|####################|- + * Sym n+1 extended -|####################|- + * + * The windows are raised-cosine: + * ____________________ + * Sym n window / \ + * ... ____/ \___________ ... + * + * Sym n+1 window ____________________ + * / \ + * ... ________________/ \__ ... + * + * The window length is 2*d_windowOverlap. + */ + + update_window(windowOverlap); + + PDEBUG("GuardIntervalInserter::GuardIntervalInserter" + "(%zu, %zu, %zu, %zu, %zu) @ %p\n", + nbSymbols, spacing, nullSize, symSize, windowOverlap, this); } +void GuardIntervalInserter::update_window(size_t new_window_overlap) +{ + std::lock_guard lock(d_windowMutex); + + d_windowOverlap = new_window_overlap; + + // d_window only contains the rising window edge. + d_window.resize(2*d_windowOverlap); + for (size_t i = 0; i < 2*d_windowOverlap; i++) { + d_window[i] = (float)(0.5 * (1.0 - cos(M_PI * i / (2*d_windowOverlap - 1)))); + } +} + +#pragma GCC optimize ("O0") int GuardIntervalInserter::process(Buffer* const dataIn, Buffer* dataOut) { PDEBUG("GuardIntervalInserter::process(dataIn: %p, dataOut: %p)\n", dataIn, dataOut); - dataOut->setLength((d_nullSize + (d_nbSymbols * d_symSize)) - * sizeof(complexf)); + std::lock_guard lock(d_windowMutex); + + // Every symbol overlaps over a length of d_windowOverlap with + // the previous symbol, and with the next symbol. First symbol + // receives no prefix window, because we don't remember the + // last symbol from the previous TF (yet). Last symbol also + // receives no suffix window, for the same reason. + // Overall output buffer length must stay independent of the windowing. + dataOut->setLength((d_nullSize + (d_nbSymbols * d_symSize)) * sizeof(complexf)); const complexf* in = reinterpret_cast(dataIn->getData()); complexf* out = reinterpret_cast(dataOut->getData()); size_t sizeIn = dataIn->getLength() / sizeof(complexf); - if (sizeIn != (d_nbSymbols + (d_nullSize ? 1 : 0)) * d_spacing) { + const size_t num_symbols = d_nbSymbols + 1; + if (sizeIn != num_symbols * d_spacing) + { PDEBUG("Nb symbols: %zu\n", d_nbSymbols); PDEBUG("Spacing: %zu\n", d_spacing); PDEBUG("Null size: %zu\n", d_nullSize); @@ -64,25 +130,153 @@ int GuardIntervalInserter::process(Buffer* const dataIn, Buffer* dataOut) "GuardIntervalInserter::process input size not valid!"); } - // Handle Null symbol separately because it is longer - if (d_nullSize) { + // TODO remember the end of the last TF so that we can do some + // windowing too. + + if (d_windowOverlap) { + { + // Handle Null symbol separately because it is longer + const size_t prefixlength = d_nullSize - d_spacing; + + // end = spacing + memcpy(out, &in[d_spacing - prefixlength], + prefixlength * sizeof(complexf)); + + memcpy(&out[prefixlength], in, (d_spacing - d_windowOverlap) * sizeof(complexf)); + + // The remaining part of the symbol must have half of the window applied, + // sloping down from 1 to 0.5 + for (size_t i = 0; i < d_windowOverlap; i++) { + const size_t out_ix = prefixlength + d_spacing - d_windowOverlap + i; + const size_t in_ix = d_spacing - d_windowOverlap + i; + out[out_ix] = in[in_ix] * d_window[2*d_windowOverlap - (i+1)]; + } + + // Suffix is taken from the beginning of the symbol, and sees the other + // half of the window applied. + for (size_t i = 0; i < d_windowOverlap; i++) { + const size_t out_ix = prefixlength + d_spacing + i; + out[out_ix] = in[i] * d_window[d_windowOverlap - (i+1)]; + } + + in += d_spacing; + out += d_nullSize; + // out is now pointing to the proper end of symbol. There are + // d_windowOverlap samples ahead that were already written. + } + + // Data symbols + for (size_t sym_ix = 0; sym_ix < d_nbSymbols; sym_ix++) { + // end = spacing + const size_t prefix_start_ix = 2*d_spacing - d_symSize - d_windowOverlap; + + // From out[-d_windowOverlap] to out[d_windowOverlap], we need to + // apply the window from 0 to 0.5, with our additional + // prefix, and add it to existing data. + for (size_t i = 0; i < 2*d_windowOverlap; i++) { + out[-i] += in[prefix_start_ix + i] * d_window[i]; + } + + const size_t remaining_prefix_length = d_symSize - d_spacing - d_windowOverlap; + + // After out[d_windowOverlap], no need to accumulate, we can copy. + memcpy( &out[d_windowOverlap], + &in[prefix_start_ix + 2*d_windowOverlap], + remaining_prefix_length * sizeof(complexf)); + + const size_t prefixlength = d_symSize - d_spacing + d_windowOverlap; + + const bool last_symbol = (sym_ix + 1 < d_nbSymbols); + if (last_symbol) { + // No windowing at all at end + memcpy(&out[prefixlength], in, d_spacing * sizeof(complexf)); + } + else { + // Copy the middle part of the symbol, d_windowOverlap samples + // short of the end. + memcpy( &out[prefixlength], + in, + (d_spacing - d_windowOverlap) * sizeof(complexf)); + + const size_t out_start = prefixlength + d_spacing - d_windowOverlap; + const size_t in_start = d_spacing - d_windowOverlap; + + // Apply window from 1 to 0.5 for the end of the symbol + for (size_t i = 0; i < d_windowOverlap; i++) { + out[out_start + i] = + in[in_start + i] * d_window[2*d_windowOverlap - (i+1)]; + } + + const size_t out_start_suffix = prefixlength + d_spacing; + + // Cyclic suffix, with window from 0.5 to 0 + for (size_t i = 0; i < d_windowOverlap; i++) { + out[out_start_suffix + i] = + in[i] * d_window[d_windowOverlap - (i+1)]; + } + } + + in += d_spacing; + out += d_symSize; + // out is now pointing to the proper end of symbol. There are + // d_windowOverlap samples ahead that were already written. + } + } + else { + // Handle Null symbol separately because it is longer // end - (nullSize - spacing) = 2 * spacing - nullSize memcpy(out, &in[2 * d_spacing - d_nullSize], (d_nullSize - d_spacing) * sizeof(complexf)); memcpy(&out[d_nullSize - d_spacing], in, d_spacing * sizeof(complexf)); in += d_spacing; out += d_nullSize; - } - // Data symbols - for (size_t i = 0; i < d_nbSymbols; ++i) { - // end - (symSize - spacing) = 2 * spacing - symSize - memcpy(out, &in[2 * d_spacing - d_symSize], - (d_symSize - d_spacing) * sizeof(complexf)); - memcpy(&out[d_symSize - d_spacing], in, d_spacing * sizeof(complexf)); - in += d_spacing; - out += d_symSize; + // Data symbols + for (size_t i = 0; i < d_nbSymbols; ++i) { + // end - (symSize - spacing) = 2 * spacing - symSize + memcpy(out, &in[2 * d_spacing - d_symSize], + (d_symSize - d_spacing) * sizeof(complexf)); + memcpy(&out[d_symSize - d_spacing], in, d_spacing * sizeof(complexf)); + in += d_spacing; + out += d_symSize; + } } return sizeIn; } + +void GuardIntervalInserter::set_parameter( + const std::string& parameter, + const std::string& value) +{ + using namespace std; + stringstream ss(value); + ss.exceptions ( stringstream::failbit | stringstream::badbit ); + + if (parameter == "windowlen") { + size_t new_window_overlap = 0; + ss >> new_window_overlap; + update_window(new_window_overlap); + } + else { + stringstream ss_err; + ss_err << "Parameter '" << parameter << + "' is not exported by controllable " << get_rc_name(); + throw ParameterError(ss_err.str()); + } +} + +const std::string GuardIntervalInserter::get_parameter(const std::string& parameter) const +{ + using namespace std; + stringstream ss; + if (parameter == "windowlen") { + ss << d_windowOverlap; + } + else { + ss << "Parameter '" << parameter << + "' is not exported by controllable " << get_rc_name(); + throw ParameterError(ss.str()); + } + return ss.str(); +} diff --git a/src/GuardIntervalInserter.h b/src/GuardIntervalInserter.h index e6b3b64..b2ac782 100644 --- a/src/GuardIntervalInserter.h +++ b/src/GuardIntervalInserter.h @@ -1,6 +1,11 @@ /* Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Her Majesty the Queen in Right of Canada (Communications Research Center Canada) + + Copyright (C) 2017 + Matthias P. Braendli, matthias.braendli@mpb.li + + http://opendigitalradio.org */ /* This file is part of ODR-DabMod. @@ -26,26 +31,47 @@ #endif #include "ModPlugin.h" +#include "RemoteControl.h" #include +#include /* The GuardIntervalInserter prepends the cyclic prefix to all - * symbols in the transmission frame. */ -class GuardIntervalInserter : public ModCodec + * symbols in the transmission frame. + * + * If windowOverlap is non-zero, it will also add a cyclic suffix of + * that length, enlarge the cyclic prefix too, and make symbols + * overlap using a raised cosine window. + * */ +class GuardIntervalInserter : public ModCodec , public RemoteControllable { -public: - GuardIntervalInserter( - size_t nbSymbols, - size_t spacing, - size_t nullSize, - size_t symSize); - - int process(Buffer* const dataIn, Buffer* dataOut); - const char* name() { return "GuardIntervalInserter"; } - -protected: - size_t d_nbSymbols; - size_t d_spacing; - size_t d_nullSize; - size_t d_symSize; + public: + GuardIntervalInserter( + size_t nbSymbols, + size_t spacing, + size_t nullSize, + size_t symSize, + size_t windowOverlap = 0); + + int process(Buffer* const dataIn, Buffer* dataOut); + const char* name() { return "GuardIntervalInserter"; } + + /******* 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: + void update_window(size_t new_window_overlap); + + size_t d_nbSymbols; + size_t d_spacing; + size_t d_nullSize; + size_t d_symSize; + + mutable std::mutex d_windowMutex; + size_t d_windowOverlap; + std::vector d_window; }; -- cgit v1.2.3 From bbda6c46e5c322a32c2267da32b0150669174c12 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Sat, 23 Dec 2017 07:50:54 +0100 Subject: Rework OFDM windowing for data symbols --- src/GuardIntervalInserter.cpp | 85 +++++++++++++++++++++++++++---------------- src/GuardIntervalInserter.h | 2 +- 2 files changed, 55 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/GuardIntervalInserter.cpp b/src/GuardIntervalInserter.cpp index 1381a3c..14027d3 100644 --- a/src/GuardIntervalInserter.cpp +++ b/src/GuardIntervalInserter.cpp @@ -167,57 +167,80 @@ int GuardIntervalInserter::process(Buffer* const dataIn, Buffer* dataOut) // Data symbols for (size_t sym_ix = 0; sym_ix < d_nbSymbols; sym_ix++) { - // end = spacing - const size_t prefix_start_ix = 2*d_spacing - d_symSize - d_windowOverlap; - - // From out[-d_windowOverlap] to out[d_windowOverlap], we need to - // apply the window from 0 to 0.5, with our additional - // prefix, and add it to existing data. - for (size_t i = 0; i < 2*d_windowOverlap; i++) { - out[-i] += in[prefix_start_ix + i] * d_window[i]; + /* _ix variables are indices into in[], _ox variables are + * indices for out[] */ + const ssize_t start_rise_ox = -d_windowOverlap; + const size_t start_rise_ix = 2 * d_spacing - d_symSize - d_windowOverlap; + /* + const size_t start_real_symbol_ox = 0; + const size_t start_real_symbol_ix = 2 * d_spacing - d_symSize; + */ + const ssize_t end_rise_ox = d_windowOverlap; + const size_t end_rise_ix = 2 * d_spacing - d_symSize + d_windowOverlap; + const ssize_t end_cyclic_prefix_ox = d_symSize - d_spacing; + /* end_cyclic_prefix_ix = end of symbol + const size_t begin_fall_ox = d_symSize - d_windowOverlap; + const size_t begin_fall_ix = d_spacing - d_windowOverlap; + const size_t end_real_symbol_ox = d_symSize; + end_real_symbol_ix = end of symbol + const size_t end_fall_ox = d_symSize + d_windowOverlap; + const size_t end_fall_ix = d_spacing + d_windowOverlap; + */ + + ssize_t ox = start_rise_ox; + size_t ix = start_rise_ix; + + for (size_t i = 0; ix < end_rise_ix; i++) { + out[ox] += in[ix] * d_window.at(i); + ix++; + ox++; } + assert(ox == end_rise_ox); - const size_t remaining_prefix_length = d_symSize - d_spacing - d_windowOverlap; - - // After out[d_windowOverlap], no need to accumulate, we can copy. - memcpy( &out[d_windowOverlap], - &in[prefix_start_ix + 2*d_windowOverlap], + const size_t remaining_prefix_length = end_cyclic_prefix_ox - end_rise_ox; + memcpy( &out[ox], &in[ix], remaining_prefix_length * sizeof(complexf)); + ox += remaining_prefix_length; + assert(ox = end_cyclic_prefix_ox); + ix = 0; - const size_t prefixlength = d_symSize - d_spacing + d_windowOverlap; - - const bool last_symbol = (sym_ix + 1 < d_nbSymbols); + const bool last_symbol = (sym_ix + 1 >= d_nbSymbols); if (last_symbol) { // No windowing at all at end - memcpy(&out[prefixlength], in, d_spacing * sizeof(complexf)); + memcpy(&out[ox], &in[ix], d_spacing * sizeof(complexf)); + ox += d_spacing; } else { // Copy the middle part of the symbol, d_windowOverlap samples // short of the end. - memcpy( &out[prefixlength], - in, + memcpy( &out[ox], + &in[ix], (d_spacing - d_windowOverlap) * sizeof(complexf)); - - const size_t out_start = prefixlength + d_spacing - d_windowOverlap; - const size_t in_start = d_spacing - d_windowOverlap; + ox += d_spacing - d_windowOverlap; + ix += d_spacing - d_windowOverlap; + assert(ox == (ssize_t)(d_symSize - d_windowOverlap)); // Apply window from 1 to 0.5 for the end of the symbol - for (size_t i = 0; i < d_windowOverlap; i++) { - out[out_start + i] = - in[in_start + i] * d_window[2*d_windowOverlap - (i+1)]; + for (size_t i = 0; ox < (ssize_t)d_symSize; i++) { + out[ox] = in[ix] * d_window[2*d_windowOverlap - (i+1)]; + ox++; + ix++; } + assert(ix == d_spacing); - const size_t out_start_suffix = prefixlength + d_spacing; - + ix = 0; // Cyclic suffix, with window from 0.5 to 0 - for (size_t i = 0; i < d_windowOverlap; i++) { - out[out_start_suffix + i] = - in[i] * d_window[d_windowOverlap - (i+1)]; + for (size_t i = 0; ox < (ssize_t)(d_symSize + d_windowOverlap); i++) { + out[ox] = in[ix] * d_window[d_windowOverlap - (i+1)]; + ox++; + ix++; } + + assert(ix == d_windowOverlap); } - in += d_spacing; out += d_symSize; + in += d_spacing; // out is now pointing to the proper end of symbol. There are // d_windowOverlap samples ahead that were already written. } diff --git a/src/GuardIntervalInserter.h b/src/GuardIntervalInserter.h index b2ac782..7714c1a 100644 --- a/src/GuardIntervalInserter.h +++ b/src/GuardIntervalInserter.h @@ -42,7 +42,7 @@ * that length, enlarge the cyclic prefix too, and make symbols * overlap using a raised cosine window. * */ -class GuardIntervalInserter : public ModCodec , public RemoteControllable +class GuardIntervalInserter : public ModCodec, public RemoteControllable { public: GuardIntervalInserter( -- cgit v1.2.3 From 215e8143e3feefd69a76d0b6eaf36ed42a7a904f Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Sat, 23 Dec 2017 07:59:14 +0100 Subject: Add OFDM windowing to config file --- doc/example.ini | 7 +++++++ src/ConfigParser.cpp | 6 +++++- src/ConfigParser.h | 2 ++ src/DabModulator.cpp | 3 ++- 4 files changed, 16 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/doc/example.ini b/doc/example.ini index cf56720..d356ee1 100644 --- a/doc/example.ini +++ b/doc/example.ini @@ -128,6 +128,13 @@ rate=2048000 ; and ;dac_clk_rate=128000000 +; When nonzero, overlap ofdmwindowing samples from each OFDM symbol +; onto the previous and next symbol, using a raised cosine window function. +; This has the effect of smoothing the transition from one symbol to the next, +; which improves spectrum shape. +; In Transmission Mode I, every data symbol is composed of 2552 samples. +;ofdmwindowing=10 + ; Settings for crest factor reduction. Statistics for ratio of ; samples that were clipped are available through the RC. [cfr] diff --git a/src/ConfigParser.cpp b/src/ConfigParser.cpp index 1cc94c0..2c93a57 100644 --- a/src/ConfigParser.cpp +++ b/src/ConfigParser.cpp @@ -159,8 +159,12 @@ static void parse_configfile( mod_settings.dabMode = pt.get("modulator.mode", mod_settings.dabMode); mod_settings.clockRate = pt.get("modulator.dac_clk_rate", (size_t)0); - mod_settings.digitalgain = pt.get("modulator.digital_gain", mod_settings.digitalgain); + mod_settings.digitalgain = pt.get("modulator.digital_gain", + mod_settings.digitalgain); + mod_settings.outputRate = pt.get("modulator.rate", mod_settings.outputRate); + mod_settings.ofdmWindowOverlap = pt.get("modulator.ofdmwindowing", + mod_settings.ofdmWindowOverlap); // FIR Filter parameters: if (pt.get("firfilter.enabled", 0) == 1) { diff --git a/src/ConfigParser.h b/src/ConfigParser.h index a8d7837..0be3558 100644 --- a/src/ConfigParser.h +++ b/src/ConfigParser.h @@ -82,6 +82,8 @@ struct mod_settings_t { float cfrClip = 1.0f; float cfrErrorClip = 1.0f; + // Settings for the OFDM windowing + unsigned ofdmWindowOverlap = 0; #if defined(HAVE_OUTPUT_UHD) OutputUHDConfig outputuhd_conf; diff --git a/src/DabModulator.cpp b/src/DabModulator.cpp index cded280..0818f4f 100644 --- a/src/DabModulator.cpp +++ b/src/DabModulator.cpp @@ -201,7 +201,8 @@ int DabModulator::process(Buffer* dataOut) rcs.enrol(cifGain.get()); auto cifGuard = make_shared( - myNbSymbols, mySpacing, myNullSize, mySymSize); + myNbSymbols, mySpacing, myNullSize, mySymSize, + m_settings.ofdmWindowOverlap); rcs.enrol(cifGuard.get()); shared_ptr cifFilter; -- cgit v1.2.3 From 626cfba78e2885200450ff8b4f4cf09ff6d0b830 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Sun, 24 Dec 2017 04:06:10 +0100 Subject: Fix TII insertion for positive frequency carriers --- doc/example.ini | 8 ++++++-- src/TII.cpp | 15 ++------------- src/TII.h | 3 +++ 3 files changed, 11 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/doc/example.ini b/doc/example.ini index d356ee1..ec0525c 100644 --- a/doc/example.ini +++ b/doc/example.ini @@ -318,8 +318,12 @@ offset=0.002 ; DAB modes I and II are supported, and must be set explicitly in ; this file. Reading DAB mode from ETI is not supported. enable=0 -comb=16 -pattern=3 +; comb is also known as sub-identifier. +comb=1 +; pattern is also known as main-identifier. If you run several transmitters +; in SFN, it is better to use the same pattern for all, and vary the comb. +; Otherwise identification of the transmitters may be more difficult. +pattern=11 ; There are two variants of TII being used. The old variant that uses the wrong ; phase on the second carrier in each carrier pairs and is therefore not ; conforming to the specification. Modern analysers can decode both variants, diff --git a/src/TII.cpp b/src/TII.cpp index af64c9f..446d9c6 100644 --- a/src/TII.cpp +++ b/src/TII.cpp @@ -197,10 +197,6 @@ int TII::process(Buffer* dataIn, Buffer* dataOut) complexf* in = reinterpret_cast(dataIn->getData()); complexf* out = reinterpret_cast(dataOut->getData()); - if ((m_enabled_carriers.size() % 2) != 0) { - throw std::logic_error("odd number of enabled carriers"); - } - /* Normalise the TII carrier power according to ETSI TR 101 496-3 * Clause 5.4.2.2 Paragraph 7: * @@ -213,13 +209,10 @@ int TII::process(Buffer* dataIn, Buffer* dataOut) */ const float normalise_factor = 0.14433756729740644112f; // = 1/sqrt(48) - for (size_t i = 0; i < m_enabled_carriers.size(); i+=2) { + for (size_t i = 0; i < m_enabled_carriers.size(); i++) { // See header file for an explanation of the old variant if (m_enabled_carriers[i]) { out[i] = normalise_factor * (m_conf.old_variant ? in[i+1] : in[i]); - } - - if (m_enabled_carriers[i+1]) { out[i+1] = normalise_factor * in[i+1]; } } @@ -239,10 +232,6 @@ void TII::enable_carrier(int k) { } m_enabled_carriers[ix] = true; - // NULL frequency is never enabled. - if (ix > 1 and (ix-1 != 768)) { - m_enabled_carriers[ix-1] = true; - } } void TII::prepare_pattern() { @@ -287,7 +276,7 @@ void TII::prepare_pattern() { } } - for (int k = 384; k <= 768; k++) { + for (int k = 385; k <= 768; k++) { for (int b = 0; b < 8; b++) { if ( k == 385 + 2 * comb + 48 * b and pattern_tm1_2_4[m_conf.pattern][b]) { diff --git a/src/TII.h b/src/TII.h index fe67978..4c5c605 100644 --- a/src/TII.h +++ b/src/TII.h @@ -122,6 +122,9 @@ class TII : public ModCodec, public RemoteControllable // m_enabled_carriers is read by modulator thread, and written // to by RC thread. mutable boost::mutex m_enabled_carriers_mutex; + + // m_enabled_carriers is true only for the first carrier in the + // active pair std::vector m_enabled_carriers; }; -- cgit v1.2.3 From 2a199ca830cb1338b5c52ca5f147ebef26330d22 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Mon, 25 Dec 2017 05:08:14 +0100 Subject: Do not use out_of_range for multiplex reconfiguration error --- src/DabMod.cpp | 15 +++++++++------ src/FrameMultiplexer.cpp | 4 ++-- src/FrameMultiplexer.h | 10 ++++++++-- 3 files changed, 19 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/DabMod.cpp b/src/DabMod.cpp index dfefb53..b6f2dee 100644 --- a/src/DabMod.cpp +++ b/src/DabMod.cpp @@ -36,6 +36,7 @@ #include "InputMemory.h" #include "OutputFile.h" #include "FormatConverter.h" +#include "FrameMultiplexer.h" #if defined(HAVE_OUTPUT_UHD) # include "OutputUHD.h" #endif @@ -534,17 +535,19 @@ run_modulator_state_t run_modulator(modulator_data& m) running = 0; ret = run_modulator_state_t::normal_end; } - } catch (zmq_input_overflow& e) { + } + catch (const zmq_input_overflow& e) { // The ZeroMQ input has overflowed its buffer etiLog.level(warn) << e.what(); ret = run_modulator_state_t::again; - } catch (std::out_of_range& e) { - // One of the DSP blocks has detected an invalid change - // or value in some settings. This can be due to a multiplex - // reconfiguration. + } + catch (const FrameMultiplexerError& e) { + // The FrameMultiplexer saw an error or a change in the size of a + // subchannel. This can be due to a multiplex reconfiguration. etiLog.level(warn) << e.what(); ret = run_modulator_state_t::reconfigure; - } catch (std::exception& e) { + } + catch (const std::exception& e) { etiLog.level(error) << "Exception caught: " << e.what(); ret = run_modulator_state_t::failure; } diff --git a/src/FrameMultiplexer.cpp b/src/FrameMultiplexer.cpp index 4cee0b2..5dc6dca 100644 --- a/src/FrameMultiplexer.cpp +++ b/src/FrameMultiplexer.cpp @@ -74,7 +74,7 @@ int FrameMultiplexer::process(std::vector dataIn, Buffer* dataOut) // Write subchannel const auto subchannels = m_etiSource.getSubchannels(); if (subchannels.size() != dataIn.size() - 1) { - throw std::out_of_range( + throw FrameMultiplexerError( "FrameMultiplexer detected subchannel size change from " + std::to_string(dataIn.size() - 1) + " to " + std::to_string(subchannels.size())); @@ -82,7 +82,7 @@ int FrameMultiplexer::process(std::vector dataIn, Buffer* dataOut) auto subchannel = subchannels.begin(); while (in != dataIn.end()) { if ((*subchannel)->framesizeCu() * 8 != (*in)->getLength()) { - throw std::out_of_range( + throw FrameMultiplexerError( "FrameMultiplexer detected invalid subchannel size! " + std::to_string((*subchannel)->framesizeCu() * 8) + " != " + std::to_string((*in)->getLength())); diff --git a/src/FrameMultiplexer.h b/src/FrameMultiplexer.h index 680cdc7..4d68d88 100644 --- a/src/FrameMultiplexer.h +++ b/src/FrameMultiplexer.h @@ -38,12 +38,18 @@ #include +class FrameMultiplexerError : public std::runtime_error { + public: + FrameMultiplexerError(const char* msg) : + std::runtime_error(msg) {} + FrameMultiplexerError(const std::string& msg) : + std::runtime_error(msg) {} +}; class FrameMultiplexer : public ModMux { public: - FrameMultiplexer( - const EtiSource& etiSource); + FrameMultiplexer(const EtiSource& etiSource); int process(std::vector dataIn, Buffer* dataOut); const char* name() { return "FrameMultiplexer"; } -- cgit v1.2.3 From 515959935cd7c741db5aca5b20bfb7611749fbfb Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Mon, 25 Dec 2017 05:08:23 +0100 Subject: Fix Soapy warning --- src/OutputSoapy.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/OutputSoapy.cpp b/src/OutputSoapy.cpp index 3f8db88..699501c 100644 --- a/src/OutputSoapy.cpp +++ b/src/OutputSoapy.cpp @@ -253,10 +253,10 @@ void OutputSoapy::set_parameter(const string& parameter, const string& value) throw ParameterError("Parameter 'overflows' is read-only"); } else { - stringstream ss; - ss << "Parameter '" << parameter + stringstream ss_err; + ss_err << "Parameter '" << parameter << "' is not exported by controllable " << get_rc_name(); - throw ParameterError(ss.str()); + throw ParameterError(ss_err.str()); } } -- cgit v1.2.3